diff options
537 files changed, 64465 insertions, 289 deletions
@@ -33,3 +33,7 @@ images/*.* images/cache cache/html/* cache/*.lesscache + +.error.log +/FunnyQuestion.conf.php +/tmp diff --git a/FunnyQuestion.conf.php.sh b/FunnyQuestion.conf.php.sh new file mode 100755 index 00000000..1ca39d1a --- /dev/null +++ b/FunnyQuestion.conf.php.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +IP=$(realpath "$(dirname "$0")") + +cmd="date -u +%V\`uname\`|sha256sum|sed 's/\W//g'" +answer="$(eval "$cmd")" + +declare -A prompts +prompts[en]='What is the output of the command <tt>%s</tt>?' + +{ + echo '<?php' + echo -n '$wgFunnyQuestions = array(' + + nl='\n' + for lang in "${!prompts[@]}"; do + printf "${nl}\t\"${lang}\" => array(\"${prompts[$lang]}\" => \"%s\")" "$cmd" "$answer" + nl=',\n' + done + + echo + echo ');' +} > "$IP/FunnyQuestion.conf.php" + +touch "$IP/extensions/FunnyQuestion/FunnyQuestion.i18n.php" diff --git a/extensions/ArchInterWiki.sql b/extensions/ArchInterWiki.sql deleted file mode 100644 index 908e5bbe..00000000 --- a/extensions/ArchInterWiki.sql +++ /dev/null @@ -1,109 +0,0 @@ -/* - * This script is intended to populate the interwiki table with entries useful - * for ArchWiki. - * - * Before deleting interwiki links, remove them from the articles. - * - * In order to find all the interlanguage links of a particular language, you - * need to do an API search, e.g. - * https://wiki.archlinux.org/api.php?action=query&list=langbacklinks&lbllimit=max&lblprop=lltitle&lbllang=de - * This example uses German ('de'), but for the other languages it is enough to - * change the value of 'lbllang' to the needed language tag. - * - * Interwiki links using a specific prefix can be found similarly, for example: - * https://wiki.archlinux.org/api.php?action=query&list=iwbacklinks&iwbllimit=max&iwblprop=iwtitle&iwblprefix=wikipedia - * This example uses 'wikipedia', but for other interwiki prefixes it is enough - * to change the value of 'iwblprefix' accordingly. - * - * Note that API queries are always limited, so if given interwiki prefix has - * more than 500 (or 5000 if you have the 'apihighlimits' right) backlinks, it - * will be necessary to continue the search as described in - * https://www.mediawiki.org/wiki/API:Query#Continuing_queries - * - * Also note that such queries do not find (all) interwiki redirects, if - * present. A search like this should do the job instead: - * https://wiki.archlinux.org/index.php?title=Special%3ASearch&profile=advanced&limit=500&offset=0&search=%22redirect%20%5B%5Bde%3A%22&fulltext=Search&ns0=1&ns1=1&ns2=1&ns3=1&ns4=1&ns5=1&ns6=1&ns7=1&ns8=1&ns9=1&ns10=1&ns11=1&ns12=1&ns13=1&ns14=1&ns15=1&redirs=1&profile=advanced - */ - --- Clear the table, we don't want the entries from maintenance/interwiki.sql -DELETE FROM interwiki; - --- Arch's interlanguage prefixes -INSERT INTO - interwiki (iw_prefix, iw_url, iw_local, iw_trans) -VALUES - ('ar', 'https://wiki.archlinux.org/index.php/$1_(%D8%A7%D9%84%D8%B9%D8%B1%D8%A8%D9%8A%D8%A9)', 1, 0), - ('bg', 'https://wiki.archlinux.org/index.php/$1_(%D0%91%D1%8A%D0%BB%D0%B3%D0%B0%D1%80%D1%81%D0%BA%D0%B8)', 1, 0), - ('cs', 'https://wiki.archlinux.org/index.php/$1_(%C4%8Cesky)', 1, 0), - ('da', 'https://wiki.archlinux.org/index.php/$1_(Dansk)', 1, 0), - ('de', 'https://wiki.archlinux.de/title/$1', 1, 0), - ('el', 'https://wiki.archlinux.org/index.php/$1_(%CE%95%CE%BB%CE%BB%CE%B7%CE%BD%CE%B9%CE%BA%CE%AC)', 1, 0), - ('en', 'https://wiki.archlinux.org/index.php/$1', 1, 0), - ('es', 'https://wiki.archlinux.org/index.php/$1_(Espa%C3%B1ol)', 1, 0), - ('fa', 'http://wiki.archusers.ir/index.php/$1', 1, 0), - ('fi', 'http://www.archlinux.fi/wiki/$1', 1, 0), - ('fr', 'http://wiki.archlinux.fr/$1', 1, 0), - ('he', 'https://wiki.archlinux.org/index.php/$1_(%D7%A2%D7%91%D7%A8%D7%99%D7%AA)', 1, 0), - ('hr', 'https://wiki.archlinux.org/index.php/$1_(Hrvatski)', 1, 0), - ('hu', 'https://wiki.archlinux.org/index.php/$1_(Magyar)', 1, 0), - ('id', 'https://wiki.archlinux.org/index.php/$1_(Indonesia)', 1, 0), - ('it', 'https://wiki.archlinux.org/index.php/$1_(Italiano)', 1, 0), - ('ja', 'https://wiki.archlinuxjp.org/index.php/$1', 1, 0), - ('ko', 'https://wiki.archlinux.org/index.php/$1_(%ED%95%9C%EA%B5%AD%EC%96%B4)', 1, 0), - ('lt', 'https://wiki.archlinux.org/index.php/$1_(Lietuvi%C5%A1kai)', 1, 0), - ('nl', 'https://wiki.archlinux.org/index.php/$1_(Nederlands)', 1, 0), - ('pl', 'https://wiki.archlinux.org/index.php/$1_(Polski)', 1, 0), - ('pt', 'https://wiki.archlinux.org/index.php/$1_(Portugu%C3%AAs)', 1, 0), - ('ro', 'http://wiki.archlinux.ro/index.php/$1', 1, 0), - ('ru', 'https://wiki.archlinux.org/index.php/$1_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9)', 1, 0), - ('sk', 'https://wiki.archlinux.org/index.php/$1_(Slovensk%C3%BD)', 1, 0), - ('sr', 'https://wiki.archlinux.org/index.php/$1_(%D0%A1%D1%80%D0%BF%D1%81%D0%BA%D0%B8)', 1, 0), - ('sv', 'http://wiki.archlinux.se/index.php?title=$1', 1, 0), - ('th', 'https://wiki.archlinux.org/index.php/$1_(%E0%B9%84%E0%B8%97%E0%B8%A2)', 1, 0), - ('tr', 'http://archtr.org/wiki/index.php?title=$1', 1, 0), - ('uk', 'https://wiki.archlinux.org/index.php/$1_(%D0%A3%D0%BA%D1%80%D0%B0%D1%97%D0%BD%D1%81%D1%8C%D0%BA%D0%B0)', 1, 0), - ('zh-cn', 'https://wiki.archlinux.org/index.php/$1_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)', 1, 0), - ('zh-tw', 'https://wiki.archlinux.org/index.php/$1_(%E6%AD%A3%E9%AB%94%E4%B8%AD%E6%96%87)', 1, 0); - --- Other interwiki prefixes -INSERT INTO interwiki (iw_prefix,iw_url,iw_local,iw_api) VALUES -('arxiv','http://www.arxiv.org/abs/$1',0,''), -('debian','https://wiki.debian.org/$1',0,''), -('doi','http://dx.doi.org/$1',0,''), -('emacswiki','http://www.emacswiki.org/cgi-bin/wiki.pl?$1',0,''), -('foldoc','http://foldoc.org/?$1',0,''), -('freebsdman','http://www.freebsd.org/cgi/man.cgi?query=$1',0,''), -('funtoo','http://www.funtoo.org/$1',0,'http://www.funtoo.org/api.php'), -('gentoo','https://wiki.gentoo.org/wiki/$1',0,'https://wiki.gentoo.org/api.php'), -('gregswiki','http://mywiki.wooledge.org/$1',0,''), -('linuxwiki','http://linuxwiki.de/$1',0,''), -('lqwiki','http://wiki.linuxquestions.org/wiki/$1',0,''), -('mozillawiki','http://wiki.mozilla.org/$1',0,'https://wiki.mozilla.org/api.php'), -('rfc','http://www.rfc-editor.org/rfc/rfc$1.txt',0,''), -('sourceforge','http://sourceforge.net/$1',0,''), -('wikia','http://www.wikia.com/wiki/$1',0,'') -; - --- Wikimedia Foundation projects and related --- based on this table: https://meta.wikimedia.org/wiki/Help:Interwiki_linking#Project_titles_and_shortcuts -INSERT INTO interwiki (iw_prefix,iw_url,iw_local,iw_api) VALUES -('wikipedia','https://en.wikipedia.org/wiki/$1',0,'https://en.wikipedia.org/w/api.php'), -('w','https://en.wikipedia.org/wiki/$1',0,'https://en.wikipedia.org/w/api.php'), -('wiktionary','https://en.wiktionary.org/wiki/$1',0,'https://en.wiktionary.org/w/api.php'), -('wikt','https://en.wiktionary.org/wiki/$1',0,'https://en.wiktionary.org/w/api.php'), -('wikinews','https://en.wikinews.org/wiki/$1',0,'https://en.wikinews.org/w/api.php'), -('wikibooks','https://en.wikibooks.org/wiki/$1',0,'https://en.wikibooks.org/w/api.php'), -('wikiquote','https://en.wikiquote.org/wiki/$1',0,'https://en.wikiquote.org/w/api.php'), -('wikisource','https://wikisource.org/wiki/$1',0,'https://wikisource.org/w/api.php'), -('wikispecies','https://species.wikimedia.org/wiki/$1',0,'https://species.wikimedia.org/w/api.php'), -('wikiversity','https://en.wikiversity.org/wiki/$1',0,'https://en.wikiversity.org/w/api.php'), -('wikivoyage','https://en.wikivoyage.org/wiki/$1',0,'https://en.wikivoyage.org/w/api.php'), -('wikimedia','https://wikimediafoundation.org/wiki/$1',0,'https://wikimediafoundation.org/w/api.php'), -('wmf','https://wikimediafoundation.org/wiki/$1',0,'https://wikimediafoundation.org/w/api.php'), -('commons','https://commons.wikimedia.org/wiki/$1',0,'https://commons.wikimedia.org/w/api.php'), -('metawikimedia','https://meta.wikimedia.org/wiki/$1',0,'https://meta.wikimedia.org/w/api.php'), -('meta','https://meta.wikimedia.org/wiki/$1',0,'https://meta.wikimedia.org/w/api.php'), -('mw','https://www.mediawiki.org/wiki/$1',0,'https://www.mediawiki.org/w/api.php'), -('phabricator','https://phabricator.wikimedia.org/$1',0,''), -('phab','https://phabricator.wikimedia.org/$1',0,'') -; diff --git a/extensions/FluxBBAuthPlugin.php b/extensions/FluxBBAuthPlugin.php deleted file mode 100644 index 32d4b145..00000000 --- a/extensions/FluxBBAuthPlugin.php +++ /dev/null @@ -1,153 +0,0 @@ -<?php - -$wgExtensionCredits['other'][] = array( - 'name' => 'FluxBBAuthPlugin', - 'version' => '1.6', - 'description' => 'Use FluxBB accounts in MediaWiki', - 'author' => 'Pierre Schmitz', - 'url' => 'https://pierre-schmitz.com/' -); - -require_once(__DIR__.'/../includes/AuthPlugin.php'); - -global $FluxBBDatabase; -$FluxBBDatabase = 'fluxbb'; - -class FluxBBAuthPlugin extends AuthPlugin { - - public static function isValidPassword($password) { - $length = strlen($password); - return $length >= 4; - } - - private function getUserData($username) { - global $FluxBBDatabase; - $dbr = wfGetDB( DB_SLAVE ); - - return $dbr->selectRow($FluxBBDatabase.'.users', array('username', 'email', 'realname'), array('username' => $username)); - } - - public function userExists( $username ) { - global $FluxBBDatabase; - $dbr = wfGetDB( DB_SLAVE ); - - try { - $result = $dbr->select($FluxBBDatabase.'.users', 'id', array('username' => $username)); - $exists = ($result->numRows() > 0 ? true : false); - $result->free(); - } catch (DBQueryError $e) { - $exists = false; - } - - return $exists; - } - - public function authenticate( $username, $password ) { - global $FluxBBDatabase; - $dbr = wfGetDB( DB_SLAVE ); - - try { - $result = $dbr->select($FluxBBDatabase.'.users', 'id', array('username' => $username, 'password' => sha1($password))); - $authenticated = ($result->numRows() > 0 ? true : false); - $result->free(); - } catch (DBQueryError $e) { - $authenticated = false; - } - - return $authenticated; - } - - public function modifyUITemplate( &$template, &$type ) { - $template->set( 'usedomain', false ); - } - - public function updateUser( &$user ) { - return $this->initUser($user); - } - - public function autoCreate() { - return true; - } - - protected function allowRealNameChange() { - return false; - } - - protected function allowEmailChange() { - return false; - } - - protected function allowNickChange() { - return false; - } - - public function allowPasswordChange() { - return false; - } - - public function allowSetLocalPassword() { - return false; - } - - public function setPassword( $user, $password ) { - return false; - } - - public function updateExternalDB( $user ) { - return false; - } - - public function updateExternalDBGroups( $user, $addgroups, $delgroups = array() ) { - return false; - } - - public function canCreateAccounts() { - return false; - } - - public function addUser( $user, $password, $email = '', $realname = '' ) { - return false; - } - - public function strict() { - return true; - } - - public function strictUserAuth( $username ) { - return true; - } - - public function initUser( &$user, $autocreate = false ) { - try { - $data = $this->getUserData($user->getName()); - if (!$data) { - return false; - } - $user->setEmail($data->email); - $user->confirmEmail(); - $user->setRealName($data->realname); - $user->saveSettings(); - } catch (Exception $e) { - return false; - } - return true; - } - - public function getCanonicalName( $username ) { - try { - $data = $this->getUserData($username); - if ($data !== false) { - return strtoupper(substr($data->username, 0, 1)).substr($data->username, 1); - } - } catch (Exception $e) { - } - return $username; - } - -} - -$wgAuth = new FluxBBAuthPlugin(); -$wgHiddenPrefs[] = 'realname'; -$wgHooks['isValidPassword'][] = 'FluxBBAuthPlugin::isValidPassword'; - -?> diff --git a/extensions/TimedMediaHandler/.gitignore b/extensions/TimedMediaHandler/.gitignore new file mode 100644 index 00000000..0172e092 --- /dev/null +++ b/extensions/TimedMediaHandler/.gitignore @@ -0,0 +1,6 @@ +.svn +*~ +*.kate-swp +.*.swp +.project +node_modules/ diff --git a/extensions/TimedMediaHandler/.gitreview b/extensions/TimedMediaHandler/.gitreview new file mode 100644 index 00000000..39e4aad6 --- /dev/null +++ b/extensions/TimedMediaHandler/.gitreview @@ -0,0 +1,5 @@ +[gerrit] +host=gerrit.wikimedia.org +port=29418 +project=mediawiki/extensions/TimedMediaHandler.git +defaultbranch=REL1_26 diff --git a/extensions/TimedMediaHandler/.jscsrc b/extensions/TimedMediaHandler/.jscsrc new file mode 100644 index 00000000..9d22e3f2 --- /dev/null +++ b/extensions/TimedMediaHandler/.jscsrc @@ -0,0 +1,3 @@ +{ + "preset": "wikimedia" +} diff --git a/extensions/TimedMediaHandler/.jshintignore b/extensions/TimedMediaHandler/.jshintignore new file mode 100644 index 00000000..0f77f29d --- /dev/null +++ b/extensions/TimedMediaHandler/.jshintignore @@ -0,0 +1 @@ +MwEmbedModules diff --git a/extensions/TimedMediaHandler/.jshintrc b/extensions/TimedMediaHandler/.jshintrc new file mode 100644 index 00000000..ef363f81 --- /dev/null +++ b/extensions/TimedMediaHandler/.jshintrc @@ -0,0 +1,44 @@ +{ + /* Common */ + + // Enforcing + "camelcase": true, + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": true, + "newcap": true, + "noarg": true, + "noempty": true, + "nonew": true, + "quotmark": "single", + "trailing": true, + "undef": true, + "unused": true, + // Legacy + "onevar": true, + + /* Local */ + + // Enforcing + "bitwise": true, + "es3": true, + // Relaxing + "laxbreak": true, + "smarttabs": true, + "multistr": true, + // Environment + "browser": true, + // Legacy + "nomen": true, + + "predef": [ + "mediaWiki", + "mw", + "jQuery", + "OGVVersion", + "OGVSupport", + "OGVPlayer", + "OGVLoader" + ] +} diff --git a/extensions/TimedMediaHandler/ApiQueryVideoInfo.php b/extensions/TimedMediaHandler/ApiQueryVideoInfo.php new file mode 100644 index 00000000..65239166 --- /dev/null +++ b/extensions/TimedMediaHandler/ApiQueryVideoInfo.php @@ -0,0 +1,268 @@ +<?php +/** + * Extends imageinfo with support for videoinfo sources property. + * + * Alternatively core ApiQueryImageInfo could support being extended in some straightforward ways. + * see: http://www.mediawiki.org/wiki/User:Catrope/Extension_review/TimedMediaHandler#ApiQueryVideoInfo.php + * + */ + +if ( !defined( 'MEDIAWIKI' ) ) { + // Eclipse helper - will be ignored in production + require_once( "ApiBase.php" ); +} + +class ApiQueryVideoInfo extends ApiQueryImageInfo { + + public function __construct( $query, $moduleName, $prefix = 'vi' ) { + // We allow a subclass to override the prefix, to create a related API module. + // Some other parts of MediaWiki construct this with a null $prefix, which used to be ignored when this only took two arguments + if ( is_null( $prefix ) ) { + $prefix = 'vi'; + } + parent::__construct( $query, $moduleName, $prefix ); + } + + /** + * @deprecated since MediaWiki core 1.25 + */ + public function getDescription() { + return 'Extends imageinfo to include video source (derivatives) information'; + } + + static function getInfo( $file, $prop, $result, $thumbParams = null, $version = 'latest' ) { + $vals = parent::getInfo( $file, $prop, $result, $thumbParams ); + if( isset( $prop['derivatives'] ) ) { + if ( $file->getHandler() && $file->getHandler() instanceof TimedMediaHandler ) { + $vals['derivatives'] = WebVideoTranscode::getSources( $file, array( 'fullurl') ); + $result->setIndexedTagName( $vals['derivatives'], "derivative" ); + } else { + // Non-TMH file, no derivatives. + $vals['derivatives'] = array(); + } + } + return $vals; + } + + public static function getPropertyNames( $filter = array() ) { + $prop = parent::getPropertyNames(); + $prop[] = 'derivatives'; + return $prop; + } + + public static function getPropertyDescriptions( $filter = array(), $modulePrefix = '' ) { + $s = parent::getPropertyDescriptions( $filter, $modulePrefix ); + $s[] = ' derivatives - Adds an array of the different format and quality versions of an audio or video file that are available.'; + return $s; + } + + /** + * @deprecated since MediaWiki core 1.25 + */ + public function getExamples() { + return array( + 'api.php?action=query&titles=File:Folgers.ogv&prop=videoinfo', + ); + } + + /** + * @see ApiBase::getExamplesMessages() + */ + protected function getExamplesMessages() { + return array( + 'action=query&titles=File:Folgers.ogv&prop=videoinfo' + => 'apihelp-query+videoinfo-example-1', + ); + } + + /** + * Execute and getAllowedprops have to be copied verbatim because of static self:: references + * + * With late static binding this would be avoidable: + * http://php.net/manual/en/language.oop5.late-static-bindings.php + */ + public function execute() { + $params = $this->extractRequestParams(); + + $prop = array_flip( $params['prop'] ); + + $scale = $this->getScale( $params ); + + $pageIds = $this->getPageSet()->getAllTitlesByNamespace(); + if ( !empty( $pageIds[NS_FILE] ) ) { + $titles = array_keys( $pageIds[NS_FILE] ); + asort( $titles ); // Ensure the order is always the same + + $skip = false; + if ( !is_null( $params['continue'] ) ) { + $skip = true; + $cont = explode( '|', $params['continue'] ); + if ( count( $cont ) != 2 ) { + $this->dieUsage( 'Invalid continue param. You should pass the original ' . + 'value returned by the previous query', '_badcontinue' ); + } + $fromTitle = strval( $cont[0] ); + $fromTimestamp = $cont[1]; + // Filter out any titles before $fromTitle + foreach ( $titles as $key => $title ) { + if ( $title < $fromTitle ) { + unset( $titles[$key] ); + } else { + break; + } + } + } + + $result = $this->getResult(); + $images = RepoGroup::singleton()->findFiles( $titles ); + foreach ( $images as $img ) { + // Skip redirects + if ( $img->getOriginalTitle()->isRedirect() ) { + continue; + } + + $start = $skip ? $fromTimestamp : $params['start']; + $pageId = $pageIds[NS_IMAGE][ $img->getOriginalTitle()->getDBkey() ]; + + $fit = $result->addValue( + array( 'query', 'pages', intval( $pageId ) ), + 'imagerepository', $img->getRepoName() + ); + if ( !$fit ) { + if ( count( $pageIds[NS_IMAGE] ) == 1 ) { + // The user is screwed. imageinfo can't be solely + // responsible for exceeding the limit in this case, + // so set a query-continue that just returns the same + // thing again. When the violating queries have been + // out-continued, the result will get through + $this->setContinueEnumParameter( 'start', + wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) ); + } else { + $this->setContinueEnumParameter( 'continue', + $this->getContinueStr( $img ) ); + } + break; + } + + // Check if we can make the requested thumbnail, and get transform parameters. + $finalThumbParams = $this->mergeThumbParams( $img, $scale, $params['urlparam'] ); + + // Get information about the current version first + // Check that the current version is within the start-end boundaries + $gotOne = false; + if ( + ( is_null( $start ) || $img->getTimestamp() <= $start ) && + ( is_null( $params['end'] ) || $img->getTimestamp() >= $params['end'] ) + ) { + $gotOne = true; + + $fit = $this->addPageSubItem( $pageId, + self::getInfo( $img, $prop, $result, $finalThumbParams ) ); + if ( !$fit ) { + if ( count( $pageIds[NS_IMAGE] ) == 1 ) { + // See the 'the user is screwed' comment above + $this->setContinueEnumParameter( 'start', + wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) ); + } else { + $this->setContinueEnumParameter( 'continue', + $this->getContinueStr( $img ) ); + } + break; + } + } + + // Now get the old revisions + // Get one more to facilitate query-continue functionality + $count = ( $gotOne ? 1 : 0 ); + $oldies = $img->getHistory( $params['limit'] - $count + 1, $start, $params['end'] ); + foreach ( $oldies as $oldie ) { + if ( ++$count > $params['limit'] ) { + // We've reached the extra one which shows that there are additional pages to be had. Stop here... + // Only set a query-continue if there was only one title + if ( count( $pageIds[NS_FILE] ) == 1 ) { + $this->setContinueEnumParameter( 'start', + wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) ); + } + break; + } + $fit = $this->addPageSubItem( $pageId, + self::getInfo( $oldie, $prop, $result, $finalThumbParams ) ); + if ( !$fit ) { + if ( count( $pageIds[NS_IMAGE] ) == 1 ) { + $this->setContinueEnumParameter( 'start', + wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) ); + } else { + $this->setContinueEnumParameter( 'continue', + $this->getContinueStr( $oldie ) ); + } + break; + } + } + if ( !$fit ) { + break; + } + $skip = false; + } + + if ( defined( 'ApiResult::META_CONTENT' ) ) { + $pages = (array)$this->getResult()->getResultData( array( 'query', 'pages' ), array( 'Strip' => 'base' ) ); + } else { + $data = $this->getResultData(); + $pages = $data['query']['pages']; + } + foreach ( $pages as $pageid => $arr ) { + if ( !isset( $arr['imagerepository'] ) ) { + $result->addValue( + array( 'query', 'pages', intval( $pageid ) ), + 'imagerepository', '' + ); + } + // The above can't fail because it doesn't increase the result size + } + } + } + + public function getAllowedParams() { + // Get imageinfo params + $params = array_intersect_key( + parent::getAllowedParams(), + array_flip( array( + 'limit', 'start', 'end', 'urlwidth', 'urlheight', 'urlparam', 'continue' + ) ) + ); + if ( defined( 'ApiBase::PARAM_HELP_MSG' ) ) { + foreach ( $params as $k => $v ) { + if ( !isset( $params[$k][ApiBase::PARAM_HELP_MSG] ) ) { + $params[$k][ApiBase::PARAM_HELP_MSG] = "apihelp-query+imageinfo-param-$k"; + } + } + } + + // Add our param + $params = array( + 'prop' => array( + ApiBase::PARAM_ISMULTI => true, + ApiBase::PARAM_DFLT => 'timestamp|user', + ApiBase::PARAM_TYPE => self::getPropertyNames(), + ), + ) + $params; + + return $params; + } + + /** + * Get API self-documentation. + * + * Needed since core calls self::getPropertyDescriptions(), + * (and not static::getPropertyDescriptions() ) which binds + * to the static method in that class instead of the static + * method of the same name in this class. + * @deprecated since MediaWiki core 1.25 + */ + public function getParamDescription() { + $params = parent::getParamDescription(); + $p = $this->getModulePrefix(); + $params['prop'] = self::getPropertyDescriptions( array(), $p ); + return $params; + } +} diff --git a/extensions/TimedMediaHandler/ApiTranscodeReset.php b/extensions/TimedMediaHandler/ApiTranscodeReset.php new file mode 100644 index 00000000..597d17e1 --- /dev/null +++ b/extensions/TimedMediaHandler/ApiTranscodeReset.php @@ -0,0 +1,184 @@ +<?php +if ( !defined( 'MEDIAWIKI' ) ) { + // Eclipse helper - will be ignored in production + require_once( 'ApiBase.php' ); +} + +/** + * Allows users with the 'transcode-reset' right to reset / re-run a transcode job. + * + * You can specify must specify a media asset title. You optionally can specify + * a transcode key, to only reset a single transcode job for a particular media asset. + * @ingroup API + */ +class ApiTranscodeReset extends ApiBase { + public function execute() { + global $wgUser, $wgEnableTranscode, $wgWaitTimeForTranscodeReset; + // Check if transcoding is enabled on this wiki at all: + if( !$wgEnableTranscode ){ + $this->dieUsage( 'Transcode is disabled on this wiki', 'disabledtranscode' ); + } + + // Confirm the user has the transcode-reset right + if( !$wgUser->isAllowed( 'transcode-reset' ) ){ + $this->dieUsage( 'You don\'t have permission to reset transcodes', 'missingpermission' ); + } + $params = $this->extractRequestParams(); + + // Make sure we have a valid Title + $titleObj = Title::newFromText( $params['title'] ); + if ( !$titleObj || $titleObj->isExternal() ) { + $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) ); + } + // Make sure the title can be transcoded + if( !TimedMediaHandlerHooks::isTranscodableTitle( $titleObj ) ){ + $this->dieUsageMsg( array( 'invalidtranscodetitle', $params['title'] ) ); + } + $transcodeKey = false; + // Make sure its a enabled transcode key we are trying to remove: + // ( if you update your transcode keys the api is not how you purge the database of expired keys ) + if( isset( $params['transcodekey'] ) ){ + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet; + $transcodeSet = array_merge($wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet); + if( !in_array( $params['transcodekey'], $transcodeSet ) ){ + $this->dieUsage( 'Invalid or disabled transcode key: ' . htmlspecialchars( $params['transcodekey'] ) , 'badtranscodekey' ); + } else { + $transcodeKey = $params['transcodekey']; + } + } + + // Don't reset if less than 1 hour has passed and we have no error ) + $file = wfFindFile( $titleObj ); + $timeSinceLastReset = self::checkTimeSinceLastRest( $file, $transcodeKey ); + if( $timeSinceLastReset < $wgWaitTimeForTranscodeReset){ + $this->dieUsage( 'Not enough time has passed since the last reset of this transcode. ' . + TimedMediaHandler::getTimePassedMsg( $wgWaitTimeForTranscodeReset - $timeSinceLastReset ) . + ' until this transcode can be reset', 'notenoughtimereset'); + } + + // All good do the transcode removal: + WebVideoTranscode::removeTranscodes( $file, $transcodeKey ); + + // Oh and we wanted to reset it, right? Trigger again. + WebVideoTranscode::updateJobQueue( $file, $transcodeKey ); + + $this->getResult()->addValue(null, 'success', 'removed transcode'); + } + + /** + * @param $file + * @param $transcodeKey + * @return int|string + */ + static public function checkTimeSinceLastRest( $file, $transcodeKey ){ + global $wgWaitTimeForTranscodeReset; + $transcodeStates = WebVideoTranscode::getTranscodeState( $file ); + if( $transcodeKey ){ + if( ! $transcodeStates[$transcodeKey] ){ + // transcode key not found + return $wgWaitTimeForTranscodeReset + 1; + } + return self::getStateResetTime( $transcodeStates[$transcodeKey] ); + } + // least wait is set to reset time: + $leastWait = $wgWaitTimeForTranscodeReset + 1; + // else check for lowest reset time + foreach($transcodeStates as $state ){ + $ctime = self::getStateResetTime( $state ); + if( $ctime < $leastWait){ + $leastWait = $ctime; + } + } + return $leastWait; + } + + /** + * @param $state + * @return int|string + */ + static public function getStateResetTime( $state ){ + global $wgWaitTimeForTranscodeReset; + $db = wfGetDB( DB_SLAVE ); + // if an error return waitTime +1 + if( !is_null( $state['time_error']) ){ + return $wgWaitTimeForTranscodeReset + 1; + } + // return wait time from most recent event + foreach( array( 'time_success', 'time_startwork', 'time_addjob' ) as $timeField ){ + if( !is_null( $state[ $timeField ] )){ + return $db->timestamp() - $db->timestamp( $state[ $timeField ] ); + } + } + // No time info, return resetWaitTime + return $wgWaitTimeForTranscodeReset + 1; + } + + public function mustBePosted() { + return true; + } + + public function isWriteMode() { + return true; + } + + /** + * @deprecated since MediaWiki core 1.25 + */ + protected function getDescription() { + return 'Users with the \'transcode-reset\' right can reset and re-run a transcode job'; + } + + protected function getAllowedParams() { + return array( + 'title' => array( + ApiBase::PARAM_TYPE => 'string', + ApiBase::PARAM_REQUIRED => true + ), + 'transcodekey' => null, + 'token' => null, + ); + } + + /** + * @deprecated since MediaWiki core 1.25 + */ + protected function getParamDescription() { + return array( + 'title' => 'The media file title', + 'transcodekey' => 'The transcode key you wish to reset', + 'token' => 'An edit token obtained via action=tokens', + ); + } + + public function needsToken() { + return 'csrf'; + } + + public function getTokenSalt() { + return ''; + } + + /** + * @deprecated since MediaWiki core 1.25 + */ + protected function getExamples() { + return array( + 'Reset all transcodes for Clip.webm :', + ' api.php?action=transcodereset&title=File:Clip.webm&token=%2B\\', + 'Reset the \'360_560kbs.webm\' transcode key for clip.webm. Get a list of transcode keys via a \'transcodestatus\' query', + ' api.php?action=transcodereset&title=File:Clip.webm&transcodekey=360_560kbs.webm&token=%2B\\', + ); + } + + /** + * @see ApiBase::getExamplesMessages() + */ + protected function getExamplesMessages() { + return array( + 'action=transcodereset&title=File:Clip.webm&token=123ABC' + => 'apihelp-transcodereset-example-1', + 'action=transcodereset&title=File:Clip.webm&transcodekey=360_560kbs.webm&token=123ABC' + => 'apihelp-transcodereset-example-2', + ); + } +} diff --git a/extensions/TimedMediaHandler/ApiTranscodeStatus.php b/extensions/TimedMediaHandler/ApiTranscodeStatus.php new file mode 100644 index 00000000..38dcccc6 --- /dev/null +++ b/extensions/TimedMediaHandler/ApiTranscodeStatus.php @@ -0,0 +1,79 @@ +<?php +/** + * Allows for api queries to get detailed information about the transcode state of a particular + * media asset. ( basically directly returns the transcode status table ) + * + * This information can be used to generate status tables similar to the one seen + * on the image page. + */ + +if ( !defined( 'MEDIAWIKI' ) ) { + // Eclipse helper - will be ignored in production + require_once( "ApiBase.php" ); +} + +class ApiTranscodeStatus extends ApiQueryBase { + public function execute() { + $pageIds = $this->getPageSet()->getAllTitlesByNamespace(); + // Make sure we have files in the title set: + if ( !empty( $pageIds[NS_FILE] ) ) { + $titles = array_keys( $pageIds[NS_FILE] ); + asort( $titles ); // Ensure the order is always the same + + $result = $this->getResult(); + $images = RepoGroup::singleton()->findFiles( $titles ); + /** + * @var $img File + */ + foreach ( $images as $img ) { + // if its a "transcode" add the transcode status table output + if( TimedMediaHandlerHooks::isTranscodableTitle( $img->getTitle() ) ){ + $transcodeStatus = WebVideoTranscode::getTranscodeState( $img ); + // remove useless properties + foreach($transcodeStatus as $key=>&$val ){ + unset( $val['id'] ); + unset( $val['image_name']); + unset( $val['key'] ); + } + $result->addValue( array( 'query', 'pages', $img->getTitle()->getArticleID() ), 'transcodestatus', $transcodeStatus ); + } + } + } + } + + public function getCacheMode( $params ) { + return 'public'; + } + + public function getAllowedParams() { + return array(); + } + + /** + * @deprecated since MediaWiki core 1.25 + */ + public function getDescription() { + return array( + 'Get transcode status for a given file page' + ); + } + + /** + * @deprecated since MediaWiki core 1.25 + */ + protected function getExamples() { + return array ( + 'api.php?action=query&prop=transcodestatus&titles=File:Clip.webm', + ); + } + + /** + * @see ApiBase::getExamplesMessages() + */ + protected function getExamplesMessages() { + return array( + 'action=query&prop=transcodestatus&titles=File:Clip.webm' + => 'apihelp-query+transcodestatus-example-1', + ); + } +} diff --git a/extensions/TimedMediaHandler/COPYING b/extensions/TimedMediaHandler/COPYING new file mode 100644 index 00000000..019694a9 --- /dev/null +++ b/extensions/TimedMediaHandler/COPYING @@ -0,0 +1,342 @@ +== GNU GENERAL PUBLIC LICENSE == + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +=== Preamble === + +The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + +We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and +modification follow. + +== TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION == + +'''0.''' This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +'''1.''' You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +'''2.''' You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + '''a)''' You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + '''b)''' You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + '''c)''' If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +'''3.''' You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + '''a)''' Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + '''b)''' Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + '''c)''' Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +'''4.''' You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +'''5.''' You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +'''6.''' Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +'''7.''' If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +'''8.''' If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +'''9.''' The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +'''10.''' If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +=== NO WARRANTY === + +'''11.''' BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + +'''12.''' IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + '''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 +convey 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) <year> <name of author> + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/extensions/TimedMediaHandler/Gruntfile.js b/extensions/TimedMediaHandler/Gruntfile.js new file mode 100644 index 00000000..45380710 --- /dev/null +++ b/extensions/TimedMediaHandler/Gruntfile.js @@ -0,0 +1,34 @@ +/*jshint node:true */ +module.exports = function ( grunt ) { + grunt.loadNpmTasks( 'grunt-contrib-jshint' ); + grunt.loadNpmTasks( 'grunt-jsonlint' ); + grunt.loadNpmTasks( 'grunt-banana-checker' ); + grunt.loadNpmTasks( 'grunt-jscs' ); + + grunt.initConfig( { + jshint: { + options: { + jshintrc: true + }, + all: [ + '*.js' + ] + }, + jscs: { + src: '<%= jshint.all %>' + }, + banana: { + all: 'i18n/' + }, + jsonlint: { + all: [ + '*.json', + '**/*.json', + '!node_modules/**' + ] + } + } ); + + grunt.registerTask( 'test', [ 'jshint', 'jscs', 'jsonlint', 'banana' ] ); + grunt.registerTask( 'default', 'test' ); +}; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.config.php b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.config.php new file mode 100644 index 00000000..af32b4d7 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.config.php @@ -0,0 +1,194 @@ +<?php + /** + * Do not edit this file instead use LocalSettings.php and + * $wgMwEmbedModuleConfig[ {configuration name} ] = value; format + */ + return array ( + // If the player controls should be overlaid on top of the video ( if supported by playback method) + // can be set to false per embed player via overlayControls attribute + 'EmbedPlayer.OverlayControls' => true, + + // The preferred media codec preference + // Note user selected format order + 'EmbedPlayer.CodecPreference' => array( 'vp9', 'webm', 'h264', 'ogg' ), + + // If video tag support should be disabled all-together, used to test + // fallback decoding methods and direct file links + 'EmbedPlayer.DisableVideoTagSupport' => false, + + // If detected browser flash support should be ignored, and flash support, + // set to false. This will eliminate support for flash based playback. + 'EmbedPlayer.DisableHTML5FlashFallback'=> false, + + // Can be used to set player sources via configuration, useful in cases, + // where metadata is loaded from an api, but actual sources need to be pointed + // to another location at runtime via config + 'EmbedPlayer.ReplaceSources' => null, + + // If the flavor selector menu option should be displayed: + // This will be enabled by default in some future release of the library + 'EmbedPlayer.EnableFlavorSelector' => false, + + // If the iPad should use html controls + // With html controls you can't access native fullscreen + // With html controls you can support html themed controls, overlays, ads etc. ) + 'EmbedPlayer.EnableIpadHTMLControls' => true, + + // If the webkit-playsinline attribute should be added to the video tag. Will cause the player + // to play inline on iPhone + 'EmbedPlayer.WebKitPlaysInline'=> false, + + // If we should use the native device fullscreen call, + // this gives you hybrid player, where controls are in HTML for in browser playback, + // and native controls when the fullscreen button is pressed. + // its not the default since often users want playback control if using html controls, + // ( i.e no add skip etc ) + 'EmbedPlayer.EnableIpadNativeFullscreen' => false, + + // By default we display an html play screen, image thumb and play button. + // even though this is still a 'native' player. + // If you are not using ad plugins you may want to set this to false + // and display the native play button: + 'EmbedPlayer.iPhoneShowHTMLPlayScreen' => true, + + // If the large play button should be disabled on replay: + 'EmbedPlayer.ForceLargeReplayButton' => false, + + // The attribution library page + 'EmbedPlayer.LibraryPage' => 'http://www.kaltura.org/project/HTML5_Video_Media_JavaScript_Library', + + // What tags will be re-written to video player by default + // Set to empty string or null to avoid automatic video tag rewrites to embedPlayer + "EmbedPlayer.RewriteSelector" => "video,audio,playlist", + + // Default video size ( if no size provided ) + "EmbedPlayer.DefaultSize" => "400x300", + + // Default player controls size: + 'EmbedPlayer.ControlsHeight' => 31, + + // Default time display size: + 'EmbedPlayer.TimeDisplayWidth' => 85, + + // If the video player should attribute kaltura + "EmbedPlayer.KalturaAttribution" => true, + + // The attribution button + 'EmbedPlayer.AttributionButton' => array( + 'title' => 'Kaltura html5 video library', + 'href' => 'http://www.kaltura.com', + // Style icon to be applied + 'class' => 'kaltura-icon', + // Style to be applied to the outer attribution button container div + 'style' => array(), + // An icon image url 16x16 image url or data url ) + 'iconurl' => false + ), + + // If the options control bar menu item should be enabled: + 'EmbedPlayer.EnableOptionsMenu' => false, + + // If users can right click on the player + 'EmbedPlayer.EnableRightClick' => true, + + // Default supported menu items is merged with skin menu items + 'EmbedPlayer.EnabledOptionsMenuItems' => array( + // Player Select + 'playerSelect', + + // Download the file menu + 'download', + + // Share the video menu + 'share', + + // Player library link + 'aboutPlayerLibrary' + ), + + // If the player should wait for metadata like video size and duration, before trying to draw + // the player interface. + 'EmbedPlayer.WaitForMeta' => true, + + // Set the browser player warning flag displays warning for non optimal playback + "EmbedPlayer.ShowNativeWarning" => true, + + // If player errors / alerts should be displayed: + "EmbedPlayer.ShowPlayerAlerts" => true, + + // If fullscreen is global enabled. + "EmbedPlayer.EnableFullscreen" => true, + + // If the embed player time display should be shown + 'EmbedPlayer.EnableTimeDisplay' => true, + + // If the embed player volume control should be displayed + 'EmbedPlayer.EnableVolumeControl' => true, + + // If fullscreen should pop-open a new window + //( instead of trying to expand the video player to browser fullscreen ) + "EmbedPlayer.NewWindowFullscreen" => false, + + // If a fullscreen tip to press f11 should be displayed when entering fullscreen + "EmbedPlayer.FullscreenTip" => true, + + // if the browser should display a warning for direct file links: + "EmbedPlayer.DirectFileLinkWarning" => false, + + "EmbedPlayer.FirefoxLink" => 'http://www.mozilla.com/en-US/firefox/upgrade.html?from=mwEmbed', + + // If mwEmbed should use the Native player controls + // this will prevent video tag rewriting and skinning + // useful for devices such as iPad / iPod that + // don't fully support DOM overlays or don't expose full-screen + // functionality to javascript + "EmbedPlayer.NativeControls" => false, + + // If mwEmbed should use native controls on mobile safari + "EmbedPlayer.NativeControlsMobileSafari" => true, + + // The z-index given to the player interface during full screen ( high z-index ) + "EmbedPlayer.FullScreenZIndex" => 999998, + + // The default share embed mode ( can be "iframe" or "xssVideo" ) + // + // "iframe" will provide a <iframe tag pointing to mwEmbedFrame.php + // Object embedding should be much more compatible with sites that + // let users embed flash applets + // "xssVideo" will include the source javascript and video tag to + // rewrite the player on the remote page DOM + // Video tag embedding is much more mash-up friendly but exposes + // the remote site to the mwEmbed javascript and can be a xss issue. + "EmbedPlayer.ShareEmbedMode" => 'iframe', + + // The skin framework list: + "EmbedPlayer.SkinList" => array( 'mvpcf', 'kskin' ), + + // Default player skin name + "EmbedPlayer.DefaultSkin" => "mvpcf", + + // Number of milliseconds between interface updates + 'EmbedPlayer.MonitorRate' => 250, + + // If on Android should use html5 ( even if flash is installed on the machine ) + 'EmbedPlayer.UseFlashOnAndroid' => false, + + // If embedPlayer should support server side temporal urls for seeking options are + // flash|always|none default is support for flash only. + 'EmbedPlayer.EnableURLTimeEncoding' => 'flash', + + // The domains which can read and send events to the video player + 'EmbedPLayer.IFramePlayer.DomainWhiteList' => '*', + + // If the iframe should send and receive javascript events across domains via postMessage + 'EmbedPlayer.EnableIframeApi' => true, + + // If set to true will output the iframe as inline contents on the same domain as page contents + 'EmbedPlayer.PageDomainIframe' => true, + + // When there is no in-browser playback mechanism provide a download link for the play button + 'EmbedPlayer.NotPlayableDownloadLink' => true, + + // A black pixel for source switching + 'EmbedPlayer.BlackPixel' => "data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%01%00%00%00%01%08%02%00%00%00%90wS%DE%00%00%00%01sRGB%00%AE%CE%1C%E9%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%07tIME%07%DB%0B%0A%17%041%80%9B%E7%F2%00%00%00%19tEXtComment%00Created%20with%20GIMPW%81%0E%17%00%00%00%0CIDAT%08%D7c%60%60%60%00%00%00%04%00%01'4'%0A%00%00%00%00IEND%AEB%60%82" + ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.loader.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.loader.js new file mode 100644 index 00000000..f63a9393 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.loader.js @@ -0,0 +1,69 @@ +/** +* EmbedPlayer loader +*/ +( function( mw, $ ) { + /** + * Add a DOM ready check for player tags + */ + $( function() { + var $selected = $( mw.config.get( 'EmbedPlayer.RewriteSelector' ) ); + if ( $selected.length ) { + var inx = 0; + var checkSetDone = function() { + if ( inx < $selected.length ) { + // put in timeout to avoid browser lockup, and function stack + $selected.slice( inx, inx + 1 ).embedPlayer( function() { + setTimeout( function() { + checkSetDone(); + }, 5 ); + } ); + } + inx++; + }; + + checkSetDone(); + } + } ); + + /** + * Add the mwEmbed jQuery loader wrapper + */ + $.fn.embedPlayer = function( readyCallback ) { + var playerSet = this; + mw.log( 'jQuery.fn.embedPlayer :: ' + $( playerSet ).length ); + + // Set up the embed video player class request: (include the skin js as well) + var dependencySet = [ + 'mw.EmbedPlayer' + ]; + + mw.loader.using( [ 'jquery.client', 'jquery.mwEmbedUtil', 'mw.MwEmbedSupport' ], function() { + $( playerSet ).each( function( inx, playerElement ) { + // we have javascript ( disable controls ) + $( playerElement ).removeAttr( 'controls' ); + // Add an overlay loader ( firefox has its own native loading spinner ) + + if ( $.client.profile().name !== 'firefox' ) { + $( playerElement ) + .parent() + .getAbsoluteOverlaySpinner() + .attr('id', 'loadingSpinner_' + $( playerElement ).attr('id') ); + } + // Allow other modules update the dependencies + $( mw ).trigger( 'EmbedPlayerUpdateDependencies', + [ playerElement, dependencySet ] ); + } ); + + // Remove any duplicates in the dependencySet: + dependencySet = $.uniqueArray( dependencySet ); + + // Do the request and process the playerElements with updated dependency set + mw.loader.using( dependencySet, function() { + // Setup the enhanced language: + mw.processEmbedPlayers( playerSet, readyCallback ); + }, function( e ) { + throw new Error( 'Error loading EmbedPlayer dependency set: ' + e.message ); + } ); + } ); + }; +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.php b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.php new file mode 100644 index 00000000..a813c8d0 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/EmbedPlayer.php @@ -0,0 +1,103 @@ +<?php + global $wgVideoPlayerSkinModule; + // Register all the EmbedPlayer modules + return array( + "mw.MediaElement" => array( + 'scripts' => 'resources/mw.MediaElement.js', + 'dependencies' => array( + 'ext.tmh.OgvJsSupport', + ) + ), + "mw.MediaPlayer" => array( 'scripts' => 'resources/mw.MediaPlayer.js' ), + "mw.MediaPlayers" => array( + 'scripts' => 'resources/mw.MediaPlayers.js', + 'dependencies' => 'mw.MediaPlayer' + ), + "mw.MediaSource" => array( 'scripts' => 'resources/mw.MediaSource.js' ), + "mw.EmbedTypes" => array( + 'scripts' => 'resources/mw.EmbedTypes.js', + 'dependencies' => array( + 'mw.MediaPlayers', + 'mediawiki.Uri', + 'jquery.client', + ) + ), + "mw.EmbedPlayer" => array( + 'scripts' => array( + "resources/mw.processEmbedPlayers.js", + "resources/mw.EmbedPlayer.js", + "resources/skins/mw.PlayerControlBuilder.js", + ), + 'dependencies' => array( + // mwEmbed support module + 'mediawiki.client', + 'mediawiki.UtilitiesTime', + 'mediawiki.Uri', + 'mediawiki.absoluteUrl', + 'mediawiki.jqueryMsg', + + // Browser fullscreen api support: + 'fullScreenApi', + + // Kinda need this + 'mw.MwEmbedSupport', + + // We always end up loading native player + 'mw.EmbedPlayerNative', + + // Sub classes: + 'mw.MediaElement', + 'mw.MediaPlayers', + 'mw.MediaSource', + 'mw.EmbedTypes', + + // jQuery dependencies: + 'jquery.client', + 'jquery.hoverIntent', + 'jquery.cookie', + 'jquery.ui.mouse', + 'jquery.debouncedresize', + 'jquery.embedMenu', + 'jquery.ui.slider', + 'jquery.ui.touchPunch', + + // Set to mw.PlayerSkinKskin or mw.PlayerSkinMvpcf in config + $wgVideoPlayerSkinModule + ), + 'styles' => "resources/skins/EmbedPlayer.css", + 'messageDir' => 'i18n', + ), + + "mw.EmbedPlayerKplayer" => array( 'scripts'=> "resources/mw.EmbedPlayerKplayer.js" ), + "mw.EmbedPlayerGeneric" => array( 'scripts'=> "resources/mw.EmbedPlayerGeneric.js" ), + "mw.EmbedPlayerNative" => array( 'scripts'=> "resources/mw.EmbedPlayerNative.js" ), + "mw.EmbedPlayerVLCApp" => array( + 'scripts'=> "resources/mw.EmbedPlayerVLCApp.js", + 'dependencies' => array( 'mediawiki.Uri' ) + ), + "mw.EmbedPlayerIEWebMPrompt" => array( + 'scripts' => 'resources/mw.EmbedPlayerIEWebMPrompt.js', + 'styles' => 'resources/mw.EmbedPlayerIEWebMPrompt.css', + ), + "mw.EmbedPlayerOgvJs" => array( + 'scripts' => 'resources/mw.EmbedPlayerOgvJs.js', + 'dependencies' => array( + 'jquery.spinner', + 'ext.tmh.OgvJsSupport', + ), + ), + "mw.EmbedPlayerImageOverlay" => array( 'scripts'=> "resources/mw.EmbedPlayerImageOverlay.js" ), + + "mw.EmbedPlayerVlc" => array( 'scripts'=> "resources/mw.EmbedPlayerVlc.js" ), + + "mw.PlayerSkinKskin" => array( + 'scripts' => "resources/skins/kskin/mw.PlayerSkinKskin.js", + 'styles' => "resources/skins/kskin/PlayerSkinKskin.css" + ), + + "mw.PlayerSkinMvpcf" => array( + 'scripts'=> "resources/skins/mvpcf/mw.PlayerSkinMvpcf.js", + 'styles'=> "resources/skins/mvpcf/PlayerSkinMvpcf.css" + ), + ); +?> diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/LightDoodleskin.swf b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/LightDoodleskin.swf Binary files differnew file mode 100644 index 00000000..5f25450e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/LightDoodleskin.swf diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/README b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/README new file mode 100644 index 00000000..7b11a51b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/README @@ -0,0 +1,20 @@ + +File: kdp3.swf + +This Kaltura Dynamic Player +Playlist (KDP) is a sub package of the taken Kaltura Community Edition (CE) Built from Kaltura.org source. + +The full Kaltura Community Edition is licensed under the ( GNU Affero General Public License v3 ) + +And the source code is available on the kaltura.org site: +http://www.kaltura.org/project/kalturaCE + +More info about the KDP: +http://www.kaltura.org/kdp-dynamic-player-and-playlist-widget + + + +File: expressInstall.swf +is part of SWFObject v2.2 <http://code.google.com/p/swfobject/> + and is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> + + diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/config.xml b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/config.xml new file mode 100644 index 00000000..a4c4e9c8 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/config.xml @@ -0,0 +1,9 @@ +<layout id="full" skinPath="assets/skin.swf"> + <HBox id="topLevel" width="100%" height="100%"> + <VBox id="player" width="100%" height="100%" styleName="black"> + <Canvas height="100%" width="100%" id="PlayerHolder" styleName="black"> + <Video id="video" width="100%" height="100%" /> + </Canvas> + </VBox> + </HBox> +</layout>
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/expressInstall.swf b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/expressInstall.swf Binary files differnew file mode 100644 index 00000000..0fbf8fca --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/expressInstall.swf diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/kdp3.3.5.27.swf b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/kdp3.3.5.27.swf Binary files differnew file mode 100644 index 00000000..b400fa68 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/kdp3.3.5.27.swf diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/kdp3.swf b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/kdp3.swf Binary files differnew file mode 100644 index 00000000..c2f3891c --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/kdp3.swf diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/skin.swf b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/skin.swf Binary files differnew file mode 100644 index 00000000..3c8bf053 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/kaltura-player/skin.swf diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING new file mode 100644 index 00000000..96498a60 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING @@ -0,0 +1,21 @@ +ogv.js & ogv.swf wrapper and player code + +Copyright (c) 2013-2014 Brion Vibber and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-ogg.txt b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-ogg.txt new file mode 100644 index 00000000..6111c6c5 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-ogg.txt @@ -0,0 +1,28 @@ +Copyright (c) 2002, Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-opus.txt b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-opus.txt new file mode 100644 index 00000000..9c739c34 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-opus.txt @@ -0,0 +1,44 @@ +Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic, + Jean-Marc Valin, Timothy B. Terriberry, + CSIRO, Gregory Maxwell, Mark Borgerding, + Erik de Castro Lopo + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Opus is subject to the royalty-free patent licenses which are +specified at: + +Xiph.Org Foundation: +https://datatracker.ietf.org/ipr/1524/ + +Microsoft Corporation: +https://datatracker.ietf.org/ipr/1914/ + +Broadcom Corporation: +https://datatracker.ietf.org/ipr/1526/ diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-theora.txt b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-theora.txt new file mode 100644 index 00000000..c8ccce4f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-theora.txt @@ -0,0 +1,28 @@ +Copyright (C) 2002-2009 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-vorbis.txt b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-vorbis.txt new file mode 100644 index 00000000..28de72a9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/COPYING-vorbis.txt @@ -0,0 +1,28 @@ +Copyright (c) 2002-2008 Xiph.org Foundation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Xiph.org Foundation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/dynamicaudio.swf b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/dynamicaudio.swf Binary files differnew file mode 100644 index 00000000..2e3ce4e4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/dynamicaudio.swf diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-audio-opus.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-audio-opus.js new file mode 100644 index 00000000..4e73c95a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-audio-opus.js @@ -0,0 +1,24 @@ +var OGVDecoderAudioOpus = function(Module) { + Module = Module || {}; + +var options=Module;Module={print:(function(str){console.log(str)})};var Module;if(!Module)Module=(typeof OGVDecoderAudioOpus!=="undefined"?OGVDecoderAudioOpus:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB;var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath["normalize"](filename);var ret=nodeFS["readFileSync"](filename);if(!ret&&filename!=nodePath["resolve"](filename)){filename=path.join(__dirname,"..","src",filename);ret=nodeFS["readFileSync"](filename)}if(ret&&!binary)ret=ret.toString();return ret};Module["readBinary"]=function readBinary(filename){return Module["read"](filename,true)};Module["load"]=function load(f){globalEval(read(f))};if(!Module["thisProgram"]){if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}else{Module["thisProgram"]="unknown-program"}}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function read(){throw"no read() available (jsc?)"}}Module["readBinary"]=function readBinary(f){if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}var data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function printErr(x){console.log(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WORKER){Module["load"]=importScripts}if(typeof Module["setWindowTitle"]==="undefined"){Module["setWindowTitle"]=(function(title){document.title=title})}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}if(!Module["thisProgram"]){Module["thisProgram"]="./this.program"}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}var Runtime={setTempRet0:(function(value){tempRet0=value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),STACK_ALIGN:16,prepVararg:(function(ptr,type){if(type==="double"||type==="i64"){if(ptr&7){assert((ptr&7)===4);ptr+=4}}else{assert((ptr&3)===0)}return ptr}),getAlignSize:(function(type,size,vararg){if(!vararg&&(type=="i64"||type=="double"))return 8;if(!type)return Math.min(size,8);return Math.min(size||(type?Runtime.getNativeFieldSize(type):0),Runtime.QUANTUM_SIZE)}),dynCall:(function(sig,ptr,args){if(args&&args.length){if(!args.splice)args=Array.prototype.slice.call(args);args.splice(0,0,ptr);return Module["dynCall_"+sig].apply(null,args)}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i<Runtime.functionPointers.length;i++){if(!Runtime.functionPointers[i]){Runtime.functionPointers[i]=func;return 2*(1+i)}}throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."}),removeFunction:(function(index){Runtime.functionPointers[(index-2)/2]=null}),warnOnce:(function(text){if(!Runtime.warnOnce.shown)Runtime.warnOnce.shown={};if(!Runtime.warnOnce.shown[text]){Runtime.warnOnce.shown[text]=1;Module.printErr(text)}}),funcWrappers:{},getFuncWrapper:(function(func,sig){assert(sig);if(!Runtime.funcWrappers[sig]){Runtime.funcWrappers[sig]={}}var sigCache=Runtime.funcWrappers[sig];if(!sigCache[func]){sigCache[func]=function dynCall_wrapper(){return Runtime.dynCall(sig,func,arguments)}}return sigCache[func]}),getCompilerSetting:(function(name){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"}),stackAlloc:(function(size){var ret=STACKTOP;STACKTOP=STACKTOP+size|0;STACKTOP=STACKTOP+15&-16;return ret}),staticAlloc:(function(size){var ret=STATICTOP;STATICTOP=STATICTOP+size|0;STATICTOP=STATICTOP+15&-16;return ret}),dynamicAlloc:(function(size){var ret=DYNAMICTOP;DYNAMICTOP=DYNAMICTOP+size|0;DYNAMICTOP=DYNAMICTOP+15&-16;if(DYNAMICTOP>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){DYNAMICTOP=ret;return 0}}return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:16))*(quantum?quantum:16);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var __THREW__=0;var ABORT=false;var EXITSTATUS=0;var undef=0;var tempValue,tempInt,tempBigInt,tempInt2,tempBigInt2,tempPair,tempBigIntI,tempBigIntR,tempBigIntS,tempBigIntP,tempBigIntD,tempDouble,tempFloat;var tempI64,tempI64b;var tempRet0,tempRet1,tempRet2,tempRet3,tempRet4,tempRet5,tempRet6,tempRet7,tempRet8,tempRet9;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var globalScope=this;function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var JSfuncs={"stackSave":(function(){Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore()}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=Runtime.stackAlloc((str.length<<2)+1);writeStringToMemory(str,ret)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args,opts){var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=Runtime.stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);if(returnType==="string")ret=Pointer_stringify(ret);if(stack!==0){if(opts&&opts.async){EmterpreterAsync.asyncFinalizers.push((function(){Runtime.stackRestore(stack)}));return}Runtime.stackRestore(stack)}return ret};var sourceRegex=/^function\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/;function parseJSFunc(jsfunc){var parsed=jsfunc.toString().match(sourceRegex).slice(1);return{arguments:parsed[0],body:parsed[1],returnValue:parsed[2]}}var JSsource={};for(var fun in JSfuncs){if(JSfuncs.hasOwnProperty(fun)){JSsource[fun]=parseJSFunc(JSfuncs[fun])}}cwrap=function cwrap(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident);var numericArgs=argTypes.every((function(type){return type==="number"}));var numericRet=returnType!=="string";if(numericRet&&numericArgs){return cfunc}var argNames=argTypes.map((function(x,i){return"$"+i}));var funcstr="(function("+argNames.join(",")+") {";var nargs=argTypes.length;if(!numericArgs){funcstr+="var stack = "+JSsource["stackSave"].body+";";for(var i=0;i<nargs;i++){var arg=argNames[i],type=argTypes[i];if(type==="number")continue;var convertCode=JSsource[type+"ToC"];funcstr+="var "+convertCode.arguments+" = "+arg+";";funcstr+=convertCode.body+";";funcstr+=arg+"="+convertCode.returnValue+";"}}var cfuncname=parseJSFunc((function(){return cfunc})).returnValue;funcstr+="var ret = "+cfuncname+"("+argNames.join(",")+");";if(!numericRet){var strgfy=parseJSFunc((function(){return Pointer_stringify})).returnValue;funcstr+="ret = "+strgfy+"(ret);"}if(!numericArgs){funcstr+=JSsource["stackRestore"].body.replace("()","(stack)")+";"}funcstr+="return ret})";return eval(funcstr)}}))();Module["cwrap"]=cwrap;Module["ccall"]=ccall;function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr<stop;ptr+=4){HEAP32[ptr>>2]=0}stop=ret+size;while(ptr<stop){HEAP8[ptr++>>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i<size){var curr=slab[i];if(typeof curr==="function"){curr=Runtime.getFunctionIndex(curr)}type=singleType||types[i];if(type===0){i++;continue}if(type=="i64")type="i32";setValue(ret+i,curr,type);if(previousType!==type){typeSize=Runtime.getNativeTypeSize(type);previousType=type}i+=typeSize}return ret}Module["allocate"]=allocate;function getMemory(size){if(!staticSealed)return Runtime.staticAlloc(size);if(typeof _sbrk!=="undefined"&&!_sbrk.called||!runtimeInitialized)return Runtime.dynamicAlloc(size);return _malloc(size)}Module["getMemory"]=getMemory;function Pointer_stringify(ptr,length){if(length===0||!ptr)return"";var hasUtf=0;var t;var i=0;while(1){t=HEAPU8[ptr+i>>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return Module["UTF8ToString"](ptr)}Module["Pointer_stringify"]=Pointer_stringify;function AsciiToString(ptr){var str="";while(1){var ch=HEAP8[ptr++>>0];if(!ch)return str;str+=String.fromCharCode(ch)}}Module["AsciiToString"]=AsciiToString;function stringToAscii(str,outPtr){return writeAsciiToMemory(str,outPtr,false)}Module["stringToAscii"]=stringToAscii;function UTF8ArrayToString(u8Array,idx){var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}Module["UTF8ArrayToString"]=UTF8ArrayToString;function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}Module["UTF8ToString"]=UTF8ToString;function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}Module["stringToUTF8Array"]=stringToUTF8Array;function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}Module["stringToUTF8"]=stringToUTF8;function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}Module["lengthBytesUTF8"]=lengthBytesUTF8;function UTF16ToString(ptr){var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}Module["UTF16ToString"]=UTF16ToString;function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}Module["stringToUTF16"]=stringToUTF16;function lengthBytesUTF16(str){return str.length*2}Module["lengthBytesUTF16"]=lengthBytesUTF16;function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}Module["UTF32ToString"]=UTF32ToString;function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}Module["stringToUTF32"]=stringToUTF32;function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}Module["lengthBytesUTF32"]=lengthBytesUTF32;function demangle(func){var hasLibcxxabi=!!Module["___cxa_demangle"];if(hasLibcxxabi){try{var buf=_malloc(func.length);writeStringToMemory(func.substr(1),buf);var status=_malloc(4);var ret=Module["___cxa_demangle"](buf,0,0,status);if(getValue(status,"i32")===0&&ret){return Pointer_stringify(ret)}}catch(e){}finally{if(buf)_free(buf);if(status)_free(status);if(ret)_free(ret)}}var i=3;var basicTypes={"v":"void","b":"bool","c":"char","s":"short","i":"int","l":"long","f":"float","d":"double","w":"wchar_t","a":"signed char","h":"unsigned char","t":"unsigned short","j":"unsigned int","m":"unsigned long","x":"long long","y":"unsigned long long","z":"..."};var subs=[];var first=true;function dump(x){if(x)Module.print(x);Module.print(func);var pre="";for(var a=0;a<i;a++)pre+=" ";Module.print(pre+"^")}function parseNested(){i++;if(func[i]==="K")i++;var parts=[];while(func[i]!=="E"){if(func[i]==="S"){i++;var next=func.indexOf("_",i);var num=func.substring(i,next)||0;parts.push(subs[num]||"?");i=next+1;continue}if(func[i]==="C"){parts.push(parts[parts.length-1]);i+=2;continue}var size=parseInt(func.substr(i));var pre=size.toString().length;if(!size||!pre){i--;break}var curr=func.substr(i+pre,size);parts.push(curr);subs.push(curr);i+=pre+size}i++;return parts}function parse(rawList,limit,allowVoid){limit=limit||Infinity;var ret="",list=[];function flushList(){return"("+list.join(", ")+")"}var name;if(func[i]==="N"){name=parseNested().join("::");limit--;if(limit===0)return rawList?[name]:name}else{if(func[i]==="K"||first&&func[i]==="L")i++;var size=parseInt(func.substr(i));if(size){var pre=size.toString().length;name=func.substr(i+pre,size);i+=pre+size}}first=false;if(func[i]==="I"){i++;var iList=parse(true);var iRet=parse(true,1,true);ret+=iRet[0]+" "+name+"<"+iList.join(", ")+">"}else{ret=name}paramLoop:while(i<func.length&&limit-->0){var c=func[i++];if(c in basicTypes){list.push(basicTypes[c])}else{switch(c){case"P":list.push(parse(true,1,true)[0]+"*");break;case"R":list.push(parse(true,1,true)[0]+"&");break;case"L":{i++;var end=func.indexOf("E",i);var size=end-i;list.push(func.substr(i,size));i+=size+2;break};case"A":{var size=parseInt(func.substr(i));i+=size.toString().length;if(func[i]!=="_")throw"?";i++;list.push(parse(true,1,true)[0]+" ["+size+"]");break};case"E":break paramLoop;default:ret+="?"+c;break paramLoop}}}if(!allowVoid&&list.length===1&&list[0]==="void")list=[];if(rawList){if(ret){list.push(ret+"?")}return list}else{return ret+flushList()}}var parsed=func;try{if(func=="Object._main"||func=="_main"){return"main()"}if(typeof func==="number")func=Pointer_stringify(func);if(func[0]!=="_")return func;if(func[1]!=="_")return func;if(func[2]!=="Z")return func;switch(func[3]){case"n":return"operator new()";case"d":return"operator delete()"}parsed=parse()}catch(e){parsed+="?"}if(parsed.indexOf("?")>=0&&!hasLibcxxabi){Runtime.warnOnce("warning: a problem occurred in builtin C++ name demangling; build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling")}return parsed}function demangleAll(text){return text.replace(/__Z[\w\d_]+/g,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){return demangleAll(jsStackTrace())}Module["stackTrace"]=stackTrace;var PAGE_SIZE=4096;function alignMemoryPage(x){if(x%4096>0){x+=4096-x%4096}return x}var HEAP;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var STATIC_BASE=0,STATICTOP=0,staticSealed=false;var STACK_BASE=0,STACKTOP=0,STACK_MAX=0;var DYNAMIC_BASE=0,DYNAMICTOP=0;function enlargeMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.")}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;var totalMemory=64*1024;while(totalMemory<TOTAL_MEMORY||totalMemory<2*TOTAL_STACK){if(totalMemory<16*1024*1024){totalMemory*=2}else{totalMemory+=16*1024*1024}}if(totalMemory!==TOTAL_MEMORY){Module.printErr("increasing TOTAL_MEMORY to "+totalMemory+" to be compliant with the asm.js spec (and given that TOTAL_STACK="+TOTAL_STACK+")");TOTAL_MEMORY=totalMemory}assert(typeof Int32Array!=="undefined"&&typeof Float64Array!=="undefined"&&!!(new Int32Array(1))["subarray"]&&!!(new Int32Array(1))["set"],"JS engine does not provide full typed array support");var buffer;buffer=new ArrayBuffer(TOTAL_MEMORY);HEAP8=new Int8Array(buffer);HEAP16=new Int16Array(buffer);HEAP32=new Int32Array(buffer);HEAPU8=new Uint8Array(buffer);HEAPU16=new Uint16Array(buffer);HEAPU32=new Uint32Array(buffer);HEAPF32=new Float32Array(buffer);HEAPF64=new Float64Array(buffer);HEAP32[0]=255;assert(HEAPU8[0]===255&&HEAPU8[3]===0,"Typed arrays 2 must be run on a little-endian system");Module["HEAP"]=HEAP;Module["buffer"]=buffer;Module["HEAP8"]=HEAP8;Module["HEAP16"]=HEAP16;Module["HEAP32"]=HEAP32;Module["HEAPU8"]=HEAPU8;Module["HEAPU16"]=HEAPU16;Module["HEAPU32"]=HEAPU32;Module["HEAPF32"]=HEAPF32;Module["HEAPF64"]=HEAPF64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Runtime.dynCall("v",func)}else{Runtime.dynCall("vi",func,[callback.arg])}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=Module.addOnPreRun=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=Module.addOnInit=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=Module.addOnPreMain=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=Module.addOnExit=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=Module.addOnPostRun=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i<array.length;i++){var chr=array[i];if(chr>255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){var array=intArrayFromString(string,dontAddNull);var i=0;while(i<array.length){var chr=array[i];HEAP8[buffer+i>>0]=chr;i=i+1}}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){for(var i=0;i<array.length;i++){HEAP8[buffer++>>0]=array[i]}}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;function unSign(value,bits,ignore){if(value>=0){return value}return bits<=32?2*Math.abs(1<<bits-1)+value:Math.pow(2,bits)+value}function reSign(value,bits,ignore){if(value<=0){return value}var half=bits<=32?Math.abs(1<<bits-1):Math.pow(2,bits-1);if(value>=half&&(bits<=32||value>half)){value=-2*half+value}return value}if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];if(!Math["clz32"])Math["clz32"]=(function(x){x=x>>>0;for(var i=0;i<32;i++){if(x&1<<31-i)return i}return 32});Math.clz32=Math["clz32"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_min=Math.min;var Math_clz32=Math.clz32;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;var ASM_CONSTS=[];STATIC_BASE=8;STATICTOP=STATIC_BASE+25856;__ATINIT__.push();allocate([0,255,0,255,0,255,0,255,0,255,0,254,1,0,1,255,0,254,0,253,2,0,1,255,0,254,0,253,3,0,1,255,0,0,206,64,0,0,200,64,0,0,184,64,0,0,170,64,0,0,162,64,0,0,154,64,0,0,144,64,0,0,140,64,0,0,156,64,0,0,150,64,0,0,146,64,0,0,142,64,0,0,156,64,0,0,148,64,0,0,138,64,0,0,144,64,0,0,140,64,0,0,148,64,0,0,152,64,0,0,142,64,0,0,112,64,0,0,112,64,0,0,112,64,0,0,112,64,0,0,112,64,0,0,0,0,224,112,44,15,3,2,1,0,254,237,192,132,70,23,4,0,255,252,226,155,61,11,2,0,250,245,234,203,71,50,42,38,35,33,31,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,179,99,0,0,0,0,0,0,232,11,0,0,240,11,0,0,0,12,0,0,0,0,0,0,32,12,0,0,72,12,0,0,152,12,0,0,0,0,0,0,32,0,10,0,20,46,100,1,56,13,0,0,120,14,0,0,184,14,0,0,208,14,0,0,112,15,0,0,184,15,0,0,0,16,0,0,0,0,0,0,32,0,16,0,102,38,171,1,24,16,0,0,24,18,0,0,88,18,0,0,120,18,0,0,120,19,0,0,192,19,0,0,8,20,0,0,0,0,0,0,92,202,190,216,182,223,154,226,156,230,120,236,122,244,204,252,52,3,134,11,136,19,100,25,102,29,74,32,66,39,164,53,249,247,246,245,244,234,210,202,201,200,197,174,82,59,56,55,54,46,22,12,11,10,9,7,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,48,20,0,0,56,20,0,0,120,0,0,0,0,0,0,0,128,64,0,0,0,0,0,0,232,158,10,0,0,0,0,0,230,0,0,0,0,0,0,0,243,221,192,181,0,0,0,0,100,0,240,0,32,0,100,0,205,60,0,48,0,32,0,0,171,85,0,0,0,0,0,0,192,128,64,0,0,0,0,0,205,154,102,51,0,0,0,0,213,171,128,85,43,0,0,0,224,192,160,128,96,64,32,0,100,40,16,7,3,1,0,0,253,250,244,233,212,182,150,131,120,110,98,85,72,60,49,40,32,25,19,15,13,11,9,8,7,6,5,4,3,2,1,0,210,208,206,203,199,193,183,168,142,104,74,52,37,27,20,14,10,6,4,2,0,0,0,0,223,201,183,167,152,138,124,111,98,88,79,70,62,56,50,44,39,35,31,27,24,21,18,16,14,12,10,8,6,4,3,2,1,0,0,0,0,0,0,0,188,176,155,138,119,97,67,43,26,10,0,0,0,0,0,0,165,119,80,61,47,35,27,20,14,9,4,0,0,0,0,0,113,63,0,0,0,0,0,0,125,51,26,18,15,12,11,10,9,8,7,6,5,4,3,2,1,0,198,105,45,22,15,12,11,10,9,8,7,6,5,4,3,2,1,0,213,162,116,83,59,43,32,24,18,15,12,9,7,6,5,3,2,0,239,187,116,59,28,16,11,10,9,8,7,6,5,4,3,2,1,0,250,229,188,135,86,51,30,19,13,10,8,6,5,4,3,2,1,0,249,235,213,185,156,128,103,83,66,53,42,33,26,21,17,13,10,0,254,249,235,206,164,118,77,46,27,16,10,7,5,4,3,2,1,0,255,253,249,239,220,191,156,119,85,57,37,23,15,10,6,4,2,0,255,253,251,246,237,223,203,179,152,124,98,75,55,40,29,21,15,0,255,254,253,247,220,162,106,67,42,28,18,12,9,6,4,3,2,0,0,0,0,0,241,190,178,132,87,74,41,14,0,223,193,157,140,106,57,39,18,0,0,0,0,0,0,0,128,0,214,42,0,235,128,21,0,244,184,72,11,0,248,214,128,42,7,0,248,225,170,80,25,5,0,251,236,198,126,54,18,3,0,250,238,211,159,82,35,15,5,0,250,231,203,168,128,88,53,25,6,0,252,238,216,185,148,108,71,40,18,4,0,253,243,225,199,166,128,90,57,31,13,3,0,254,246,233,212,183,147,109,73,44,23,10,2,0,255,250,240,223,198,166,128,90,58,33,16,6,1,0,255,251,244,231,210,181,146,110,75,46,25,12,5,1,0,255,253,248,238,221,196,164,128,92,60,35,18,8,3,1,0,255,253,249,242,229,208,180,146,110,76,48,27,14,7,3,1,0,129,0,207,50,0,236,129,20,0,245,185,72,10,0,249,213,129,42,6,0,250,226,169,87,27,4,0,251,233,194,130,62,20,4,0,250,236,207,160,99,47,17,3,0,255,240,217,182,131,81,41,11,1,0,255,254,233,201,159,107,61,20,2,1,0,255,249,233,206,170,128,86,50,23,7,1,0,255,250,238,217,186,148,108,70,39,18,6,1,0,255,252,243,226,200,166,128,90,56,30,13,4,1,0,255,252,245,231,209,180,146,110,76,47,25,11,4,1,0,255,253,248,237,219,194,163,128,93,62,37,19,8,3,1,0,255,254,250,241,226,205,177,145,111,79,51,30,15,6,2,1,0,129,0,203,54,0,234,129,23,0,245,184,73,10,0,250,215,129,41,5,0,252,232,173,86,24,3,0,253,240,200,129,56,15,2,0,253,244,217,164,94,38,10,1,0,253,245,226,189,132,71,27,7,1,0,253,246,231,203,159,105,56,23,6,1,0,255,248,235,213,179,133,85,47,19,5,1,0,255,254,243,221,194,159,117,70,37,12,2,1,0,255,254,248,234,208,171,128,85,48,22,8,2,1,0,255,254,250,240,220,189,149,107,67,36,16,6,2,1,0,255,254,251,243,227,201,166,128,90,55,29,13,5,2,1,0,255,254,252,246,234,213,183,147,109,73,43,22,10,4,2,1,0,130,0,200,58,0,231,130,26,0,244,184,76,12,0,249,214,130,43,6,0,252,232,173,87,24,3,0,253,241,203,131,56,14,2,0,254,246,221,167,94,35,8,1,0,254,249,232,193,130,65,23,5,1,0,255,251,239,211,162,99,45,15,4,1,0,255,251,243,223,186,131,74,33,11,3,1,0,255,252,245,230,202,158,105,57,24,8,2,1,0,255,253,247,235,214,179,132,84,44,19,7,2,1,0,255,254,250,240,223,196,159,112,69,36,15,6,2,1,0,255,254,253,245,231,209,176,136,93,55,27,11,3,2,1,0,255,254,253,252,239,221,194,158,117,76,42,18,4,3,2,1,0,0,0,2,5,9,14,20,27,35,44,54,65,77,90,104,119,135,0,0,0,0,0,0,0,254,49,67,77,82,93,99,198,11,18,24,31,36,45,255,46,66,78,87,94,104,208,14,21,32,42,51,66,255,94,104,109,112,115,118,248,53,69,80,88,95,102,0,0,0,0,0,0,0,32,254,31,246,31,234,31,216,31,194,31,168,31,136,31,98,31,58,31,10,31,216,30,160,30,98,30,34,30,220,29,144,29,66,29,238,28,150,28,58,28,216,27,114,27,10,27,156,26,42,26,180,25,58,25,188,24,60,24,182,23,46,23,160,22,16,22,126,21,232,20,78,20,176,19,16,19,110,18,200,17,30,17,116,16,198,15,22,15,100,14,174,13,248,12,64,12,132,11,200,10,10,10,74,9,138,8,198,7,2,7,62,6,120,5,178,4,234,3,34,3,90,2,146,1,202,0,0,0,54,255,110,254,166,253,222,252,22,252,78,251,136,250,194,249,254,248,58,248,118,247,182,246,246,245,56,245,124,244,192,243,8,243,82,242,156,241,234,240,58,240,140,239,226,238,56,238,146,237,240,236,80,236,178,235,24,235,130,234,240,233,96,233,210,232,74,232,196,231,68,231,198,230,76,230,214,229,100,229,246,228,142,228,40,228,198,227,106,227,18,227,190,226,112,226,36,226,222,225,158,225,96,225,40,225,246,224,198,224,158,224,120,224,88,224,62,224,40,224,22,224,10,224,2,224,0,224,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,255,1,255,2,254,2,254,3,253,0,1,0,1,255,2,255,2,254,3,254,3,0,2,255,255,255,0,0,1,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,255,2,1,0,1,1,0,0,255,255,0,0,0,0,0,0,1,255,0,1,255,0,255,1,254,2,254,254,2,253,2,3,253,252,3,252,4,4,251,5,250,251,6,249,6,5,8,247,0,0,1,0,0,0,0,0,0,0,255,1,0,0,1,255,0,1,255,255,1,255,2,1,255,2,254,254,2,254,2,2,3,253,0,1,0,0,0,0,0,0,1,0,1,0,0,1,255,1,0,0,2,1,255,2,255,255,2,255,2,2,255,3,254,254,254,3,0,1,0,0,1,0,1,255,2,255,2,255,2,3,254,3,254,254,4,4,253,5,253,252,6,252,6,5,251,8,250,251,249,9,42,175,213,201,207,255,64,0,17,0,99,255,97,1,16,254,163,0,39,43,189,86,217,255,6,0,91,0,86,255,186,0,23,0,128,252,192,24,216,77,237,255,220,255,102,0,167,255,232,255,72,1,73,252,8,10,37,62,0,0,0,0,0,0,135,199,61,201,64,0,128,0,134,255,36,0,54,1,0,253,72,2,51,36,69,69,12,0,128,0,18,0,114,255,32,1,139,255,159,252,27,16,123,56,104,2,13,200,246,255,39,0,58,0,210,255,172,255,120,0,184,0,197,254,227,253,4,5,4,21,64,35,0,0,0,0,230,62,198,196,243,255,0,0,20,0,26,0,5,0,225,255,213,255,252,255,65,0,90,0,7,0,99,255,8,255,212,255,81,2,47,6,52,10,199,12,228,87,5,197,3,0,242,255,236,255,241,255,2,0,25,0,37,0,25,0,240,255,185,255,149,255,177,255,50,0,36,1,111,2,214,3,8,5,184,5,148,107,103,196,17,0,12,0,8,0,1,0,246,255,234,255,226,255,224,255,234,255,3,0,44,0,100,0,168,0,243,0,61,1,125,1,173,1,199,1,189,0,168,253,105,2,103,119,117,0,97,255,210,251,8,116,52,0,221,0,168,246,116,110,252,255,17,2,234,242,229,102,208,255,246,2,140,240,165,93,176,255,137,3,117,239,6,83,157,255,204,3,130,239,102,71,149,255,199,3,139,240,39,59,153,255,128,3,97,242,174,46,165,255,5,3,207,244,94,34,185,255,99,2,161,247,152,22,210,255,169,1,161,250,180,11,0,0,157,62,0,64,94,62,0,192,4,62,0,128,237,62,0,64,137,62,0,0,0,0,0,192,76,63,0,0,205,61,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,25,23,2,0,0,0,0,0,126,124,119,109,87,41,19,9,4,2,0,0,0,0,0,0,24,78,0,0,216,80,0,0,148,83,0,0,76,86,0,0,0,89,0,0,176,91,0,0,92,94,0,0,196,95,0,0,128,96,0,0,244,96,0,0,64,97,0,0,120,97,0,0,152,97,0,0,176,97,0,0,188,97,0,0,0,0,0,0,149,139,0,0,55,152,0,0,255,165,0,0,4,181,0,0,103,197,0,0,69,215,0,0,193,234,0,0,255,255,0,0,112,20,0,0,0,0,0,0,72,127,65,129,66,128,65,128,64,128,62,128,64,128,64,128,92,78,92,79,92,78,90,79,116,41,115,40,114,40,132,26,132,26,145,17,161,12,176,10,177,11,24,179,48,138,54,135,54,132,53,134,56,133,55,132,55,132,61,114,70,96,74,88,75,88,87,74,89,66,91,67,100,59,108,50,120,40,122,37,97,43,78,50,83,78,84,81,88,75,86,74,87,71,90,73,93,74,93,74,109,40,114,36,117,34,117,34,143,17,145,18,146,19,162,12,165,10,178,7,189,6,190,8,177,9,23,178,54,115,63,102,66,98,69,99,74,89,71,91,73,91,78,89,86,80,92,66,93,64,102,59,103,60,104,60,117,52,123,44,138,35,133,31,97,38,77,45,61,90,93,60,105,42,107,41,110,45,116,38,113,38,112,38,124,26,132,27,136,19,140,20,155,14,159,16,158,18,170,13,177,10,187,8,192,6,175,9,159,10,21,178,59,110,71,86,75,85,84,83,91,66,88,73,87,72,92,75,98,72,105,58,107,54,115,52,114,55,112,56,129,51,132,40,150,33,140,29,98,35,77,42,42,121,96,66,108,43,111,40,117,44,123,32,120,36,119,33,127,33,134,34,139,21,147,23,152,20,158,25,154,26,166,21,173,16,184,13,184,10,150,13,139,15,22,178,63,114,74,82,84,83,92,82,103,62,96,72,96,67,101,73,107,72,113,55,118,52,125,52,118,52,117,55,135,49,137,39,157,32,145,29,97,33,77,40,0,0,102,63,0,0,76,63,0,0,38,63,0,0,0,63,0,134,107,63,0,20,46,63,0,112,189,62,0,208,76,62,2,1,0,0,0,0,0,0,0,8,13,16,19,21,23,24,26,27,28,29,30,31,32,32,33,34,34,35,36,36,37,37,6,0,0,0,4,0,0,0,3,0,0,0,0,0,0,0,0,15,8,7,4,11,12,3,2,13,10,5,6,9,14,1,0,9,6,3,4,5,8,1,2,7,0,0,0,0,0,0,6,0,3,0,7,3,0,1,10,0,2,6,18,10,12,0,4,0,2,0,0,0,9,4,7,4,0,3,12,7,7,0,210,6,138,58,171,152,0,0,198,26,169,100,246,216,0,0,71,56,43,30,21,12,6,0,199,165,144,124,109,96,84,71,61,51,42,32,23,15,8,0,241,225,211,199,187,175,164,153,142,132,123,114,105,96,88,80,72,64,57,50,44,38,33,29,24,20,16,12,9,5,2,0,4,6,24,7,5,0,0,2,0,0,12,28,41,13,252,247,15,42,25,14,1,254,62,41,247,246,37,65,252,3,250,4,66,7,248,16,14,38,253,33,13,22,39,23,12,255,36,64,27,250,249,10,55,43,17,1,1,8,1,1,6,245,74,53,247,244,55,76,244,8,253,3,93,27,252,26,39,59,3,248,2,0,77,11,9,248,22,44,250,7,40,9,26,3,9,249,20,101,249,4,3,248,42,26,0,241,33,68,2,23,254,55,46,254,15,3,255,21,16,41,250,27,61,39,5,245,42,88,4,1,254,60,65,6,252,255,251,73,56,1,247,19,94,29,247,0,12,99,6,4,8,237,102,46,243,3,2,13,3,2,9,235,84,72,238,245,46,104,234,8,18,38,48,23,0,240,70,83,235,11,5,245,117,22,248,250,23,117,244,3,3,248,95,28,4,246,15,77,60,241,255,4,124,2,252,3,38,84,24,231,2,13,42,13,31,21,252,56,46,255,255,35,79,243,19,249,65,88,247,242,20,4,81,49,227,20,0,75,3,239,5,247,44,92,248,1,253,22,69,31,250,95,41,244,5,39,67,16,252,1,0,250,120,55,220,243,44,122,4,232,81,5,11,3,7,2,0,9,10,88,12,35,60,83,108,132,157,180,206,228,15,32,55,77,101,125,151,175,201,225,19,42,66,89,114,137,162,184,209,230,12,25,50,72,97,120,147,172,200,223,26,44,69,90,114,135,159,180,205,225,13,22,53,80,106,130,156,180,205,228,15,25,44,64,90,115,142,168,196,222,19,24,62,82,100,120,145,168,190,214,22,31,50,79,103,120,151,170,203,227,21,29,45,65,106,124,150,171,196,224,30,49,75,97,121,142,165,186,209,229,19,25,52,70,93,116,143,166,192,219,26,34,62,75,97,118,145,167,194,217,25,33,56,70,91,113,143,165,196,223,21,34,51,72,97,117,145,171,196,222,20,29,50,67,90,117,144,168,197,221,22,31,48,66,95,117,146,168,196,222,24,33,51,77,116,134,158,180,200,224,21,28,70,87,106,124,149,170,194,217,26,33,53,64,83,117,152,173,204,225,27,34,65,95,108,129,155,174,210,225,20,26,72,99,113,131,154,176,200,219,34,43,61,78,93,114,155,177,205,229,23,29,54,97,124,138,163,179,209,229,30,38,56,89,118,129,158,178,200,231,21,29,49,63,85,111,142,163,193,222,27,48,77,103,133,158,179,196,215,232,29,47,74,99,124,151,176,198,220,237,33,42,61,76,93,121,155,174,207,225,29,53,87,112,136,154,170,188,208,227,24,30,52,84,131,150,166,186,203,229,37,48,64,84,104,118,156,177,201,230,212,178,148,129,108,96,85,82,79,77,61,59,57,56,51,49,48,45,42,41,40,38,36,34,31,30,21,12,10,3,1,0,255,245,244,236,233,225,217,203,190,176,175,161,149,136,125,114,102,91,81,71,60,52,43,35,28,20,19,18,12,11,5,0,179,138,140,148,151,149,153,151,163,116,67,82,59,92,72,100,89,92,0,0,0,0,0,0,16,0,0,0,0,99,66,36,36,34,36,34,34,34,34,83,69,36,52,34,116,102,70,68,68,176,102,68,68,34,65,85,68,84,36,116,141,152,139,170,132,187,184,216,137,132,249,168,185,139,104,102,100,68,68,178,218,185,185,170,244,216,187,187,170,244,187,187,219,138,103,155,184,185,137,116,183,155,152,136,132,217,184,184,170,164,217,171,155,139,244,169,184,185,170,164,216,223,218,138,214,143,188,218,168,244,141,136,155,170,168,138,220,219,139,164,219,202,216,137,168,186,246,185,139,116,185,219,185,138,100,100,134,100,102,34,68,68,100,68,168,203,221,218,168,167,154,136,104,70,164,246,171,137,139,137,155,218,219,139,255,254,253,238,14,3,2,1,0,255,254,252,218,35,3,2,1,0,255,254,250,208,59,4,2,1,0,255,254,246,194,71,10,2,1,0,255,252,236,183,82,8,2,1,0,255,252,235,180,90,17,2,1,0,255,248,224,171,97,30,4,1,0,255,254,236,173,95,37,7,1,0,255,255,255,131,6,145,255,255,255,255,255,236,93,15,96,255,255,255,255,255,194,83,25,71,221,255,255,255,255,162,73,34,66,162,255,255,255,210,126,73,43,57,173,255,255,255,201,125,71,48,58,130,255,255,255,166,110,73,57,62,104,210,255,255,251,123,65,55,68,100,171,255,250,0,3,0,6,0,3,0,3,0,3,0,4,0,3,0,3,0,3,0,205,1,0,0,7,23,38,54,69,85,100,116,131,147,162,178,193,208,223,239,13,25,41,55,69,83,98,112,127,142,157,171,187,203,220,236,15,21,34,51,61,78,92,106,126,136,152,167,185,205,225,240,10,21,36,50,63,79,95,110,126,141,157,173,189,205,221,237,17,20,37,51,59,78,89,107,123,134,150,164,184,205,224,240,10,15,32,51,67,81,96,112,129,142,158,173,189,204,220,236,8,21,37,51,65,79,98,113,126,138,155,168,179,192,209,218,12,15,34,55,63,78,87,108,118,131,148,167,185,203,219,236,16,19,32,36,56,79,91,108,118,136,154,171,186,204,220,237,11,28,43,58,74,89,105,120,135,150,165,180,196,211,226,241,6,16,33,46,60,75,92,107,123,137,156,169,185,199,214,225,11,19,30,44,57,74,89,105,121,135,152,169,186,202,218,234,12,19,29,46,57,71,88,100,120,132,148,165,182,199,216,233,17,23,35,46,56,77,92,106,123,134,152,167,185,204,222,237,14,17,45,53,63,75,89,107,115,132,151,171,188,206,221,240,9,16,29,40,56,71,88,103,119,137,154,171,189,205,222,237,16,19,36,48,57,76,87,105,118,132,150,167,185,202,218,236,12,17,29,54,71,81,94,104,126,136,149,164,182,201,221,237,15,28,47,62,79,97,115,129,142,155,168,180,194,208,223,238,8,14,30,45,62,78,94,111,127,143,159,175,192,207,223,239,17,30,49,62,79,92,107,119,132,145,160,174,190,204,220,235,14,19,36,45,61,76,91,108,121,138,154,172,189,205,222,238,12,18,31,45,60,76,91,107,123,138,154,171,187,204,221,236,13,17,31,43,53,70,83,103,114,131,149,167,185,203,220,237,17,22,35,42,58,78,93,110,125,139,155,170,188,206,224,240,8,15,34,50,67,83,99,115,131,146,162,178,193,209,224,239,13,16,41,66,73,86,95,111,128,137,150,163,183,206,225,241,17,25,37,52,63,75,92,102,119,132,144,160,175,191,212,231,19,31,49,65,83,100,117,133,147,161,174,187,200,213,227,242,18,31,52,68,88,103,117,126,138,149,163,177,192,207,223,239,16,29,47,61,76,90,106,119,133,147,161,176,193,209,224,240,15,21,35,50,61,73,86,97,110,119,129,141,175,198,218,237,225,204,201,184,183,175,158,154,153,135,119,115,113,110,109,99,98,95,79,68,52,50,48,45,43,32,31,27,18,10,3,0,255,251,235,230,212,201,196,182,167,166,163,151,138,124,110,104,90,78,76,70,69,57,45,34,24,21,11,6,5,4,3,0,175,148,160,176,178,173,174,164,177,174,196,182,198,192,182,68,62,66,60,72,117,85,90,118,136,151,142,160,142,155,0,0,0,0,0,0,0,0,0,1,100,102,102,68,68,36,34,96,164,107,158,185,180,185,139,102,64,66,36,34,34,0,1,32,208,139,141,191,152,185,155,104,96,171,104,166,102,102,102,132,1,0,0,0,0,16,16,0,80,109,78,107,185,139,103,101,208,212,141,139,173,153,123,103,36,0,0,0,0,0,0,1,48,0,0,0,0,0,0,32,68,135,123,119,119,103,69,98,68,103,120,118,118,102,71,98,134,136,157,184,182,153,139,134,208,168,248,75,189,143,121,107,32,49,34,34,34,0,17,2,210,235,139,123,185,137,105,134,98,135,104,182,100,183,171,134,100,70,68,70,66,66,34,131,64,166,102,68,36,2,1,0,134,166,102,68,34,34,66,132,212,246,158,139,107,107,87,102,100,219,125,122,137,118,103,132,114,135,137,105,171,106,50,34,164,214,141,143,185,151,121,103,192,34,0,0,0,0,0,1,208,109,74,187,134,249,159,137,102,110,154,118,87,101,119,101,0,2,0,36,36,66,68,35,96,164,102,100,36,0,2,33,167,138,174,102,100,84,2,2,100,107,120,119,36,197,24,0,255,254,253,244,12,3,2,1,0,255,254,252,224,38,3,2,1,0,255,254,251,209,57,4,2,1,0,255,254,244,195,69,4,2,1,0,255,251,232,184,84,7,2,1,0,255,254,240,186,86,14,2,1,0,255,254,239,178,91,30,5,1,0,255,248,227,177,100,19,2,1,0,255,255,255,156,4,154,255,255,255,255,255,227,102,15,92,255,255,255,255,255,213,83,24,72,236,255,255,255,255,150,76,33,63,214,255,255,255,190,121,77,43,55,185,255,255,255,245,137,71,43,59,139,255,255,255,255,131,66,50,66,107,194,255,255,166,116,76,55,53,125,255,255,100,0,3,0,40,0,3,0,3,0,3,0,5,0,14,0,14,0,10,0,11,0,3,0,8,0,9,0,7,0,3,0,91,1,0,0,0,0,0,0,203,150,0,0,0,0,0,0,215,195,166,125,110,82,0,0,255,255,0,0,0,0,0,0,184,126,154,121,0,0,0,0,154,121,102,102,0,0,0,0,184,126,51,115,0,0,0,0,15,0,0,0,10,0,0,0,5,0,0,0,0,0,0,0,128,187,0,0,120,0,0,0,21,0,0,0,21,0,0,0,0,154,89,63,0,0,0,0,0,0,128,63,0,0,128,63,224,20,0,0,3,0,0,0,8,0,0,0,120,0,0,0,11,0,0,0,16,21,0,0,248,21,0,0,40,22,0,0,128,7,0,0,3,0,0,0,8,24,0,0,64,24,0,0,120,24,0,0,176,24,0,0,232,24,0,0,136,1,0,0,8,53,0,0,224,53,0,0,104,55,0,0,0,0,0,0,0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,10,0,12,0,14,0,16,0,20,0,24,0,28,0,34,0,40,0,48,0,60,0,78,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,80,75,69,63,56,49,40,34,29,20,18,10,0,0,0,0,0,0,0,0,110,100,90,84,78,71,65,58,51,45,39,32,26,20,12,0,0,0,0,0,0,118,110,103,93,86,80,75,70,65,59,53,47,40,31,23,15,4,0,0,0,0,126,119,112,104,95,89,83,78,72,66,60,54,47,39,32,25,17,12,1,0,0,134,127,120,114,103,97,91,85,78,72,66,60,54,47,41,35,29,23,16,10,1,144,137,130,124,113,107,101,95,88,82,76,70,64,57,51,45,39,33,26,15,1,152,145,138,132,123,117,111,105,98,92,86,80,74,67,61,55,49,43,36,20,1,162,155,148,142,133,127,121,115,108,102,96,90,84,77,71,65,59,53,46,30,1,172,165,158,152,143,137,131,125,118,112,106,100,94,87,81,75,69,63,56,45,20,200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,8,0,8,0,8,0,16,0,16,0,16,0,21,0,21,0,24,0,29,0,34,0,36,0,0,0,0,0,0,0,106,28,141,56,82,187,30,58,8,105,220,58,130,237,87,59,137,99,178,59,3,42,5,60,48,220,57,60,180,62,119,60,28,163,158,60,209,242,197,60,254,134,241,60,155,171,16,61,5,173,42,61,132,194,70,61,83,230,100,61,17,137,130,61,135,159,147,61,203,178,165,61,209,190,184,61,58,191,204,61,84,175,225,61,20,138,247,61,14,37,7,62,217,244,18,62,95,49,31,62,104,215,43,62,138,227,56,62,48,82,70,62,148,31,84,62,191,71,98,62,142,198,112,62,176,151,127,62,82,91,135,62,96,15,143,62,152,229,150,62,121,219,158,62,112,238,166,62,216,27,175,62,251,96,183,62,17,187,191,62,70,39,200,62,183,162,208,62,120,42,217,62,148,187,225,62,12,83,234,62,222,237,242,62,6,137,251,62,190,16,2,63,31,90,6,63,36,159,10,63,80,222,14,63,43,22,19,63,65,69,23,63,37,106,27,63,115,131,31,63,206,143,35,63,230,141,39,63,116,124,43,63,63,90,47,63,25,38,51,63,231,222,54,63,153,131,58,63,51,19,62,63,197,140,65,63,119,239,68,63,127,58,72,63,39,109,75,63,206,134,78,63,229,134,81,63,241,108,84,63,142,56,87,63,105,233,89,63,69,127,92,63,250,249,94,63,115,89,97,63,175,157,99,63,193,198,101,63,207,212,103,63,17,200,105,63,210,160,107,63,110,95,109,63,80,4,111,63,244,143,112,63,230,2,114,63,189,93,115,63,31,161,116,63,191,205,117,63,87,228,118,63,176,229,119,63,151,210,120,63,227,171,121,63,115,114,122,63,39,39,123,63,231,202,123,63,157,94,124,63,53,227,124,63,156,89,125,63,189,194,125,63,134,31,126,63,222,112,126,63,171,183,126,63,207,244,126,63,38,41,127,63,134,85,127,63,190,122,127,63,150,153,127,63,204,178,127,63,20,199,127,63,28,215,127,63,130,227,127,63,221,236,127,63,182,243,127,63,138,248,127,63,200,251,127,63,214,253,127,63,7,255,127,63,165,255,127,63,232,255,127,63,253,255,127,63,0,0,128,63,224,1,0,0,135,136,8,59,255,255,255,255,5,0,96,0,3,0,32,0,4,0,8,0,2,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,88,74,0,0,136,56,0,0,0,0,0,0,240,0,0,0,137,136,136,59,1,0,0,0,5,0,48,0,3,0,16,0,4,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,72,0,0,136,56,0,0,0,0,0,0,120,0,0,0,136,136,8,60,2,0,0,0,5,0,24,0,3,0,8,0,2,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,136,71,0,0,136,56,0,0,0,0,0,0,60,0,0,0,137,136,136,60,3,0,0,0,5,0,12,0,3,0,4,0,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,56,0,0,136,56,0,0,0,0,0,0,255,255,127,63,142,255,127,63,106,254,127,63,147,252,127,63,7,250,127,63,200,246,127,63,214,242,127,63,48,238,127,63,214,232,127,63,200,226,127,63,7,220,127,63,147,212,127,63,107,204,127,63,143,195,127,63,0,186,127,63,189,175,127,63,199,164,127,63,29,153,127,63,192,140,127,63,176,127,127,63,236,113,127,63,118,99,127,63,75,84,127,63,110,68,127,63,222,51,127,63,154,34,127,63,163,16,127,63,250,253,126,63,157,234,126,63,141,214,126,63,203,193,126,63,86,172,126,63,46,150,126,63,83,127,126,63,198,103,126,63,134,79,126,63,148,54,126,63,239,28,126,63,152,2,126,63,143,231,125,63,211,203,125,63,102,175,125,63,70,146,125,63,116,116,125,63,241,85,125,63,188,54,125,63,213,22,125,63,60,246,124,63,242,212,124,63,246,178,124,63,73,144,124,63,235,108,124,63,219,72,124,63,27,36,124,63,169,254,123,63,135,216,123,63,180,177,123,63,48,138,123,63,252,97,123,63,23,57,123,63,130,15,123,63,61,229,122,63,72,186,122,63,162,142,122,63,77,98,122,63,72,53,122,63,148,7,122,63,48,217,121,63,29,170,121,63,90,122,121,63,233,73,121,63,200,24,121,63,249,230,120,63,123,180,120,63,78,129,120,63,115,77,120,63,234,24,120,63,178,227,119,63,205,173,119,63,58,119,119,63,249,63,119,63,10,8,119,63,110,207,118,63,37,150,118,63,47,92,118,63,140,33,118,63,60,230,117,63,64,170,117,63,151,109,117,63,66,48,117,63,65,242,116,63,148,179,116,63,59,116,116,63,55,52,116,63,135,243,115,63,44,178,115,63,38,112,115,63,118,45,115,63,26,234,114,63,20,166,114,63,100,97,114,63,10,28,114,63,5,214,113,63,87,143,113,63,0,72,113,63,255,255,112,63,85,183,112,63,2,110,112,63,6,36,112,63,98,217,111,63,21,142,111,63,32,66,111,63,132,245,110,63,63,168,110,63,83,90,110,63,192,11,110,63,134,188,109,63,165,108,109,63,29,28,109,63,239,202,108,63,27,121,108,63,161,38,108,63,128,211,107,63,187,127,107,63,80,43,107,63,64,214,106,63,140,128,106,63,50,42,106,63,53,211,105,63,147,123,105,63,77,35,105,63,100,202,104,63,216,112,104,63,168,22,104,63,213,187,103,63,96,96,103,63,72,4,103,63,143,167,102,63,51,74,102,63,54,236,101,63,151,141,101,63,87,46,101,63,119,206,100,63,245,109,100,63,212,12,100,63,18,171,99,63,177,72,99,63,176,229,98,63,16,130,98,63,209,29,98,63,243,184,97,63,119,83,97,63,92,237,96,63,164,134,96,63,78,31,96,63,91,183,95,63,203,78,95,63,158,229,94,63,213,123,94,63,112,17,94,63,110,166,93,63,210,58,93,63,154,206,92,63,198,97,92,63,89,244,91,63,81,134,91,63,174,23,91,63,114,168,90,63,157,56,90,63,46,200,89,63,39,87,89,63,135,229,88,63,79,115,88,63,127,0,88,63,23,141,87,63,24,25,87,63,130,164,86,63,86,47,86,63,147,185,85,63,58,67,85,63,75,204,84,63,199,84,84,63,174,220,83,63,1,100,83,63,191,234,82,63,233,112,82,63,127,246,81,63,130,123,81,63,242,255,80,63,207,131,80,63,26,7,80,63,210,137,79,63,250,11,79,63,144,141,78,63,148,14,78,63,9,143,77,63,237,14,77,63,65,142,76,63,5,13,76,63,59,139,75,63,225,8,75,63,249,133,74,63,131,2,74,63,127,126,73,63,238,249,72,63,207,116,72,63,36,239,71,63,237,104,71,63,41,226,70,63,218,90,70,63,0,211,69,63,155,74,69,63,172,193,68,63,50,56,68,63,47,174,67,63,162,35,67,63,141,152,66,63,239,12,66,63,200,128,65,63,26,244,64,63,229,102,64,63,40,217,63,63,229,74,63,63,27,188,62,63,204,44,62,63,247,156,61,63,157,12,61,63,190,123,60,63,92,234,59,63,117,88,59,63,10,198,58,63,29,51,58,63,173,159,57,63,187,11,57,63,71,119,56,63,81,226,55,63,218,76,55,63,227,182,54,63,107,32,54,63,116,137,53,63,253,241,52,63,7,90,52,63,147,193,51,63,160,40,51,63,48,143,50,63,66,245,49,63,216,90,49,63,241,191,48,63,142,36,48,63,175,136,47,63,85,236,46,63,129,79,46,63,50,178,45,63,105,20,45,63,39,118,44,63,107,215,43,63,55,56,43,63,139,152,42,63,103,248,41,63,204,87,41,63,186,182,40,63,50,21,40,63,51,115,39,63,191,208,38,63,214,45,38,63,121,138,37,63,167,230,36,63,97,66,36,63,169,157,35,63,125,248,34,63,223,82,34,63,207,172,33,63,77,6,33,63,91,95,32,63,248,183,31,63,37,16,31,63,226,103,30,63,48,191,29,63,16,22,29,63,129,108,28,63,132,194,27,63,26,24,27,63,67,109,26,63,0,194,25,63,81,22,25,63,54,106,24,63,177,189,23,63,193,16,23,63,103,99,22,63,163,181,21,63,118,7,21,63,225,88,20,63,228,169,19,63,127,250,18,63,179,74,18,63,128,154,17,63,231,233,16,63,232,56,16,63,132,135,15,63,187,213,14,63,142,35,14,63,254,112,13,63,10,190,12,63,179,10,12,63,250,86,11,63,223,162,10,63,99,238,9,63,134,57,9,63,73,132,8,63,172,206,7,63,175,24,7,63,84,98,6,63,155,171,5,63,131,244,4,63,15,61,4,63,61,133,3,63,15,205,2,63,134,20,2,63,161,91,1,63,97,162,0,63,143,209,255,62,167,93,254,62,14,233,252,62,194,115,251,62,198,253,249,62,27,135,248,62,193,15,247,62,186,151,245,62,6,31,244,62,168,165,242,62,158,43,241,62,236,176,239,62,145,53,238,62,144,185,236,62,232,60,235,62,154,191,233,62,169,65,232,62,21,195,230,62,223,67,229,62,8,196,227,62,145,67,226,62,124,194,224,62,200,64,223,62,120,190,221,62,140,59,220,62,6,184,218,62,230,51,217,62,46,175,215,62,223,41,214,62,249,163,212,62,125,29,211,62,110,150,209,62,204,14,208,62,151,134,206,62,210,253,204,62,125,116,203,62,153,234,201,62,39,96,200,62,40,213,198,62,159,73,197,62,138,189,195,62,236,48,194,62,198,163,192,62,25,22,191,62,230,135,189,62,45,249,187,62,241,105,186,62,50,218,184,62,241,73,183,62,47,185,181,62,238,39,180,62,47,150,178,62,242,3,177,62,57,113,175,62,4,222,173,62,86,74,172,62,47,182,170,62,144,33,169,62,122,140,167,62,239,246,165,62,239,96,164,62,124,202,162,62,151,51,161,62,64,156,159,62,122,4,158,62,68,108,156,62,161,211,154,62,145,58,153,62,22,161,151,62,48,7,150,62,225,108,148,62,41,210,146,62,11,55,145,62,135,155,143,62,158,255,141,62,81,99,140,62,162,198,138,62,145,41,137,62,32,140,135,62,80,238,133,62,34,80,132,62,151,177,130,62,176,18,129,62,222,230,126,62,169,167,123,62,195,103,120,62,47,39,117,62,238,229,113,62,4,164,110,62,115,97,107,62,60,30,104,62,98,218,100,62,232,149,97,62,207,80,94,62,26,11,91,62,204,196,87,62,230,125,84,62,107,54,81,62,93,238,77,62,191,165,74,62,146,92,71,62,218,18,68,62,151,200,64,62,206,125,61,62,128,50,58,62,174,230,54,62,93,154,51,62,141,77,48,62,66,0,45,62,125,178,41,62,66,100,38,62,145,21,35,62,110,198,31,62,219,118,28,62,218,38,25,62,109,214,21,62,152,133,18,62,91,52,15,62,186,226,11,62,183,144,8,62,84,62,5,62,148,235,1,62,240,48,253,61,6,138,246,61,113,226,239,61,51,58,233,61,79,145,226,61,207,231,219,61,181,61,213,61,3,147,206,61,192,231,199,61,242,59,193,61,156,143,186,61,195,226,179,61,108,53,173,61,155,135,166,61,85,217,159,61,159,42,153,61,126,123,146,61,246,203,139,61,11,28,133,61,135,215,124,61,70,118,111,61,93,20,98,61,214,177,84,61,185,78,71,61,16,235,57,61,229,134,44,61,64,34,31,61,44,189,17,61,178,87,4,61,181,227,237,60,96,23,211,60,118,74,184,60,11,125,157,60,50,175,130,60,250,193,79,60,254,36,26,60,42,15,201,59,153,167,59,59,46,125,214,185,210,70,113,187,171,222,227,187,166,140,39,188,129,41,93,188,225,98,137,188,160,48,164,188,236,253,190,188,179,202,217,188,224,150,244,188,49,177,7,189,147,22,21,189,140,123,34,189,19,224,47,189,30,68,61,189,165,167,74,189,157,10,88,189,254,108,101,189,190,206,114,189,234,23,128,189,27,200,134,189,237,119,141,189,92,39,148,189,99,214,154,189,253,132,161,189,38,51,168,189,217,224,174,189,17,142,181,189,202,58,188,189,254,230,194,189,170,146,201,189,200,61,208,189,84,232,214,189,74,146,221,189,164,59,228,189,93,228,234,189,114,140,241,189,221,51,248,189,154,218,254,189,82,192,2,190,252,18,6,190,71,101,9,190,50,183,12,190,186,8,16,190,221,89,19,190,152,170,22,190,234,250,25,190,208,74,29,190,71,154,32,190,78,233,35,190,225,55,39,190,0,134,42,190,166,211,45,190,211,32,49,190,131,109,52,190,181,185,55,190,101,5,59,190,147,80,62,190,58,155,65,190,90,229,68,190,240,46,72,190,249,119,75,190,116,192,78,190,93,8,82,190,179,79,85,190,115,150,88,190,156,220,91,190,42,34,95,190,27,103,98,190,109,171,101,190,31,239,104,190,44,50,108,190,148,116,111,190,84,182,114,190,106,247,117,190,211,55,121,190,141,119,124,190,150,182,127,190,117,122,129,190,69,25,131,190,185,183,132,190,208,85,134,190,136,243,135,190,225,144,137,190,218,45,139,190,112,202,140,190,164,102,142,190,116,2,144,190,223,157,145,190,228,56,147,190,129,211,148,190,182,109,150,190,129,7,152,190,226,160,153,190,215,57,155,190,95,210,156,190,121,106,158,190,35,2,160,190,94,153,161,190,38,48,163,190,125,198,164,190,96,92,166,190,206,241,167,190,198,134,169,190,71,27,171,190,80,175,172,190,224,66,174,190,245,213,175,190,143,104,177,190,173,250,178,190,77,140,180,190,110,29,182,190,16,174,183,190,48,62,185,190,207,205,186,190,234,92,188,190,130,235,189,190,148,121,191,190,31,7,193,190,35,148,194,190,159,32,196,190,145,172,197,190,248,55,199,190,211,194,200,190,34,77,202,190,226,214,203,190,19,96,205,190,181,232,206,190,197,112,208,190,66,248,209,190,45,127,211,190,131,5,213,190,67,139,214,190,109,16,216,190,255,148,217,190,249,24,219,190,89,156,220,190,29,31,222,190,70,161,223,190,211,34,225,190,193,163,226,190,16,36,228,190,190,163,229,190,204,34,231,190,56,161,232,190,0,31,234,190,36,156,235,190,162,24,237,190,122,148,238,190,171,15,240,190,51,138,241,190,18,4,243,190,70,125,244,190,207,245,245,190,170,109,247,190,217,228,248,190,88,91,250,190,40,209,251,190,71,70,253,190,181,186,254,190,56,23,0,191,187,208,0,191,228,137,1,191,178,66,2,191,37,251,2,191,59,179,3,191,246,106,4,191,83,34,5,191,83,217,5,191,245,143,6,191,56,70,7,191,29,252,7,191,162,177,8,191,199,102,9,191,140,27,10,191,240,207,10,191,243,131,11,191,147,55,12,191,209,234,12,191,172,157,13,191,36,80,14,191,56,2,15,191,232,179,15,191,50,101,16,191,24,22,17,191,151,198,17,191,176,118,18,191,99,38,19,191,174,213,19,191,145,132,20,191,13,51,21,191,31,225,21,191,200,142,22,191,8,60,23,191,221,232,23,191,72,149,24,191,72,65,25,191,220,236,25,191,4,152,26,191,192,66,27,191,15,237,27,191,240,150,28,191,99,64,29,191,104,233,29,191,254,145,30,191,37,58,31,191,220,225,31,191,35,137,32,191,250,47,33,191,95,214,33,191,82,124,34,191,212,33,35,191,227,198,35,191,127,107,36,191,167,15,37,191,92,179,37,191,157,86,38,191,104,249,38,191,191,155,39,191,160,61,40,191,11,223,40,191,255,127,41,191,125,32,42,191,131,192,42,191,17,96,43,191,39,255,43,191,196,157,44,191,232,59,45,191,146,217,45,191,195,118,46,191,121,19,47,191,180,175,47,191,115,75,48,191,183,230,48,191,127,129,49,191,203,27,50,191,153,181,50,191,234,78,51,191,189,231,51,191,18,128,52,191,232,23,53,191,63,175,53,191,22,70,54,191,110,220,54,191,69,114,55,191,156,7,56,191,113,156,56,191,197,48,57,191,150,196,57,191,230,87,58,191,178,234,58,191,252,124,59,191,194,14,60,191,3,160,60,191,193,48,61,191,250,192,61,191,173,80,62,191,219,223,62,191,131,110,63,191,165,252,63,191,64,138,64,191,83,23,65,191,224,163,65,191,228,47,66,191,96,187,66,191,83,70,67,191,190,208,67,191,158,90,68,191,246,227,68,191,194,108,69,191,5,245,69,191,188,124,70,191,232,3,71,191,137,138,71,191,157,16,72,191,37,150,72,191,32,27,73,191,142,159,73,191,111,35,74,191,193,166,74,191,134,41,75,191,188,171,75,191,99,45,76,191,122,174,76,191,2,47,77,191,250,174,77,191,98,46,78,191,57,173,78,191,126,43,79,191,51,169,79,191,85,38,80,191,230,162,80,191,228,30,81,191,80,154,81,191,40,21,82,191,109,143,82,191,30,9,83,191,59,130,83,191,195,250,83,191,183,114,84,191,22,234,84,191,223,96,85,191,18,215,85,191,176,76,86,191,183,193,86,191,39,54,87,191,0,170,87,191,66,29,88,191,236,143,88,191,254,1,89,191,120,115,89,191,89,228,89,191,162,84,90,191,81,196,90,191,102,51,91,191,226,161,91,191,195,15,92,191,10,125,92,191,183,233,92,191,200,85,93,191,62,193,93,191,24,44,94,191,87,150,94,191,249,255,94,191,255,104,95,191,104,209,95,191,51,57,96,191,98,160,96,191,243,6,97,191,229,108,97,191,58,210,97,191,240,54,98,191,8,155,98,191,128,254,98,191,89,97,99,191,146,195,99,191,44,37,100,191,37,134,100,191,126,230,100,191,55,70,101,191,78,165,101,191,197,3,102,191,154,97,102,191,205,190,102,191,94,27,103,191,77,119,103,191,154,210,103,191,68,45,104,191,75,135,104,191,174,224,104,191,111,57,105,191,139,145,105,191,4,233,105,191,217,63,106,191,9,150,106,191,148,235,106,191,123,64,107,191,188,148,107,191,89,232,107,191,79,59,108,191,160,141,108,191,75,223,108,191,79,48,109,191,173,128,109,191,101,208,109,191,117,31,110,191,223,109,110,191,161,187,110,191,187,8,111,191,46,85,111,191,248,160,111,191,27,236,111,191,149,54,112,191,103,128,112,191,144,201,112,191,15,18,113,191,230,89,113,191,19,161,113,191,151,231,113,191,113,45,114,191,160,114,114,191,38,183,114,191,1,251,114,191,50,62,115,191,184,128,115,191,148,194,115,191,196,3,116,191,73,68,116,191,34,132,116,191,80,195,116,191,210,1,117,191,168,63,117,191,210,124,117,191,80,185,117,191,33,245,117,191,69,48,118,191,189,106,118,191,136,164,118,191,166,221,118,191,22,22,119,191,217,77,119,191,239,132,119,191,87,187,119,191,17,241,119,191,29,38,120,191,122,90,120,191,42,142,120,191,43,193,120,191,125,243,120,191,33,37,121,191,22,86,121,191,92,134,121,191,242,181,121,191,218,228,121,191,18,19,122,191,154,64,122,191,115,109,122,191,157,153,122,191,22,197,122,191,223,239,122,191,248,25,123,191,97,67,123,191,26,108,123,191,34,148,123,191,122,187,123,191,32,226,123,191,23,8,124,191,92,45,124,191,240,81,124,191,211,117,124,191,5,153,124,191,134,187,124,191,85,221,124,191,115,254,124,191,223,30,125,191,154,62,125,191,163,93,125,191,250,123,125,191,159,153,125,191,146,182,125,191,211,210,125,191,98,238,125,191,63,9,126,191,105,35,126,191,225,60,126,191,167,85,126,191,186,109,126,191,27,133,126,191,201,155,126,191,196,177,126,191,13,199,126,191,162,219,126,191,133,239,126,191,181,2,127,191,50,21,127,191,252,38,127,191,19,56,127,191,118,72,127,191,39,88,127,191,36,103,127,191,110,117,127,191,5,131,127,191,232,143,127,191,25,156,127,191,149,167,127,191,95,178,127,191,116,188,127,191,215,197,127,191,133,206,127,191,129,214,127,191,200,221,127,191,93,228,127,191,61,234,127,191,106,239,127,191,227,243,127,191,169,247,127,191,187,250,127,191,25,253,127,191,196,254,127,191,187,255,127,191,250,255,127,63,57,254,127,63,169,249,127,63,75,242,127,63,30,232,127,63,35,219,127,63,89,203,127,63,193,184,127,63],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);allocate([91,163,127,63,40,139,127,63,39,112,127,63,90,82,127,63,191,49,127,63,88,14,127,63,37,232,126,63,38,191,126,63,92,147,126,63,200,100,126,63,105,51,126,63,65,255,125,63,79,200,125,63,150,142,125,63,20,82,125,63,203,18,125,63,188,208,124,63,231,139,124,63,77,68,124,63,239,249,123,63,205,172,123,63,233,92,123,63,67,10,123,63,221,180,122,63,182,92,122,63,209,1,122,63,46,164,121,63,206,67,121,63,178,224,120,63,220,122,120,63,76,18,120,63,4,167,119,63,4,57,119,63,79,200,118,63,228,84,118,63,198,222,117,63,246,101,117,63,117,234,116,63,68,108,116,63,101,235,115,63,218,103,115,63,163,225,114,63,194,88,114,63,57,205,113,63,9,63,113,63,52,174,112,63,187,26,112,63,160,132,111,63,228,235,110,63,138,80,110,63,147,178,109,63,1,18,109,63,213,110,108,63,17,201,107,63,183,32,107,63,201,117,106,63,73,200,105,63,57,24,105,63,155,101,104,63,111,176,103,63,186,248,102,63,124,62,102,63,184,129,101,63,111,194,100,63,164,0,100,63,90,60,99,63,145,117,98,63,76,172,97,63,142,224,96,63,89,18,96,63,174,65,95,63,145,110,94,63,3,153,93,63,8,193,92,63,160,230,91,63,207,9,91,63,152,42,90,63,251,72,89,63,253,100,88,63,159,126,87,63,229,149,86,63,208,170,85,63,99,189,84,63,161,205,83,63,140,219,82,63,39,231,81,63,117,240,80,63,121,247,79,63,52,252,78,63,171,254,77,63,223,254,76,63,212,252,75,63,140,248,74,63,10,242,73,63,82,233,72,63,101,222,71,63,71,209,70,63,251,193,69,63,132,176,68,63,229,156,67,63,32,135,66,63,58,111,65,63,52,85,64,63,19,57,63,63,216,26,62,63,136,250,60,63,38,216,59,63,180,179,58,63,54,141,57,63,175,100,56,63,34,58,55,63,147,13,54,63,5,223,52,63,124,174,51,63,249,123,50,63,130,71,49,63,25,17,48,63,194,216,46,63,127,158,45,63,86,98,44,63,72,36,43,63,90,228,41,63,144,162,40,63,235,94,39,63,113,25,38,63,37,210,36,63,9,137,35,63,35,62,34,63,117,241,32,63,4,163,31,63,210,82,30,63,228,0,29,63,61,173,27,63,225,87,26,63,211,0,25,63,25,168,23,63,180,77,22,63,170,241,20,63,253,147,19,63,178,52,18,63,204,211,16,63,80,113,15,63,66,13,14,63,164,167,12,63,124,64,11,63,205,215,9,63,154,109,8,63,233,1,7,63,189,148,5,63,25,38,4,63,3,182,2,63,126,68,1,63,28,163,255,62,110,186,252,62,250,206,249,62,202,224,246,62,228,239,243,62,81,252,240,62,26,6,238,62,71,13,235,62,224,17,232,62,237,19,229,62,119,19,226,62,135,16,223,62,36,11,220,62,88,3,217,62,42,249,213,62,164,236,210,62,205,221,207,62,175,204,204,62,82,185,201,62,191,163,198,62,254,139,195,62,24,114,192,62,22,86,189,62,0,56,186,62,224,23,183,62,189,245,179,62,161,209,176,62,149,171,173,62,162,131,170,62,207,89,167,62,39,46,164,62,178,0,161,62,121,209,157,62,133,160,154,62,223,109,151,62,143,57,148,62,160,3,145,62,26,204,141,62,5,147,138,62,107,88,135,62,86,28,132,62,205,222,128,62,182,63,123,62,16,191,116,62,187,59,110,62,201,181,103,62,77,45,97,62,89,162,90,62,255,20,84,62,81,133,77,62,99,243,70,62,70,95,64,62,13,201,57,62,202,48,51,62,144,150,44,62,114,250,37,62,130,92,31,62,210,188,24,62,118,27,18,62,127,120,11,62,1,212,4,62,29,92,252,61,114,13,239,61,41,188,225,61,102,104,212,61,78,18,199,61,8,186,185,61,184,95,172,61,132,3,159,61,146,165,145,61,7,70,132,61,18,202,109,61,122,5,83,61,145,62,56,61,164,117,29,61,252,170,2,61,202,189,207,60,86,35,154,60,97,14,73,60,197,167,187,59,61,122,86,186,9,70,241,187,18,221,99,188,80,138,167,188,65,36,221,188,227,93,9,189,35,40,36,189,150,240,62,189,242,182,89,189,234,122,116,189,26,158,135,189,66,253,148,189,200,90,162,189,134,182,175,189,87,16,189,189,22,104,202,189,155,189,215,189,195,16,229,189,105,97,242,189,101,175,255,189,74,125,6,190,104,33,13,190,250,195,19,190,237,100,26,190,46,4,33,190,172,161,39,190,83,61,46,190,16,215,52,190,210,110,59,190,134,4,66,190,25,152,72,190,121,41,79,190,148,184,85,190,86,69,92,190,174,207,98,190,137,87,105,190,214,220,111,190,128,95,118,190,120,223,124,190,84,174,129,190,129,235,132,190,56,39,136,190,114,97,139,190,36,154,142,190,69,209,145,190,205,6,149,190,179,58,152,190,238,108,155,190,116,157,158,190,61,204,161,190,64,249,164,190,115,36,168,190,207,77,171,190,73,117,174,190,218,154,177,190,120,190,180,190,27,224,183,190,186,255,186,190,75,29,190,190,199,56,193,190,37,82,196,190,91,105,199,190,97,126,202,190,48,145,205,190,188,161,208,190,0,176,211,190,241,187,214,190,135,197,217,190,186,204,220,190,129,209,223,190,211,211,226,190,169,211,229,190,250,208,232,190,189,203,235,190,234,195,238,190,120,185,241,190,96,172,244,190,154,156,247,190,28,138,250,190,223,116,253,190,109,46,0,191,3,161,1,191,45,18,3,191,230,129,4,191,44,240,5,191,250,92,7,191,76,200,8,191,30,50,10,191,108,154,11,191,50,1,13,191,108,102,14,191,23,202,15,191,45,44,17,191,172,140,18,191,144,235,19,191,213,72,21,191,118,164,22,191,113,254,23,191,192,86,25,191,98,173,26,191,81,2,28,191,138,85,29,191,9,167,30,191,203,246,31,191,204,68,33,191,9,145,34,191,124,219,35,191,36,36,37,191,253,106,38,191,2,176,39,191,48,243,40,191,132,52,42,191,250,115,43,191,143,177,44,191,63,237,45,191,7,39,47,191,227,94,48,191,208,148,49,191,202,200,50,191,206,250,51,191,218,42,53,191,232,88,54,191,247,132,55,191,2,175,56,191,7,215,57,191,3,253,58,191,241,32,60,191,207,66,61,191,154,98,62,191,79,128,63,191,233,155,64,191,104,181,65,191,198,204,66,191,1,226,67,191,23,245,68,191,3,6,70,191,196,20,71,191,86,33,72,191,182,43,73,191,225,51,74,191,212,57,75,191,141,61,76,191,9,63,77,191,68,62,78,191,61,59,79,191,240,53,80,191,90,46,81,191,121,36,82,191,74,24,83,191,202,9,84,191,247,248,84,191,206,229,85,191,77,208,86,191,112,184,87,191,55,158,88,191,156,129,89,191,160,98,90,191,62,65,91,191,117,29,92,191,65,247,92,191,162,206,93,191,148,163,94,191,20,118,95,191,34,70,96,191,186,19,97,191,217,222,97,191,127,167,98,191,169,109,99,191,84,49,100,191,126,242,100,191,38,177,101,191,73,109,102,191,229,38,103,191,248,221,103,191,128,146,104,191,123,68,105,191,232,243,105,191,195,160,106,191,12,75,107,191,192,242,107,191,222,151,108,191,100,58,109,191,80,218,109,191,160,119,110,191,83,18,111,191,102,170,111,191,217,63,112,191,169,210,112,191,213,98,113,191,91,240,113,191,58,123,114,191,113,3,115,191,253,136,115,191,222,11,116,191,17,140,116,191,150,9,117,191,107,132,117,191,143,252,117,191,0,114,118,191,189,228,118,191,198,84,119,191,24,194,119,191,178,44,120,191,147,148,120,191,187,249,120,191,40,92,121,191,217,187,121,191,205,24,122,191,2,115,122,191,121,202,122,191,47,31,123,191,36,113,123,191,88,192,123,191,201,12,124,191,118,86,124,191,95,157,124,191,130,225,124,191,224,34,125,191,119,97,125,191,71,157,125,191,79,214,125,191,142,12,126,191,4,64,126,191,176,112,126,191,146,158,126,191,169,201,126,191,245,241,126,191,117,23,127,191,41,58,127,191,16,90,127,191,43,119,127,191,120,145,127,191,248,168,127,191,170,189,127,191,143,207,127,191,165,222,127,191,237,234,127,191,102,244,127,191,17,251,127,191,237,254,127,191,234,255,127,63,229,248,127,63,166,230,127,63,45,201,127,63,124,160,127,63,149,108,127,63,121,45,127,63,44,227,126,63,177,141,126,63,11,45,126,63,63,193,125,63,82,74,125,63,72,200,124,63,40,59,124,63,247,162,123,63,189,255,122,63,128,81,122,63,72,152,121,63,30,212,120,63,9,5,120,63,19,43,119,63,70,70,118,63,172,86,117,63,78,92,116,63,56,87,115,63,118,71,114,63,19,45,113,63,28,8,112,63,158,216,110,63,165,158,109,63,64,90,108,63,126,11,107,63,107,178,105,63,25,79,104,63,150,225,102,63,242,105,101,63,62,232,99,63,139,92,98,63,234,198,96,63,109,39,95,63,38,126,93,63,40,203,91,63,133,14,90,63,83,72,88,63,163,120,86,63,139,159,84,63,32,189,82,63,118,209,80,63,163,220,78,63,189,222,76,63,219,215,74,63,19,200,72,63,124,175,70,63,46,142,68,63,65,100,66,63,206,49,64,63,236,246,61,63,180,179,59,63,66,104,57,63,173,20,55,63,16,185,52,63,134,85,50,63,41,234,47,63,21,119,45,63,101,252,42,63,53,122,40,63,161,240,37,63,198,95,35,63,192,199,32,63,172,40,30,63,169,130,27,63,212,213,24,63,74,34,22,63,42,104,19,63,147,167,16,63,164,224,13,63,123,19,11,63,57,64,8,63,253,102,5,63,231,135,2,63,45,70,255,62,91,113,249,62,151,145,243,62,36,167,237,62,69,178,231,62,60,179,225,62,76,170,219,62,186,151,213,62,201,123,207,62,190,86,201,62,223,40,195,62,112,242,188,62,183,179,182,62,251,108,176,62,129,30,170,62,146,200,163,62,115,107,157,62,108,7,151,62,197,156,144,62,199,43,138,62,185,180,131,62,199,111,122,62,33,107,109,62,17,92,96,62,41,67,83,62,253,32,70,62,32,246,56,62,38,195,43,62,164,136,30,62,45,71,17,62,87,255,3,62,110,99,237,61,194,189,210,61,218,14,184,61,222,87,157,61,251,153,130,61,188,172,79,61,101,28,26,61,153,10,201,60,42,167,59,60,193,120,214,186,45,68,113,188,87,215,227,188,76,129,39,189,148,15,93,189,21,74,137,189,90,6,164,189,109,187,190,189,34,104,217,189,78,11,244,189,227,81,7,190,47,152,20,190,247,215,33,190,165,16,47,190,166,65,60,190,100,106,73,190,77,138,86,190,205,160,99,190,80,173,112,190,69,175,125,190,13,83,133,190,158,200,139,190,13,56,146,190,18,161,152,190,102,3,159,190,191,94,165,190,216,178,171,190,105,255,177,190,43,68,184,190,216,128,190,190,42,181,196,190,219,224,202,190,165,3,209,190,69,29,215,190,117,45,221,190,241,51,227,190,118,48,233,190,192,34,239,190,141,10,245,190,155,231,250,190,211,92,0,191,56,64,3,191,219,29,6,191,155,245,8,191,90,199,11,191,247,146,14,191,84,88,17,191,80,23,20,191,205,207,22,191,172,129,25,191,208,44,28,191,26,209,30,191,109,110,33,191,171,4,36,191,183,147,38,191,116,27,41,191,199,155,43,191,147,20,46,191,187,133,48,191,38,239,50,191,183,80,53,191,85,170,55,191,227,251,57,191,74,69,60,191,110,134,62,191,55,191,64,191,139,239,66,191,83,23,69,191,117,54,71,191,218,76,73,191,107,90,75,191,16,95,77,191,179,90,79,191,62,77,81,191,154,54,83,191,179,22,85,191,114,237,86,191,197,186,88,191,149,126,90,191,208,56,92,191,98,233,93,191,56,144,95,191,64,45,97,191,103,192,98,191,156,73,100,191,206,200,101,191,235,61,103,191,227,168,104,191,167,9,106,191,39,96,107,191,84,172,108,191,31,238,109,191,122,37,111,191,88,82,112,191,171,116,113,191,103,140,114,191,127,153,115,191,231,155,116,191,149,147,117,191,126,128,118,191,150,98,119,191,212,57,120,191,47,6,121,191,158,199,121,191,23,126,122,191,148,41,123,191,13,202,123,191,122,95,124,191,213,233,124,191,24,105,125,191,62,221,125,191,64,70,126,191,28,164,126,191,204,246,126,191,77,62,127,191,156,122,127,191,182,171,127,191,153,209,127,191,67,236,127,191,180,251,127,191,166,255,127,63,148,227,127,63,156,154,127,63,204,36,127,63,56,130,126,63,253,178,125,63,63,183,124,63,42,143,123,63,243,58,122,63,212,186,120,63,17,15,119,63,246,55,117,63,213,53,115,63,8,9,113,63,241,177,110,63,249,48,108,63,144,134,105,63,47,179,102,63,83,183,99,63,132,147,96,63,78,72,93,63,69,214,89,63,3,62,86,63,43,128,82,63,101,157,78,63,94,150,74,63,204,107,70,63,106,30,66,63,249,174,61,63,64,30,57,63,13,109,52,63,50,156,47,63,135,172,42,63,235,158,37,63,63,116,32,63,109,45,27,63,97,203,21,63,13,79,16,63,104,185,10,63,107,11,5,63,46,140,254,62,221,212,242,62,241,242,230,62,127,232,218,62,166,183,206,62,136,98,194,62,78,235,181,62,42,84,169,62,81,159,156,62,253,206,143,62,109,229,130,62,206,201,107,62,98,159,81,62,48,80,55,62,211,224,28,62,241,85,2,62,98,104,207,61,124,0,154,61,36,251,72,61,27,164,187,60,243,119,86,187,100,61,241,188,187,192,99,189,103,93,167,189,20,189,220,189,3,251,8,190,115,127,35,190,52,231,61,190,164,45,88,190,38,78,114,190,18,34,134,190,137,5,147,190,52,207,159,190,213,124,172,190,51,12,185,190,26,123,197,190,91,199,209,190,205,238,221,190,80,239,233,190,199,198,245,190,144,185,0,191,38,121,6,191,36,33,12,191,141,176,17,191,102,38,23,191,186,129,28,191,152,193,33,191,21,229,38,191,74,235,43,191,86,211,48,191,91,156,53,191,131,69,58,191,253,205,62,191,252,52,67,191,188,121,71,191,125,155,75,191,132,153,79,191,31,115,83,191,161,39,87,191,99,182,90,191,198,30,94,191,48,96,97,191,15,122,100,191,216,107,103,191,7,53,106,191,31,213,108,191,169,75,111,191,55,152,113,191,98,186,115,191,201,177,117,191,22,126,119,191,246,30,121,191,33,148,122,191,85,221,123,191,89,250,124,191,250,234,125,191,14,175,126,191,116,70,127,191,15,177,127,191,206,238,127,191,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,41,0,41,0,41,0,82,0,82,0,123,0,164,0,200,0,222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,41,0,41,0,41,0,123,0,123,0,123,0,164,0,164,0,240,0,10,1,27,1,39,1,41,0,41,0,41,0,41,0,41,0,41,0,41,0,41,0,123,0,123,0,123,0,123,0,240,0,240,0,240,0,10,1,10,1,49,1,62,1,72,1,80,1,123,0,123,0,123,0,123,0,123,0,123,0,123,0,123,0,240,0,240,0,240,0,240,0,49,1,49,1,49,1,62,1,62,1,87,1,95,1,102,1,108,1,240,0,240,0,240,0,240,0,240,0,240,0,240,0,240,0,49,1,49,1,49,1,49,1,87,1,87,1,87,1,95,1,95,1,114,1,120,1,126,1,131,1,0,0,0,0,0,0,40,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,40,15,23,28,31,34,36,38,39,41,42,43,44,45,46,47,47,49,50,51,52,53,54,55,55,57,58,59,60,61,62,63,63,65,66,67,68,69,70,71,71,40,20,33,41,48,53,57,61,64,66,69,71,73,75,76,78,80,82,85,87,89,91,92,94,96,98,101,103,105,107,108,110,112,114,117,119,121,123,124,126,128,40,23,39,51,60,67,73,79,83,87,91,94,97,100,102,105,107,111,115,118,121,124,126,129,131,135,139,142,145,148,150,153,155,159,163,166,169,172,174,177,179,35,28,49,65,78,89,99,107,114,120,126,132,136,141,145,149,153,159,165,171,176,180,185,189,192,199,205,211,216,220,225,229,232,239,245,251,21,33,58,79,97,112,125,137,148,157,166,174,182,189,195,201,207,217,227,235,243,251,17,35,63,86,106,123,139,152,165,177,187,197,206,214,222,230,237,250,25,31,55,75,91,105,117,128,138,146,154,161,168,174,180,185,190,200,208,215,222,229,235,240,245,255,16,36,65,89,110,128,144,159,173,185,196,207,217,226,234,242,250,11,41,74,103,128,151,172,191,209,225,241,255,9,43,79,110,138,163,186,207,227,246,12,39,71,99,123,144,164,182,198,214,228,241,253,9,44,81,113,142,168,192,214,235,255,7,49,90,127,160,191,220,247,6,51,95,134,170,203,234,7,47,87,123,155,184,212,237,6,52,97,137,174,208,240,5,57,106,151,192,231,5,59,111,158,202,243,5,55,103,147,187,224,5,60,113,161,206,248,4,65,122,175,224,4,67,127,182,234,224,224,224,224,224,224,224,224,160,160,160,160,185,185,185,178,178,168,134,61,37,224,224,224,224,224,224,224,224,240,240,240,240,207,207,207,198,198,183,144,66,40,160,160,160,160,160,160,160,160,185,185,185,185,193,193,193,183,183,172,138,64,38,240,240,240,240,240,240,240,240,207,207,207,207,204,204,204,193,193,180,143,66,40,185,185,185,185,185,185,185,185,193,193,193,193,193,193,193,183,183,172,138,65,39,207,207,207,207,207,207,207,207,204,204,204,204,201,201,201,188,188,176,141,66,40,193,193,193,193,193,193,193,193,193,193,193,193,194,194,194,184,184,173,139,65,39,204,204,204,204,204,204,204,204,201,201,201,201,198,198,198,187,187,175,140,66,40,0,0,12,0,24,0,36,0,48,0,4,0,16,0,28,0,40,0,52,0,8,0,20,0,32,0,44,0,56,0,1,0,13,0,25,0,37,0,49,0,5,0,17,0,29,0,41,0,53,0,9,0,21,0,33,0,45,0,57,0,2,0,14,0,26,0,38,0,50,0,6,0,18,0,30,0,42,0,54,0,10,0,22,0,34,0,46,0,58,0,3,0,15,0,27,0,39,0,51,0,7,0,19,0,31,0,43,0,55,0,11,0,23,0,35,0,47,0,59,0,0,0,128,63,0,0,0,128,99,250,127,63,191,117,86,188,139,233,127,63,10,113,214,188,121,205,127,63,231,206,32,189,47,166,127,63,58,94,86,189,175,115,127,63,19,242,133,189,249,53,127,63,42,175,160,189,18,237,126,63,51,101,187,189,253,152,126,63,4,19,214,189,188,57,126,63,115,183,240,189,85,207,125,63,168,168,5,190,203,89,125,63,187,239,18,190,37,217,124,63,92,48,32,190,103,77,124,63,245,105,45,190,152,182,123,63,243,155,58,190,190,20,123,63,194,197,71,190,226,103,122,63,205,230,84,190,9,176,121,63,130,254,97,190,60,237,120,63,77,12,111,190,132,31,120,63,156,15,124,190,234,70,119,63,238,131,132,190,119,99,118,63,62,250,138,190,54,117,117,63,117,106,145,190,48,124,116,63,76,212,151,190,113,120,115,63,122,55,158,190,3,106,114,63,183,147,164,190,244,80,113,63,188,232,170,190,79,45,112,63,65,54,177,190,33,255,110,63,1,124,183,190,118,198,109,63,180,185,189,190,94,131,108,63,21,239,195,190,231,53,107,63,222,27,202,190,30,222,105,63,201,63,208,190,18,124,104,63,146,90,214,190,212,15,103,63,243,107,220,190,116,153,101,63,170,115,226,190,1,25,100,63,113,113,232,190,141,142,98,63,7,101,238,190,40,250,96,63,39,78,244,190,230,91,95,63,144,44,250,190,215,179,93,63,0,0,0,191,15,2,92,63,27,228,2,191,160,70,90,63,119,194,5,191,158,129,88,63,246,154,8,191,29,179,86,63,119,109,11,191,49,219,84,63,218,57,14,191,239,249,82,63,0,0,17,191,108,15,81,63,202,191,19,191,189,27,79,63,24,121,22,191,248,30,77,63,205,43,25,191,52,25,75,63,202,215,27,191,136,10,73,63,241,124,30,191,10,243,70,63,36,27,33,191,209,210,68,63,70,178,35,191,247,169,66,63,58,66,38,191,147,120,64,63,227,202,40,191,189,62,62,63,37,76,43,191,143,252,59,63,227,197,45,191,34,178,57,63,1,56,48,191,144,95,55,63,101,162,50,191,243,4,53,63,243,4,53,191,101,162,50,63,144,95,55,191,1,56,48,63,34,178,57,191,227,197,45,63,143,252,59,191,37,76,43,63,189,62,62,191,227,202,40,63,147,120,64,191,58,66,38,63,247,169,66,191,70,178,35,63,209,210,68,191,36,27,33,63,10,243,70,191,241,124,30,63,136,10,73,191,202,215,27,63,52,25,75,191,205,43,25,63,248,30,77,191,24,121,22,63,189,27,79,191,202,191,19,63,108,15,81,191,0,0,17,63,239,249,82,191,218,57,14,63,49,219,84,191,119,109,11,63,29,179,86,191,246,154,8,63,158,129,88,191,119,194,5,63,160,70,90,191,27,228,2,63,15,2,92,191,0,0,0,63,215,179,93,191,144,44,250,62,230,91,95,191,39,78,244,62,40,250,96,191,7,101,238,62,141,142,98,191,113,113,232,62,1,25,100,191,170,115,226,62,116,153,101,191,243,107,220,62,212,15,103,191,146,90,214,62,18,124,104,191,201,63,208,62,30,222,105,191,222,27,202,62,231,53,107,191,21,239,195,62,94,131,108,191,180,185,189,62,118,198,109,191,1,124,183,62,33,255,110,191,65,54,177,62,79,45,112,191,188,232,170,62,244,80,113,191,183,147,164,62,3,106,114,191,122,55,158,62,113,120,115,191,76,212,151,62,48,124,116,191,117,106,145,62,54,117,117,191,62,250,138,62,119,99,118,191,238,131,132,62,234,70,119,191,156,15,124,62,132,31,120,191,77,12,111,62,60,237,120,191,130,254,97,62,9,176,121,191,205,230,84,62,226,103,122,191,194,197,71,62,190,20,123,191,243,155,58,62,152,182,123,191,245,105,45,62,103,77,124,191,92,48,32,62,37,217,124,191,187,239,18,62,203,89,125,191,168,168,5,62,85,207,125,191,115,183,240,61,188,57,126,191,4,19,214,61,253,152,126,191,51,101,187,61,18,237,126,191,42,175,160,61,249,53,127,191,19,242,133,61,175,115,127,191,58,94,86,61,47,166,127,191,231,206,32,61,121,205,127,191,10,113,214,60,139,233,127,191,191,117,86,60,99,250,127,191,0,48,141,36,0,0,128,191,191,117,86,188,99,250,127,191,10,113,214,188,139,233,127,191,231,206,32,189,121,205,127,191,58,94,86,189,47,166,127,191,19,242,133,189,175,115,127,191,42,175,160,189,249,53,127,191,51,101,187,189,18,237,126,191,4,19,214,189,253,152,126,191,115,183,240,189,188,57,126,191,168,168,5,190,85,207,125,191,187,239,18,190,203,89,125,191,92,48,32,190,37,217,124,191,245,105,45,190,103,77,124,191,243,155,58,190,152,182,123,191,194,197,71,190,190,20,123,191,205,230,84,190,226,103,122,191,130,254,97,190,9,176,121,191,77,12,111,190,60,237,120,191,156,15,124,190,132,31,120,191,238,131,132,190,234,70,119,191,62,250,138,190,119,99,118,191,117,106,145,190,54,117,117,191,76,212,151,190,48,124,116,191,122,55,158,190,113,120,115,191,183,147,164,190,3,106,114,191,188,232,170,190,244,80,113,191,65,54,177,190,79,45,112,191,1,124,183,190,33,255,110,191,180,185,189,190,118,198,109,191,21,239,195,190,94,131,108,191,222,27,202,190,231,53,107,191,201,63,208,190,30,222,105,191,146,90,214,190,18,124,104,191,243,107,220,190,212,15,103,191,170,115,226,190,116,153,101,191,113,113,232,190,1,25,100,191,7,101,238,190,141,142,98,191,39,78,244,190,40,250,96,191,144,44,250,190,230,91,95,191,0,0,0,191,215,179,93,191,27,228,2,191,15,2,92,191,119,194,5,191,160,70,90,191,246,154,8,191,158,129,88,191,119,109,11,191,29,179,86,191,218,57,14,191,49,219,84,191,0,0,17,191,239,249,82,191,202,191,19,191,108,15,81,191,24,121,22,191,189,27,79,191,205,43,25,191,248,30,77,191,202,215,27,191,52,25,75,191,241,124,30,191,136,10,73,191,36,27,33,191,10,243,70,191,70,178,35,191,209,210,68,191,58,66,38,191,247,169,66,191,227,202,40,191,147,120,64,191,37,76,43,191,189,62,62,191,227,197,45,191,143,252,59,191,1,56,48,191,34,178,57,191,101,162,50,191,144,95,55,191,243,4,53,191,243,4,53,191,144,95,55,191,101,162,50,191,34,178,57,191,1,56,48,191,143,252,59,191,227,197,45,191,189,62,62,191,37,76,43,191,147,120,64,191,227,202,40,191,247,169,66,191,58,66,38,191,209,210,68,191,70,178,35,191,10,243,70,191,36,27,33,191,136,10,73,191,241,124,30,191,52,25,75,191,202,215,27,191,248,30,77,191,205,43,25,191,189,27,79,191,24,121,22,191,108,15,81,191,202,191,19,191,239,249,82,191,0,0,17,191,49,219,84,191,218,57,14,191,29,179,86,191,119,109,11,191,158,129,88,191,246,154,8,191,160,70,90,191,119,194,5,191,15,2,92,191,27,228,2,191,215,179,93,191,0,0,0,191,230,91,95,191,144,44,250,190,40,250,96,191,39,78,244,190,141,142,98,191,7,101,238,190,1,25,100,191,113,113,232,190,116,153,101,191,170,115,226,190,212,15,103,191,243,107,220,190,18,124,104,191,146,90,214,190,30,222,105,191,201,63,208,190,231,53,107,191,222,27,202,190,94,131,108,191,21,239,195,190,118,198,109,191,180,185,189,190,33,255,110,191,1,124,183,190,79,45,112,191,65,54,177,190,244,80,113,191,188,232,170,190,3,106,114,191,183,147,164,190,113,120,115,191,122,55,158,190,48,124,116,191,76,212,151,190,54,117,117,191,117,106,145,190,119,99,118,191,62,250,138,190,234,70,119,191,238,131,132,190,132,31,120,191,156,15,124,190,60,237,120,191,77,12,111,190,9,176,121,191,130,254,97,190,226,103,122,191,205,230,84,190,190,20,123,191,194,197,71,190,152,182,123,191,243,155,58,190,103,77,124,191,245,105,45,190,37,217,124,191,92,48,32,190,203,89,125,191,187,239,18,190,85,207,125,191,168,168,5,190,188,57,126,191,115,183,240,189,253,152,126,191,4,19,214,189,18,237,126,191,51,101,187,189,249,53,127,191,42,175,160,189,175,115,127,191,19,242,133,189,47,166,127,191,58,94,86,189,121,205,127,191,231,206,32,189,139,233,127,191,10,113,214,188,99,250,127,191,191,117,86,188,0,0,128,191,0,48,13,165,99,250,127,191,191,117,86,60,139,233,127,191,10,113,214,60,121,205,127,191,231,206,32,61,47,166,127,191,58,94,86,61,175,115,127,191,19,242,133,61,249,53,127,191,42,175,160,61,18,237,126,191,51,101,187,61,253,152,126,191,4,19,214,61,188,57,126,191,115,183,240,61,85,207,125,191,168,168,5,62,203,89,125,191,187,239,18,62,37,217,124,191,92,48,32,62,103,77,124,191,245,105,45,62,152,182,123,191,243,155,58,62,190,20,123,191,194,197,71,62,226,103,122,191,205,230,84,62,9,176,121,191,130,254,97,62,60,237,120,191,77,12,111,62,132,31,120,191,156,15,124,62,234,70,119,191,238,131,132,62,119,99,118,191,62,250,138,62,54,117,117,191,117,106,145,62,48,124,116,191,76,212,151,62,113,120,115,191,122,55,158,62,3,106,114,191,183,147,164,62,244,80,113,191,188,232,170,62,79,45,112,191,65,54,177,62,33,255,110,191,1,124,183,62,118,198,109,191,180,185,189,62,94,131,108,191,21,239,195,62,231,53,107,191,222,27,202,62,30,222,105,191,201,63,208,62,18,124,104,191,146,90,214,62,212,15,103,191,243,107,220,62,116,153,101,191,170,115,226,62,1,25,100,191,113,113,232,62,141,142,98,191,7,101,238,62,40,250,96,191,39,78,244,62,230,91,95,191,144,44,250,62,215,179,93,191,0,0,0,63,15,2,92,191,27,228,2,63,160,70,90,191,119,194,5,63,158,129,88,191,246,154,8,63,29,179,86,191,119,109,11,63,49,219,84,191,218,57,14,63,239,249,82,191,0,0,17,63,108,15,81,191,202,191,19,63,189,27,79,191,24,121,22,63,248,30,77,191,205,43,25,63,52,25,75,191,202,215,27,63,136,10,73,191,241,124,30,63,10,243,70,191,36,27,33,63,209,210,68,191,70,178,35,63,247,169,66,191,58,66,38,63,147,120,64,191,227,202,40,63,189,62,62,191,37,76,43,63,143,252,59,191,227,197,45,63,34,178,57,191,1,56,48,63,144,95,55,191,101,162,50,63,243,4,53,191,243,4,53,63,101,162,50,191,144,95,55,63,1,56,48,191,34,178,57,63,227,197,45,191,143,252,59,63,37,76,43,191,189,62,62,63,227,202,40,191,147,120,64,63,58,66,38,191,247,169,66,63,70,178,35,191,209,210,68,63,36,27,33,191,10,243,70,63,241,124,30,191,136,10,73,63,202,215,27,191,52,25,75,63,205,43,25,191,248,30,77,63,24,121,22,191,189,27,79,63,202,191,19,191,108,15,81,63,0,0,17,191,239,249,82,63,218,57,14,191,49,219,84,63,119,109,11,191,29,179,86,63,246,154,8,191,158,129,88,63,119,194,5,191,160,70,90,63,27,228,2,191,15,2,92,63,0,0,0,191,215,179,93,63,144,44,250,190,230,91,95,63,39,78,244,190,40,250,96,63,7,101,238,190,141,142,98,63,113,113,232,190,1,25,100,63,170,115,226,190,116,153,101,63,243,107,220,190,212,15,103,63,146,90,214,190,18,124,104,63,201,63,208,190,30,222,105,63,222,27,202,190,231,53,107,63,21,239,195,190,94,131,108,63,180,185,189,190,118,198,109,63,1,124,183,190,33,255,110,63,65,54,177,190,79,45,112,63,188,232,170,190,244,80,113,63,183,147,164,190,3,106,114,63,122,55,158,190,113,120,115,63,76,212,151,190,48,124,116,63,117,106,145,190,54,117,117,63,62,250,138,190,119,99,118,63,238,131,132,190,234,70,119,63,156,15,124,190,132,31,120,63,77,12,111,190,60,237,120,63,130,254,97,190,9,176,121,63,205,230,84,190,226,103,122,63,194,197,71,190,190,20,123,63,243,155,58,190,152,182,123,63,245,105,45,190,103,77,124,63,92,48,32,190,37,217,124,63,187,239,18,190,203,89,125,63,168,168,5,190,85,207,125,63,115,183,240,189,188,57,126,63,4,19,214,189,253,152,126,63,51,101,187,189,18,237,126,63,42,175,160,189,249,53,127,63,19,242,133,189,175,115,127,63,58,94,86,189,47,166,127,63,231,206,32,189,121,205,127,63,10,113,214,188,139,233,127,63,191,117,86,188,99,250,127,63,0,200,83,165,0,0,128,63,191,117,86,60,99,250,127,63,10,113,214,60,139,233,127,63,231,206,32,61,121,205,127,63,58,94,86,61,47,166,127,63,19,242,133,61,175,115,127,63,42,175,160,61,249,53,127,63,51,101,187,61,18,237,126,63,4,19,214,61,253,152,126,63,115,183,240,61,188,57,126,63,168,168,5,62,85,207,125,63,187,239,18,62,203,89,125,63,92,48,32,62,37,217,124,63,245,105,45,62,103,77,124,63,243,155,58,62,152,182,123,63,194,197,71,62,190,20,123,63,205,230,84,62,226,103,122,63,130,254,97,62,9,176,121,63,77,12,111,62,60,237,120,63,156,15,124,62,132,31,120,63,238,131,132,62,234,70,119,63,62,250,138,62,119,99,118,63,117,106,145,62,54,117,117,63,76,212,151,62,48,124,116,63,122,55,158,62,113,120,115,63,183,147,164,62,3,106,114,63,188,232,170,62,244,80,113,63,65,54,177,62,79,45,112,63,1,124,183,62,33,255,110,63,180,185,189,62,118,198,109,63,21,239,195,62,94,131,108,63,222,27,202,62,231,53,107,63,201,63,208,62,30,222,105,63,146,90,214,62,18,124,104,63,243,107,220,62,212,15,103,63,170,115,226,62,116,153,101,63,113,113,232,62,1,25,100,63,7,101,238,62,141,142,98,63,39,78,244,62,40,250,96,63,144,44,250,62,230,91,95,63,0,0,0,63,215,179,93,63,27,228,2,63,15,2,92,63,119,194,5,63,160,70,90,63,246,154,8,63,158,129,88,63,119,109,11,63,29,179,86,63,218,57,14,63,49,219,84,63,0,0,17,63,239,249,82,63,202,191,19,63,108,15,81,63,24,121,22,63,189,27,79,63,205,43,25,63,248,30,77,63,202,215,27,63,52,25,75,63,241,124,30,63,136,10,73,63,36,27,33,63,10,243,70,63,70,178,35,63,209,210,68,63,58,66,38,63,247,169,66,63,227,202,40,63,147,120,64,63,37,76,43,63,189,62,62,63,227,197,45,63,143,252,59,63,1,56,48,63,34,178,57,63,101,162,50,63,144,95,55,63,243,4,53,63,243,4,53,63,144,95,55,63,101,162,50,63,34,178,57,63,1,56,48,63,143,252,59,63,227,197,45,63,189,62,62,63,37,76,43,63,147,120,64,63,227,202,40,63,247,169,66,63,58,66,38,63,209,210,68,63,70,178,35,63,10,243,70,63,36,27,33,63,136,10,73,63,241,124,30,63,52,25,75,63,202,215,27,63,248,30,77,63,205,43,25,63,189,27,79,63,24,121,22,63,108,15,81,63,202,191,19,63,239,249,82,63,0,0,17,63,49,219,84,63,218,57,14,63,29,179,86,63,119,109,11,63,158,129,88,63,246,154,8,63,160,70,90,63,119,194,5,63,15,2,92,63,27,228,2,63,215,179,93,63,0,0,0,63,230,91,95,63,144,44,250,62,40,250,96,63,39,78,244,62,141,142,98,63,7,101,238,62,1,25,100,63,113,113,232,62,116,153,101,63,170,115,226,62,212,15,103,63,243,107,220,62,18,124,104,63,146,90,214,62,30,222,105,63,201,63,208,62,231,53,107,63,222,27,202,62,94,131,108,63,21,239,195,62,118,198,109,63,180,185,189,62,33,255,110,63,1,124,183,62,79,45,112,63,65,54,177,62,244,80,113,63,188,232,170,62,3,106,114,63,183,147,164,62,113,120,115,63,122,55,158,62,48,124,116,63,76,212,151,62,54,117,117,63,117,106,145,62,119,99,118,63,62,250,138,62,234,70,119,63,238,131,132,62,132,31,120,63,156,15,124,62,60,237,120,63,77,12,111,62,9,176,121,63,130,254,97,62,226,103,122,63,205,230,84,62,190,20,123,63,194,197,71,62,152,182,123,63,243,155,58,62,103,77,124,63,245,105,45,62,37,217,124,63,92,48,32,62,203,89,125,63,187,239,18,62,85,207,125,63,168,168,5,62,188,57,126,63,115,183,240,61,253,152,126,63,4,19,214,61,18,237,126,63,51,101,187,61,249,53,127,63,42,175,160,61,175,115,127,63,19,242,133,61,47,166,127,63,58,94,86,61,121,205,127,63,231,206,32,61,139,233,127,63,10,113,214,60,99,250,127,63,191,117,86,60,0,0,24,0,48,0,72,0,96,0,8,0,32,0,56,0,80,0,104,0,16,0,40,0,64,0,88,0,112,0,4,0,28,0,52,0,76,0,100,0,12,0,36,0,60,0,84,0,108,0,20,0,44,0,68,0,92,0,116,0,1,0,25,0,49,0,73,0,97,0,9,0,33,0,57,0,81,0,105,0,17,0,41,0,65,0,89,0,113,0,5,0,29,0,53,0,77,0,101,0,13,0,37,0,61,0,85,0,109,0,21,0,45,0,69,0,93,0,117,0,2,0,26,0,50,0,74,0,98,0,10,0,34,0,58,0,82,0,106,0,18,0,42,0,66,0,90,0,114,0,6,0,30,0,54,0,78,0,102,0,14,0,38,0,62,0,86,0,110,0,22,0,46,0,70,0,94,0,118,0,3,0,27,0,51,0,75,0,99,0,11,0,35,0,59,0,83,0,107,0,19,0,43,0,67,0,91,0,115,0,7,0,31,0,55,0,79,0,103,0,15,0,39,0,63,0,87,0,111,0,23,0,47,0,71,0,95,0,119,0,0,0,48,0,96,0,144,0,192,0,16,0,64,0,112,0,160,0,208,0,32,0,80,0,128,0,176,0,224,0,4,0,52,0,100,0,148,0,196,0,20,0,68,0,116,0,164,0,212,0,36,0,84,0,132,0,180,0,228,0,8,0,56,0,104,0,152,0,200,0,24,0,72,0,120,0,168,0,216,0,40,0,88,0,136,0,184,0,232,0,12,0,60,0,108,0,156,0,204,0,28,0,76,0,124,0,172,0,220,0,44,0,92,0,140,0,188,0,236,0,1,0,49,0,97,0,145,0,193,0,17,0,65,0,113,0,161,0,209,0,33,0,81,0,129,0,177,0,225,0,5,0,53,0,101,0,149,0,197,0,21,0,69,0,117,0,165,0,213,0,37,0,85,0,133,0,181,0,229,0,9,0,57,0,105,0,153,0,201,0,25,0,73,0,121,0,169,0,217,0,41,0,89,0,137,0,185,0,233,0,13,0,61,0,109,0,157,0,205,0,29,0,77,0,125,0,173,0,221,0,45,0,93,0,141,0,189,0,237,0,2,0,50,0,98,0,146,0,194,0,18,0,66,0,114,0,162,0,210,0,34,0,82,0,130,0,178,0,226,0,6,0,54,0,102,0,150,0,198,0,22,0,70,0,118,0,166,0,214,0,38,0,86,0,134,0,182,0,230,0,10,0,58,0,106,0,154,0,202,0,26,0,74,0,122,0,170,0,218,0,42,0,90,0,138,0,186,0,234,0,14,0,62,0,110,0,158,0,206,0,30,0,78,0,126,0,174,0,222,0,46,0,94,0,142,0,190,0,238,0,3,0,51,0,99,0,147,0,195,0,19,0,67,0,115,0,163,0,211,0,35,0,83,0,131,0,179,0,227,0,7,0,55,0,103,0,151,0,199,0,23,0,71,0,119,0,167,0,215,0,39,0,87,0,135,0,183,0,231,0,11,0,59,0,107,0,155,0,203,0,27,0,75,0,123,0,171,0,219,0,43,0,91,0,139,0,187,0,235,0,15,0,63,0,111,0,159,0,207,0,31,0,79,0,127,0,175,0,223,0,47,0,95,0,143,0,191,0,239,0,0,0,96,0,192,0,32,1,128,1,32,0,128,0,224,0,64,1,160,1,64,0,160,0,0,1,96,1,192,1,8,0,104,0,200,0,40,1,136,1,40,0,136,0,232,0,72,1,168,1,72,0,168,0,8,1,104,1,200,1,16,0,112,0,208,0,48,1,144,1,48,0,144,0,240,0,80,1,176,1,80,0,176,0,16,1,112,1,208,1,24,0,120,0,216,0,56,1,152,1,56,0,152,0,248,0,88,1,184,1,88,0,184,0,24,1,120,1,216,1,4,0,100,0,196,0,36,1,132,1,36,0,132,0,228,0,68,1,164,1,68,0,164,0,4,1,100,1,196,1,12,0,108,0,204,0,44,1,140,1,44,0,140,0,236,0,76,1,172,1,76,0,172,0,12,1,108,1,204,1,20,0,116,0,212,0,52,1,148,1,52,0,148,0,244,0,84,1,180,1,84,0,180,0,20,1,116,1,212,1,28,0,124,0,220,0,60,1,156,1,60,0,156,0,252,0,92,1,188,1,92,0,188,0,28,1,124,1,220,1,1,0,97,0,193,0,33,1,129,1,33,0,129,0,225,0,65,1,161,1,65,0,161,0,1,1,97,1,193,1,9,0,105,0,201,0,41,1,137,1,41,0,137,0,233,0,73,1,169,1,73,0,169,0,9,1,105,1,201,1,17,0,113,0,209,0,49,1,145,1,49,0,145,0,241,0,81,1,177,1,81,0,177,0,17,1,113,1,209,1,25,0,121,0,217,0,57,1,153,1,57,0,153,0,249,0,89,1,185,1,89,0,185,0,25,1,121,1,217,1,5,0,101,0,197,0,37,1,133,1,37,0,133,0,229,0,69,1,165,1,69,0,165,0,5,1,101,1,197,1,13,0,109,0,205,0,45,1,141,1,45,0,141,0,237,0,77,1,173,1,77,0,173,0,13,1,109,1,205,1,21,0,117,0,213,0,53,1,149,1,53,0,149,0,245,0,85,1,181,1,85,0,181,0,21,1,117,1,213,1,29,0,125,0,221,0,61,1,157,1,61,0,157,0,253,0,93,1,189,1,93,0,189,0,29,1,125,1,221,1,2,0,98,0,194,0,34,1,130,1,34,0,130,0,226,0,66,1,162,1,66,0,162,0,2,1,98,1,194,1,10,0,106,0,202,0,42,1,138,1,42,0,138,0,234,0,74,1,170,1,74,0,170,0,10,1,106,1,202,1,18,0,114,0,210,0,50,1,146,1,50,0,146,0,242,0,82,1,178,1,82,0,178,0,18,1,114,1,210,1,26,0,122,0,218,0,58,1,154,1,58,0,154,0,250,0,90,1,186,1,90,0,186,0,26,1,122,1,218,1,6,0,102,0,198,0,38,1,134,1,38,0,134,0,230,0,70,1,166,1,70,0,166,0,6,1,102,1,198,1,14,0,110,0,206,0,46,1,142,1,46,0,142,0,238,0,78,1,174,1,78,0,174,0,14,1,110,1,206,1,22,0,118,0,214,0,54,1,150,1,54,0,150,0,246,0,86,1,182,1,86,0,182,0,22,1,118,1,214,1,30,0,126,0,222,0,62,1,158,1,62,0,158,0,254,0,94,1,190,1,94,0,190,0,30,1,126,1,222,1,3,0,99,0,195,0,35,1,131,1,35,0,131,0,227,0,67,1,163,1,67,0,163,0,3,1,99,1,195,1,11,0,107,0,203,0,43,1,139,1,43,0,139,0,235,0,75,1,171,1,75,0,171,0,11,1,107,1,203,1,19,0,115,0,211,0,51,1,147,1,51,0,147,0,243,0,83,1,179,1,83,0,179,0,19,1,115,1,211,1,27,0,123,0,219,0,59,1,155,1,59,0,155,0,251,0,91,1,187,1,91,0,187,0,27,1,123,1,219,1,7,0,103,0,199,0,39,1,135,1,39,0,135,0,231,0,71,1,167,1,71,0,167,0,7,1,103,1,199,1,15,0,111,0,207,0,47,1,143,1,47,0,143,0,239,0,79,1,175,1,79,0,175,0,15,1,111,1,207,1,23,0,119,0,215,0,55,1,151,1,55,0,151,0,247,0,87,1,183,1,87,0,183,0,23,1,119,1,215,1,31,0,127,0,223,0,63,1,159,1,63,0,159,0,255,0,95,1,191,1,95,0,191,0,31,1,127,1,223,1,1],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE+10240);allocate([1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,3,0,0,0,5,0,0,0,7,0,0,0,9,0,0,0,11,0,0,0,13,0,0,0,15,0,0,0,17,0,0,0,19,0,0,0,21,0,0,0,23,0,0,0,25,0,0,0,27,0,0,0,29,0,0,0,31,0,0,0,33,0,0,0,35,0,0,0,37,0,0,0,39,0,0,0,41,0,0,0,43,0,0,0,45,0,0,0,47,0,0,0,49,0,0,0,51,0,0,0,53,0,0,0,55,0,0,0,57,0,0,0,59,0,0,0,61,0,0,0,63,0,0,0,65,0,0,0,67,0,0,0,69,0,0,0,71,0,0,0,73,0,0,0,75,0,0,0,77,0,0,0,79,0,0,0,81,0,0,0,83,0,0,0,85,0,0,0,87,0,0,0,89,0,0,0,91,0,0,0,93,0,0,0,95,0,0,0,97,0,0,0,99,0,0,0,101,0,0,0,103,0,0,0,105,0,0,0,107,0,0,0,109,0,0,0,111,0,0,0,113,0,0,0,115,0,0,0,117,0,0,0,119,0,0,0,121,0,0,0,123,0,0,0,125,0,0,0,127,0,0,0,129,0,0,0,131,0,0,0,133,0,0,0,135,0,0,0,137,0,0,0,139,0,0,0,141,0,0,0,143,0,0,0,145,0,0,0,147,0,0,0,149,0,0,0,151,0,0,0,153,0,0,0,155,0,0,0,157,0,0,0,159,0,0,0,161,0,0,0,163,0,0,0,165,0,0,0,167,0,0,0,169,0,0,0,171,0,0,0,173,0,0,0,175,0,0,0,177,0,0,0,179,0,0,0,181,0,0,0,183,0,0,0,185,0,0,0,187,0,0,0,189,0,0,0,191,0,0,0,193,0,0,0,195,0,0,0,197,0,0,0,199,0,0,0,201,0,0,0,203,0,0,0,205,0,0,0,207,0,0,0,209,0,0,0,211,0,0,0,213,0,0,0,215,0,0,0,217,0,0,0,219,0,0,0,221,0,0,0,223,0,0,0,225,0,0,0,227,0,0,0,229,0,0,0,231,0,0,0,233,0,0,0,235,0,0,0,237,0,0,0,239,0,0,0,241,0,0,0,243,0,0,0,245,0,0,0,247,0,0,0,249,0,0,0,251,0,0,0,253,0,0,0,255,0,0,0,1,1,0,0,3,1,0,0,5,1,0,0,7,1,0,0,9,1,0,0,11,1,0,0,13,1,0,0,15,1,0,0,17,1,0,0,19,1,0,0,21,1,0,0,23,1,0,0,25,1,0,0,27,1,0,0,29,1,0,0,31,1,0,0,33,1,0,0,35,1,0,0,37,1,0,0,39,1,0,0,41,1,0,0,43,1,0,0,45,1,0,0,47,1,0,0,49,1,0,0,51,1,0,0,53,1,0,0,55,1,0,0,57,1,0,0,59,1,0,0,61,1,0,0,63,1,0,0,65,1,0,0,67,1,0,0,69,1,0,0,71,1,0,0,73,1,0,0,75,1,0,0,77,1,0,0,79,1,0,0,81,1,0,0,83,1,0,0,85,1,0,0,87,1,0,0,89,1,0,0,91,1,0,0,93,1,0,0,95,1,0,0,13,0,0,0,25,0,0,0,41,0,0,0,61,0,0,0,85,0,0,0,113,0,0,0,145,0,0,0,181,0,0,0,221,0,0,0,9,1,0,0,57,1,0,0,109,1,0,0,165,1,0,0,225,1,0,0,33,2,0,0,101,2,0,0,173,2,0,0,249,2,0,0,73,3,0,0,157,3,0,0,245,3,0,0,81,4,0,0,177,4,0,0,21,5,0,0,125,5,0,0,233,5,0,0,89,6,0,0,205,6,0,0,69,7,0,0,193,7,0,0,65,8,0,0,197,8,0,0,77,9,0,0,217,9,0,0,105,10,0,0,253,10,0,0,149,11,0,0,49,12,0,0,209,12,0,0,117,13,0,0,29,14,0,0,201,14,0,0,121,15,0,0,45,16,0,0,229,16,0,0,161,17,0,0,97,18,0,0,37,19,0,0,237,19,0,0,185,20,0,0,137,21,0,0,93,22,0,0,53,23,0,0,17,24,0,0,241,24,0,0,213,25,0,0,189,26,0,0,169,27,0,0,153,28,0,0,141,29,0,0,133,30,0,0,129,31,0,0,129,32,0,0,133,33,0,0,141,34,0,0,153,35,0,0,169,36,0,0,189,37,0,0,213,38,0,0,241,39,0,0,17,41,0,0,53,42,0,0,93,43,0,0,137,44,0,0,185,45,0,0,237,46,0,0,37,48,0,0,97,49,0,0,161,50,0,0,229,51,0,0,45,53,0,0,121,54,0,0,201,55,0,0,29,57,0,0,117,58,0,0,209,59,0,0,49,61,0,0,149,62,0,0,253,63,0,0,105,65,0,0,217,66,0,0,77,68,0,0,197,69,0,0,65,71,0,0,193,72,0,0,69,74,0,0,205,75,0,0,89,77,0,0,233,78,0,0,125,80,0,0,21,82,0,0,177,83,0,0,81,85,0,0,245,86,0,0,157,88,0,0,73,90,0,0,249,91,0,0,173,93,0,0,101,95,0,0,33,97,0,0,225,98,0,0,165,100,0,0,109,102,0,0,57,104,0,0,9,106,0,0,221,107,0,0,181,109,0,0,145,111,0,0,113,113,0,0,85,115,0,0,61,117,0,0,41,119,0,0,25,121,0,0,13,123,0,0,5,125,0,0,1,127,0,0,1,129,0,0,5,131,0,0,13,133,0,0,25,135,0,0,41,137,0,0,61,139,0,0,85,141,0,0,113,143,0,0,145,145,0,0,181,147,0,0,221,149,0,0,9,152,0,0,57,154,0,0,109,156,0,0,165,158,0,0,225,160,0,0,33,163,0,0,101,165,0,0,173,167,0,0,249,169,0,0,73,172,0,0,157,174,0,0,245,176,0,0,81,179,0,0,177,181,0,0,21,184,0,0,125,186,0,0,233,188,0,0,89,191,0,0,205,193,0,0,69,196,0,0,193,198,0,0,65,201,0,0,197,203,0,0,77,206,0,0,217,208,0,0,105,211,0,0,253,213,0,0,149,216,0,0,49,219,0,0,209,221,0,0,117,224,0,0,29,227,0,0,201,229,0,0,121,232,0,0,45,235,0,0,229,237,0,0,161,240,0,0,63,0,0,0,129,0,0,0,231,0,0,0,121,1,0,0,63,2,0,0,65,3,0,0,135,4,0,0,25,6,0,0,255,7,0,0,65,10,0,0,231,12,0,0,249,15,0,0,127,19,0,0,129,23,0,0,7,28,0,0,25,33,0,0,191,38,0,0,1,45,0,0,231,51,0,0,121,59,0,0,191,67,0,0,193,76,0,0,135,86,0,0,25,97,0,0,127,108,0,0,193,120,0,0,231,133,0,0,249,147,0,0,255,162,0,0,1,179,0,0,7,196,0,0,25,214,0,0,63,233,0,0,129,253,0,0,231,18,1,0,121,41,1,0,63,65,1,0,65,90,1,0,135,116,1,0,25,144,1,0,255,172,1,0,65,203,1,0,231,234,1,0,249,11,2,0,127,46,2,0,129,82,2,0,7,120,2,0,25,159,2,0,191,199,2,0,1,242,2,0,231,29,3,0,121,75,3,0,191,122,3,0,193,171,3,0,135,222,3,0,25,19,4,0,127,73,4,0,193,129,4,0,231,187,4,0,249,247,4,0,255,53,5,0,1,118,5,0,7,184,5,0,25,252,5,0,63,66,6,0,129,138,6,0,231,212,6,0,121,33,7,0,63,112,7,0,65,193,7,0,135,20,8,0,25,106,8,0,255,193,8,0,65,28,9,0,231,120,9,0,249,215,9,0,127,57,10,0,129,157,10,0,7,4,11,0,25,109,11,0,191,216,11,0,1,71,12,0,231,183,12,0,121,43,13,0,191,161,13,0,193,26,14,0,135,150,14,0,25,21,15,0,127,150,15,0,193,26,16,0,231,161,16,0,249,43,17,0,255,184,17,0,1,73,18,0,7,220,18,0,25,114,19,0,63,11,20,0,129,167,20,0,231,70,21,0,121,233,21,0,63,143,22,0,65,56,23,0,135,228,23,0,25,148,24,0,255,70,25,0,65,253,25,0,231,182,26,0,249,115,27,0,127,52,28,0,129,248,28,0,7,192,29,0,25,139,30,0,191,89,31,0,1,44,32,0,231,1,33,0,121,219,33,0,191,184,34,0,193,153,35,0,135,126,36,0,25,103,37,0,127,83,38,0,193,67,39,0,231,55,40,0,249,47,41,0,255,43,42,0,1,44,43,0,7,48,44,0,25,56,45,0,63,68,46,0,129,84,47,0,231,104,48,0,121,129,49,0,63,158,50,0,65,191,51,0,135,228,52,0,25,14,54,0,255,59,55,0,65,110,56,0,231,164,57,0,249,223,58,0,127,31,60,0,129,99,61,0,7,172,62,0,25,249,63,0,191,74,65,0,1,161,66,0,231,251,67,0,121,91,69,0,191,191,70,0,193,40,72,0,135,150,73,0,25,9,75,0,127,128,76,0,193,252,77,0,231,125,79,0,249,3,81,0,255,142,82,0,1,31,84,0,7,180,85,0,25,78,87,0,63,237,88,0,129,145,90,0,231,58,92,0,121,233,93,0,63,157,95,0,65,86,97,0,135,20,99,0,25,216,100,0,255,160,102,0,65,111,104,0,231,66,106,0,249,27,108,0,127,250,109,0,65,1,0,0,169,2,0,0,9,5,0,0,193,8,0,0,65,14,0,0,9,22,0,0,169,32,0,0,193,46,0,0,1,65,0,0,41,88,0,0,9,117,0,0,129,152,0,0,129,195,0,0,9,247,0,0,41,52,1,0,1,124,1,0,193,207,1,0,169,48,2,0,9,160,2,0,65,31,3,0,193,175,3,0,9,83,4,0,169,10,5,0,65,216,5,0,129,189,6,0,41,188,7,0,9,214,8,0,1,13,10,0,1,99,11,0,9,218,12,0,41,116,14,0,129,51,16,0,65,26,18,0,169,42,20,0,9,103,22,0,193,209,24,0,65,109,27,0,9,60,30,0,169,64,33,0,193,125,36,0,1,246,39,0,41,172,43,0,9,163,47,0,129,221,51,0,129,94,56,0,9,41,61,0,41,64,66,0,1,167,71,0,193,96,77,0,169,112,83,0,9,218,89,0,65,160,96,0,193,198,103,0,9,81,111,0,169,66,119,0,65,159,127,0,129,106,136,0,41,168,145,0,9,92,155,0,1,138,165,0,1,54,176,0,9,100,187,0,41,24,199,0,129,86,211,0,65,35,224,0,169,130,237,0,9,121,251,0,193,10,10,1,65,60,25,1,9,18,41,1,169,144,57,1,193,188,74,1,1,155,92,1,41,48,111,1,9,129,130,1,129,146,150,1,129,105,171,1,9,11,193,1,41,124,215,1,1,194,238,1,193,225,6,2,169,224,31,2,9,196,57,2,65,145,84,2,193,77,112,2,9,255,140,2,169,170,170,2,65,86,201,2,129,7,233,2,41,196,9,3,9,146,43,3,1,119,78,3,1,121,114,3,9,158,151,3,41,236,189,3,129,105,229,3,65,28,14,4,169,10,56,4,9,59,99,4,193,179,143,4,65,123,189,4,9,152,236,4,169,16,29,5,193,235,78,5,1,48,130,5,41,228,182,5,9,15,237,5,129,183,36,6,129,228,93,6,9,157,152,6,41,232,212,6,1,205,18,7,193,82,82,7,169,128,147,7,9,94,214,7,65,242,26,8,193,68,97,8,9,93,169,8,169,66,243,8,65,253,62,9,129,148,140,9,41,16,220,9,9,120,45,10,1,212,128,10,1,44,214,10,9,136,45,11,41,240,134,11,129,108,226,11,65,5,64,12,169,194,159,12,9,173,1,13,193,204,101,13,65,42,204,13,9,206,52,14,169,192,159,14,193,10,13,15,1,181,124,15,41,200,238,15,9,77,99,16,129,76,218,16,129,207,83,17,9,223,207,17,41,132,78,18,1,200,207,18,193,179,83,19,169,80,218,19,9,168,99,20,65,195,239,20,193,171,126,21,9,107,16,22,169,10,165,22,65,148,60,23,129,17,215,23,41,140,116,24,9,14,21,25,1,161,184,25,1,79,95,26,9,34,9,27,41,36,182,27,129,95,102,28,65,222,25,29,169,170,208,29,9,207,138,30,193,85,72,31,65,73,9,32,9,180,205,32,169,160,149,33,193,25,97,34,1,42,48,35,41,220,2,36,9,59,217,36,129,81,179,37,147,6,0,0,69,14,0,0,15,28,0,0,17,51,0,0,91,87,0,0,13,142,0,0,119,221,0,0,57,77,1,0,99,230,1,0,149,179,2,0,31,193,3,0,33,29,5,0,171,215,6,0,221,2,9,0,7,179,11,0,201,254,14,0,51,255,18,0,229,207,23,0,47,143,29,0,49,94,36,0,251,96,44,0,173,190,53,0,151,161,64,0,89,55,77,0,3,177,91,0,53,67,108,0,63,38,127,0,65,150,148,0,75,211,172,0,125,33,200,0,39,201,230,0,233,22,9,1,211,91,47,1,133,237,89,1,79,38,137,1,81,101,189,1,155,14,247,1,77,139,54,2,183,73,124,2,121,189,200,2,163,95,28,3,213,174,119,3,95,47,219,3,97,107,71,4,235,242,188,4,29,92,60,5,71,67,198,5,9,75,91,6,115,28,252,6,37,103,169,7,111,225,99,8,113,72,44,9,59,96,3,10,237,243,233,10,215,213,224,11,153,223,232,12,67,242,2,14,117,246,47,15,127,220,112,16,129,156,198,17,139,54,50,19,189,178,180,20,103,33,79,22,41,155,2,24,19,65,208,25,197,60,185,27,143,192,190,29,145,7,226,31,219,85,36,34,141,248,134,36,247,69,11,39,185,157,178,41,227,104,126,44,21,26,112,47,159,45,137,50,161,41,203,53,43,158,55,57,93,37,208,60,135,99,150,64,73,7,140,68,179,201,178,72,101,110,12,77,175,195,154,81,177,162,95,86,123,239,92,91,45,153,148,96,23,154,8,102,217,247,186,107,131,195,173,113,181,25,227,119,191,34,93,126,29,35,0,0,113,77,0,0,145,156,0,0,253,38,1,0,101,12,2,0,233,119,3,0,153,162,5,0,53,214,8,0,45,112,13,0,225,228,19,0,33,195,28,0,237,183,40,0,117,146,56,0,89,72,77,0,41,250,103,0,37,248,137,0,61,199,180,0,81,38,234,0,177,19,44,1,221,210,124,1,133,242,222,1,201,82,85,2,185,43,227,2,21,20,140,3,77,8,84,4,193,113,63,5,65,46,83,6,205,151,148,7,149,140,9,9,57,119,184,10,73,87,168,12,5,202,224,14,93,19,106,17,49,39,77,20,209,178,147,23,189,38,72,27,165,192,117,31,169,149,40,36,217,156,109,41,245,185,82,47,109,200,230,53,161,166,57,61,97,65,92,69,173,159,96,78,181,238,89,88,25,142,92,99,105,28,126,111,229,131,213,124,255,189,0,0,1,168,1,0,143,107,3,0,241,158,6,0,63,35,12,0,193,61,21,0,143,182,35,0,241,252,57,0,255,81,91,0,1,250,139,0,15,117,209,0,113,191,50,1,63,154,184,1,193,220,109,2,15,207,95,3,113,142,158,4,255,123,61,6,1,182,83,8,143,156,252,10,241,97,88,14,63,167,140,18,193,37,197,23,143,101,52,30,241,129,20,38,255,251,167,47,1,156,58,59,15,98,34,73,113,134,192,89,63,138,130,109,193,88,227,132,1,14,4,0,145,33,9,0,17,44,19,0,65,238,37,0,65,79,71,0,145,67,128,0,17,247,221,0,1,70,115,1,1,146,90,2,17,1,184,3,145,53,188,5,65,143,167,8,65,6,206,12,17,178,155,18,145,15,154,26,1,26,118,37,1,76,7,52,145,158,87,71,17,157,172,96,65,166,145,129,35,81,22,0,197,158,50,0,23,185,107,0,153,246,216,0,107,137,160,1,13,196,254,2,31,1,80,5,33,217,29,9,51,108,48,15,213,162,164,24,167,103,8,39,41,253,125,60,123,181,231,91,29,119,29,137,175,160,45,201,173,142,123,0,137,230,25,1,57,150,94,2,61,22,216,4,181,99,119,9,225,40,198,17,33,3,52,32,117,72,130,56,125,87,87,96,191,91,175,2,129,216,39,6,247,132,94,13,233,254,173,27,127,139,235,54,129,183,229,104,23,3,156,193,193,12,255,14,57,106,133,34,25,238,145,75,129,120,43,158,51,225,9,84,0,64,202,69,27,76,255,82,130,90,179,98,162,107,96,117,0,1,1,1,2,3,3,3,2,3,3,3,2,3,3,3,0,3,12,15,48,51,60,63,192,195,204,207,240,243,252,255,1,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,6,0,0,0,1,0,0,0,5,0,0,0,2,0,0,0,15,0,0,0,0,0,0,0,8,0,0,0,7,0,0,0,12,0,0,0,3,0,0,0,11,0,0,0,4,0,0,0,14,0,0,0,1,0,0,0,9,0,0,0,6,0,0,0,13,0,0,0,2,0,0,0,10,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,79,112,117,115,32,100,101,99,111,100,105,110,103,32,101,114,114,111,114,44,32,99,111,100,101,32,37,100,10,0,0,0,79,112,117,115,72,101,97,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE+20692);var tempDoublePtr=Runtime.alignMemory(allocate(12,"i8",ALLOC_STATIC),8);assert(tempDoublePtr%8==0);function copyTempFloat(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3]}function copyTempDouble(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3];HEAP8[tempDoublePtr+4]=HEAP8[ptr+4];HEAP8[tempDoublePtr+5]=HEAP8[ptr+5];HEAP8[tempDoublePtr+6]=HEAP8[ptr+6];HEAP8[tempDoublePtr+7]=HEAP8[ptr+7]}Module["_bitshift64Ashr"]=_bitshift64Ashr;function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}var ___errno_state=0;function ___setErrNo(value){HEAP32[___errno_state>>2]=value;return value}var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 85:return totalMemory/PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 79:return 0;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(ERRNO_CODES.EINVAL);return-1}var _llvm_ctlz_i32=true;function ___errno_location(){return ___errno_state}Module["_memset"]=_memset;function _ogvjs_callback_audio(buffers,channels,sampleCount){var HEAPU32=Module.HEAPU32;var HEAPF32=Module.HEAPF32;var outputBuffers=[];if(buffers!==0){var inPtr,inArray,outArray,i;for(var channel=0;channel<channels;channel++){inPtr=HEAPU32[buffers/4+channel];inArray=HEAPF32.subarray(inPtr/4,inPtr/4+sampleCount);outArray=new Float32Array(inArray);outputBuffers.push(outArray)}}Module.audioBuffer=outputBuffers}function _abort(){Module["abort"]()}var FS=undefined;var SOCKFS=undefined;function _send(fd,buf,len,flags){var sock=SOCKFS.getSocket(fd);if(!sock){___setErrNo(ERRNO_CODES.EBADF);return-1}return _write(fd,buf,len)}function _pwrite(fildes,buf,nbyte,offset){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte,offset)}catch(e){FS.handleFSError(e);return-1}}function _write(fildes,buf,nbyte){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte)}catch(e){FS.handleFSError(e);return-1}}function _fileno(stream){stream=FS.getStreamFromPtr(stream);if(!stream)return-1;return stream.fd}function _fwrite(ptr,size,nitems,stream){var bytesToWrite=nitems*size;if(bytesToWrite==0)return 0;var fd=_fileno(stream);var bytesWritten=_write(fd,ptr,bytesToWrite);if(bytesWritten==-1){var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=true;return 0}else{return bytesWritten/size|0}}Module["_strlen"]=_strlen;function __reallyNegative(x){return x<0||x===0&&1/x===-Infinity}function __formatString(format,varargs){assert((varargs&3)===0);var textIndex=format;var argIndex=0;function getNextArg(type){var ret;argIndex=Runtime.prepVararg(argIndex,type);if(type==="double"){ret=(HEAP32[tempDoublePtr>>2]=HEAP32[varargs+argIndex>>2],HEAP32[tempDoublePtr+4>>2]=HEAP32[varargs+(argIndex+4)>>2],+HEAPF64[tempDoublePtr>>3]);argIndex+=8}else if(type=="i64"){ret=[HEAP32[varargs+argIndex>>2],HEAP32[varargs+(argIndex+4)>>2]];argIndex+=8}else{assert((argIndex&3)===0);type="i32";ret=HEAP32[varargs+argIndex>>2];argIndex+=4}return ret}var ret=[];var curr,next,currArg;while(1){var startTextIndex=textIndex;curr=HEAP8[textIndex>>0];if(curr===0)break;next=HEAP8[textIndex+1>>0];if(curr==37){var flagAlwaysSigned=false;var flagLeftAlign=false;var flagAlternative=false;var flagZeroPad=false;var flagPadSign=false;flagsLoop:while(1){switch(next){case 43:flagAlwaysSigned=true;break;case 45:flagLeftAlign=true;break;case 35:flagAlternative=true;break;case 48:if(flagZeroPad){break flagsLoop}else{flagZeroPad=true;break};case 32:flagPadSign=true;break;default:break flagsLoop}textIndex++;next=HEAP8[textIndex+1>>0]}var width=0;if(next==42){width=getNextArg("i32");textIndex++;next=HEAP8[textIndex+1>>0]}else{while(next>=48&&next<=57){width=width*10+(next-48);textIndex++;next=HEAP8[textIndex+1>>0]}}var precisionSet=false,precision=-1;if(next==46){precision=0;precisionSet=true;textIndex++;next=HEAP8[textIndex+1>>0];if(next==42){precision=getNextArg("i32");textIndex++}else{while(1){var precisionChr=HEAP8[textIndex+1>>0];if(precisionChr<48||precisionChr>57)break;precision=precision*10+(precisionChr-48);textIndex++}}next=HEAP8[textIndex+1>>0]}if(precision<0){precision=6;precisionSet=false}var argSize;switch(String.fromCharCode(next)){case"h":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==104){textIndex++;argSize=1}else{argSize=2}break;case"l":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==108){textIndex++;argSize=8}else{argSize=4}break;case"L":case"q":case"j":argSize=8;break;case"z":case"t":case"I":argSize=4;break;default:argSize=null}if(argSize)textIndex++;next=HEAP8[textIndex+1>>0];switch(String.fromCharCode(next)){case"d":case"i":case"u":case"o":case"x":case"X":case"p":{var signed=next==100||next==105;argSize=argSize||4;var currArg=getNextArg("i"+argSize*8);var origArg=currArg;var argText;if(argSize==8){currArg=Runtime.makeBigInt(currArg[0],currArg[1],next==117)}if(argSize<=4){var limit=Math.pow(256,argSize)-1;currArg=(signed?reSign:unSign)(currArg&limit,argSize*8)}var currAbsArg=Math.abs(currArg);var prefix="";if(next==100||next==105){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],null);else argText=reSign(currArg,8*argSize,1).toString(10)}else if(next==117){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],true);else argText=unSign(currArg,8*argSize,1).toString(10);currArg=Math.abs(currArg)}else if(next==111){argText=(flagAlternative?"0":"")+currAbsArg.toString(8)}else if(next==120||next==88){prefix=flagAlternative&&currArg!=0?"0x":"";if(argSize==8&&i64Math){if(origArg[1]){argText=(origArg[1]>>>0).toString(16);var lower=(origArg[0]>>>0).toString(16);while(lower.length<8)lower="0"+lower;argText+=lower}else{argText=(origArg[0]>>>0).toString(16)}}else if(currArg<0){currArg=-currArg;argText=(currAbsArg-1).toString(16);var buffer=[];for(var i=0;i<argText.length;i++){buffer.push((15-parseInt(argText[i],16)).toString(16))}argText=buffer.join("");while(argText.length<argSize*2)argText="f"+argText}else{argText=currAbsArg.toString(16)}if(next==88){prefix=prefix.toUpperCase();argText=argText.toUpperCase()}}else if(next==112){if(currAbsArg===0){argText="(nil)"}else{prefix="0x";argText=currAbsArg.toString(16)}}if(precisionSet){while(argText.length<precision){argText="0"+argText}}if(currArg>=0){if(flagAlwaysSigned){prefix="+"+prefix}else if(flagPadSign){prefix=" "+prefix}}if(argText.charAt(0)=="-"){prefix="-"+prefix;argText=argText.substr(1)}while(prefix.length+argText.length<width){if(flagLeftAlign){argText+=" "}else{if(flagZeroPad){argText="0"+argText}else{prefix=" "+prefix}}}argText=prefix+argText;argText.split("").forEach((function(chr){ret.push(chr.charCodeAt(0))}));break};case"f":case"F":case"e":case"E":case"g":case"G":{var currArg=getNextArg("double");var argText;if(isNaN(currArg)){argText="nan";flagZeroPad=false}else if(!isFinite(currArg)){argText=(currArg<0?"-":"")+"inf";flagZeroPad=false}else{var isGeneral=false;var effectivePrecision=Math.min(precision,20);if(next==103||next==71){isGeneral=true;precision=precision||1;var exponent=parseInt(currArg.toExponential(effectivePrecision).split("e")[1],10);if(precision>exponent&&exponent>=-4){next=(next==103?"f":"F").charCodeAt(0);precision-=exponent+1}else{next=(next==103?"e":"E").charCodeAt(0);precision--}effectivePrecision=Math.min(precision,20)}if(next==101||next==69){argText=currArg.toExponential(effectivePrecision);if(/[eE][-+]\d$/.test(argText)){argText=argText.slice(0,-1)+"0"+argText.slice(-1)}}else if(next==102||next==70){argText=currArg.toFixed(effectivePrecision);if(currArg===0&&__reallyNegative(currArg)){argText="-"+argText}}var parts=argText.split("e");if(isGeneral&&!flagAlternative){while(parts[0].length>1&&parts[0].indexOf(".")!=-1&&(parts[0].slice(-1)=="0"||parts[0].slice(-1)==".")){parts[0]=parts[0].slice(0,-1)}}else{if(flagAlternative&&argText.indexOf(".")==-1)parts[0]+=".";while(precision>effectivePrecision++)parts[0]+="0"}argText=parts[0]+(parts.length>1?"e"+parts[1]:"");if(next==69)argText=argText.toUpperCase();if(currArg>=0){if(flagAlwaysSigned){argText="+"+argText}else if(flagPadSign){argText=" "+argText}}}while(argText.length<width){if(flagLeftAlign){argText+=" "}else{if(flagZeroPad&&(argText[0]=="-"||argText[0]=="+")){argText=argText[0]+"0"+argText.slice(1)}else{argText=(flagZeroPad?"0":" ")+argText}}}if(next<97)argText=argText.toUpperCase();argText.split("").forEach((function(chr){ret.push(chr.charCodeAt(0))}));break};case"s":{var arg=getNextArg("i8*");var argLength=arg?_strlen(arg):"(null)".length;if(precisionSet)argLength=Math.min(argLength,precision);if(!flagLeftAlign){while(argLength<width--){ret.push(32)}}if(arg){for(var i=0;i<argLength;i++){ret.push(HEAPU8[arg++>>0])}}else{ret=ret.concat(intArrayFromString("(null)".substr(0,argLength),true))}if(flagLeftAlign){while(argLength<width--){ret.push(32)}}break};case"c":{if(flagLeftAlign)ret.push(getNextArg("i8"));while(--width>0){ret.push(32)}if(!flagLeftAlign)ret.push(getNextArg("i8"));break};case"n":{var ptr=getNextArg("i32*");HEAP32[ptr>>2]=ret.length;break};case"%":{ret.push(curr);break};default:{for(var i=startTextIndex;i<textIndex+2;i++){ret.push(HEAP8[i>>0])}}}textIndex+=2}else{ret.push(curr);textIndex+=1}}return ret}function _fprintf(stream,format,varargs){var result=__formatString(format,varargs);var stack=Runtime.stackSave();var ret=_fwrite(allocate(result,"i8",ALLOC_STACK),1,result.length,stream);Runtime.stackRestore(stack);return ret}function _printf(format,varargs){var result=__formatString(format,varargs);var string=intArrayToString(result);if(string[string.length-1]==="\n")string=string.substr(0,string.length-1);Module.print(string);return result.length}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}Module["_memcpy"]=_memcpy;function _llvm_stackrestore(p){var self=_llvm_stacksave;var ret=self.LLVM_SAVEDSTACKS[p];self.LLVM_SAVEDSTACKS.splice(p,1);Runtime.stackRestore(ret)}var _cos=Math_cos;Module["_i64Add"]=_i64Add;var _fabs=Math_abs;var _floor=Math_floor;function _llvm_stacksave(){var self=_llvm_stacksave;if(!self.LLVM_SAVEDSTACKS){self.LLVM_SAVEDSTACKS=[]}self.LLVM_SAVEDSTACKS.push(Runtime.stackSave());return self.LLVM_SAVEDSTACKS.length-1}function _ogvjs_callback_init_audio(channels,rate){Module.audioFormat={channels:channels,rate:rate};Module.loadedMetadata=true}var _sqrt=Math_sqrt;var _atan2=Math_atan2;var _abs=Math_abs;function _sbrk(bytes){var self=_sbrk;if(!self.called){DYNAMICTOP=alignMemoryPage(DYNAMICTOP);self.called=true;assert(Runtime.dynamicAlloc);self.alloc=Runtime.dynamicAlloc;Runtime.dynamicAlloc=(function(){abort("cannot dynamically allocate, sbrk now has control")})}var ret=DYNAMICTOP;if(bytes!=0){var success=self.alloc(bytes);if(!success)return-1>>>0}return ret}var _exp=Math_exp;var _llvm_pow_f64=Math_pow;Module["_memmove"]=_memmove;___errno_state=Runtime.staticAlloc(4);HEAP32[___errno_state>>2]=0;STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP);staticSealed=true;STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=DYNAMICTOP=Runtime.alignMemory(STACK_MAX);assert(DYNAMIC_BASE<TOTAL_MEMORY,"TOTAL_MEMORY not big enough for stack");var cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_DYNAMIC);function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6){try{Module["dynCall_viiiiii"](index,a1,a2,a3,a4,a5,a6)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}Module.asmGlobalArg={"Math":Math,"Int8Array":Int8Array,"Int16Array":Int16Array,"Int32Array":Int32Array,"Uint8Array":Uint8Array,"Uint16Array":Uint16Array,"Uint32Array":Uint32Array,"Float32Array":Float32Array,"Float64Array":Float64Array,"NaN":NaN,"Infinity":Infinity};Module.asmLibraryArg={"abort":abort,"assert":assert,"invoke_viiiiii":invoke_viiiiii,"_fabs":_fabs,"_exp":_exp,"_llvm_pow_f64":_llvm_pow_f64,"_send":_send,"_atan2":_atan2,"___setErrNo":___setErrNo,"_llvm_stackrestore":_llvm_stackrestore,"_floor":_floor,"_pwrite":_pwrite,"__reallyNegative":__reallyNegative,"_sbrk":_sbrk,"_ogvjs_callback_init_audio":_ogvjs_callback_init_audio,"_fileno":_fileno,"_sysconf":_sysconf,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_cos":_cos,"_llvm_stacksave":_llvm_stacksave,"_printf":_printf,"_ogvjs_callback_audio":_ogvjs_callback_audio,"_write":_write,"___errno_location":___errno_location,"_abort":_abort,"_fwrite":_fwrite,"_time":_time,"_fprintf":_fprintf,"_abs":_abs,"__formatString":__formatString,"_sqrt":_sqrt,"STACKTOP":STACKTOP,"STACK_MAX":STACK_MAX,"tempDoublePtr":tempDoublePtr,"ABORT":ABORT,"cttz_i8":cttz_i8};// EMSCRIPTEN_START_ASM +var asm=(function(global,env,buffer) { +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=env.cttz_i8|0;var n=0;var o=0;var p=0;var q=0;var r=global.NaN,s=global.Infinity;var t=0,u=0,v=0,w=0,x=0.0,y=0,z=0,A=0,B=0.0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=0;var M=global.Math.floor;var N=global.Math.abs;var O=global.Math.sqrt;var P=global.Math.pow;var Q=global.Math.cos;var R=global.Math.sin;var S=global.Math.tan;var T=global.Math.acos;var U=global.Math.asin;var V=global.Math.atan;var W=global.Math.atan2;var X=global.Math.exp;var Y=global.Math.log;var Z=global.Math.ceil;var _=global.Math.imul;var $=global.Math.min;var aa=global.Math.clz32;var ba=env.abort;var ca=env.assert;var da=env.invoke_viiiiii;var ea=env._fabs;var fa=env._exp;var ga=env._llvm_pow_f64;var ha=env._send;var ia=env._atan2;var ja=env.___setErrNo;var ka=env._llvm_stackrestore;var la=env._floor;var ma=env._pwrite;var na=env.__reallyNegative;var oa=env._sbrk;var pa=env._ogvjs_callback_init_audio;var qa=env._fileno;var ra=env._sysconf;var sa=env._emscripten_memcpy_big;var ta=env._cos;var ua=env._llvm_stacksave;var va=env._printf;var wa=env._ogvjs_callback_audio;var xa=env._write;var ya=env.___errno_location;var za=env._abort;var Aa=env._fwrite;var Ba=env._time;var Ca=env._fprintf;var Da=env._abs;var Ea=env.__formatString;var Fa=env._sqrt;var Ga=0.0; +// EMSCRIPTEN_START_FUNCS +function kc(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;f=i;i=i+48|0;g=f+12|0;h=f+16|0;j=f+28|0;k=f+4|0;l=f+32|0;m=f+36|0;n=f+40|0;o=f+44|0;p=f+20|0;q=f+8|0;r=f;s=f+24|0;c[g>>2]=a;c[h>>2]=d;c[j>>2]=e;c[l>>2]=0;c[n>>2]=0;while(1){if((c[n>>2]|0)>=20)break;c[q>>2]=(b[c[g>>2]>>1]|0)-(b[c[h>>2]>>1]|0);c[l>>2]=0;c[k>>2]=1;while(1){if((c[k>>2]|0)>((c[j>>2]|0)-1|0))break;c[p>>2]=(b[(c[g>>2]|0)+(c[k>>2]<<1)>>1]|0)-((b[(c[g>>2]|0)+((c[k>>2]|0)-1<<1)>>1]|0)+(b[(c[h>>2]|0)+(c[k>>2]<<1)>>1]|0));if((c[p>>2]|0)<(c[q>>2]|0)){c[q>>2]=c[p>>2];c[l>>2]=c[k>>2]}c[k>>2]=(c[k>>2]|0)+1}c[p>>2]=32768-((b[(c[g>>2]|0)+((c[j>>2]|0)-1<<1)>>1]|0)+(b[(c[h>>2]|0)+(c[j>>2]<<1)>>1]|0));if((c[p>>2]|0)<(c[q>>2]|0)){c[q>>2]=c[p>>2];c[l>>2]=c[j>>2]}if((c[q>>2]|0)>=0){t=41;break}do if(!(c[l>>2]|0))b[c[g>>2]>>1]=b[c[h>>2]>>1]|0;else{if((c[l>>2]|0)==(c[j>>2]|0)){b[(c[g>>2]|0)+((c[j>>2]|0)-1<<1)>>1]=32768-(b[(c[h>>2]|0)+(c[j>>2]<<1)>>1]|0);break}c[r>>2]=0;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[l>>2]|0))break;c[r>>2]=(c[r>>2]|0)+(b[(c[h>>2]|0)+(c[m>>2]<<1)>>1]|0);c[m>>2]=(c[m>>2]|0)+1}c[r>>2]=(c[r>>2]|0)+(b[(c[h>>2]|0)+(c[l>>2]<<1)>>1]>>1);c[s>>2]=32768;c[m>>2]=c[j>>2];while(1){if((c[m>>2]|0)<=(c[l>>2]|0))break;c[s>>2]=(c[s>>2]|0)-(b[(c[h>>2]|0)+(c[m>>2]<<1)>>1]|0);c[m>>2]=(c[m>>2]|0)+-1}c[s>>2]=(c[s>>2]|0)-(b[(c[h>>2]|0)+(c[l>>2]<<1)>>1]>>1);e=((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)>>1)+((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)&1)|0;do if((c[r>>2]|0)>(c[s>>2]|0)){if((e|0)>(c[r>>2]|0)){u=c[r>>2]|0;break}if((((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)>>1)+((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)&1)|0)<(c[s>>2]|0)){u=c[s>>2]|0;break}else{u=((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)>>1)+((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)&1)|0;break}}else{if((e|0)>(c[s>>2]|0)){u=c[s>>2]|0;break}if((((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)>>1)+((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)&1)|0)<(c[r>>2]|0)){u=c[r>>2]|0;break}else{u=((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)>>1)+((b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]|0)&1)|0;break}}while(0);b[o>>1]=u;b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]=(b[o>>1]|0)-(b[(c[h>>2]|0)+(c[l>>2]<<1)>>1]>>1);b[(c[g>>2]|0)+(c[l>>2]<<1)>>1]=(b[(c[g>>2]|0)+((c[l>>2]|0)-1<<1)>>1]|0)+(b[(c[h>>2]|0)+(c[l>>2]<<1)>>1]|0)}while(0);c[n>>2]=(c[n>>2]|0)+1}if((t|0)==41){i=f;return}if((c[n>>2]|0)!=20){i=f;return}tc(c[g>>2]|0,c[j>>2]|0);n=(Rd(b[c[g>>2]>>1]|0,b[c[h>>2]>>1]|0)|0)&65535;b[c[g>>2]>>1]=n;c[k>>2]=1;while(1){if((c[k>>2]|0)>=(c[j>>2]|0))break;n=(Rd(b[(c[g>>2]|0)+(c[k>>2]<<1)>>1]|0,(b[(c[g>>2]|0)+((c[k>>2]|0)-1<<1)>>1]|0)+(b[(c[h>>2]|0)+(c[k>>2]<<1)>>1]|0)|0)|0)&65535;b[(c[g>>2]|0)+(c[k>>2]<<1)>>1]=n;c[k>>2]=(c[k>>2]|0)+1}n=(Sd(b[(c[g>>2]|0)+((c[j>>2]|0)-1<<1)>>1]|0,32768-(b[(c[h>>2]|0)+(c[j>>2]<<1)>>1]|0)|0)|0)&65535;b[(c[g>>2]|0)+((c[j>>2]|0)-1<<1)>>1]=n;c[k>>2]=(c[j>>2]|0)-2;while(1){if((c[k>>2]|0)<0)break;j=(Sd(b[(c[g>>2]|0)+(c[k>>2]<<1)>>1]|0,(b[(c[g>>2]|0)+((c[k>>2]|0)+1<<1)>>1]|0)-(b[(c[h>>2]|0)+((c[k>>2]|0)+1<<1)>>1]|0)|0)|0)&65535;b[(c[g>>2]|0)+(c[k>>2]<<1)>>1]=j;c[k>>2]=(c[k>>2]|0)+-1}i=f;return}function lc(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f+8|0;l=f+4|0;m=f;c[g>>2]=a;c[h>>2]=d;c[j>>2]=e;c[l>>2]=Td(b[c[h>>2]>>1]|0,1)|0;c[l>>2]=131072/(c[l>>2]|0)|0;c[m>>2]=Td((b[(c[h>>2]|0)+2>>1]|0)-(b[c[h>>2]>>1]|0)|0,1)|0;c[m>>2]=131072/(c[m>>2]|0)|0;e=(Ud((c[l>>2]|0)+(c[m>>2]|0)|0,32767)|0)&65535;b[c[g>>2]>>1]=e;c[k>>2]=1;while(1){if((c[k>>2]|0)>=((c[j>>2]|0)-1|0))break;c[l>>2]=Td((b[(c[h>>2]|0)+((c[k>>2]|0)+1<<1)>>1]|0)-(b[(c[h>>2]|0)+(c[k>>2]<<1)>>1]|0)|0,1)|0;c[l>>2]=131072/(c[l>>2]|0)|0;e=(Ud((c[l>>2]|0)+(c[m>>2]|0)|0,32767)|0)&65535;b[(c[g>>2]|0)+(c[k>>2]<<1)>>1]=e;c[m>>2]=Td((b[(c[h>>2]|0)+((c[k>>2]|0)+2<<1)>>1]|0)-(b[(c[h>>2]|0)+((c[k>>2]|0)+1<<1)>>1]|0)|0,1)|0;c[m>>2]=131072/(c[m>>2]|0)|0;e=(Ud((c[l>>2]|0)+(c[m>>2]|0)|0,32767)|0)&65535;b[(c[g>>2]|0)+((c[k>>2]|0)+1<<1)>>1]=e;c[k>>2]=(c[k>>2]|0)+2}c[l>>2]=Td(32768-(b[(c[h>>2]|0)+((c[j>>2]|0)-1<<1)>>1]|0)|0,1)|0;c[l>>2]=131072/(c[l>>2]|0)|0;h=(Ud((c[l>>2]|0)+(c[m>>2]|0)|0,32767)|0)&65535;b[(c[g>>2]|0)+((c[j>>2]|0)-1<<1)>>1]=h;i=f;return}function mc(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;g=i;i=i+32|0;h=g+20|0;j=g+16|0;k=g+12|0;l=g+8|0;m=g+4|0;n=g;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;bf(c[j>>2]|0,0,300)|0;f=(c[k>>2]|0)!=8e3&(c[k>>2]|0)!=12e3&(c[k>>2]|0)!=16e3;do if(c[m>>2]|0){if(!(f&(c[k>>2]|0)!=24e3&(c[k>>2]|0)!=48e3)?!((c[l>>2]|0)!=8e3&(c[l>>2]|0)!=12e3&(c[l>>2]|0)!=16e3):0){c[(c[j>>2]|0)+292>>2]=a[3e3+((((c[k>>2]>>12)-((c[k>>2]|0)>16e3&1)>>((c[k>>2]|0)>24e3&1))-1|0)*3|0)+(((c[l>>2]>>12)-((c[l>>2]|0)>16e3&1)>>((c[l>>2]|0)>24e3&1))-1)>>0];break}c[h>>2]=-1;o=c[h>>2]|0;i=g;return o|0}else{if(!f?!((c[l>>2]|0)!=8e3&(c[l>>2]|0)!=12e3&(c[l>>2]|0)!=16e3&(c[l>>2]|0)!=24e3&(c[l>>2]|0)!=48e3):0){c[(c[j>>2]|0)+292>>2]=a[3016+((((c[k>>2]>>12)-((c[k>>2]|0)>16e3&1)>>((c[k>>2]|0)>24e3&1))-1|0)*5|0)+(((c[l>>2]>>12)-((c[l>>2]|0)>16e3&1)>>((c[l>>2]|0)>24e3&1))-1)>>0];break}c[h>>2]=-1;o=c[h>>2]|0;i=g;return o|0}while(0);c[(c[j>>2]|0)+284>>2]=(c[k>>2]|0)/1e3|0;c[(c[j>>2]|0)+288>>2]=(c[l>>2]|0)/1e3|0;c[(c[j>>2]|0)+268>>2]=(c[(c[j>>2]|0)+284>>2]|0)*10;c[n>>2]=0;f=c[l>>2]|0;m=c[k>>2]|0;do if((c[l>>2]|0)>(c[k>>2]|0)){e=(c[j>>2]|0)+264|0;if((f|0)==(m<<1|0)){c[e>>2]=1;break}else{c[e>>2]=2;c[n>>2]=1;break}}else{e=(c[j>>2]|0)+264|0;if((f|0)>=(m|0)){c[e>>2]=0;break}c[e>>2]=3;if((c[l>>2]<<2|0)==((c[k>>2]|0)*3|0)){c[(c[j>>2]|0)+280>>2]=3;c[(c[j>>2]|0)+276>>2]=18;c[(c[j>>2]|0)+296>>2]=2024;break}if(((c[l>>2]|0)*3|0)==(c[k>>2]<<1|0)){c[(c[j>>2]|0)+280>>2]=2;c[(c[j>>2]|0)+276>>2]=18;c[(c[j>>2]|0)+296>>2]=2088;break}if((c[l>>2]<<1|0)==(c[k>>2]|0)){c[(c[j>>2]|0)+280>>2]=1;c[(c[j>>2]|0)+276>>2]=24;c[(c[j>>2]|0)+296>>2]=2128;break}if(((c[l>>2]|0)*3|0)==(c[k>>2]|0)){c[(c[j>>2]|0)+280>>2]=1;c[(c[j>>2]|0)+276>>2]=36;c[(c[j>>2]|0)+296>>2]=2160;break}if((c[l>>2]<<2|0)==(c[k>>2]|0)){c[(c[j>>2]|0)+280>>2]=1;c[(c[j>>2]|0)+276>>2]=36;c[(c[j>>2]|0)+296>>2]=2200;break}if(((c[l>>2]|0)*6|0)==(c[k>>2]|0)){c[(c[j>>2]|0)+280>>2]=1;c[(c[j>>2]|0)+276>>2]=36;c[(c[j>>2]|0)+296>>2]=2240;break}c[h>>2]=-1;o=c[h>>2]|0;i=g;return o|0}while(0);c[(c[j>>2]|0)+272>>2]=((c[k>>2]<<14+(c[n>>2]|0)|0)/(c[l>>2]|0)|0)<<2;while(1){m=_(c[(c[j>>2]|0)+272>>2]>>16,(c[l>>2]&65535)<<16>>16)|0;f=m+((_(c[(c[j>>2]|0)+272>>2]&65535,(c[l>>2]&65535)<<16>>16)|0)>>16)|0;m=f+(_(c[(c[j>>2]|0)+272>>2]|0,(c[l>>2]>>15)+1>>1)|0)|0;if((m|0)>=(c[k>>2]<<c[n>>2]|0))break;m=(c[j>>2]|0)+272|0;c[m>>2]=(c[m>>2]|0)+1}c[h>>2]=0;o=c[h>>2]|0;i=g;return o|0}function nc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[l>>2]=(c[(c[g>>2]|0)+284>>2]|0)-(c[(c[g>>2]|0)+292>>2]|0);df((c[g>>2]|0)+168+(c[(c[g>>2]|0)+292>>2]<<1)|0,c[j>>2]|0,c[l>>2]<<1|0)|0;e=c[(c[g>>2]|0)+264>>2]|0;if((e|0)==1){sc(c[g>>2]|0,c[h>>2]|0,(c[g>>2]|0)+168|0,c[(c[g>>2]|0)+284>>2]|0);sc(c[g>>2]|0,(c[h>>2]|0)+(c[(c[g>>2]|0)+288>>2]<<1)|0,(c[j>>2]|0)+(c[l>>2]<<1)|0,(c[k>>2]|0)-(c[(c[g>>2]|0)+284>>2]|0)|0)}else if((e|0)==2){qc(c[g>>2]|0,c[h>>2]|0,(c[g>>2]|0)+168|0,c[(c[g>>2]|0)+284>>2]|0);qc(c[g>>2]|0,(c[h>>2]|0)+(c[(c[g>>2]|0)+288>>2]<<1)|0,(c[j>>2]|0)+(c[l>>2]<<1)|0,(c[k>>2]|0)-(c[(c[g>>2]|0)+284>>2]|0)|0)}else if((e|0)==3){pc(c[g>>2]|0,c[h>>2]|0,(c[g>>2]|0)+168|0,c[(c[g>>2]|0)+284>>2]|0);pc(c[g>>2]|0,(c[h>>2]|0)+(c[(c[g>>2]|0)+288>>2]<<1)|0,(c[j>>2]|0)+(c[l>>2]<<1)|0,(c[k>>2]|0)-(c[(c[g>>2]|0)+284>>2]|0)|0)}else{df(c[h>>2]|0,(c[g>>2]|0)+168|0,c[(c[g>>2]|0)+284>>2]<<1|0)|0;df((c[h>>2]|0)+(c[(c[g>>2]|0)+288>>2]<<1)|0,(c[j>>2]|0)+(c[l>>2]<<1)|0,(c[k>>2]|0)-(c[(c[g>>2]|0)+284>>2]|0)<<1|0)|0}df((c[g>>2]|0)+168|0,(c[j>>2]|0)+((c[k>>2]|0)-(c[(c[g>>2]|0)+292>>2]|0)<<1)|0,c[(c[g>>2]|0)+292>>2]<<1|0)|0;i=f;return 0}function oc(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=i;i=i+32|0;j=h+8|0;k=h+16|0;l=h+20|0;m=h+24|0;n=h+4|0;o=h;p=h+12|0;c[j>>2]=a;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[o>>2]=0;while(1){if((c[o>>2]|0)>=(c[n>>2]|0))break;c[p>>2]=(c[c[j>>2]>>2]|0)+(b[(c[l>>2]|0)+(c[o>>2]<<1)>>1]<<8);c[(c[k>>2]|0)+(c[o>>2]<<2)>>2]=c[p>>2];c[p>>2]=c[p>>2]<<2;g=_(c[p>>2]>>16,b[c[m>>2]>>1]|0)|0;f=(c[(c[j>>2]|0)+4>>2]|0)+(g+((_(c[p>>2]&65535,b[c[m>>2]>>1]|0)|0)>>16))|0;c[c[j>>2]>>2]=f;f=_(c[p>>2]>>16,b[(c[m>>2]|0)+2>>1]|0)|0;g=f+((_(c[p>>2]&65535,b[(c[m>>2]|0)+2>>1]|0)|0)>>16)|0;c[(c[j>>2]|0)+4>>2]=g;c[o>>2]=(c[o>>2]|0)+1}i=h;return}function pc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;f=i;i=i+48|0;g=f;h=f+16|0;j=f+28|0;k=f+4|0;l=f+32|0;m=f+36|0;n=f+12|0;o=f+24|0;p=f+20|0;q=f+8|0;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[l>>2]=c[g>>2];g=(c[(c[l>>2]|0)+268>>2]|0)+(c[(c[l>>2]|0)+276>>2]|0)|0;c[q>>2]=ua()|0;e=i;i=i+((1*(g<<2)|0)+15&-16)|0;df(e|0,(c[l>>2]|0)+24|0,c[(c[l>>2]|0)+276>>2]<<2|0)|0;c[p>>2]=(c[(c[l>>2]|0)+296>>2]|0)+4;c[o>>2]=c[(c[l>>2]|0)+272>>2];while(1){if((c[k>>2]|0)<(c[(c[l>>2]|0)+268>>2]|0))r=c[k>>2]|0;else r=c[(c[l>>2]|0)+268>>2]|0;c[m>>2]=r;oc(c[l>>2]|0,e+(c[(c[l>>2]|0)+276>>2]<<2)|0,c[j>>2]|0,c[(c[l>>2]|0)+296>>2]|0,c[m>>2]|0);c[n>>2]=c[m>>2]<<16;c[h>>2]=Vd(c[h>>2]|0,e,c[p>>2]|0,c[(c[l>>2]|0)+276>>2]|0,c[(c[l>>2]|0)+280>>2]|0,c[n>>2]|0,c[o>>2]|0)|0;c[j>>2]=(c[j>>2]|0)+(c[m>>2]<<1);c[k>>2]=(c[k>>2]|0)-(c[m>>2]|0);if((c[k>>2]|0)<=1)break;df(e|0,e+(c[m>>2]<<2)|0,c[(c[l>>2]|0)+276>>2]<<2|0)|0}df((c[l>>2]|0)+24|0,e+(c[m>>2]<<2)|0,c[(c[l>>2]|0)+276>>2]<<2|0)|0;ka(c[q>>2]|0);i=f;return}function qc(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;g=i;i=i+48|0;h=g+28|0;j=g+16|0;k=g+4|0;l=g+8|0;m=g+32|0;n=g;o=g+12|0;p=g+24|0;q=g+20|0;c[h>>2]=a;c[j>>2]=d;c[k>>2]=e;c[l>>2]=f;c[m>>2]=c[h>>2];h=(c[(c[m>>2]|0)+268>>2]<<1)+8|0;c[q>>2]=ua()|0;f=i;i=i+((1*(h<<1)|0)+15&-16)|0;h=(c[m>>2]|0)+24|0;b[f>>1]=b[h>>1]|0;b[f+2>>1]=b[h+2>>1]|0;b[f+4>>1]=b[h+4>>1]|0;b[f+6>>1]=b[h+6>>1]|0;b[f+8>>1]=b[h+8>>1]|0;b[f+10>>1]=b[h+10>>1]|0;b[f+12>>1]=b[h+12>>1]|0;b[f+14>>1]=b[h+14>>1]|0;c[p>>2]=c[(c[m>>2]|0)+272>>2];while(1){if((c[l>>2]|0)<(c[(c[m>>2]|0)+268>>2]|0))r=c[l>>2]|0;else r=c[(c[m>>2]|0)+268>>2]|0;c[n>>2]=r;rc(c[m>>2]|0,f+16|0,c[k>>2]|0,c[n>>2]|0);c[o>>2]=c[n>>2]<<17;c[j>>2]=Wd(c[j>>2]|0,f,c[o>>2]|0,c[p>>2]|0)|0;c[k>>2]=(c[k>>2]|0)+(c[n>>2]<<1);c[l>>2]=(c[l>>2]|0)-(c[n>>2]|0);if((c[l>>2]|0)<=0)break;h=f+(c[n>>2]<<1<<1)|0;b[f>>1]=b[h>>1]|0;b[f+2>>1]=b[h+2>>1]|0;b[f+4>>1]=b[h+4>>1]|0;b[f+6>>1]=b[h+6>>1]|0;b[f+8>>1]=b[h+8>>1]|0;b[f+10>>1]=b[h+10>>1]|0;b[f+12>>1]=b[h+12>>1]|0;b[f+14>>1]=b[h+14>>1]|0}l=(c[m>>2]|0)+24|0;m=f+(c[n>>2]<<1<<1)|0;b[l>>1]=b[m>>1]|0;b[l+2>>1]=b[m+2>>1]|0;b[l+4>>1]=b[m+4>>1]|0;b[l+6>>1]=b[m+6>>1]|0;b[l+8>>1]=b[m+8>>1]|0;b[l+10>>1]=b[m+10>>1]|0;b[l+12>>1]=b[m+12>>1]|0;b[l+14>>1]=b[m+14>>1]|0;ka(c[q>>2]|0);i=g;return}function rc(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;g=i;i=i+48|0;h=g;j=g+16|0;k=g+28|0;l=g+4|0;m=g+32|0;n=g+36|0;o=g+12|0;p=g+24|0;q=g+20|0;r=g+8|0;c[h>>2]=a;c[j>>2]=d;c[k>>2]=e;c[l>>2]=f;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[l>>2]|0))break;c[n>>2]=b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]<<10;c[q>>2]=(c[n>>2]|0)-(c[c[h>>2]>>2]|0);f=_(c[q>>2]>>16,b[1516]|0)|0;c[r>>2]=f+((_(c[q>>2]&65535,b[1516]|0)|0)>>16);c[o>>2]=(c[c[h>>2]>>2]|0)+(c[r>>2]|0);c[c[h>>2]>>2]=(c[n>>2]|0)+(c[r>>2]|0);c[q>>2]=(c[o>>2]|0)-(c[(c[h>>2]|0)+4>>2]|0);f=_(c[q>>2]>>16,b[1517]|0)|0;c[r>>2]=f+((_(c[q>>2]&65535,b[1517]|0)|0)>>16);c[p>>2]=(c[(c[h>>2]|0)+4>>2]|0)+(c[r>>2]|0);c[(c[h>>2]|0)+4>>2]=(c[o>>2]|0)+(c[r>>2]|0);c[q>>2]=(c[p>>2]|0)-(c[(c[h>>2]|0)+8>>2]|0);f=_(c[q>>2]>>16,b[1518]|0)|0;c[r>>2]=(c[q>>2]|0)+(f+((_(c[q>>2]&65535,b[1518]|0)|0)>>16));c[o>>2]=(c[(c[h>>2]|0)+8>>2]|0)+(c[r>>2]|0);c[(c[h>>2]|0)+8>>2]=(c[p>>2]|0)+(c[r>>2]|0);if(((c[o>>2]>>9)+1>>1|0)<=32767)if(((c[o>>2]>>9)+1>>1|0)<-32768)s=-32768;else s=(c[o>>2]>>9)+1>>1;else s=32767;b[(c[j>>2]|0)+(c[m>>2]<<1<<1)>>1]=s;c[q>>2]=(c[n>>2]|0)-(c[(c[h>>2]|0)+12>>2]|0);f=_(c[q>>2]>>16,b[1520]|0)|0;c[r>>2]=f+((_(c[q>>2]&65535,b[1520]|0)|0)>>16);c[o>>2]=(c[(c[h>>2]|0)+12>>2]|0)+(c[r>>2]|0);c[(c[h>>2]|0)+12>>2]=(c[n>>2]|0)+(c[r>>2]|0);c[q>>2]=(c[o>>2]|0)-(c[(c[h>>2]|0)+16>>2]|0);f=_(c[q>>2]>>16,b[1521]|0)|0;c[r>>2]=f+((_(c[q>>2]&65535,b[1521]|0)|0)>>16);c[p>>2]=(c[(c[h>>2]|0)+16>>2]|0)+(c[r>>2]|0);c[(c[h>>2]|0)+16>>2]=(c[o>>2]|0)+(c[r>>2]|0);c[q>>2]=(c[p>>2]|0)-(c[(c[h>>2]|0)+20>>2]|0);f=_(c[q>>2]>>16,b[1522]|0)|0;c[r>>2]=(c[q>>2]|0)+(f+((_(c[q>>2]&65535,b[1522]|0)|0)>>16));c[o>>2]=(c[(c[h>>2]|0)+20>>2]|0)+(c[r>>2]|0);c[(c[h>>2]|0)+20>>2]=(c[p>>2]|0)+(c[r>>2]|0);if(((c[o>>2]>>9)+1>>1|0)<=32767)if(((c[o>>2]>>9)+1>>1|0)<-32768)t=-32768;else t=(c[o>>2]>>9)+1>>1;else t=32767;b[(c[j>>2]|0)+((c[m>>2]<<1)+1<<1)>>1]=t;c[m>>2]=(c[m>>2]|0)+1}i=g;return}function sc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[l>>2]=c[g>>2];rc(c[l>>2]|0,c[h>>2]|0,c[j>>2]|0,c[k>>2]|0);i=f;return}function tc(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[f>>2]=a;c[g>>2]=d;c[j>>2]=1;while(1){if((c[j>>2]|0)>=(c[g>>2]|0))break;c[h>>2]=b[(c[f>>2]|0)+(c[j>>2]<<1)>>1];c[k>>2]=(c[j>>2]|0)-1;while(1){if((c[k>>2]|0)<0)break;if((c[h>>2]|0)>=(b[(c[f>>2]|0)+(c[k>>2]<<1)>>1]|0))break;b[(c[f>>2]|0)+((c[k>>2]|0)+1<<1)>>1]=b[(c[f>>2]|0)+(c[k>>2]<<1)>>1]|0;c[k>>2]=(c[k>>2]|0)+-1}b[(c[f>>2]|0)+((c[k>>2]|0)+1<<1)>>1]=c[h>>2];c[j>>2]=(c[j>>2]|0)+1}i=e;return}function uc(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;g=i;i=i+32|0;h=g+4|0;j=g+16|0;k=g+8|0;l=g+20|0;m=g+28|0;n=g;o=g+12|0;p=g+24|0;c[h>>2]=a;c[j>>2]=d;c[k>>2]=e;c[l>>2]=f;c[p>>2]=0;c[n>>2]=0;c[l>>2]=(c[l>>2]|0)+-1;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[l>>2]|0))break;c[p>>2]=(c[p>>2]|0)+(_(b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]|0,b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]|0)|0);c[p>>2]=(c[p>>2]|0)+(_(b[(c[k>>2]|0)+((c[m>>2]|0)+1<<1)>>1]|0,b[(c[k>>2]|0)+((c[m>>2]|0)+1<<1)>>1]|0)|0);if((c[p>>2]|0)<0){q=4;break}c[m>>2]=(c[m>>2]|0)+2}if((q|0)==4){c[p>>2]=(c[p>>2]|0)>>>2;c[n>>2]=2}while(1){r=c[m>>2]|0;if((c[m>>2]|0)>=(c[l>>2]|0))break;c[o>>2]=_(b[(c[k>>2]|0)+(r<<1)>>1]|0,b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(_(b[(c[k>>2]|0)+((c[m>>2]|0)+1<<1)>>1]|0,b[(c[k>>2]|0)+((c[m>>2]|0)+1<<1)>>1]|0)|0);c[p>>2]=(c[p>>2]|0)+((c[o>>2]|0)>>>(c[n>>2]|0));if((c[p>>2]|0)<0){c[p>>2]=(c[p>>2]|0)>>>2;c[n>>2]=(c[n>>2]|0)+2}c[m>>2]=(c[m>>2]|0)+2}if((r|0)==(c[l>>2]|0)){c[o>>2]=_(b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]|0,b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]|0)|0;c[p>>2]=(c[p>>2]|0)+(c[o>>2]>>c[n>>2])}if(!(c[p>>2]&-1073741824)){s=c[n>>2]|0;t=c[j>>2]|0;c[t>>2]=s;u=c[p>>2]|0;v=c[h>>2]|0;c[v>>2]=u;i=g;return}c[p>>2]=(c[p>>2]|0)>>>2;c[n>>2]=(c[n>>2]|0)+2;s=c[n>>2]|0;t=c[j>>2]|0;c[t>>2]=s;u=c[p>>2]|0;v=c[h>>2]|0;c[v>>2]=u;i=g;return}function vc(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+48|0;f=e+40|0;g=e+36|0;h=e+32|0;j=e+8|0;k=e+4|0;l=e;c[f>>2]=a;c[g>>2]=d;c[h>>2]=jb(c[f>>2]|0,368,8)|0;c[j+8>>2]=(c[h>>2]|0)/5|0;c[j+12+8>>2]=(c[h>>2]|0)-((c[j+8>>2]|0)*5|0);c[h>>2]=0;while(1){if((c[h>>2]|0)>=2)break;d=jb(c[f>>2]|0,472,8)|0;c[j+((c[h>>2]|0)*12|0)>>2]=d;d=jb(c[f>>2]|0,488,8)|0;c[j+((c[h>>2]|0)*12|0)+4>>2]=d;c[h>>2]=(c[h>>2]|0)+1}c[h>>2]=0;while(1){if((c[h>>2]|0)>=2)break;f=j+((c[h>>2]|0)*12|0)|0;c[f>>2]=(c[f>>2]|0)+((c[j+((c[h>>2]|0)*12|0)+8>>2]|0)*3|0);c[k>>2]=b[336+(c[j+((c[h>>2]|0)*12|0)>>2]<<1)>>1];c[l>>2]=(((b[336+((c[j+((c[h>>2]|0)*12|0)>>2]|0)+1<<1)>>1]|0)-(c[k>>2]|0)>>16)*6554|0)+(((b[336+((c[j+((c[h>>2]|0)*12|0)>>2]|0)+1<<1)>>1]|0)-(c[k>>2]|0)&65535)*6554>>16);f=(c[k>>2]|0)+(_((c[l>>2]&65535)<<16>>16,((c[j+((c[h>>2]|0)*12|0)+4>>2]<<1)+1&65535)<<16>>16)|0)|0;c[(c[g>>2]|0)+(c[h>>2]<<2)>>2]=f;c[h>>2]=(c[h>>2]|0)+1}h=c[g>>2]|0;c[h>>2]=(c[h>>2]|0)-(c[(c[g>>2]|0)+4>>2]|0);i=e;return}function wc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;b=jb(c[e>>2]|0,400,8)|0;c[c[f>>2]>>2]=b;i=d;return}function xc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0.0,A=0.0,B=0,C=0,D=0.0,E=0.0;f=i;i=i+80|0;h=f+60|0;j=f+44|0;k=f+24|0;l=f+28|0;m=f+12|0;n=f+40|0;o=f+48|0;p=f+56|0;q=f+64|0;r=f+8|0;s=f+4|0;t=f+32|0;u=f;v=f+16|0;w=f+36|0;x=f+20|0;y=f+52|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;if(!((((c[k>>2]|0)<1|(c[j>>2]|0)<1)^1)&(c[h>>2]|0)!=0&(c[l>>2]|0)!=0)){i=f;return}c[n>>2]=0;while(1){if((c[n>>2]|0)>=(_(c[j>>2]|0,c[k>>2]|0)|0))break;if(2.0<+g[(c[h>>2]|0)+(c[n>>2]<<2)>>2])z=2.0;else z=+g[(c[h>>2]|0)+(c[n>>2]<<2)>>2];if(!(-2.0>z))if(2.0<+g[(c[h>>2]|0)+(c[n>>2]<<2)>>2])A=2.0;else A=+g[(c[h>>2]|0)+(c[n>>2]<<2)>>2];else A=-2.0;g[(c[h>>2]|0)+(c[n>>2]<<2)>>2]=A;c[n>>2]=(c[n>>2]|0)+1}c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;c[o>>2]=(c[h>>2]|0)+(c[m>>2]<<2);g[p>>2]=+g[(c[l>>2]|0)+(c[m>>2]<<2)>>2];c[n>>2]=0;while(1){if((c[n>>2]|0)>=(c[j>>2]|0))break;e=_(c[n>>2]|0,c[k>>2]|0)|0;if(+g[(c[o>>2]|0)+(e<<2)>>2]*+g[p>>2]>=0.0)break;e=_(c[n>>2]|0,c[k>>2]|0)|0;d=_(c[n>>2]|0,c[k>>2]|0)|0;b=_(c[n>>2]|0,c[k>>2]|0)|0;a=_(c[n>>2]|0,c[k>>2]|0)|0;g[(c[o>>2]|0)+(a<<2)>>2]=+g[(c[o>>2]|0)+(e<<2)>>2]+ +g[p>>2]*+g[(c[o>>2]|0)+(d<<2)>>2]*+g[(c[o>>2]|0)+(b<<2)>>2];c[n>>2]=(c[n>>2]|0)+1}c[r>>2]=0;g[q>>2]=+g[c[o>>2]>>2];do{c[v>>2]=0;c[n>>2]=c[r>>2];while(1){if((c[n>>2]|0)>=(c[j>>2]|0))break;b=_(c[n>>2]|0,c[k>>2]|0)|0;if(+g[(c[o>>2]|0)+(b<<2)>>2]>1.0)break;b=_(c[n>>2]|0,c[k>>2]|0)|0;if(+g[(c[o>>2]|0)+(b<<2)>>2]<-1.0)break;c[n>>2]=(c[n>>2]|0)+1}if((c[n>>2]|0)==(c[j>>2]|0)){B=23;break}c[w>>2]=c[n>>2];b=c[n>>2]|0;c[t>>2]=b;c[s>>2]=b;b=_(c[n>>2]|0,c[k>>2]|0)|0;g[u>>2]=+N(+(+g[(c[o>>2]|0)+(b<<2)>>2]));while(1){if((c[s>>2]|0)<=0)break;b=_(c[n>>2]|0,c[k>>2]|0)|0;d=_((c[s>>2]|0)-1|0,c[k>>2]|0)|0;if(!(+g[(c[o>>2]|0)+(b<<2)>>2]*+g[(c[o>>2]|0)+(d<<2)>>2]>=0.0))break;c[s>>2]=(c[s>>2]|0)+-1}while(1){if((c[t>>2]|0)>=(c[j>>2]|0))break;d=_(c[n>>2]|0,c[k>>2]|0)|0;b=_(c[t>>2]|0,c[k>>2]|0)|0;if(!(+g[(c[o>>2]|0)+(d<<2)>>2]*+g[(c[o>>2]|0)+(b<<2)>>2]>=0.0))break;b=_(c[t>>2]|0,c[k>>2]|0)|0;A=+N(+(+g[(c[o>>2]|0)+(b<<2)>>2]));if(A>+g[u>>2]){b=_(c[t>>2]|0,c[k>>2]|0)|0;g[u>>2]=+N(+(+g[(c[o>>2]|0)+(b<<2)>>2]));c[w>>2]=c[t>>2]}c[t>>2]=(c[t>>2]|0)+1}if(!(c[s>>2]|0)){b=_(c[n>>2]|0,c[k>>2]|0)|0;C=+g[(c[o>>2]|0)+(b<<2)>>2]*+g[c[o>>2]>>2]>=0.0}else C=0;c[v>>2]=C&1;g[p>>2]=(+g[u>>2]-1.0)/(+g[u>>2]*+g[u>>2]);b=_(c[n>>2]|0,c[k>>2]|0)|0;if(+g[(c[o>>2]|0)+(b<<2)>>2]>0.0)g[p>>2]=-+g[p>>2];c[n>>2]=c[s>>2];while(1){if((c[n>>2]|0)>=(c[t>>2]|0))break;b=_(c[n>>2]|0,c[k>>2]|0)|0;d=_(c[n>>2]|0,c[k>>2]|0)|0;e=_(c[n>>2]|0,c[k>>2]|0)|0;a=_(c[n>>2]|0,c[k>>2]|0)|0;g[(c[o>>2]|0)+(a<<2)>>2]=+g[(c[o>>2]|0)+(b<<2)>>2]+ +g[p>>2]*+g[(c[o>>2]|0)+(d<<2)>>2]*+g[(c[o>>2]|0)+(e<<2)>>2];c[n>>2]=(c[n>>2]|0)+1}a:do if((c[v>>2]|0)!=0&(c[w>>2]|0)>=2){g[y>>2]=+g[q>>2]-+g[c[o>>2]>>2];g[x>>2]=+g[y>>2]/+(c[w>>2]|0);c[n>>2]=c[r>>2];while(1){if((c[n>>2]|0)>=(c[w>>2]|0))break a;g[y>>2]=+g[y>>2]-+g[x>>2];e=_(c[n>>2]|0,c[k>>2]|0)|0;d=(c[o>>2]|0)+(e<<2)|0;g[d>>2]=+g[d>>2]+ +g[y>>2];d=_(c[n>>2]|0,c[k>>2]|0)|0;if(1.0<+g[(c[o>>2]|0)+(d<<2)>>2])D=1.0;else{d=_(c[n>>2]|0,c[k>>2]|0)|0;D=+g[(c[o>>2]|0)+(d<<2)>>2]}if(!(-1.0>D)){d=_(c[n>>2]|0,c[k>>2]|0)|0;if(1.0<+g[(c[o>>2]|0)+(d<<2)>>2])E=1.0;else{d=_(c[n>>2]|0,c[k>>2]|0)|0;E=+g[(c[o>>2]|0)+(d<<2)>>2]}}else E=-1.0;d=_(c[n>>2]|0,c[k>>2]|0)|0;g[(c[o>>2]|0)+(d<<2)>>2]=E;c[n>>2]=(c[n>>2]|0)+1}}while(0);c[r>>2]=c[t>>2]}while((c[r>>2]|0)!=(c[j>>2]|0));if((B|0)==23){B=0;g[p>>2]=0.0}g[(c[l>>2]|0)+(c[m>>2]<<2)>>2]=+g[p>>2];c[m>>2]=(c[m>>2]|0)+1}i=f;return}function yc(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[f>>2]=a;c[g>>2]=b;b=d[c[f>>2]>>0]|0;if((d[c[f>>2]>>0]|0)&128){c[h>>2]=b>>3&3;c[h>>2]=(c[g>>2]<<c[h>>2]|0)/400|0;j=c[h>>2]|0;i=e;return j|0}a=d[c[f>>2]>>0]|0;if((b&96|0)==96){b=c[g>>2]|0;c[h>>2]=(a&8|0)!=0?(b|0)/50|0:(b|0)/100|0;j=c[h>>2]|0;i=e;return j|0}c[h>>2]=a>>3&3;a=c[g>>2]|0;if((c[h>>2]|0)==3){c[h>>2]=(a*60|0)/1e3|0;j=c[h>>2]|0;i=e;return j|0}else{c[h>>2]=(a<<c[h>>2]|0)/100|0;j=c[h>>2]|0;i=e;return j|0}return 0}function zc(e,f,g,h,j,k,l,m){e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;n=i;i=i+80|0;o=n+36|0;p=n+24|0;q=n+44|0;r=n+60|0;s=n+12|0;t=n+16|0;u=n+48|0;v=n+56|0;w=n+64|0;x=n+68|0;y=n+72|0;z=n+8|0;A=n;B=n+76|0;C=n+77|0;D=n+20|0;E=n+52|0;F=n+28|0;G=n+32|0;H=n+40|0;I=n+4|0;c[p>>2]=e;c[q>>2]=f;c[r>>2]=g;c[s>>2]=h;c[t>>2]=j;c[u>>2]=k;c[v>>2]=l;c[w>>2]=m;c[F>>2]=0;c[G>>2]=c[p>>2];if(!(c[u>>2]|0)){c[o>>2]=-1;J=c[o>>2]|0;i=n;return J|0}c[D>>2]=yc(c[p>>2]|0,48e3)|0;c[A>>2]=0;m=c[p>>2]|0;c[p>>2]=m+1;a[C>>0]=a[m>>0]|0;c[q>>2]=(c[q>>2]|0)+-1;c[E>>2]=c[q>>2];m=d[C>>0]&3;a:do if(!m)c[z>>2]=1;else if((m|0)==1){c[z>>2]=2;c[A>>2]=1;if(!(c[r>>2]|0)){if(!(c[q>>2]&1)){c[E>>2]=(c[q>>2]|0)/2|0;b[c[u>>2]>>1]=c[E>>2];break}c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}}else if((m|0)==2){c[z>>2]=2;c[y>>2]=Xd(c[p>>2]|0,c[q>>2]|0,c[u>>2]|0)|0;c[q>>2]=(c[q>>2]|0)-(c[y>>2]|0);if((b[c[u>>2]>>1]|0)>=0?(b[c[u>>2]>>1]|0)<=(c[q>>2]|0):0){c[p>>2]=(c[p>>2]|0)+(c[y>>2]|0);c[E>>2]=(c[q>>2]|0)-(b[c[u>>2]>>1]|0);break}c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}else{if((c[q>>2]|0)<1){c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}l=c[p>>2]|0;c[p>>2]=l+1;a[B>>0]=a[l>>0]|0;c[z>>2]=d[B>>0]&63;if((c[z>>2]|0)>0?(_(c[D>>2]|0,c[z>>2]|0)|0)<=5760:0){c[q>>2]=(c[q>>2]|0)+-1;b:do if(d[B>>0]&64){while(1){if((c[q>>2]|0)<=0)break;l=c[p>>2]|0;c[p>>2]=l+1;c[H>>2]=d[l>>0];c[q>>2]=(c[q>>2]|0)+-1;c[I>>2]=(c[H>>2]|0)==255?254:c[H>>2]|0;c[q>>2]=(c[q>>2]|0)-(c[I>>2]|0);c[F>>2]=(c[F>>2]|0)+(c[I>>2]|0);if((c[H>>2]|0)!=255)break b}c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}while(0);if((c[q>>2]|0)<0){c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}c[A>>2]=((d[B>>0]&128|0)!=0^1)&1;if(c[A>>2]|0){if(c[r>>2]|0)break;c[E>>2]=(c[q>>2]|0)/(c[z>>2]|0)|0;l=_(c[E>>2]|0,c[z>>2]|0)|0;if((l|0)!=(c[q>>2]|0)){c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}c[x>>2]=0;while(1){if((c[x>>2]|0)>=((c[z>>2]|0)-1|0))break a;b[(c[u>>2]|0)+(c[x>>2]<<1)>>1]=c[E>>2];c[x>>2]=(c[x>>2]|0)+1}}c[E>>2]=c[q>>2];c[x>>2]=0;while(1){if((c[x>>2]|0)>=((c[z>>2]|0)-1|0))break;c[y>>2]=Xd(c[p>>2]|0,c[q>>2]|0,(c[u>>2]|0)+(c[x>>2]<<1)|0)|0;c[q>>2]=(c[q>>2]|0)-(c[y>>2]|0);if((b[(c[u>>2]|0)+(c[x>>2]<<1)>>1]|0)<0){K=29;break}if((b[(c[u>>2]|0)+(c[x>>2]<<1)>>1]|0)>(c[q>>2]|0)){K=29;break}c[p>>2]=(c[p>>2]|0)+(c[y>>2]|0);c[E>>2]=(c[E>>2]|0)-((c[y>>2]|0)+(b[(c[u>>2]|0)+(c[x>>2]<<1)>>1]|0));c[x>>2]=(c[x>>2]|0)+1}if((K|0)==29){c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}if((c[E>>2]|0)>=0)break;c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}while(0);c:do if(c[r>>2]|0){c[y>>2]=Xd(c[p>>2]|0,c[q>>2]|0,(c[u>>2]|0)+(c[z>>2]<<1)+-2|0)|0;c[q>>2]=(c[q>>2]|0)-(c[y>>2]|0);if((b[(c[u>>2]|0)+((c[z>>2]|0)-1<<1)>>1]|0)>=0?(b[(c[u>>2]|0)+((c[z>>2]|0)-1<<1)>>1]|0)<=(c[q>>2]|0):0){c[p>>2]=(c[p>>2]|0)+(c[y>>2]|0);if(!(c[A>>2]|0)){if(((c[y>>2]|0)+(b[(c[u>>2]|0)+((c[z>>2]|0)-1<<1)>>1]|0)|0)<=(c[E>>2]|0))break;c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}K=_(b[(c[u>>2]|0)+((c[z>>2]|0)-1<<1)>>1]|0,c[z>>2]|0)|0;if((K|0)>(c[q>>2]|0)){c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}c[x>>2]=0;while(1){if((c[x>>2]|0)>=((c[z>>2]|0)-1|0))break c;b[(c[u>>2]|0)+(c[x>>2]<<1)>>1]=b[(c[u>>2]|0)+((c[z>>2]|0)-1<<1)>>1]|0;c[x>>2]=(c[x>>2]|0)+1}}c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}else{if((c[E>>2]|0)<=1275){b[(c[u>>2]|0)+((c[z>>2]|0)-1<<1)>>1]=c[E>>2];break}c[o>>2]=-4;J=c[o>>2]|0;i=n;return J|0}while(0);if(c[v>>2]|0)c[c[v>>2]>>2]=(c[p>>2]|0)-(c[G>>2]|0);c[x>>2]=0;while(1){if((c[x>>2]|0)>=(c[z>>2]|0))break;if(c[t>>2]|0)c[(c[t>>2]|0)+(c[x>>2]<<2)>>2]=c[p>>2];c[p>>2]=(c[p>>2]|0)+(b[(c[u>>2]|0)+(c[x>>2]<<1)>>1]|0);c[x>>2]=(c[x>>2]|0)+1}if(c[w>>2]|0)c[c[w>>2]>>2]=(c[F>>2]|0)+((c[p>>2]|0)-(c[G>>2]|0));if(c[s>>2]|0)a[c[s>>2]>>0]=a[C>>0]|0;c[o>>2]=c[z>>2];J=c[o>>2]|0;i=n;return J|0}function Ac(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0;b=i;i=i+32|0;d=b+16|0;e=b+12|0;f=b+8|0;g=b+4|0;h=b;c[e>>2]=a;if((c[e>>2]|0)<1|(c[e>>2]|0)>2){c[d>>2]=0;j=c[d>>2]|0;i=b;return j|0}c[h>>2]=Ub(f)|0;if(c[h>>2]|0){c[d>>2]=0;j=c[d>>2]|0;i=b;return j|0}else{c[f>>2]=Yd(c[f>>2]|0)|0;c[g>>2]=Za(c[e>>2]|0)|0;e=Yd(84)|0;c[d>>2]=e+(c[f>>2]|0)+(c[g>>2]|0);j=c[d>>2]|0;i=b;return j|0}return 0}function Bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;e=i;i=i+48|0;f=e;g=e+24|0;h=e+20|0;j=e+8|0;k=e+16|0;l=e+4|0;m=e+12|0;n=e+28|0;o=e+32|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;if(!((c[j>>2]|0)!=48e3&(c[j>>2]|0)!=24e3&(c[j>>2]|0)!=16e3&(c[j>>2]|0)!=12e3&(c[j>>2]|0)!=8e3)?!((c[k>>2]|0)!=1&(c[k>>2]|0)!=2):0){d=c[h>>2]|0;bf(d|0,0,Ac(c[k>>2]|0)|0)|0;c[n>>2]=Ub(o)|0;if(c[n>>2]|0){c[g>>2]=-3;p=c[g>>2]|0;i=e;return p|0}c[o>>2]=Yd(c[o>>2]|0)|0;d=Yd(84)|0;c[(c[h>>2]|0)+4>>2]=d;c[c[h>>2]>>2]=(c[(c[h>>2]|0)+4>>2]|0)+(c[o>>2]|0);c[l>>2]=(c[h>>2]|0)+(c[(c[h>>2]|0)+4>>2]|0);c[m>>2]=(c[h>>2]|0)+(c[c[h>>2]>>2]|0);o=c[k>>2]|0;c[(c[h>>2]|0)+8>>2]=o;c[(c[h>>2]|0)+44>>2]=o;c[(c[h>>2]|0)+12>>2]=c[j>>2];c[(c[h>>2]|0)+16+8>>2]=c[(c[h>>2]|0)+12>>2];c[(c[h>>2]|0)+16>>2]=c[(c[h>>2]|0)+8>>2];c[n>>2]=Vb(c[l>>2]|0)|0;if(c[n>>2]|0){c[g>>2]=-3;p=c[g>>2]|0;i=e;return p|0}c[n>>2]=_a(c[m>>2]|0,c[j>>2]|0,c[k>>2]|0)|0;if(c[n>>2]|0){c[g>>2]=-3;p=c[g>>2]|0;i=e;return p|0}else{n=c[m>>2]|0;c[f>>2]=0;ab(n,10016,f)|0;c[(c[h>>2]|0)+56>>2]=0;c[(c[h>>2]|0)+60>>2]=(c[j>>2]|0)/400|0;c[g>>2]=0;p=c[g>>2]|0;i=e;return p|0}}c[g>>2]=-1;p=c[g>>2]|0;i=e;return p|0}function Cc(a,d,e,f,h,j,k,l,m){a=a|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0;n=i;i=i+208|0;o=n+44|0;p=n+4|0;q=n;r=n+76|0;s=n+36|0;t=n+16|0;u=n+20|0;v=n+24|0;w=n+64|0;x=n+72|0;y=n+80|0;z=n+84|0;A=n+88|0;B=n+48|0;C=n+192|0;D=n+8|0;E=n+56|0;F=n+28|0;G=n+60|0;H=n+96|0;I=n+32|0;J=n+68|0;K=n+40|0;L=n+12|0;M=n+52|0;c[p>>2]=a;c[q>>2]=d;c[r>>2]=e;c[s>>2]=f;c[t>>2]=h;c[u>>2]=j;c[v>>2]=k;c[w>>2]=l;c[x>>2]=m;if((c[u>>2]|0)<0|(c[u>>2]|0)>1){c[o>>2]=-1;N=c[o>>2]|0;i=n;return N|0}if((c[u>>2]|0)!=0|(c[r>>2]|0)==0|(c[q>>2]|0)==0?((c[t>>2]|0)%((c[(c[p>>2]|0)+12>>2]|0)/400|0|0)|0|0)!=0:0){c[o>>2]=-1;N=c[o>>2]|0;i=n;return N|0}if((c[r>>2]|0)==0|(c[q>>2]|0)==0){c[I>>2]=0;while(1){m=(c[s>>2]|0)+((_(c[I>>2]|0,c[(c[p>>2]|0)+8>>2]|0)|0)<<2)|0;c[J>>2]=Zd(c[p>>2]|0,0,0,m,(c[t>>2]|0)-(c[I>>2]|0)|0,0)|0;O=c[J>>2]|0;if((c[J>>2]|0)<0){P=9;break}c[I>>2]=(c[I>>2]|0)+O;if((c[I>>2]|0)>=(c[t>>2]|0)){P=11;break}}if((P|0)==9){c[o>>2]=O;N=c[o>>2]|0;i=n;return N|0}else if((P|0)==11){_d()|0;c[(c[p>>2]|0)+68>>2]=c[I>>2];c[o>>2]=c[I>>2];N=c[o>>2]|0;i=n;return N|0}}if((c[r>>2]|0)<0){c[o>>2]=-1;N=c[o>>2]|0;i=n;return N|0}c[F>>2]=$d(c[q>>2]|0)|0;c[E>>2]=Dc(c[q>>2]|0)|0;c[D>>2]=yc(c[q>>2]|0,c[(c[p>>2]|0)+12>>2]|0)|0;c[G>>2]=Ec(c[q>>2]|0)|0;c[A>>2]=zc(c[q>>2]|0,c[r>>2]|0,c[v>>2]|0,C,0,H,B,c[w>>2]|0)|0;if((c[A>>2]|0)<0){c[o>>2]=c[A>>2];N=c[o>>2]|0;i=n;return N|0}c[q>>2]=(c[q>>2]|0)+(c[B>>2]|0);if(c[u>>2]|0){if(!((c[F>>2]|0)==1002?1:(c[t>>2]|0)<(c[D>>2]|0))?(c[(c[p>>2]|0)+52>>2]|0)!=1002:0){c[K>>2]=c[(c[p>>2]|0)+68>>2];if(((c[t>>2]|0)-(c[D>>2]|0)|0)!=0?(c[L>>2]=Cc(c[p>>2]|0,0,0,c[s>>2]|0,(c[t>>2]|0)-(c[D>>2]|0)|0,0,0,0,c[x>>2]|0)|0,(c[L>>2]|0)<0):0){c[(c[p>>2]|0)+68>>2]=c[K>>2];c[o>>2]=c[L>>2];N=c[o>>2]|0;i=n;return N|0}c[(c[p>>2]|0)+52>>2]=c[F>>2];c[(c[p>>2]|0)+48>>2]=c[E>>2];c[(c[p>>2]|0)+60>>2]=c[D>>2];c[(c[p>>2]|0)+44>>2]=c[G>>2];K=(c[s>>2]|0)+((_(c[(c[p>>2]|0)+8>>2]|0,(c[t>>2]|0)-(c[D>>2]|0)|0)|0)<<2)|0;c[L>>2]=Zd(c[p>>2]|0,c[q>>2]|0,b[H>>1]|0,K,c[D>>2]|0,1)|0;if((c[L>>2]|0)<0){c[o>>2]=c[L>>2];N=c[o>>2]|0;i=n;return N|0}else{_d()|0;c[(c[p>>2]|0)+68>>2]=c[t>>2];c[o>>2]=c[t>>2];N=c[o>>2]|0;i=n;return N|0}}c[o>>2]=Cc(c[p>>2]|0,0,0,c[s>>2]|0,c[t>>2]|0,0,0,0,c[x>>2]|0)|0;N=c[o>>2]|0;i=n;return N|0}L=_(c[A>>2]|0,c[D>>2]|0)|0;if((L|0)>(c[t>>2]|0)){c[o>>2]=-2;N=c[o>>2]|0;i=n;return N|0}c[(c[p>>2]|0)+52>>2]=c[F>>2];c[(c[p>>2]|0)+48>>2]=c[E>>2];c[(c[p>>2]|0)+60>>2]=c[D>>2];c[(c[p>>2]|0)+44>>2]=c[G>>2];c[z>>2]=0;c[y>>2]=0;while(1){if((c[y>>2]|0)>=(c[A>>2]|0))break;G=(c[s>>2]|0)+((_(c[z>>2]|0,c[(c[p>>2]|0)+8>>2]|0)|0)<<2)|0;c[M>>2]=Zd(c[p>>2]|0,c[q>>2]|0,b[H+(c[y>>2]<<1)>>1]|0,G,(c[t>>2]|0)-(c[z>>2]|0)|0,0)|0;if((c[M>>2]|0)<0){P=31;break}c[q>>2]=(c[q>>2]|0)+(b[H+(c[y>>2]<<1)>>1]|0);c[z>>2]=(c[z>>2]|0)+(c[M>>2]|0);c[y>>2]=(c[y>>2]|0)+1}if((P|0)==31){c[o>>2]=c[M>>2];N=c[o>>2]|0;i=n;return N|0}c[(c[p>>2]|0)+68>>2]=c[z>>2];_d()|0;if(c[x>>2]|0)xc(c[s>>2]|0,c[z>>2]|0,c[(c[p>>2]|0)+8>>2]|0,(c[p>>2]|0)+72|0);else{g[(c[p>>2]|0)+72+4>>2]=0.0;g[(c[p>>2]|0)+72>>2]=0.0}c[o>>2]=c[z>>2];N=c[o>>2]|0;i=n;return N|0}function Dc(a){a=a|0;var b=0,e=0,f=0,g=0,h=0;b=i;i=i+16|0;e=b+4|0;f=b;c[e>>2]=a;a=d[c[e>>2]>>0]|0;if((d[c[e>>2]>>0]|0)&128){g=1102+(a>>5&3)|0;c[f>>2]=g;c[f>>2]=(c[f>>2]|0)==1102?1101:g;h=c[f>>2]|0;i=b;return h|0}g=d[c[e>>2]>>0]|0;if((a&96|0)==96){c[f>>2]=(g&16|0)!=0?1105:1104;h=c[f>>2]|0;i=b;return h|0}else{c[f>>2]=1101+(g>>5&3);h=c[f>>2]|0;i=b;return h|0}return 0}function Ec(a){a=a|0;var b=0,e=0;b=i;i=i+16|0;e=b;c[e>>2]=a;i=b;return (((d[c[e>>2]>>0]|0)&4|0)!=0?2:1)|0}function Fc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;e=i;i=i+80|0;f=e+8|0;g=e;h=e+12|0;j=e+16|0;k=e+20|0;l=e+44|0;m=e+24|0;n=e+40|0;o=e+48|0;p=e+52|0;q=e+56|0;r=e+60|0;s=e+64|0;t=e+68|0;u=e+72|0;v=e+76|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=0;c[n>>2]=(c[j>>2]|0)+(c[(c[j>>2]|0)+4>>2]|0);c[o>>2]=(c[j>>2]|0)+(c[c[j>>2]>>2]|0);c[m>>2]=d;a:do switch(c[k>>2]|0){case 4029:{d=(c[m>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[m>>2]=d+4;c[r>>2]=b;if(c[r>>2]|0){c[c[r>>2]>>2]=c[(c[j>>2]|0)+12>>2];w=20}else w=21;break}case 4033:{b=(c[m>>2]|0)+(4-1)&~(4-1);d=c[b>>2]|0;c[m>>2]=b+4;c[s>>2]=d;if(c[s>>2]|0)if((c[(c[j>>2]|0)+56>>2]|0)==1002){d=c[o>>2]|0;c[f>>2]=(c[s>>2]|0)+((((c[s>>2]|0)-(c[s>>2]|0)|0)/4|0)<<2);ab(d,4033,f)|0;w=20;break a}else{c[c[s>>2]>>2]=c[(c[j>>2]|0)+16+20>>2];w=20;break a}else w=21;break}case 4045:{d=(c[m>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[m>>2]=d+4;c[t>>2]=b;if(c[t>>2]|0){c[c[t>>2]>>2]=c[(c[j>>2]|0)+40>>2];w=20}else w=21;break}case 4034:{b=(c[m>>2]|0)+(4-1)&~(4-1);d=c[b>>2]|0;c[m>>2]=b+4;c[u>>2]=d;if((c[u>>2]|0)<-32768|(c[u>>2]|0)>32767)w=21;else{c[(c[j>>2]|0)+40>>2]=c[u>>2];w=20}break}case 4039:{d=(c[m>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[m>>2]=d+4;c[v>>2]=b;if(c[v>>2]|0){c[c[v>>2]>>2]=c[(c[j>>2]|0)+68>>2];w=20}else w=21;break}case 4009:{b=(c[m>>2]|0)+(4-1)&~(4-1);d=c[b>>2]|0;c[m>>2]=b+4;c[p>>2]=d;if(c[p>>2]|0){c[c[p>>2]>>2]=c[(c[j>>2]|0)+48>>2];w=20}else w=21;break}case 4031:{d=(c[m>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[m>>2]=d+4;c[q>>2]=b;if(c[q>>2]|0){c[c[q>>2]>>2]=c[(c[j>>2]|0)+80>>2];w=20}else w=21;break}case 4028:{bf((c[j>>2]|0)+44|0,0,84-((c[j>>2]|0)+44-(c[j>>2]|0))|0)|0;ab(c[o>>2]|0,4028,g)|0;Vb(c[n>>2]|0)|0;c[(c[j>>2]|0)+44>>2]=c[(c[j>>2]|0)+8>>2];c[(c[j>>2]|0)+60>>2]=(c[(c[j>>2]|0)+12>>2]|0)/400|0;w=20;break}default:{c[l>>2]=-5;w=20}}while(0);if((w|0)==20){c[h>>2]=c[l>>2];x=c[h>>2]|0;i=e;return x|0}else if((w|0)==21){c[h>>2]=-1;x=c[h>>2]|0;i=e;return x|0}return 0}function Gc(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;j=e;c[g>>2]=a;c[h>>2]=b;do if((c[h>>2]|0)>=1){c[j>>2]=(d[c[g>>2]>>0]|0)&3;if(!(c[j>>2]|0)){c[f>>2]=1;break}if((c[j>>2]|0)!=3){c[f>>2]=2;break}if((c[h>>2]|0)<2){c[f>>2]=-4;break}else{c[f>>2]=(d[(c[g>>2]|0)+1>>0]|0)&63;break}}else c[f>>2]=-1;while(0);i=e;return c[f>>2]|0}function Hc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[l>>2]=Gc(c[g>>2]|0,c[h>>2]|0)|0;h=c[l>>2]|0;if((c[l>>2]|0)<0){c[f>>2]=h;m=c[f>>2]|0;i=e;return m|0}c[k>>2]=_(h,yc(c[g>>2]|0,c[j>>2]|0)|0)|0;if(((c[k>>2]|0)*25|0)>((c[j>>2]|0)*3|0)){c[f>>2]=-4;m=c[f>>2]|0;i=e;return m|0}else{c[f>>2]=c[k>>2];m=c[f>>2]|0;i=e;return m|0}return 0}function Ic(a){a=a|0;var b=0,e=0,f=0,g=0,h=0,j=0,k=0;b=i;i=i+16|0;e=b+12|0;f=b+8|0;g=b+4|0;h=b;c[f>>2]=a;c[h>>2]=(c[(c[f>>2]|0)+4>>2]|0)+(c[(c[f>>2]|0)+8>>2]|0);if((c[h>>2]|0)>255){c[e>>2]=0;j=c[e>>2]|0;i=b;return j|0}c[g>>2]=0;while(1){if((c[g>>2]|0)>=(c[c[f>>2]>>2]|0)){k=9;break}if((d[(c[f>>2]|0)+12+(c[g>>2]|0)>>0]|0|0)>=(c[h>>2]|0)?(d[(c[f>>2]|0)+12+(c[g>>2]|0)>>0]|0|0)!=255:0){k=7;break}c[g>>2]=(c[g>>2]|0)+1}if((k|0)==7){c[e>>2]=0;j=c[e>>2]|0;i=b;return j|0}else if((k|0)==9){c[e>>2]=1;j=c[e>>2]|0;i=b;return j|0}return 0}function Jc(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=e;c[l>>2]=(c[k>>2]|0)<0?0:(c[k>>2]|0)+1|0;while(1){if((c[l>>2]|0)>=(c[c[h>>2]>>2]|0)){m=6;break}n=c[l>>2]|0;if((d[(c[h>>2]|0)+12+(c[l>>2]|0)>>0]|0|0)==(c[j>>2]<<1|0)){m=4;break}c[l>>2]=n+1}if((m|0)==4){c[g>>2]=n;o=c[g>>2]|0;i=f;return o|0}else if((m|0)==6){c[g>>2]=-1;o=c[g>>2]|0;i=f;return o|0}return 0}function Kc(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=e;c[l>>2]=(c[k>>2]|0)<0?0:(c[k>>2]|0)+1|0;while(1){if((c[l>>2]|0)>=(c[c[h>>2]>>2]|0)){m=6;break}n=c[l>>2]|0;if((d[(c[h>>2]|0)+12+(c[l>>2]|0)>>0]|0|0)==((c[j>>2]<<1)+1|0)){m=4;break}c[l>>2]=n+1}if((m|0)==4){c[g>>2]=n;o=c[g>>2]|0;i=f;return o|0}else if((m|0)==6){c[g>>2]=-1;o=c[g>>2]|0;i=f;return o|0}return 0}function Lc(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=e;c[l>>2]=(c[k>>2]|0)<0?0:(c[k>>2]|0)+1|0;while(1){if((c[l>>2]|0)>=(c[c[h>>2]>>2]|0)){m=6;break}n=c[l>>2]|0;if((d[(c[h>>2]|0)+12+(c[l>>2]|0)>>0]|0|0)==((c[j>>2]|0)+(c[(c[h>>2]|0)+8>>2]|0)|0)){m=4;break}c[l>>2]=n+1}if((m|0)==4){c[g>>2]=n;o=c[g>>2]|0;i=f;return o|0}else if((m|0)==6){c[g>>2]=-1;o=c[g>>2]|0;i=f;return o|0}return 0}function Mc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;d=i;i=i+32|0;e=d+16|0;f=d+12|0;g=d+8|0;h=d+4|0;j=d;c[f>>2]=a;c[g>>2]=b;if((c[f>>2]|0)>=1?!((c[g>>2]|0)<0?1:(c[g>>2]|0)>(c[f>>2]|0)):0){c[h>>2]=Ac(2)|0;c[j>>2]=Ac(1)|0;b=ae(268)|0;a=c[g>>2]|0;k=b+(_(a,ae(c[h>>2]|0)|0)|0)|0;h=(c[f>>2]|0)-(c[g>>2]|0)|0;c[e>>2]=k+(_(h,ae(c[j>>2]|0)|0)|0);l=c[e>>2]|0;i=d;return l|0}c[e>>2]=0;l=c[e>>2]|0;i=d;return l|0}function Nc(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;j=i;i=i+48|0;k=j+4|0;l=j+16|0;m=j+36|0;n=j;o=j+32|0;p=j+40|0;q=j+44|0;r=j+24|0;s=j+20|0;t=j+8|0;u=j+12|0;v=j+28|0;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=g;c[q>>2]=h;if((!((c[n>>2]|0)>255|(c[n>>2]|0)<1)?(c[p>>2]|0)<=(c[o>>2]|0):0)?!(((c[o>>2]|0)<1?1:((c[p>>2]|0)+(c[o>>2]|0)|0)>255)|(c[p>>2]|0)<0):0){c[c[l>>2]>>2]=c[n>>2];c[(c[l>>2]|0)+4>>2]=c[o>>2];c[(c[l>>2]|0)+8>>2]=c[p>>2];c[t>>2]=0;while(1){if((c[t>>2]|0)>=(c[c[l>>2]>>2]|0))break;a[(c[l>>2]|0)+12+(c[t>>2]|0)>>0]=a[(c[q>>2]|0)+(c[t>>2]|0)>>0]|0;c[t>>2]=(c[t>>2]|0)+1}if(!(Ic(c[l>>2]|0)|0)){c[k>>2]=-1;w=c[k>>2]|0;i=j;return w|0}q=c[l>>2]|0;c[v>>2]=q+(ae(268)|0);c[r>>2]=Ac(2)|0;c[s>>2]=Ac(1)|0;c[t>>2]=0;while(1){if((c[t>>2]|0)>=(c[(c[l>>2]|0)+8>>2]|0))break;c[u>>2]=Bc(c[v>>2]|0,c[m>>2]|0,2)|0;if(c[u>>2]|0){x=13;break}q=ae(c[r>>2]|0)|0;c[v>>2]=(c[v>>2]|0)+q;c[t>>2]=(c[t>>2]|0)+1}if((x|0)==13){c[k>>2]=c[u>>2];w=c[k>>2]|0;i=j;return w|0}while(1){if((c[t>>2]|0)>=(c[(c[l>>2]|0)+4>>2]|0)){x=19;break}c[u>>2]=Bc(c[v>>2]|0,c[m>>2]|0,1)|0;if(c[u>>2]|0){x=17;break}r=ae(c[s>>2]|0)|0;c[v>>2]=(c[v>>2]|0)+r;c[t>>2]=(c[t>>2]|0)+1}if((x|0)==17){c[k>>2]=c[u>>2];w=c[k>>2]|0;i=j;return w|0}else if((x|0)==19){c[k>>2]=0;w=c[k>>2]|0;i=j;return w|0}}c[k>>2]=-1;w=c[k>>2]|0;i=j;return w|0}function Oc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;h=i;i=i+48|0;j=h+28|0;k=h+16|0;l=h+4|0;m=h+8|0;n=h+32|0;o=h;p=h+12|0;q=h+24|0;r=h+20|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=g;if((!((c[l>>2]|0)>255|(c[l>>2]|0)<1)?(c[n>>2]|0)<=(c[m>>2]|0):0)?!(((c[m>>2]|0)<1?1:((c[n>>2]|0)+(c[m>>2]|0)|0)>255)|(c[n>>2]|0)<0):0){c[r>>2]=be(Mc(c[m>>2]|0,c[n>>2]|0)|0)|0;if(!(c[r>>2]|0)){if(c[p>>2]|0)c[c[p>>2]>>2]=-7;c[j>>2]=0;s=c[j>>2]|0;i=h;return s|0}c[q>>2]=Nc(c[r>>2]|0,c[k>>2]|0,c[l>>2]|0,c[m>>2]|0,c[n>>2]|0,c[o>>2]|0)|0;if(c[p>>2]|0)c[c[p>>2]>>2]=c[q>>2];if(c[q>>2]|0){ce(c[r>>2]|0);c[r>>2]=0}c[j>>2]=c[r>>2];s=c[j>>2]|0;i=h;return s|0}if(c[p>>2]|0)c[c[p>>2]>>2]=-1;c[j>>2]=0;s=c[j>>2]|0;i=h;return s|0}function Pc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0;h=i;i=i+32|0;j=h+20|0;k=h+16|0;l=h+12|0;m=h+8|0;n=h+4|0;o=h;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;g=de(c[j>>2]|0,c[k>>2]|0,c[l>>2]|0,c[m>>2]|0,1,c[n>>2]|0,c[o>>2]|0,0)|0;i=h;return g|0}function Qc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;e=i;i=i+128|0;f=e+8|0;g=e;h=e+24|0;j=e+16|0;k=e+44|0;l=e+36|0;m=e+32|0;n=e+80|0;o=e+52|0;p=e+40|0;q=e+48|0;r=e+28|0;s=e+56|0;t=e+60|0;u=e+64|0;v=e+72|0;w=e+68|0;x=e+76|0;y=e+96|0;z=e+100|0;A=e+104|0;B=e+108|0;C=e+112|0;D=e+116|0;E=e+120|0;F=e+124|0;c[l>>2]=a;c[m>>2]=b;c[r>>2]=0;c[n>>2]=d;c[o>>2]=Ac(2)|0;c[p>>2]=Ac(1)|0;d=c[l>>2]|0;c[q>>2]=d+(ae(268)|0);a:do switch(c[m>>2]|0){case 4031:{d=(c[n>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[n>>2]=d+4;c[v>>2]=b;if(c[v>>2]|0){c[c[v>>2]>>2]=0;c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[(c[l>>2]|0)+4>>2]|0)){G=37;break a}c[x>>2]=c[q>>2];if((c[u>>2]|0)<(c[(c[l>>2]|0)+8>>2]|0)){b=ae(c[o>>2]|0)|0;c[q>>2]=(c[q>>2]|0)+b}else{b=ae(c[p>>2]|0)|0;c[q>>2]=(c[q>>2]|0)+b}b=c[x>>2]|0;d=c[m>>2]|0;c[h>>2]=w;c[r>>2]=Fc(b,d,h)|0;if(c[r>>2]|0){G=37;break a}d=c[v>>2]|0;c[d>>2]=c[d>>2]^c[w>>2];c[u>>2]=(c[u>>2]|0)+1}}else G=38;break}case 4028:{c[y>>2]=0;while(1){if((c[y>>2]|0)>=(c[(c[l>>2]|0)+4>>2]|0)){G=37;break a}c[z>>2]=c[q>>2];if((c[y>>2]|0)<(c[(c[l>>2]|0)+8>>2]|0)){d=ae(c[o>>2]|0)|0;c[q>>2]=(c[q>>2]|0)+d}else{d=ae(c[p>>2]|0)|0;c[q>>2]=(c[q>>2]|0)+d}c[r>>2]=Fc(c[z>>2]|0,4028,g)|0;if(c[r>>2]|0){G=37;break a}c[y>>2]=(c[y>>2]|0)+1}break}case 5122:{d=(c[n>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[n>>2]=d+4;c[B>>2]=b;if(!((c[B>>2]|0)>=0?(c[B>>2]|0)<(c[(c[l>>2]|0)+4>>2]|0):0))c[r>>2]=-1;b=(c[n>>2]|0)+(4-1)&~(4-1);d=c[b>>2]|0;c[n>>2]=b+4;c[C>>2]=d;if(c[C>>2]|0){c[A>>2]=0;while(1){if((c[A>>2]|0)>=(c[B>>2]|0))break;if((c[A>>2]|0)<(c[(c[l>>2]|0)+8>>2]|0)){d=ae(c[o>>2]|0)|0;c[q>>2]=(c[q>>2]|0)+d}else{d=ae(c[p>>2]|0)|0;c[q>>2]=(c[q>>2]|0)+d}c[A>>2]=(c[A>>2]|0)+1}c[c[C>>2]>>2]=c[q>>2];G=37}else G=38;break}case 4034:{d=(c[n>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[n>>2]=d+4;c[E>>2]=b;c[D>>2]=0;while(1){if((c[D>>2]|0)>=(c[(c[l>>2]|0)+4>>2]|0)){G=37;break a}c[F>>2]=c[q>>2];if((c[D>>2]|0)<(c[(c[l>>2]|0)+8>>2]|0)){b=ae(c[o>>2]|0)|0;c[q>>2]=(c[q>>2]|0)+b}else{b=ae(c[p>>2]|0)|0;c[q>>2]=(c[q>>2]|0)+b}b=c[F>>2]|0;d=c[m>>2]|0;c[f>>2]=c[E>>2];c[r>>2]=Fc(b,d,f)|0;if(c[r>>2]|0){G=37;break a}c[D>>2]=(c[D>>2]|0)+1}break}case 4039:case 4045:case 4029:case 4009:{d=(c[n>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[n>>2]=d+4;c[t>>2]=b;c[s>>2]=c[q>>2];b=c[s>>2]|0;d=c[m>>2]|0;c[j>>2]=c[t>>2];c[r>>2]=Fc(b,d,j)|0;G=37;break}default:{c[r>>2]=-5;G=37}}while(0);if((G|0)==37){c[k>>2]=c[r>>2];H=c[k>>2]|0;i=e;return H|0}else if((G|0)==38){c[k>>2]=-1;H=c[k>>2]|0;i=e;return H|0}return 0}function Rc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>>>0)/((c[f>>2]|0)>>>0)|0|0}function Sc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return (c[e>>2]|0)/(c[f>>2]|0)|0|0}function Tc(a,b,e,f,h,j,k,l,m,n,o){a=a|0;b=b|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=+m;n=n|0;o=o|0;var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0;p=i;i=i+112|0;q=p+48|0;r=p+44|0;s=p+84|0;t=p+92|0;u=p+40|0;v=p+16|0;w=p+20|0;x=p+24|0;y=p+28|0;z=p+72|0;A=p+80|0;B=p+88|0;C=p+96|0;D=p+100|0;E=p+52|0;F=p+56|0;G=p+60|0;H=p+64|0;I=p+8|0;J=p+12|0;K=p+68|0;L=p+32|0;M=p+36|0;N=p+76|0;P=p;Q=p+4|0;c[r>>2]=a;c[s>>2]=b;c[t>>2]=e;c[u>>2]=f;c[v>>2]=h;c[w>>2]=j;c[x>>2]=k;c[y>>2]=l;g[z>>2]=m;c[A>>2]=n;c[B>>2]=o;c[C>>2]=c[t>>2];c[D>>2]=c[t>>2];c[F>>2]=c[v>>2];c[G>>2]=0;c[H>>2]=0;c[J>>2]=0;c[K>>2]=((c[c[r>>2]>>2]|0)!=0^1)&1;c[M>>2]=c[c[r>>2]>>2];c[N>>2]=c[(c[r>>2]|0)+20>>2];c[I>>2]=(c[F>>2]|0)==1&1;c[D>>2]=Rc(c[D>>2]|0,c[v>>2]|0)|0;if((c[t>>2]|0)==1){c[q>>2]=Ce(c[r>>2]|0,c[s>>2]|0,0,c[u>>2]|0,c[y>>2]|0)|0;R=c[q>>2]|0;i=p;return R|0}if((c[N>>2]|0)>0)c[H>>2]=c[N>>2];do if((c[A>>2]|0)!=0&(c[w>>2]|0)!=0){if((c[H>>2]|0)==0?!((c[D>>2]&1|0)==0&(c[N>>2]|0)<0|(c[F>>2]|0)>1):0)break;df(c[A>>2]|0,c[w>>2]|0,(c[t>>2]<<2)+0|0)|0;c[w>>2]=c[A>>2]}while(0);c[L>>2]=0;while(1){if((c[L>>2]|0)>=(c[H>>2]|0))break;if(c[M>>2]|0)Ua(c[s>>2]|0,c[t>>2]>>c[L>>2],1<<c[L>>2]);if(c[w>>2]|0)Ua(c[w>>2]|0,c[t>>2]>>c[L>>2],1<<c[L>>2]);c[B>>2]=d[25096+(c[B>>2]&15)>>0]|0|(d[25096+(c[B>>2]>>4)>>0]|0)<<2;c[L>>2]=(c[L>>2]|0)+1}c[v>>2]=c[v>>2]>>c[H>>2];c[D>>2]=c[D>>2]<<c[H>>2];while(1){if(!((c[D>>2]&1|0)==0?(c[N>>2]|0)<0:0))break;if(c[M>>2]|0)Ua(c[s>>2]|0,c[D>>2]|0,c[v>>2]|0);if(c[w>>2]|0)Ua(c[w>>2]|0,c[D>>2]|0,c[v>>2]|0);c[B>>2]=c[B>>2]|c[B>>2]<<c[v>>2];c[v>>2]=c[v>>2]<<1;c[D>>2]=c[D>>2]>>1;c[G>>2]=(c[G>>2]|0)+1;c[N>>2]=(c[N>>2]|0)+1}c[F>>2]=c[v>>2];c[E>>2]=c[D>>2];if((c[F>>2]|0)>1){if(c[M>>2]|0)Le(c[s>>2]|0,c[D>>2]>>c[H>>2],c[F>>2]<<c[H>>2],c[I>>2]|0);if(c[w>>2]|0)Le(c[w>>2]|0,c[D>>2]>>c[H>>2],c[F>>2]<<c[H>>2],c[I>>2]|0)}c[J>>2]=Me(c[r>>2]|0,c[s>>2]|0,c[t>>2]|0,c[u>>2]|0,c[v>>2]|0,c[w>>2]|0,c[x>>2]|0,+g[z>>2],c[B>>2]|0)|0;if(c[K>>2]|0){if((c[F>>2]|0)>1)Ne(c[s>>2]|0,c[D>>2]>>c[H>>2],c[F>>2]<<c[H>>2],c[I>>2]|0);c[D>>2]=c[E>>2];c[v>>2]=c[F>>2];c[L>>2]=0;while(1){if((c[L>>2]|0)>=(c[G>>2]|0))break;c[v>>2]=c[v>>2]>>1;c[D>>2]=c[D>>2]<<1;c[J>>2]=c[J>>2]|(c[J>>2]|0)>>>(c[v>>2]|0);Ua(c[s>>2]|0,c[D>>2]|0,c[v>>2]|0);c[L>>2]=(c[L>>2]|0)+1}c[L>>2]=0;while(1){if((c[L>>2]|0)>=(c[H>>2]|0))break;c[J>>2]=d[25112+(c[J>>2]|0)>>0];Ua(c[s>>2]|0,c[C>>2]>>c[L>>2],1<<c[L>>2]);c[L>>2]=(c[L>>2]|0)+1}c[v>>2]=c[v>>2]<<c[H>>2];a:do if(c[y>>2]|0){g[Q>>2]=+O(+(+(c[C>>2]|0)));c[P>>2]=0;while(1){if((c[P>>2]|0)>=(c[C>>2]|0))break a;g[(c[y>>2]|0)+(c[P>>2]<<2)>>2]=+g[Q>>2]*+g[(c[s>>2]|0)+(c[P>>2]<<2)>>2];c[P>>2]=(c[P>>2]|0)+1}}while(0);c[J>>2]=c[J>>2]&(1<<c[v>>2])-1}c[q>>2]=c[J>>2];R=c[q>>2]|0;i=p;return R|0}function Uc(a,b,d,e,f,h,j,k,l,m,n){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0;o=i;i=i+176|0;p=o+156|0;q=o+132|0;r=o+8|0;s=o+56|0;t=o+64|0;u=o+16|0;v=o+20|0;w=o+24|0;x=o+28|0;y=o+32|0;z=o+36|0;A=o+40|0;B=o+44|0;C=o+128|0;D=o+136|0;E=o+144|0;F=o+152|0;G=o+160|0;H=o+68|0;I=o+72|0;J=o+76|0;K=o+80|0;L=o+84|0;M=o+88|0;N=o+96|0;O=o+12|0;P=o+4|0;Q=o;R=o+120|0;S=o+48|0;T=o+124|0;U=o+52|0;V=o+140|0;W=o+60|0;X=o+148|0;c[q>>2]=a;c[r>>2]=b;c[s>>2]=d;c[t>>2]=e;c[u>>2]=f;c[v>>2]=h;c[w>>2]=j;c[x>>2]=k;c[y>>2]=l;c[z>>2]=m;c[A>>2]=n;c[B>>2]=0;c[C>>2]=0;c[D>>2]=0;g[E>>2]=0.0;g[F>>2]=0.0;c[G>>2]=0;c[H>>2]=((c[c[q>>2]>>2]|0)!=0^1)&1;c[P>>2]=c[c[q>>2]>>2];c[Q>>2]=c[(c[q>>2]|0)+24>>2];if((c[t>>2]|0)==1){c[p>>2]=Ce(c[q>>2]|0,c[r>>2]|0,c[s>>2]|0,c[u>>2]|0,c[y>>2]|0)|0;Y=c[p>>2]|0;i=o;return Y|0}c[O>>2]=c[A>>2];De(c[q>>2]|0,N,c[r>>2]|0,c[s>>2]|0,c[t>>2]|0,u,c[v>>2]|0,c[v>>2]|0,c[x>>2]|0,1,A);c[D>>2]=c[N>>2];c[B>>2]=c[N+4>>2];c[C>>2]=c[N+8>>2];c[K>>2]=c[N+12>>2];c[L>>2]=c[N+16>>2];c[M>>2]=c[N+20>>2];g[E>>2]=+(c[B>>2]|0)*.000030517578125;g[F>>2]=+(c[C>>2]|0)*.000030517578125;do if((c[t>>2]|0)==2){c[S>>2]=0;c[I>>2]=c[u>>2];c[J>>2]=0;c[J>>2]=(c[L>>2]|0)!=0&(c[L>>2]|0)!=16384?8:0;c[I>>2]=(c[I>>2]|0)-(c[J>>2]|0);c[R>>2]=(c[L>>2]|0)>8192&1;C=(c[q>>2]|0)+28|0;c[C>>2]=(c[C>>2]|0)-((c[M>>2]|0)+(c[J>>2]|0));c[T>>2]=(c[R>>2]|0)!=0?c[s>>2]|0:c[r>>2]|0;c[U>>2]=(c[R>>2]|0)!=0?c[r>>2]|0:c[s>>2]|0;do if(c[J>>2]|0)if(c[P>>2]|0){c[S>>2]=+g[c[T>>2]>>2]*+g[(c[U>>2]|0)+4>>2]-+g[(c[T>>2]|0)+4>>2]*+g[c[U>>2]>>2]<0.0&1;pb(c[Q>>2]|0,c[S>>2]|0,1);break}else{c[S>>2]=lb(c[Q>>2]|0,1)|0;break}while(0);c[S>>2]=1-(c[S>>2]<<1);c[G>>2]=Tc(c[q>>2]|0,c[T>>2]|0,c[t>>2]|0,c[I>>2]|0,c[v>>2]|0,c[w>>2]|0,c[x>>2]|0,c[y>>2]|0,1.0,c[z>>2]|0,c[O>>2]|0)|0;g[c[U>>2]>>2]=+(0-(c[S>>2]|0)|0)*+g[(c[T>>2]|0)+4>>2];g[(c[U>>2]|0)+4>>2]=+(c[S>>2]|0)*+g[c[T>>2]>>2];if(c[H>>2]|0){g[c[r>>2]>>2]=+g[E>>2]*+g[c[r>>2]>>2];g[(c[r>>2]|0)+4>>2]=+g[E>>2]*+g[(c[r>>2]|0)+4>>2];g[c[s>>2]>>2]=+g[F>>2]*+g[c[s>>2]>>2];g[(c[s>>2]|0)+4>>2]=+g[F>>2]*+g[(c[s>>2]|0)+4>>2];g[V>>2]=+g[c[r>>2]>>2];g[c[r>>2]>>2]=+g[V>>2]-+g[c[s>>2]>>2];g[c[s>>2]>>2]=+g[V>>2]+ +g[c[s>>2]>>2];g[V>>2]=+g[(c[r>>2]|0)+4>>2];g[(c[r>>2]|0)+4>>2]=+g[V>>2]-+g[(c[s>>2]|0)+4>>2];g[(c[s>>2]|0)+4>>2]=+g[V>>2]+ +g[(c[s>>2]|0)+4>>2]}}else{C=c[u>>2]|0;if((c[u>>2]|0)<(((c[u>>2]|0)-(c[K>>2]|0)|0)/2|0|0))Z=C;else Z=(C-(c[K>>2]|0)|0)/2|0;if(0<=(Z|0)){C=c[u>>2]|0;if((c[u>>2]|0)<(((c[u>>2]|0)-(c[K>>2]|0)|0)/2|0|0))_=C;else _=(C-(c[K>>2]|0)|0)/2|0}else _=0;c[I>>2]=_;c[J>>2]=(c[u>>2]|0)-(c[I>>2]|0);C=(c[q>>2]|0)+28|0;c[C>>2]=(c[C>>2]|0)-(c[M>>2]|0);c[W>>2]=c[(c[q>>2]|0)+28>>2];C=c[q>>2]|0;if((c[I>>2]|0)>=(c[J>>2]|0)){c[G>>2]=Tc(C,c[r>>2]|0,c[t>>2]|0,c[I>>2]|0,c[v>>2]|0,c[w>>2]|0,c[x>>2]|0,c[y>>2]|0,1.0,c[z>>2]|0,c[A>>2]|0)|0;c[W>>2]=(c[I>>2]|0)-((c[W>>2]|0)-(c[(c[q>>2]|0)+28>>2]|0));if((c[W>>2]|0)>24&(c[L>>2]|0)!=0)c[J>>2]=(c[J>>2]|0)+((c[W>>2]|0)-24);B=Tc(c[q>>2]|0,c[s>>2]|0,c[t>>2]|0,c[J>>2]|0,c[v>>2]|0,0,c[x>>2]|0,0,+g[F>>2],0,c[A>>2]>>c[v>>2])|0;c[G>>2]=c[G>>2]|B;break}else{c[G>>2]=Tc(C,c[s>>2]|0,c[t>>2]|0,c[J>>2]|0,c[v>>2]|0,0,c[x>>2]|0,0,+g[F>>2],0,c[A>>2]>>c[v>>2])|0;c[W>>2]=(c[J>>2]|0)-((c[W>>2]|0)-(c[(c[q>>2]|0)+28>>2]|0));if((c[W>>2]|0)>24&(c[L>>2]|0)!=16384)c[I>>2]=(c[I>>2]|0)+((c[W>>2]|0)-24);C=Tc(c[q>>2]|0,c[r>>2]|0,c[t>>2]|0,c[I>>2]|0,c[v>>2]|0,c[w>>2]|0,c[x>>2]|0,c[y>>2]|0,1.0,c[z>>2]|0,c[A>>2]|0)|0;c[G>>2]=c[G>>2]|C;break}}while(0);a:do if(c[H>>2]|0){if((c[t>>2]|0)!=2)Ee(c[r>>2]|0,c[s>>2]|0,+g[E>>2],c[t>>2]|0);if(c[D>>2]|0){c[X>>2]=0;while(1){if((c[X>>2]|0)>=(c[t>>2]|0))break a;g[(c[s>>2]|0)+(c[X>>2]<<2)>>2]=-+g[(c[s>>2]|0)+(c[X>>2]<<2)>>2];c[X>>2]=(c[X>>2]|0)+1}}}while(0);c[p>>2]=c[G>>2];Y=c[p>>2]|0;i=o;return Y|0}function Vc(a,b,d,e,f,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=+f;h=+h;j=+j;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;k=i;i=i+64|0;l=k+44|0;m=k+36|0;n=k+20|0;o=k+16|0;p=k+32|0;q=k+40|0;r=k+48|0;s=k+8|0;t=k+4|0;u=k+24|0;v=k+12|0;w=k+28|0;x=k;c[l>>2]=a;c[m>>2]=b;c[n>>2]=d;c[o>>2]=e;g[p>>2]=f;g[q>>2]=h;g[r>>2]=j;g[w>>2]=+g[(c[m>>2]|0)+(0-(c[n>>2]|0)-2<<2)>>2];g[v>>2]=+g[(c[m>>2]|0)+(0-(c[n>>2]|0)-1<<2)>>2];g[u>>2]=+g[(c[m>>2]|0)+(0-(c[n>>2]|0)<<2)>>2];g[t>>2]=+g[(c[m>>2]|0)+(0-(c[n>>2]|0)+1<<2)>>2];c[x>>2]=0;while(1){if((c[x>>2]|0)>=(c[o>>2]|0))break;g[s>>2]=+g[(c[m>>2]|0)+((c[x>>2]|0)-(c[n>>2]|0)+2<<2)>>2];g[(c[l>>2]|0)+(c[x>>2]<<2)>>2]=+g[(c[m>>2]|0)+(c[x>>2]<<2)>>2]+ +g[p>>2]*+g[u>>2]+ +g[q>>2]*(+g[t>>2]+ +g[v>>2])+ +g[r>>2]*(+g[s>>2]+ +g[w>>2]);g[w>>2]=+g[v>>2];g[v>>2]=+g[u>>2];g[u>>2]=+g[t>>2];g[t>>2]=+g[s>>2];c[x>>2]=(c[x>>2]|0)+1}i=k;return}function Wc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[e>>2]=a;c[f>>2]=b;b=88+((_(c[f>>2]|0,2048+(c[(c[e>>2]|0)+4>>2]|0)|0)|0)-1<<2)|0;c[g>>2]=b+((c[f>>2]|0)*24<<2)+(c[(c[e>>2]|0)+8>>2]<<3<<2);i=d;return c[g>>2]|0}function Xc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;if((c[j>>2]|0)<0|(c[j>>2]|0)>2){c[f>>2]=-1;k=c[f>>2]|0;i=e;return k|0}if(!(c[g>>2]|0)){c[f>>2]=-7;k=c[f>>2]|0;i=e;return k|0}else{d=c[g>>2]|0;bf(d|0,0,Wc(c[h>>2]|0,c[j>>2]|0)|0)|0;c[c[g>>2]>>2]=c[h>>2];c[(c[g>>2]|0)+4>>2]=c[(c[h>>2]|0)+4>>2];h=c[j>>2]|0;c[(c[g>>2]|0)+8>>2]=h;c[(c[g>>2]|0)+12>>2]=h;c[(c[g>>2]|0)+16>>2]=1;c[(c[g>>2]|0)+20>>2]=0;c[(c[g>>2]|0)+24>>2]=c[(c[c[g>>2]>>2]|0)+12>>2];c[(c[g>>2]|0)+28>>2]=1;h=Be()|0;c[(c[g>>2]|0)+32>>2]=h;c[(c[g>>2]|0)+48>>2]=0;ab(c[g>>2]|0,4028,e)|0;c[f>>2]=0;k=c[f>>2]|0;i=e;return k|0}return 0}function Yc(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0;f=i;i=i+4624|0;h=f+212|0;j=f+204|0;k=f+4568|0;l=f+12|0;m=f+4584|0;n=f+4600|0;o=f+24|0;p=f+32|0;q=f+40|0;r=f+44|0;s=f+48|0;t=f+52|0;u=f+56|0;v=f+60|0;w=f+64|0;x=f+68|0;y=f+72|0;z=f+76|0;A=f+80|0;B=f+84|0;C=f+88|0;D=f+92|0;E=f+4572|0;F=f+4580|0;G=f+4588|0;H=f+4596|0;I=f+4604|0;J=f+4608|0;K=f+216|0;L=f+220|0;M=f+224|0;N=f+228|0;P=f+232|0;Q=f+240|0;R=f+4336|0;S=f+4340|0;T=f+4344|0;U=f+4348|0;V=f+4352|0;W=f+4356|0;X=f+4360|0;Y=f+4364|0;Z=f+4368|0;$=f+4472|0;aa=f+16|0;ba=f+4|0;ca=f+8|0;da=f;ea=f+96|0;fa=f+104|0;ga=f+4576|0;ha=f+200|0;ia=f+4592|0;ja=f+208|0;c[h>>2]=a;c[j>>2]=d;c[k>>2]=e;c[n>>2]=c[(c[h>>2]|0)+8>>2];c[v>>2]=c[c[h>>2]>>2];c[w>>2]=c[(c[v>>2]|0)+8>>2];c[x>>2]=c[(c[v>>2]|0)+4>>2];c[B>>2]=c[(c[v>>2]|0)+32>>2];c[l>>2]=0;do{e=(c[h>>2]|0)+84+((_(c[l>>2]|0,2048+(c[x>>2]|0)|0)|0)<<2)|0;c[o+(c[l>>2]<<2)>>2]=e;c[p+(c[l>>2]<<2)>>2]=(c[o+(c[l>>2]<<2)>>2]|0)+8192+(0-(c[j>>2]|0)<<2);e=(c[l>>2]|0)+1|0;c[l>>2]=e}while((e|0)<(c[n>>2]|0));c[q>>2]=(c[h>>2]|0)+84+((_(2048+(c[x>>2]|0)|0,c[n>>2]|0)|0)<<2);c[r>>2]=(c[q>>2]|0)+((c[n>>2]|0)*24<<2);c[s>>2]=(c[r>>2]|0)+(c[w>>2]<<1<<2);c[t>>2]=(c[s>>2]|0)+(c[w>>2]<<1<<2);c[u>>2]=(c[t>>2]|0)+(c[w>>2]<<1<<2);c[z>>2]=c[(c[h>>2]|0)+48>>2];c[y>>2]=c[(c[h>>2]|0)+20>>2];c[A>>2]=((c[z>>2]|0)>=5?1:(c[y>>2]|0)!=0)&1;if(c[A>>2]|0){c[E>>2]=c[(c[h>>2]|0)+24>>2];if((c[E>>2]|0)<(c[(c[v>>2]|0)+12>>2]|0))la=c[E>>2]|0;else la=c[(c[v>>2]|0)+12>>2]|0;do if((c[y>>2]|0)<=(la|0))if((c[E>>2]|0)<(c[(c[v>>2]|0)+12>>2]|0)){ma=c[E>>2]|0;break}else{ma=c[(c[v>>2]|0)+12>>2]|0;break}else ma=c[y>>2]|0;while(0);c[F>>2]=ma;ma=_(c[n>>2]|0,c[j>>2]|0)|0;c[G>>2]=ua()|0;la=i;i=i+((1*(ma<<2)|0)+15&-16)|0;if((c[z>>2]|0)>=5)c[D>>2]=c[u>>2];else{g[H>>2]=(c[z>>2]|0)==0?1.5:.5;c[l>>2]=0;do{c[m>>2]=c[y>>2];while(1){if((c[m>>2]|0)>=(c[E>>2]|0))break;u=_(c[l>>2]|0,c[w>>2]|0)|0;ma=(c[r>>2]|0)+(u+(c[m>>2]|0)<<2)|0;g[ma>>2]=+g[ma>>2]-+g[H>>2];c[m>>2]=(c[m>>2]|0)+1}ma=(c[l>>2]|0)+1|0;c[l>>2]=ma}while((ma|0)<(c[n>>2]|0));c[D>>2]=c[r>>2]}c[C>>2]=c[(c[h>>2]|0)+36>>2];c[l>>2]=0;while(1){if((c[l>>2]|0)>=(c[n>>2]|0))break;c[m>>2]=c[y>>2];while(1){if((c[m>>2]|0)>=(c[F>>2]|0))break;r=_(c[j>>2]|0,c[l>>2]|0)|0;c[J>>2]=r+(b[(c[B>>2]|0)+(c[m>>2]<<1)>>1]<<c[k>>2]);c[K>>2]=(b[(c[B>>2]|0)+((c[m>>2]|0)+1<<1)>>1]|0)-(b[(c[B>>2]|0)+(c[m>>2]<<1)>>1]|0)<<c[k>>2];c[I>>2]=0;while(1){if((c[I>>2]|0)>=(c[K>>2]|0))break;c[C>>2]=Ra(c[C>>2]|0)|0;g[la+((c[J>>2]|0)+(c[I>>2]|0)<<2)>>2]=+(c[C>>2]>>20|0);c[I>>2]=(c[I>>2]|0)+1}Ib(la+(c[J>>2]<<2)|0,c[K>>2]|0,1.0);c[m>>2]=(c[m>>2]|0)+1}c[l>>2]=(c[l>>2]|0)+1}c[(c[h>>2]|0)+36>>2]=c[C>>2];c[l>>2]=0;do{ff(c[o+(c[l>>2]<<2)>>2]|0,(c[o+(c[l>>2]<<2)>>2]|0)+(c[j>>2]<<2)|0,(2048-(c[j>>2]|0)+(c[x>>2]>>1)<<2)+0|0)|0;C=(c[l>>2]|0)+1|0;c[l>>2]=C}while((C|0)<(c[n>>2]|0));ad(c[v>>2]|0,la,p,c[D>>2]|0,c[y>>2]|0,c[F>>2]|0,c[n>>2]|0,c[n>>2]|0,0,c[k>>2]|0,c[(c[h>>2]|0)+16>>2]|0,0);ka(c[G>>2]|0);na=c[z>>2]|0;oa=na+1|0;pa=c[h>>2]|0;qa=pa+48|0;c[qa>>2]=oa;i=f;return}g[M>>2]=1.0;if(!(c[z>>2]|0)){G=Ae(o,c[n>>2]|0,c[(c[h>>2]|0)+32>>2]|0)|0;c[N>>2]=G;c[(c[h>>2]|0)+44>>2]=G}else{c[N>>2]=c[(c[h>>2]|0)+44>>2];g[M>>2]=.800000011920929}G=c[x>>2]|0;c[P>>2]=ua()|0;k=i;i=i+((1*(G<<2)|0)+15&-16)|0;c[L>>2]=c[(c[v>>2]|0)+60>>2];c[l>>2]=0;do{g[T>>2]=0.0;c[U>>2]=c[o+(c[l>>2]<<2)>>2];c[m>>2]=0;while(1){if((c[m>>2]|0)>=1024)break;g[Q+(c[m>>2]<<2)>>2]=+g[(c[U>>2]|0)+(1024+(c[m>>2]|0)<<2)>>2];c[m>>2]=(c[m>>2]|0)+1}if(!(c[z>>2]|0)){Bb(Q,Z,c[L>>2]|0,c[x>>2]|0,24,1024,c[(c[h>>2]|0)+32>>2]|0)|0;g[Z>>2]=+g[Z>>2]*1.000100016593933;c[m>>2]=1;while(1){if((c[m>>2]|0)>24)break;v=Z+(c[m>>2]<<2)|0;g[v>>2]=+g[v>>2]-+g[Z+(c[m>>2]<<2)>>2]*6.400000711437315e-05*+(c[m>>2]|0)*+(c[m>>2]|0);c[m>>2]=(c[m>>2]|0)+1}yb((c[q>>2]|0)+((c[l>>2]|0)*24<<2)|0,Z,24)}c[X>>2]=(c[N>>2]<<1|0)<1024?c[N>>2]<<1:1024;c[m>>2]=0;while(1){if((c[m>>2]|0)>=24)break;g[$+(c[m>>2]<<2)>>2]=+g[(c[U>>2]|0)+(2048-(c[X>>2]|0)-1-(c[m>>2]|0)<<2)>>2];c[m>>2]=(c[m>>2]|0)+1}zb(Q+4096+(0-(c[X>>2]|0)<<2)|0,(c[q>>2]|0)+((c[l>>2]|0)*24<<2)|0,Q+4096+(0-(c[X>>2]|0)<<2)|0,c[X>>2]|0,24,$);g[aa>>2]=1.0;g[ba>>2]=1.0;c[ca>>2]=c[X>>2]>>1;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[ca>>2]|0))break;g[da>>2]=+g[Q+(1024-(c[ca>>2]|0)+(c[m>>2]|0)<<2)>>2];g[aa>>2]=+g[aa>>2]+ +g[da>>2]*+g[da>>2];g[da>>2]=+g[Q+(1024-(c[ca>>2]<<1)+(c[m>>2]|0)<<2)>>2];g[ba>>2]=+g[ba>>2]+ +g[da>>2]*+g[da>>2];c[m>>2]=(c[m>>2]|0)+1}g[aa>>2]=+g[aa>>2]<+g[ba>>2]?+g[aa>>2]:+g[ba>>2];g[R>>2]=+O(+(+g[aa>>2]/+g[ba>>2]));ff(c[U>>2]|0,(c[U>>2]|0)+(c[j>>2]<<2)|0,(2048-(c[j>>2]|0)<<2)+0|0)|0;c[V>>2]=1024-(c[N>>2]|0);c[W>>2]=(c[j>>2]|0)+(c[x>>2]|0);g[S>>2]=+g[M>>2]*+g[R>>2];c[Y>>2]=0;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[W>>2]|0))break;if((c[Y>>2]|0)>=(c[N>>2]|0)){c[Y>>2]=(c[Y>>2]|0)-(c[N>>2]|0);g[S>>2]=+g[S>>2]*+g[R>>2]}g[(c[U>>2]|0)+(2048-(c[j>>2]|0)+(c[m>>2]|0)<<2)>>2]=+g[S>>2]*+g[Q+((c[V>>2]|0)+(c[Y>>2]|0)<<2)>>2];g[ea>>2]=+g[(c[U>>2]|0)+(1024-(c[j>>2]|0)+(c[V>>2]|0)+(c[Y>>2]|0)<<2)>>2];g[T>>2]=+g[T>>2]+ +g[ea>>2]*+g[ea>>2];c[m>>2]=(c[m>>2]|0)+1;c[Y>>2]=(c[Y>>2]|0)+1}c[m>>2]=0;while(1){if((c[m>>2]|0)>=24)break;g[fa+(c[m>>2]<<2)>>2]=+g[(c[U>>2]|0)+(2048-(c[j>>2]|0)-1-(c[m>>2]|0)<<2)>>2];c[m>>2]=(c[m>>2]|0)+1}Ab((c[U>>2]|0)+8192+(0-(c[j>>2]|0)<<2)|0,(c[q>>2]|0)+((c[l>>2]|0)*24<<2)|0,(c[U>>2]|0)+8192+(0-(c[j>>2]|0)<<2)|0,c[W>>2]|0,24,fa);g[ga>>2]=0.0;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[W>>2]|0))break;g[ha>>2]=+g[(c[U>>2]|0)+(2048-(c[j>>2]|0)+(c[m>>2]|0)<<2)>>2];g[ga>>2]=+g[ga>>2]+ +g[ha>>2]*+g[ha>>2];c[m>>2]=(c[m>>2]|0)+1}a:do if(+g[T>>2]>+g[ga>>2]*.20000000298023224){if(+g[T>>2]<+g[ga>>2]){g[ia>>2]=+O(+((+g[T>>2]+1.0)/(+g[ga>>2]+1.0)));c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[x>>2]|0))break;g[ja>>2]=1.0-+g[(c[L>>2]|0)+(c[m>>2]<<2)>>2]*(1.0-+g[ia>>2]);g[(c[U>>2]|0)+(2048-(c[j>>2]|0)+(c[m>>2]|0)<<2)>>2]=+g[ja>>2]*+g[(c[U>>2]|0)+(2048-(c[j>>2]|0)+(c[m>>2]|0)<<2)>>2];c[m>>2]=(c[m>>2]|0)+1}c[m>>2]=c[x>>2];while(1){if((c[m>>2]|0)>=(c[W>>2]|0))break a;g[(c[U>>2]|0)+(2048-(c[j>>2]|0)+(c[m>>2]|0)<<2)>>2]=+g[ia>>2]*+g[(c[U>>2]|0)+(2048-(c[j>>2]|0)+(c[m>>2]|0)<<2)>>2];c[m>>2]=(c[m>>2]|0)+1}}}else{c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[W>>2]|0))break a;g[(c[U>>2]|0)+(2048-(c[j>>2]|0)+(c[m>>2]|0)<<2)>>2]=0.0;c[m>>2]=(c[m>>2]|0)+1}}while(0);Xa(k,(c[U>>2]|0)+8192|0,c[(c[h>>2]|0)+52>>2]|0,c[(c[h>>2]|0)+52>>2]|0,c[x>>2]|0,-+g[(c[h>>2]|0)+60>>2],-+g[(c[h>>2]|0)+60>>2],c[(c[h>>2]|0)+68>>2]|0,c[(c[h>>2]|0)+68>>2]|0,0,0);c[m>>2]=0;while(1){if((c[m>>2]|0)>=((c[x>>2]|0)/2|0|0))break;g[(c[U>>2]|0)+(2048+(c[m>>2]|0)<<2)>>2]=+g[(c[L>>2]|0)+(c[m>>2]<<2)>>2]*+g[k+((c[x>>2]|0)-1-(c[m>>2]|0)<<2)>>2]+ +g[(c[L>>2]|0)+((c[x>>2]|0)-(c[m>>2]|0)-1<<2)>>2]*+g[k+(c[m>>2]<<2)>>2];c[m>>2]=(c[m>>2]|0)+1}v=(c[l>>2]|0)+1|0;c[l>>2]=v}while((v|0)<(c[n>>2]|0));ka(c[P>>2]|0);na=c[z>>2]|0;oa=na+1|0;pa=c[h>>2]|0;qa=pa+48|0;c[qa>>2]=oa;i=f;return}function Zc(a,b,d,e,f,h,j,k){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0.0;l=i;i=i+80|0;m=l+68|0;n=l+44|0;o=l+24|0;p=l+32|0;q=l+12|0;r=l+16|0;s=l+48|0;t=l+64|0;u=l+72|0;v=l+36|0;w=l+8|0;x=l;y=l+4|0;z=l+40|0;A=l+20|0;B=l+52|0;C=l+28|0;D=l+60|0;c[m>>2]=a;c[n>>2]=b;c[o>>2]=d;c[p>>2]=e;c[q>>2]=f;c[r>>2]=h;c[s>>2]=j;c[l+56>>2]=k;c[v>>2]=0;k=c[o>>2]|0;c[x>>2]=ua()|0;j=i;i=i+((1*(k<<2)|0)+15&-16)|0;g[w>>2]=+g[c[r>>2]>>2];c[u>>2]=(c[o>>2]|0)/(c[q>>2]|0)|0;c[t>>2]=0;do{g[B>>2]=+g[(c[s>>2]|0)+(c[t>>2]<<2)>>2];c[z>>2]=c[(c[m>>2]|0)+(c[t>>2]<<2)>>2];c[A>>2]=(c[n>>2]|0)+(c[t>>2]<<2);r=(c[q>>2]|0)>1;c[y>>2]=0;a:do if(r){while(1){if((c[y>>2]|0)>=(c[o>>2]|0))break;g[C>>2]=+g[(c[z>>2]|0)+(c[y>>2]<<2)>>2]+ +g[B>>2]+1.0000000031710769e-30;g[B>>2]=+g[w>>2]*+g[C>>2];g[j+(c[y>>2]<<2)>>2]=+g[C>>2];c[y>>2]=(c[y>>2]|0)+1}c[v>>2]=1}else while(1){if((c[y>>2]|0)>=(c[o>>2]|0))break a;g[D>>2]=+g[(c[z>>2]|0)+(c[y>>2]<<2)>>2]+ +g[B>>2]+1.0000000031710769e-30;g[B>>2]=+g[w>>2]*+g[D>>2];k=_(c[y>>2]|0,c[p>>2]|0)|0;g[(c[A>>2]|0)+(k<<2)>>2]=+g[D>>2]*.000030517578125;c[y>>2]=(c[y>>2]|0)+1}while(0);g[(c[s>>2]|0)+(c[t>>2]<<2)>>2]=+g[B>>2];b:do if(c[v>>2]|0){c[y>>2]=0;while(1){if((c[y>>2]|0)>=(c[u>>2]|0))break b;E=+g[j+((_(c[y>>2]|0,c[q>>2]|0)|0)<<2)>>2]*.000030517578125;r=_(c[y>>2]|0,c[p>>2]|0)|0;g[(c[A>>2]|0)+(r<<2)>>2]=E;c[y>>2]=(c[y>>2]|0)+1}}while(0);r=(c[t>>2]|0)+1|0;c[t>>2]=r}while((r|0)<(c[p>>2]|0));ka(c[x>>2]|0);i=l;return}function _c(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=(c[(c[d>>2]|0)+20>>2]|0)-(32-(aa(c[(c[d>>2]|0)+28>>2]|0)|0))|0;i=b;return a|0}function $c(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;j=i;i=i+64|0;k=j+24|0;l=j+20|0;m=j+44|0;n=j+36|0;o=j+32|0;p=j+40|0;q=j+48|0;r=j+52|0;s=j+8|0;t=j+4|0;u=j+28|0;v=j+12|0;w=j;x=j+16|0;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[p>>2]=h;c[w>>2]=c[(c[p>>2]|0)+4>>2]<<3;c[x>>2]=_c(c[p>>2]|0)|0;c[v>>2]=(c[m>>2]|0)!=0?2:4;if((c[o>>2]|0)>0)y=((c[x>>2]|0)+(c[v>>2]|0)+1|0)>>>0<=(c[w>>2]|0)>>>0;else y=0;c[t>>2]=y&1;c[w>>2]=(c[w>>2]|0)-(c[t>>2]|0);c[r>>2]=0;c[u>>2]=0;c[q>>2]=c[k>>2];while(1){if((c[q>>2]|0)>=(c[l>>2]|0))break;if(((c[x>>2]|0)+(c[v>>2]|0)|0)>>>0<=(c[w>>2]|0)>>>0){y=ib(c[p>>2]|0,c[v>>2]|0)|0;c[r>>2]=c[r>>2]^y;c[x>>2]=_c(c[p>>2]|0)|0;c[u>>2]=c[u>>2]|c[r>>2]}c[(c[n>>2]|0)+(c[q>>2]<<2)>>2]=c[r>>2];c[v>>2]=(c[m>>2]|0)!=0?4:5;c[q>>2]=(c[q>>2]|0)+1}c[s>>2]=0;if((c[t>>2]|0)!=0?(a[8+(c[o>>2]<<3)+((c[m>>2]<<2)+0+(c[u>>2]|0))>>0]|0)!=(a[8+(c[o>>2]<<3)+((c[m>>2]<<2)+2+(c[u>>2]|0))>>0]|0):0)c[s>>2]=ib(c[p>>2]|0,1)|0;c[q>>2]=c[k>>2];while(1){if((c[q>>2]|0)>=(c[l>>2]|0))break;c[(c[n>>2]|0)+(c[q>>2]<<2)>>2]=a[8+(c[o>>2]<<3)+((c[m>>2]<<2)+(c[s>>2]<<1)+(c[(c[n>>2]|0)+(c[q>>2]<<2)>>2]|0))>>0];c[q>>2]=(c[q>>2]|0)+1}i=j;return}function ad(a,b,d,e,f,h,j,k,l,m,n,o){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0;p=i;i=i+112|0;q=p+92|0;r=p+84|0;s=p+40|0;t=p+44|0;u=p;v=p+16|0;w=p+20|0;x=p+24|0;y=p+28|0;z=p+72|0;A=p+80|0;B=p+88|0;C=p+96|0;D=p+48|0;E=p+52|0;F=p+56|0;G=p+60|0;H=p+8|0;I=p+64|0;J=p+12|0;K=p+32|0;L=p+68|0;M=p+36|0;N=p+76|0;O=p+4|0;c[q>>2]=a;c[r>>2]=b;c[s>>2]=d;c[t>>2]=e;c[u>>2]=f;c[v>>2]=h;c[w>>2]=j;c[x>>2]=k;c[y>>2]=l;c[z>>2]=m;c[A>>2]=n;c[B>>2]=o;c[L>>2]=c[(c[q>>2]|0)+4>>2];c[K>>2]=c[(c[q>>2]|0)+8>>2];c[H>>2]=c[(c[q>>2]|0)+44>>2]<<c[z>>2];o=c[H>>2]|0;c[M>>2]=ua()|0;n=i;i=i+((1*(o<<2)|0)+15&-16)|0;c[E>>2]=1<<c[z>>2];if(c[y>>2]|0){c[G>>2]=c[E>>2];c[I>>2]=c[(c[q>>2]|0)+44>>2];c[J>>2]=c[(c[q>>2]|0)+36>>2]}else{c[G>>2]=1;c[I>>2]=c[(c[q>>2]|0)+44>>2]<<c[z>>2];c[J>>2]=(c[(c[q>>2]|0)+36>>2]|0)-(c[z>>2]|0)}if((c[x>>2]|0)==2&(c[w>>2]|0)==1){Sa(c[q>>2]|0,c[r>>2]|0,n,c[t>>2]|0,c[u>>2]|0,c[v>>2]|0,c[E>>2]|0,c[A>>2]|0,c[B>>2]|0);c[N>>2]=(c[(c[s>>2]|0)+4>>2]|0)+(((c[L>>2]|0)/2|0)<<2);df(c[N>>2]|0,n|0,(c[H>>2]<<2)+0|0)|0;c[F>>2]=0;while(1){if((c[F>>2]|0)>=(c[G>>2]|0))break;z=(c[c[s>>2]>>2]|0)+((_(c[I>>2]|0,c[F>>2]|0)|0)<<2)|0;tb((c[q>>2]|0)+64|0,(c[N>>2]|0)+(c[F>>2]<<2)|0,z,c[(c[q>>2]|0)+60>>2]|0,c[L>>2]|0,c[J>>2]|0,c[G>>2]|0);c[F>>2]=(c[F>>2]|0)+1}c[F>>2]=0;while(1){if((c[F>>2]|0)>=(c[G>>2]|0))break;N=(c[(c[s>>2]|0)+4>>2]|0)+((_(c[I>>2]|0,c[F>>2]|0)|0)<<2)|0;tb((c[q>>2]|0)+64|0,n+(c[F>>2]<<2)|0,N,c[(c[q>>2]|0)+60>>2]|0,c[L>>2]|0,c[J>>2]|0,c[G>>2]|0);c[F>>2]=(c[F>>2]|0)+1}P=c[M>>2]|0;ka(P|0);i=p;return}if(!((c[x>>2]|0)==1&(c[w>>2]|0)==2)){c[C>>2]=0;do{w=(c[r>>2]|0)+((_(c[C>>2]|0,c[H>>2]|0)|0)<<2)|0;N=(c[t>>2]|0)+((_(c[C>>2]|0,c[K>>2]|0)|0)<<2)|0;Sa(c[q>>2]|0,w,n,N,c[u>>2]|0,c[v>>2]|0,c[E>>2]|0,c[A>>2]|0,c[B>>2]|0);c[F>>2]=0;while(1){if((c[F>>2]|0)>=(c[G>>2]|0))break;N=(c[(c[s>>2]|0)+(c[C>>2]<<2)>>2]|0)+((_(c[I>>2]|0,c[F>>2]|0)|0)<<2)|0;tb((c[q>>2]|0)+64|0,n+(c[F>>2]<<2)|0,N,c[(c[q>>2]|0)+60>>2]|0,c[L>>2]|0,c[J>>2]|0,c[G>>2]|0);c[F>>2]=(c[F>>2]|0)+1}N=(c[C>>2]|0)+1|0;c[C>>2]=N}while((N|0)<(c[x>>2]|0));P=c[M>>2]|0;ka(P|0);i=p;return}c[O>>2]=(c[c[s>>2]>>2]|0)+(((c[L>>2]|0)/2|0)<<2);Sa(c[q>>2]|0,c[r>>2]|0,n,c[t>>2]|0,c[u>>2]|0,c[v>>2]|0,c[E>>2]|0,c[A>>2]|0,c[B>>2]|0);Sa(c[q>>2]|0,(c[r>>2]|0)+(c[H>>2]<<2)|0,c[O>>2]|0,(c[t>>2]|0)+(c[K>>2]<<2)|0,c[u>>2]|0,c[v>>2]|0,c[E>>2]|0,c[A>>2]|0,c[B>>2]|0);c[D>>2]=0;while(1){if((c[D>>2]|0)>=(c[H>>2]|0))break;g[n+(c[D>>2]<<2)>>2]=(+g[n+(c[D>>2]<<2)>>2]+ +g[(c[O>>2]|0)+(c[D>>2]<<2)>>2])*.5;c[D>>2]=(c[D>>2]|0)+1}c[F>>2]=0;while(1){if((c[F>>2]|0)>=(c[G>>2]|0))break;D=(c[c[s>>2]>>2]|0)+((_(c[I>>2]|0,c[F>>2]|0)|0)<<2)|0;tb((c[q>>2]|0)+64|0,n+(c[F>>2]<<2)|0,D,c[(c[q>>2]|0)+60>>2]|0,c[L>>2]|0,c[J>>2]|0,c[G>>2]|0);c[F>>2]=(c[F>>2]|0)+1}P=c[M>>2]|0;ka(P|0);i=p;return}function bd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;i=b;return c[(c[d>>2]|0)+44>>2]|0}function cd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;d=i;i=i+32|0;e=d+16|0;f=d+12|0;g=d+8|0;h=d+4|0;j=d;c[e>>2]=a;c[f>>2]=b;c[h>>2]=(c[e>>2]|0)-1;c[g>>2]=(c[(c[f>>2]|0)+(c[h>>2]<<2)>>2]|0)<0&1;c[j>>2]=N(c[(c[f>>2]|0)+(c[h>>2]<<2)>>2]|0)|0;do{c[h>>2]=(c[h>>2]|0)+-1;if(((c[e>>2]|0)-(c[h>>2]|0)|0)>(c[j>>2]|0))k=(c[e>>2]|0)-(c[h>>2]|0)|0;else k=c[j>>2]|0;if(((c[e>>2]|0)-(c[h>>2]|0)|0)<(c[j>>2]|0))l=(c[e>>2]|0)-(c[h>>2]|0)|0;else l=c[j>>2]|0;c[g>>2]=(c[g>>2]|0)+(c[(c[2448+(l<<2)>>2]|0)+(k<<2)>>2]|0);b=N(c[(c[f>>2]|0)+(c[h>>2]<<2)>>2]|0)|0;c[j>>2]=(c[j>>2]|0)+b;if((c[(c[f>>2]|0)+(c[h>>2]<<2)>>2]|0)<0){if(((c[e>>2]|0)-(c[h>>2]|0)|0)>((c[j>>2]|0)+1|0))m=(c[e>>2]|0)-(c[h>>2]|0)|0;else m=(c[j>>2]|0)+1|0;if(((c[e>>2]|0)-(c[h>>2]|0)|0)<((c[j>>2]|0)+1|0))n=(c[e>>2]|0)-(c[h>>2]|0)|0;else n=(c[j>>2]|0)+1|0;c[g>>2]=(c[g>>2]|0)+(c[(c[2448+(n<<2)>>2]|0)+(m<<2)>>2]|0)}}while((c[h>>2]|0)>0);i=d;return c[g>>2]|0}function dd(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0.0,I=0,J=0.0,K=0,L=0.0,M=0.0,N=0.0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0.0,_=0,$=0.0,aa=0,ba=0.0,ca=0.0,da=0.0,ea=0.0;h=i;i=i+48|0;j=h;k=h+16|0;l=h+4|0;m=h+8|0;n=h+32|0;o=h+36|0;p=h+12|0;q=h+40|0;r=h+20|0;s=h+28|0;t=h+24|0;c[j>>2]=a;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;g[r>>2]=0.0;while(1){u=c[k>>2]|0;if((c[j>>2]|0)<=2)break;f=c[j>>2]|0;do if((u|0)>=(c[j>>2]|0)){c[t>>2]=c[2448+(f<<2)>>2];c[n>>2]=c[(c[t>>2]|0)+((c[k>>2]|0)+1<<2)>>2];c[o>>2]=0-((c[l>>2]|0)>>>0>=(c[n>>2]|0)>>>0&1);c[l>>2]=(c[l>>2]|0)-(c[n>>2]&c[o>>2]);c[p>>2]=c[k>>2];c[s>>2]=c[(c[t>>2]|0)+(c[j>>2]<<2)>>2];a:do if((c[s>>2]|0)>>>0>(c[l>>2]|0)>>>0){c[k>>2]=c[j>>2];do{e=c[j>>2]|0;d=(c[k>>2]|0)+-1|0;c[k>>2]=d;c[n>>2]=c[(c[2448+(d<<2)>>2]|0)+(e<<2)>>2]}while((c[n>>2]|0)>>>0>(c[l>>2]|0)>>>0)}else{c[n>>2]=c[(c[t>>2]|0)+(c[k>>2]<<2)>>2];while(1){if((c[n>>2]|0)>>>0<=(c[l>>2]|0)>>>0)break a;c[k>>2]=(c[k>>2]|0)+-1;c[n>>2]=c[(c[t>>2]|0)+(c[k>>2]<<2)>>2]}}while(0);c[l>>2]=(c[l>>2]|0)-(c[n>>2]|0);b[q>>1]=(c[p>>2]|0)-(c[k>>2]|0)+(c[o>>2]|0)^c[o>>2];e=b[q>>1]|0;d=c[m>>2]|0;c[m>>2]=d+4;c[d>>2]=e;g[r>>2]=+g[r>>2]+ +(b[q>>1]|0)*+(b[q>>1]|0)}else{c[n>>2]=c[(c[2448+(c[k>>2]<<2)>>2]|0)+(f<<2)>>2];c[s>>2]=c[(c[2448+((c[k>>2]|0)+1<<2)>>2]|0)+(c[j>>2]<<2)>>2];if((c[n>>2]|0)>>>0<=(c[l>>2]|0)>>>0?(c[l>>2]|0)>>>0<(c[s>>2]|0)>>>0:0){c[l>>2]=(c[l>>2]|0)-(c[n>>2]|0);e=c[m>>2]|0;c[m>>2]=e+4;c[e>>2]=0;break}c[o>>2]=0-((c[l>>2]|0)>>>0>=(c[s>>2]|0)>>>0&1);c[l>>2]=(c[l>>2]|0)-(c[s>>2]&c[o>>2]);c[p>>2]=c[k>>2];do{e=c[j>>2]|0;d=(c[k>>2]|0)+-1|0;c[k>>2]=d;c[n>>2]=c[(c[2448+(d<<2)>>2]|0)+(e<<2)>>2]}while((c[n>>2]|0)>>>0>(c[l>>2]|0)>>>0);c[l>>2]=(c[l>>2]|0)-(c[n>>2]|0);b[q>>1]=(c[p>>2]|0)-(c[k>>2]|0)+(c[o>>2]|0)^c[o>>2];e=b[q>>1]|0;d=c[m>>2]|0;c[m>>2]=d+4;c[d>>2]=e;g[r>>2]=+g[r>>2]+ +(b[q>>1]|0)*+(b[q>>1]|0)}while(0);c[j>>2]=(c[j>>2]|0)+-1}c[n>>2]=(u<<1)+1;c[o>>2]=0-((c[l>>2]|0)>>>0>=(c[n>>2]|0)>>>0&1);c[l>>2]=(c[l>>2]|0)-(c[n>>2]&c[o>>2]);c[p>>2]=c[k>>2];c[k>>2]=((c[l>>2]|0)+1|0)>>>1;if(!(c[k>>2]|0)){v=c[p>>2]|0;w=c[k>>2]|0;x=v-w|0;y=c[o>>2]|0;z=x+y|0;A=c[o>>2]|0;B=z^A;C=B&65535;b[q>>1]=C;D=b[q>>1]|0;E=D<<16>>16;F=c[m>>2]|0;G=F+4|0;c[m>>2]=G;c[F>>2]=E;H=+g[r>>2];I=b[q>>1]|0;J=+(I<<16>>16);K=b[q>>1]|0;L=+(K<<16>>16);M=J*L;N=H+M;g[r>>2]=N;O=c[l>>2]|0;P=0-O|0;c[o>>2]=P;Q=c[k>>2]|0;R=c[o>>2]|0;S=Q+R|0;T=c[o>>2]|0;U=S^T;V=U&65535;b[q>>1]=V;W=b[q>>1]|0;X=W<<16>>16;Y=c[m>>2]|0;c[Y>>2]=X;Z=+g[r>>2];_=b[q>>1]|0;$=+(_<<16>>16);aa=b[q>>1]|0;ba=+(aa<<16>>16);ca=$*ba;da=Z+ca;g[r>>2]=da;ea=+g[r>>2];i=h;return +ea}c[l>>2]=(c[l>>2]|0)-((c[k>>2]<<1)-1);v=c[p>>2]|0;w=c[k>>2]|0;x=v-w|0;y=c[o>>2]|0;z=x+y|0;A=c[o>>2]|0;B=z^A;C=B&65535;b[q>>1]=C;D=b[q>>1]|0;E=D<<16>>16;F=c[m>>2]|0;G=F+4|0;c[m>>2]=G;c[F>>2]=E;H=+g[r>>2];I=b[q>>1]|0;J=+(I<<16>>16);K=b[q>>1]|0;L=+(K<<16>>16);M=J*L;N=H+M;g[r>>2]=N;O=c[l>>2]|0;P=0-O|0;c[o>>2]=P;Q=c[k>>2]|0;R=c[o>>2]|0;S=Q+R|0;T=c[o>>2]|0;U=S^T;V=U&65535;b[q>>1]=V;W=b[q>>1]|0;X=W<<16>>16;Y=c[m>>2]|0;c[Y>>2]=X;Z=+g[r>>2];_=b[q>>1]|0;$=+(_<<16>>16);aa=b[q>>1]|0;ba=+(aa<<16>>16);ca=$*ba;da=Z+ca;g[r>>2]=da;ea=+g[r>>2];i=h;return +ea}function ed(a){a=a|0;var b=0,e=0,f=0,g=0;b=i;i=i+16|0;e=b;c[e>>2]=a;if((c[(c[e>>2]|0)+24>>2]|0)>>>0>=(c[(c[e>>2]|0)+4>>2]|0)>>>0){f=0;i=b;return f|0}a=(c[e>>2]|0)+24|0;g=c[a>>2]|0;c[a>>2]=g+1;f=d[(c[c[e>>2]>>2]|0)+g>>0]|0;i=b;return f|0}function fd(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;while(1){if((c[(c[d>>2]|0)+28>>2]|0)>>>0>8388608)break;a=(c[d>>2]|0)+20|0;c[a>>2]=(c[a>>2]|0)+8;a=(c[d>>2]|0)+28|0;c[a>>2]=c[a>>2]<<8;c[e>>2]=c[(c[d>>2]|0)+40>>2];a=ed(c[d>>2]|0)|0;c[(c[d>>2]|0)+40>>2]=a;c[e>>2]=(c[e>>2]<<8|c[(c[d>>2]|0)+40>>2])>>1;c[(c[d>>2]|0)+32>>2]=(c[(c[d>>2]|0)+32>>2]<<8)+(255&~c[e>>2])&2147483647}i=b;return}function gd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>>>0)/((c[f>>2]|0)>>>0)|0|0}function hd(a){a=a|0;var b=0,e=0,f=0,g=0,h=0;b=i;i=i+16|0;e=b;c[e>>2]=a;if((c[(c[e>>2]|0)+8>>2]|0)>>>0>=(c[(c[e>>2]|0)+4>>2]|0)>>>0){f=0;i=b;return f|0}a=c[(c[e>>2]|0)+4>>2]|0;g=(c[e>>2]|0)+8|0;h=(c[g>>2]|0)+1|0;c[g>>2]=h;f=d[(c[c[e>>2]>>2]|0)+(a-h)>>0]|0;i=b;return f|0}function id(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>>>0)/((c[f>>2]|0)>>>0)|0|0}function jd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;while(1){if((c[(c[d>>2]|0)+28>>2]|0)>>>0>8388608)break;ld(c[d>>2]|0,(c[(c[d>>2]|0)+32>>2]|0)>>>23);c[(c[d>>2]|0)+32>>2]=c[(c[d>>2]|0)+32>>2]<<8&2147483647;a=(c[d>>2]|0)+28|0;c[a>>2]=c[a>>2]<<8;a=(c[d>>2]|0)+20|0;c[a>>2]=(c[a>>2]|0)+8}i=b;return}function kd(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[g>>2]=b;c[h>>2]=d;if(((c[(c[g>>2]|0)+24>>2]|0)+(c[(c[g>>2]|0)+8>>2]|0)|0)>>>0>=(c[(c[g>>2]|0)+4>>2]|0)>>>0){c[f>>2]=-1;j=c[f>>2]|0;i=e;return j|0}else{d=c[h>>2]&255;h=c[(c[g>>2]|0)+4>>2]|0;b=(c[g>>2]|0)+8|0;k=(c[b>>2]|0)+1|0;c[b>>2]=k;a[(c[c[g>>2]>>2]|0)+(h-k)>>0]=d;c[f>>2]=0;j=c[f>>2]|0;i=e;return j|0}return 0}function ld(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[e>>2]=a;c[f>>2]=b;if((c[f>>2]|0)==255){b=(c[e>>2]|0)+36|0;c[b>>2]=(c[b>>2]|0)+1;i=d;return}c[g>>2]=c[f>>2]>>8;if((c[(c[e>>2]|0)+40>>2]|0)>=0){b=ze(c[e>>2]|0,(c[(c[e>>2]|0)+40>>2]|0)+(c[g>>2]|0)|0)|0;a=(c[e>>2]|0)+44|0;c[a>>2]=c[a>>2]|b}if((c[(c[e>>2]|0)+36>>2]|0)>>>0>0){c[h>>2]=255+(c[g>>2]|0)&255;do{g=ze(c[e>>2]|0,c[h>>2]|0)|0;b=(c[e>>2]|0)+44|0;c[b>>2]=c[b>>2]|g;g=(c[e>>2]|0)+36|0;b=(c[g>>2]|0)+-1|0;c[g>>2]=b}while(b>>>0>0)}c[(c[e>>2]|0)+40>>2]=c[f>>2]&255;i=d;return}function md(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0;e=i;i=i+48|0;f=e+8|0;h=e+28|0;j=e+32|0;k=e+4|0;l=e;m=e+16|0;c[f>>2]=a;c[e+24>>2]=b;c[h>>2]=d;g[l>>2]=.7071067690849304;c[k>>2]=0;while(1){if((c[k>>2]|0)>=(c[h>>2]|0))break;c[j>>2]=(c[f>>2]|0)+32;d=c[j>>2]|0;c[m>>2]=c[d>>2];c[m+4>>2]=c[d+4>>2];g[c[j>>2]>>2]=+g[c[f>>2]>>2]-+g[m>>2];g[(c[j>>2]|0)+4>>2]=+g[(c[f>>2]|0)+4>>2]-+g[m+4>>2];d=c[f>>2]|0;g[d>>2]=+g[d>>2]+ +g[m>>2];d=(c[f>>2]|0)+4|0;g[d>>2]=+g[d>>2]+ +g[m+4>>2];g[m>>2]=(+g[(c[j>>2]|0)+8>>2]+ +g[(c[j>>2]|0)+8+4>>2])*+g[l>>2];g[m+4>>2]=(+g[(c[j>>2]|0)+8+4>>2]-+g[(c[j>>2]|0)+8>>2])*+g[l>>2];g[(c[j>>2]|0)+8>>2]=+g[(c[f>>2]|0)+8>>2]-+g[m>>2];g[(c[j>>2]|0)+8+4>>2]=+g[(c[f>>2]|0)+8+4>>2]-+g[m+4>>2];d=(c[f>>2]|0)+8|0;g[d>>2]=+g[d>>2]+ +g[m>>2];d=(c[f>>2]|0)+8+4|0;g[d>>2]=+g[d>>2]+ +g[m+4>>2];g[m>>2]=+g[(c[j>>2]|0)+16+4>>2];g[m+4>>2]=-+g[(c[j>>2]|0)+16>>2];g[(c[j>>2]|0)+16>>2]=+g[(c[f>>2]|0)+16>>2]-+g[m>>2];g[(c[j>>2]|0)+16+4>>2]=+g[(c[f>>2]|0)+16+4>>2]-+g[m+4>>2];d=(c[f>>2]|0)+16|0;g[d>>2]=+g[d>>2]+ +g[m>>2];d=(c[f>>2]|0)+16+4|0;g[d>>2]=+g[d>>2]+ +g[m+4>>2];g[m>>2]=(+g[(c[j>>2]|0)+24+4>>2]-+g[(c[j>>2]|0)+24>>2])*+g[l>>2];g[m+4>>2]=(-+g[(c[j>>2]|0)+24+4>>2]-+g[(c[j>>2]|0)+24>>2])*+g[l>>2];g[(c[j>>2]|0)+24>>2]=+g[(c[f>>2]|0)+24>>2]-+g[m>>2];g[(c[j>>2]|0)+24+4>>2]=+g[(c[f>>2]|0)+24+4>>2]-+g[m+4>>2];d=(c[f>>2]|0)+24|0;g[d>>2]=+g[d>>2]+ +g[m>>2];d=(c[f>>2]|0)+24+4|0;g[d>>2]=+g[d>>2]+ +g[m+4>>2];c[f>>2]=(c[f>>2]|0)+64;c[k>>2]=(c[k>>2]|0)+1}i=e;return}function nd(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;j=i;i=i+128|0;k=j+112|0;l=j+88|0;m=j+64|0;n=j+60|0;o=j+48|0;p=j+84|0;q=j+92|0;r=j+104|0;s=j+120|0;t=j+68|0;u=j;v=j+76|0;w=j+72|0;x=j+52|0;y=j+80|0;z=j+56|0;A=j+96|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;if((c[n>>2]|0)==1){c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;g[r>>2]=+g[c[k>>2]>>2]-+g[(c[k>>2]|0)+16>>2];g[r+4>>2]=+g[(c[k>>2]|0)+4>>2]-+g[(c[k>>2]|0)+16+4>>2];h=c[k>>2]|0;g[h>>2]=+g[h>>2]+ +g[(c[k>>2]|0)+16>>2];h=(c[k>>2]|0)+4|0;g[h>>2]=+g[h>>2]+ +g[(c[k>>2]|0)+16+4>>2];g[s>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[(c[k>>2]|0)+24>>2];g[s+4>>2]=+g[(c[k>>2]|0)+8+4>>2]+ +g[(c[k>>2]|0)+24+4>>2];g[(c[k>>2]|0)+16>>2]=+g[c[k>>2]>>2]-+g[s>>2];g[(c[k>>2]|0)+16+4>>2]=+g[(c[k>>2]|0)+4>>2]-+g[s+4>>2];h=c[k>>2]|0;g[h>>2]=+g[h>>2]+ +g[s>>2];h=(c[k>>2]|0)+4|0;g[h>>2]=+g[h>>2]+ +g[s+4>>2];g[s>>2]=+g[(c[k>>2]|0)+8>>2]-+g[(c[k>>2]|0)+24>>2];g[s+4>>2]=+g[(c[k>>2]|0)+8+4>>2]-+g[(c[k>>2]|0)+24+4>>2];g[(c[k>>2]|0)+8>>2]=+g[r>>2]+ +g[s+4>>2];g[(c[k>>2]|0)+8+4>>2]=+g[r+4>>2]-+g[s>>2];g[(c[k>>2]|0)+24>>2]=+g[r>>2]-+g[s+4>>2];g[(c[k>>2]|0)+24+4>>2]=+g[r+4>>2]+ +g[s>>2];c[k>>2]=(c[k>>2]|0)+32;c[q>>2]=(c[q>>2]|0)+1}i=j;return}c[y>>2]=c[n>>2]<<1;c[z>>2]=(c[n>>2]|0)*3;c[A>>2]=c[k>>2];c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;c[k>>2]=(c[A>>2]|0)+((_(c[q>>2]|0,c[p>>2]|0)|0)<<3);s=c[(c[m>>2]|0)+48>>2]|0;c[v>>2]=s;c[w>>2]=s;c[x>>2]=s;c[t>>2]=0;while(1){if((c[t>>2]|0)>=(c[n>>2]|0))break;g[u>>2]=+g[(c[k>>2]|0)+(c[n>>2]<<3)>>2]*+g[c[v>>2]>>2]-+g[(c[k>>2]|0)+(c[n>>2]<<3)+4>>2]*+g[(c[v>>2]|0)+4>>2];g[u+4>>2]=+g[(c[k>>2]|0)+(c[n>>2]<<3)>>2]*+g[(c[v>>2]|0)+4>>2]+ +g[(c[k>>2]|0)+(c[n>>2]<<3)+4>>2]*+g[c[v>>2]>>2];g[u+8>>2]=+g[(c[k>>2]|0)+(c[y>>2]<<3)>>2]*+g[c[w>>2]>>2]-+g[(c[k>>2]|0)+(c[y>>2]<<3)+4>>2]*+g[(c[w>>2]|0)+4>>2];g[u+8+4>>2]=+g[(c[k>>2]|0)+(c[y>>2]<<3)>>2]*+g[(c[w>>2]|0)+4>>2]+ +g[(c[k>>2]|0)+(c[y>>2]<<3)+4>>2]*+g[c[w>>2]>>2];g[u+16>>2]=+g[(c[k>>2]|0)+(c[z>>2]<<3)>>2]*+g[c[x>>2]>>2]-+g[(c[k>>2]|0)+(c[z>>2]<<3)+4>>2]*+g[(c[x>>2]|0)+4>>2];g[u+16+4>>2]=+g[(c[k>>2]|0)+(c[z>>2]<<3)>>2]*+g[(c[x>>2]|0)+4>>2]+ +g[(c[k>>2]|0)+(c[z>>2]<<3)+4>>2]*+g[c[x>>2]>>2];g[u+40>>2]=+g[c[k>>2]>>2]-+g[u+8>>2];g[u+40+4>>2]=+g[(c[k>>2]|0)+4>>2]-+g[u+8+4>>2];s=c[k>>2]|0;g[s>>2]=+g[s>>2]+ +g[u+8>>2];s=(c[k>>2]|0)+4|0;g[s>>2]=+g[s>>2]+ +g[u+8+4>>2];g[u+24>>2]=+g[u>>2]+ +g[u+16>>2];g[u+24+4>>2]=+g[u+4>>2]+ +g[u+16+4>>2];g[u+32>>2]=+g[u>>2]-+g[u+16>>2];g[u+32+4>>2]=+g[u+4>>2]-+g[u+16+4>>2];g[(c[k>>2]|0)+(c[y>>2]<<3)>>2]=+g[c[k>>2]>>2]-+g[u+24>>2];g[(c[k>>2]|0)+(c[y>>2]<<3)+4>>2]=+g[(c[k>>2]|0)+4>>2]-+g[u+24+4>>2];c[v>>2]=(c[v>>2]|0)+(c[l>>2]<<3);c[w>>2]=(c[w>>2]|0)+(c[l>>2]<<1<<3);c[x>>2]=(c[x>>2]|0)+((c[l>>2]|0)*3<<3);s=c[k>>2]|0;g[s>>2]=+g[s>>2]+ +g[u+24>>2];s=(c[k>>2]|0)+4|0;g[s>>2]=+g[s>>2]+ +g[u+24+4>>2];g[(c[k>>2]|0)+(c[n>>2]<<3)>>2]=+g[u+40>>2]+ +g[u+32+4>>2];g[(c[k>>2]|0)+(c[n>>2]<<3)+4>>2]=+g[u+40+4>>2]-+g[u+32>>2];g[(c[k>>2]|0)+(c[z>>2]<<3)>>2]=+g[u+40>>2]-+g[u+32+4>>2];g[(c[k>>2]|0)+(c[z>>2]<<3)+4>>2]=+g[u+40+4>>2]+ +g[u+32>>2];c[k>>2]=(c[k>>2]|0)+8;c[t>>2]=(c[t>>2]|0)+1}c[q>>2]=(c[q>>2]|0)+1}i=j;return}function od(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;j=i;i=i+112|0;k=j+56|0;l=j+52|0;m=j+88|0;n=j+80|0;o=j+76|0;p=j+84|0;q=j+92|0;r=j+96|0;s=j+60|0;t=j;u=j+72|0;v=j+8|0;w=j+64|0;x=j+48|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;c[s>>2]=c[n>>2]<<1;c[x>>2]=c[k>>2];h=_(c[l>>2]|0,c[n>>2]|0)|0;f=(c[(c[m>>2]|0)+48>>2]|0)+(h<<3)|0;c[w>>2]=c[f>>2];c[w+4>>2]=c[f+4>>2];c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;c[k>>2]=(c[x>>2]|0)+((_(c[q>>2]|0,c[p>>2]|0)|0)<<3);f=c[(c[m>>2]|0)+48>>2]|0;c[u>>2]=f;c[t>>2]=f;c[r>>2]=c[n>>2];do{g[v+8>>2]=+g[(c[k>>2]|0)+(c[n>>2]<<3)>>2]*+g[c[t>>2]>>2]-+g[(c[k>>2]|0)+(c[n>>2]<<3)+4>>2]*+g[(c[t>>2]|0)+4>>2];g[v+8+4>>2]=+g[(c[k>>2]|0)+(c[n>>2]<<3)>>2]*+g[(c[t>>2]|0)+4>>2]+ +g[(c[k>>2]|0)+(c[n>>2]<<3)+4>>2]*+g[c[t>>2]>>2];g[v+16>>2]=+g[(c[k>>2]|0)+(c[s>>2]<<3)>>2]*+g[c[u>>2]>>2]-+g[(c[k>>2]|0)+(c[s>>2]<<3)+4>>2]*+g[(c[u>>2]|0)+4>>2];g[v+16+4>>2]=+g[(c[k>>2]|0)+(c[s>>2]<<3)>>2]*+g[(c[u>>2]|0)+4>>2]+ +g[(c[k>>2]|0)+(c[s>>2]<<3)+4>>2]*+g[c[u>>2]>>2];g[v+24>>2]=+g[v+8>>2]+ +g[v+16>>2];g[v+24+4>>2]=+g[v+8+4>>2]+ +g[v+16+4>>2];g[v>>2]=+g[v+8>>2]-+g[v+16>>2];g[v+4>>2]=+g[v+8+4>>2]-+g[v+16+4>>2];c[t>>2]=(c[t>>2]|0)+(c[l>>2]<<3);c[u>>2]=(c[u>>2]|0)+(c[l>>2]<<1<<3);g[(c[k>>2]|0)+(c[n>>2]<<3)>>2]=+g[c[k>>2]>>2]-+g[v+24>>2]*.5;g[(c[k>>2]|0)+(c[n>>2]<<3)+4>>2]=+g[(c[k>>2]|0)+4>>2]-+g[v+24+4>>2]*.5;g[v>>2]=+g[v>>2]*+g[w+4>>2];f=v+4|0;g[f>>2]=+g[f>>2]*+g[w+4>>2];f=c[k>>2]|0;g[f>>2]=+g[f>>2]+ +g[v+24>>2];f=(c[k>>2]|0)+4|0;g[f>>2]=+g[f>>2]+ +g[v+24+4>>2];g[(c[k>>2]|0)+(c[s>>2]<<3)>>2]=+g[(c[k>>2]|0)+(c[n>>2]<<3)>>2]+ +g[v+4>>2];g[(c[k>>2]|0)+(c[s>>2]<<3)+4>>2]=+g[(c[k>>2]|0)+(c[n>>2]<<3)+4>>2]-+g[v>>2];f=(c[k>>2]|0)+(c[n>>2]<<3)|0;g[f>>2]=+g[f>>2]-+g[v+4>>2];f=(c[k>>2]|0)+(c[n>>2]<<3)+4|0;g[f>>2]=+g[f>>2]+ +g[v>>2];c[k>>2]=(c[k>>2]|0)+8;f=(c[r>>2]|0)+-1|0;c[r>>2]=f}while((f|0)!=0);c[q>>2]=(c[q>>2]|0)+1}i=j;return}function pd(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;j=i;i=i+192|0;k=j+28|0;l=j+32|0;m=j+156|0;n=j+180|0;o=j+4|0;p=j+152|0;q=j+160|0;r=j+176|0;s=j+184|0;t=j+188|0;u=j+36|0;v=j;w=j+40|0;x=j+48|0;y=j+8|0;z=j+16|0;A=j+168|0;B=j+24|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;c[B>>2]=c[k>>2];h=_(c[l>>2]|0,c[n>>2]|0)|0;f=(c[(c[m>>2]|0)+48>>2]|0)+(h<<3)|0;c[z>>2]=c[f>>2];c[z+4>>2]=c[f+4>>2];f=_(c[l>>2]<<1,c[n>>2]|0)|0;h=(c[(c[m>>2]|0)+48>>2]|0)+(f<<3)|0;c[A>>2]=c[h>>2];c[A+4>>2]=c[h+4>>2];c[y>>2]=c[(c[m>>2]|0)+48>>2];c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[o>>2]|0))break;c[k>>2]=(c[B>>2]|0)+((_(c[v>>2]|0,c[p>>2]|0)|0)<<3);c[q>>2]=c[k>>2];c[r>>2]=(c[q>>2]|0)+(c[n>>2]<<3);c[s>>2]=(c[q>>2]|0)+(c[n>>2]<<1<<3);c[t>>2]=(c[q>>2]|0)+((c[n>>2]|0)*3<<3);c[u>>2]=(c[q>>2]|0)+(c[n>>2]<<2<<3);c[w>>2]=0;while(1){if((c[w>>2]|0)>=(c[n>>2]|0))break;m=c[q>>2]|0;c[x>>2]=c[m>>2];c[x+4>>2]=c[m+4>>2];m=_(c[w>>2]|0,c[l>>2]|0)|0;h=_(c[w>>2]|0,c[l>>2]|0)|0;g[x+8>>2]=+g[c[r>>2]>>2]*+g[(c[y>>2]|0)+(m<<3)>>2]-+g[(c[r>>2]|0)+4>>2]*+g[(c[y>>2]|0)+(h<<3)+4>>2];h=_(c[w>>2]|0,c[l>>2]|0)|0;m=_(c[w>>2]|0,c[l>>2]|0)|0;g[x+8+4>>2]=+g[c[r>>2]>>2]*+g[(c[y>>2]|0)+(h<<3)+4>>2]+ +g[(c[r>>2]|0)+4>>2]*+g[(c[y>>2]|0)+(m<<3)>>2];m=_(c[w>>2]<<1,c[l>>2]|0)|0;h=_(c[w>>2]<<1,c[l>>2]|0)|0;g[x+16>>2]=+g[c[s>>2]>>2]*+g[(c[y>>2]|0)+(m<<3)>>2]-+g[(c[s>>2]|0)+4>>2]*+g[(c[y>>2]|0)+(h<<3)+4>>2];h=_(c[w>>2]<<1,c[l>>2]|0)|0;m=_(c[w>>2]<<1,c[l>>2]|0)|0;g[x+16+4>>2]=+g[c[s>>2]>>2]*+g[(c[y>>2]|0)+(h<<3)+4>>2]+ +g[(c[s>>2]|0)+4>>2]*+g[(c[y>>2]|0)+(m<<3)>>2];m=_((c[w>>2]|0)*3|0,c[l>>2]|0)|0;h=_((c[w>>2]|0)*3|0,c[l>>2]|0)|0;g[x+24>>2]=+g[c[t>>2]>>2]*+g[(c[y>>2]|0)+(m<<3)>>2]-+g[(c[t>>2]|0)+4>>2]*+g[(c[y>>2]|0)+(h<<3)+4>>2];h=_((c[w>>2]|0)*3|0,c[l>>2]|0)|0;m=_((c[w>>2]|0)*3|0,c[l>>2]|0)|0;g[x+24+4>>2]=+g[c[t>>2]>>2]*+g[(c[y>>2]|0)+(h<<3)+4>>2]+ +g[(c[t>>2]|0)+4>>2]*+g[(c[y>>2]|0)+(m<<3)>>2];m=_(c[w>>2]<<2,c[l>>2]|0)|0;h=_(c[w>>2]<<2,c[l>>2]|0)|0;g[x+32>>2]=+g[c[u>>2]>>2]*+g[(c[y>>2]|0)+(m<<3)>>2]-+g[(c[u>>2]|0)+4>>2]*+g[(c[y>>2]|0)+(h<<3)+4>>2];h=_(c[w>>2]<<2,c[l>>2]|0)|0;m=_(c[w>>2]<<2,c[l>>2]|0)|0;g[x+32+4>>2]=+g[c[u>>2]>>2]*+g[(c[y>>2]|0)+(h<<3)+4>>2]+ +g[(c[u>>2]|0)+4>>2]*+g[(c[y>>2]|0)+(m<<3)>>2];g[x+56>>2]=+g[x+8>>2]+ +g[x+32>>2];g[x+56+4>>2]=+g[x+8+4>>2]+ +g[x+32+4>>2];g[x+80>>2]=+g[x+8>>2]-+g[x+32>>2];g[x+80+4>>2]=+g[x+8+4>>2]-+g[x+32+4>>2];g[x+64>>2]=+g[x+16>>2]+ +g[x+24>>2];g[x+64+4>>2]=+g[x+16+4>>2]+ +g[x+24+4>>2];g[x+72>>2]=+g[x+16>>2]-+g[x+24>>2];g[x+72+4>>2]=+g[x+16+4>>2]-+g[x+24+4>>2];m=c[q>>2]|0;g[m>>2]=+g[m>>2]+(+g[x+56>>2]+ +g[x+64>>2]);m=(c[q>>2]|0)+4|0;g[m>>2]=+g[m>>2]+(+g[x+56+4>>2]+ +g[x+64+4>>2]);g[x+40>>2]=+g[x>>2]+ +g[x+56>>2]*+g[z>>2]+ +g[x+64>>2]*+g[A>>2];g[x+40+4>>2]=+g[x+4>>2]+ +g[x+56+4>>2]*+g[z>>2]+ +g[x+64+4>>2]*+g[A>>2];g[x+48>>2]=+g[x+80+4>>2]*+g[z+4>>2]+ +g[x+72+4>>2]*+g[A+4>>2];g[x+48+4>>2]=-(+g[x+80>>2]*+g[z+4>>2])-+g[x+72>>2]*+g[A+4>>2];g[c[r>>2]>>2]=+g[x+40>>2]-+g[x+48>>2];g[(c[r>>2]|0)+4>>2]=+g[x+40+4>>2]-+g[x+48+4>>2];g[c[u>>2]>>2]=+g[x+40>>2]+ +g[x+48>>2];g[(c[u>>2]|0)+4>>2]=+g[x+40+4>>2]+ +g[x+48+4>>2];g[x+88>>2]=+g[x>>2]+ +g[x+56>>2]*+g[A>>2]+ +g[x+64>>2]*+g[z>>2];g[x+88+4>>2]=+g[x+4>>2]+ +g[x+56+4>>2]*+g[A>>2]+ +g[x+64+4>>2]*+g[z>>2];g[x+96>>2]=-(+g[x+80+4>>2]*+g[A+4>>2])+ +g[x+72+4>>2]*+g[z+4>>2];g[x+96+4>>2]=+g[x+80>>2]*+g[A+4>>2]-+g[x+72>>2]*+g[z+4>>2];g[c[s>>2]>>2]=+g[x+88>>2]+ +g[x+96>>2];g[(c[s>>2]|0)+4>>2]=+g[x+88+4>>2]+ +g[x+96+4>>2];g[c[t>>2]>>2]=+g[x+88>>2]-+g[x+96>>2];g[(c[t>>2]|0)+4>>2]=+g[x+88+4>>2]-+g[x+96+4>>2];c[q>>2]=(c[q>>2]|0)+8;c[r>>2]=(c[r>>2]|0)+8;c[s>>2]=(c[s>>2]|0)+8;c[t>>2]=(c[t>>2]|0)+8;c[u>>2]=(c[u>>2]|0)+8;c[w>>2]=(c[w>>2]|0)+1}c[v>>2]=(c[v>>2]|0)+1}i=j;return}function qd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[e>>2]=a;c[f>>2]=b;c[g>>2]=32736-(c[e>>2]|0);e=(_(c[g>>2]|0,16384-(c[f>>2]|0)|0)|0)>>>15;i=d;return e|0}function rd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;h=i;i=i+80|0;j=h+60|0;k=h+44|0;l=h+20|0;m=h+16|0;n=h+4|0;o=h+40|0;p=h+48|0;q=h+56|0;r=h+64|0;s=h+24|0;t=h;u=h+32|0;v=h+28|0;w=h+8|0;x=h+36|0;y=h+12|0;z=h+52|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;g[p>>2]=+g[c[k>>2]>>2];g[q>>2]=+g[(c[k>>2]|0)+4>>2];g[r>>2]=+g[(c[k>>2]|0)+8>>2];g[s>>2]=+g[(c[k>>2]|0)+12>>2];g[t>>2]=+g[(c[k>>2]|0)+16>>2];g[u>>2]=+g[c[n>>2]>>2];g[v>>2]=+g[(c[n>>2]|0)+4>>2];g[w>>2]=+g[(c[n>>2]|0)+8>>2];g[x>>2]=+g[(c[n>>2]|0)+12>>2];g[y>>2]=+g[(c[n>>2]|0)+16>>2];c[o>>2]=0;while(1){if((c[o>>2]|0)>=(c[m>>2]|0))break;g[z>>2]=+g[(c[j>>2]|0)+(c[o>>2]<<2)>>2];g[z>>2]=+g[z>>2]+ +g[p>>2]*+g[u>>2];g[z>>2]=+g[z>>2]+ +g[q>>2]*+g[v>>2];g[z>>2]=+g[z>>2]+ +g[r>>2]*+g[w>>2];g[z>>2]=+g[z>>2]+ +g[s>>2]*+g[x>>2];g[z>>2]=+g[z>>2]+ +g[t>>2]*+g[y>>2];g[y>>2]=+g[x>>2];g[x>>2]=+g[w>>2];g[w>>2]=+g[v>>2];g[v>>2]=+g[u>>2];g[u>>2]=+g[(c[j>>2]|0)+(c[o>>2]<<2)>>2];g[(c[l>>2]|0)+(c[o>>2]<<2)>>2]=+g[z>>2];c[o>>2]=(c[o>>2]|0)+1}g[c[n>>2]>>2]=+g[u>>2];g[(c[n>>2]|0)+4>>2]=+g[v>>2];g[(c[n>>2]|0)+8>>2]=+g[w>>2];g[(c[n>>2]|0)+12>>2]=+g[x>>2];g[(c[n>>2]|0)+16>>2]=+g[y>>2];i=h;return}function sd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;f=i;i=i+64|0;h=f+44|0;j=f+36|0;k=f+12|0;l=f+8|0;m=f+32|0;n=f+40|0;o=f+48|0;p=f+16|0;q=f;r=f+24|0;s=f+4|0;t=f+28|0;u=f+20|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;g[q>>2]=0.0;e=c[j>>2]|0;c[j>>2]=e+4;g[n>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[o>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[p>>2]=+g[e>>2];c[m>>2]=0;while(1){if((c[m>>2]|0)>=((c[l>>2]|0)-3|0))break;e=c[h>>2]|0;c[h>>2]=e+4;g[r>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[q>>2]=+g[e>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[r>>2]*+g[n>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[r>>2]*+g[o>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[r>>2]*+g[p>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[r>>2]*+g[q>>2];e=c[h>>2]|0;c[h>>2]=e+4;g[r>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[n>>2]=+g[e>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[r>>2]*+g[o>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[r>>2]*+g[p>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[r>>2]*+g[q>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[r>>2]*+g[n>>2];e=c[h>>2]|0;c[h>>2]=e+4;g[r>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[o>>2]=+g[e>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[r>>2]*+g[p>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[r>>2]*+g[q>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[r>>2]*+g[n>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[r>>2]*+g[o>>2];e=c[h>>2]|0;c[h>>2]=e+4;g[r>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[p>>2]=+g[e>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[r>>2]*+g[q>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[r>>2]*+g[n>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[r>>2]*+g[o>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[r>>2]*+g[p>>2];c[m>>2]=(c[m>>2]|0)+4}r=c[m>>2]|0;c[m>>2]=r+1;if((r|0)<(c[l>>2]|0)){r=c[h>>2]|0;c[h>>2]=r+4;g[s>>2]=+g[r>>2];r=c[j>>2]|0;c[j>>2]=r+4;g[q>>2]=+g[r>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[s>>2]*+g[n>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[s>>2]*+g[o>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[s>>2]*+g[p>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[s>>2]*+g[q>>2]}s=c[m>>2]|0;c[m>>2]=s+1;if((s|0)<(c[l>>2]|0)){s=c[h>>2]|0;c[h>>2]=s+4;g[t>>2]=+g[s>>2];s=c[j>>2]|0;c[j>>2]=s+4;g[n>>2]=+g[s>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[t>>2]*+g[o>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[t>>2]*+g[p>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[t>>2]*+g[q>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[t>>2]*+g[n>>2]}if((c[m>>2]|0)>=(c[l>>2]|0)){i=f;return}l=c[h>>2]|0;c[h>>2]=l+4;g[u>>2]=+g[l>>2];l=c[j>>2]|0;c[j>>2]=l+4;g[o>>2]=+g[l>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[u>>2]*+g[p>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[u>>2]*+g[q>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[u>>2]*+g[n>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[u>>2]*+g[o>>2];i=f;return}function td(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0.0;e=i;i=i+32|0;f=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[f>>2]=a;c[h>>2]=b;c[j>>2]=d;g[l>>2]=0.0;c[k>>2]=0;while(1){m=+g[l>>2];if((c[k>>2]|0)>=(c[j>>2]|0))break;g[l>>2]=m+ +g[(c[f>>2]|0)+(c[k>>2]<<2)>>2]*+g[(c[h>>2]|0)+(c[k>>2]<<2)>>2];c[k>>2]=(c[k>>2]|0)+1}i=e;return +m}function ud(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+64|0;j=h;k=h+8|0;l=h+52|0;m=h+24|0;n=h+48|0;o=h+56|0;p=h+60|0;q=h+40|0;r=h+32|0;s=h+16|0;t=h+4|0;u=h+44|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;g[q>>2]=1.0;g[r>>2]=-1.0;g[r+4>>2]=-1.0;g[s>>2]=0.0;g[s+4>>2]=0.0;c[c[n>>2]>>2]=0;c[(c[n>>2]|0)+4>>2]=1;c[p>>2]=0;while(1){if((c[p>>2]|0)>=(c[l>>2]|0))break;g[q>>2]=+g[q>>2]+ +g[(c[k>>2]|0)+(c[p>>2]<<2)>>2]*+g[(c[k>>2]|0)+(c[p>>2]<<2)>>2];c[p>>2]=(c[p>>2]|0)+1}c[o>>2]=0;while(1){if((c[o>>2]|0)>=(c[m>>2]|0))break;do if(+g[(c[j>>2]|0)+(c[o>>2]<<2)>>2]>0.0?(g[u>>2]=+g[(c[j>>2]|0)+(c[o>>2]<<2)>>2],g[u>>2]=+g[u>>2]*9.999999960041972e-13,g[t>>2]=+g[u>>2]*+g[u>>2],+g[t>>2]*+g[s+4>>2]>+g[r+4>>2]*+g[q>>2]):0)if(+g[t>>2]*+g[s>>2]>+g[r>>2]*+g[q>>2]){g[r+4>>2]=+g[r>>2];g[s+4>>2]=+g[s>>2];c[(c[n>>2]|0)+4>>2]=c[c[n>>2]>>2];g[r>>2]=+g[t>>2];g[s>>2]=+g[q>>2];c[c[n>>2]>>2]=c[o>>2];break}else{g[r+4>>2]=+g[t>>2];g[s+4>>2]=+g[q>>2];c[(c[n>>2]|0)+4>>2]=c[o>>2];break}while(0);g[q>>2]=+g[q>>2]+(+g[(c[k>>2]|0)+((c[o>>2]|0)+(c[l>>2]|0)<<2)>>2]*+g[(c[k>>2]|0)+((c[o>>2]|0)+(c[l>>2]|0)<<2)>>2]-+g[(c[k>>2]|0)+(c[o>>2]<<2)>>2]*+g[(c[k>>2]|0)+(c[o>>2]<<2)>>2]);g[q>>2]=1.0>+g[q>>2]?1.0:+g[q>>2];c[o>>2]=(c[o>>2]|0)+1}i=h;return}function vd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;f=i;i=i+64|0;h=f+44|0;j=f+36|0;k=f+12|0;l=f+8|0;m=f+32|0;n=f+40|0;o=f+48|0;p=f+16|0;q=f;r=f+24|0;s=f+4|0;t=f+28|0;u=f+20|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;g[q>>2]=0.0;e=c[j>>2]|0;c[j>>2]=e+4;g[n>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[o>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[p>>2]=+g[e>>2];c[m>>2]=0;while(1){if((c[m>>2]|0)>=((c[l>>2]|0)-3|0))break;e=c[h>>2]|0;c[h>>2]=e+4;g[r>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[q>>2]=+g[e>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[r>>2]*+g[n>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[r>>2]*+g[o>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[r>>2]*+g[p>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[r>>2]*+g[q>>2];e=c[h>>2]|0;c[h>>2]=e+4;g[r>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[n>>2]=+g[e>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[r>>2]*+g[o>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[r>>2]*+g[p>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[r>>2]*+g[q>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[r>>2]*+g[n>>2];e=c[h>>2]|0;c[h>>2]=e+4;g[r>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[o>>2]=+g[e>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[r>>2]*+g[p>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[r>>2]*+g[q>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[r>>2]*+g[n>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[r>>2]*+g[o>>2];e=c[h>>2]|0;c[h>>2]=e+4;g[r>>2]=+g[e>>2];e=c[j>>2]|0;c[j>>2]=e+4;g[p>>2]=+g[e>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[r>>2]*+g[q>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[r>>2]*+g[n>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[r>>2]*+g[o>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[r>>2]*+g[p>>2];c[m>>2]=(c[m>>2]|0)+4}r=c[m>>2]|0;c[m>>2]=r+1;if((r|0)<(c[l>>2]|0)){r=c[h>>2]|0;c[h>>2]=r+4;g[s>>2]=+g[r>>2];r=c[j>>2]|0;c[j>>2]=r+4;g[q>>2]=+g[r>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[s>>2]*+g[n>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[s>>2]*+g[o>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[s>>2]*+g[p>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[s>>2]*+g[q>>2]}s=c[m>>2]|0;c[m>>2]=s+1;if((s|0)<(c[l>>2]|0)){s=c[h>>2]|0;c[h>>2]=s+4;g[t>>2]=+g[s>>2];s=c[j>>2]|0;c[j>>2]=s+4;g[n>>2]=+g[s>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[t>>2]*+g[o>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[t>>2]*+g[p>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[t>>2]*+g[q>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[t>>2]*+g[n>>2]}if((c[m>>2]|0)>=(c[l>>2]|0)){i=f;return}l=c[h>>2]|0;c[h>>2]=l+4;g[u>>2]=+g[l>>2];l=c[j>>2]|0;c[j>>2]=l+4;g[o>>2]=+g[l>>2];g[c[k>>2]>>2]=+g[c[k>>2]>>2]+ +g[u>>2]*+g[p>>2];g[(c[k>>2]|0)+4>>2]=+g[(c[k>>2]|0)+4>>2]+ +g[u>>2]*+g[q>>2];g[(c[k>>2]|0)+8>>2]=+g[(c[k>>2]|0)+8>>2]+ +g[u>>2]*+g[n>>2];g[(c[k>>2]|0)+12>>2]=+g[(c[k>>2]|0)+12>>2]+ +g[u>>2]*+g[o>>2];i=f;return}function wd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=(c[(c[d>>2]|0)+20>>2]|0)-(32-(aa(c[(c[d>>2]|0)+28>>2]|0)|0))|0;i=b;return a|0}function xd(a,e,f,g,h,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B){a=a|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0;r=r|0;s=s|0;t=t|0;u=u|0;v=v|0;w=w|0;x=x|0;y=y|0;z=z|0;A=A|0;B=B|0;var C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0;C=i;i=i+224|0;D=C+204|0;E=C+188|0;F=C+168|0;G=C+68|0;H=C+80|0;I=C+84|0;J=C+12|0;K=C+156|0;L=C+16|0;M=C+20|0;N=C+24|0;O=C+28|0;P=C+32|0;Q=C+36|0;R=C+40|0;S=C+152|0;T=C+44|0;U=C+48|0;V=C+52|0;W=C+56|0;X=C+60|0;Y=C+64|0;Z=C+176|0;$=C+184|0;aa=C+192|0;ba=C+200|0;ca=C+208|0;da=C+88|0;ea=C+92|0;fa=C+96|0;ga=C+100|0;ha=C+148|0;ia=C+104|0;ja=C+108|0;ka=C+112|0;la=C+116|0;ma=C+120|0;na=C+124|0;oa=C+128|0;pa=C+132|0;qa=C+136|0;ra=C+140|0;sa=C+144|0;ta=C+8|0;ua=C;va=C+160|0;wa=C+164|0;xa=C+4|0;ya=C+172|0;za=C+72|0;Aa=C+180|0;Ba=C+76|0;Ca=C+196|0;c[D>>2]=a;c[E>>2]=e;c[F>>2]=f;c[G>>2]=g;c[H>>2]=h;c[I>>2]=j;c[J>>2]=k;c[K>>2]=l;c[L>>2]=m;c[M>>2]=n;c[N>>2]=o;c[O>>2]=p;c[P>>2]=q;c[Q>>2]=r;c[R>>2]=s;c[S>>2]=t;c[T>>2]=u;c[U>>2]=v;c[V>>2]=w;c[W>>2]=x;c[X>>2]=y;c[Y>>2]=z;c[Z>>2]=A;c[$>>2]=B;c[ha>>2]=-1;c[ia>>2]=c[V>>2]<<3;c[ga>>2]=(c[V>>2]|0)>1&1;c[fa>>2]=c[W>>2]<<3;c[ba>>2]=0;c[ca>>2]=64;c[da>>2]=0;while(1){if((c[da>>2]|0)>=6)break;c[na>>2]=(c[ba>>2]|0)+(c[ca>>2]|0)>>1;c[aa>>2]=0;c[la>>2]=0;c[ea>>2]=c[F>>2];while(1){B=c[ea>>2]|0;c[ea>>2]=B+-1;if((B|0)<=(c[E>>2]|0))break;c[oa>>2]=(c[(c[H>>2]|0)+(c[ea>>2]<<2)>>2]|0)+((_(c[na>>2]|0,c[(c[I>>2]|0)+(c[ea>>2]<<2)>>2]|0)|0)>>6);if(!((c[la>>2]|0)!=0?1:(c[oa>>2]|0)>=(c[(c[J>>2]|0)+(c[ea>>2]<<2)>>2]|0))){if((c[oa>>2]|0)<(c[ia>>2]|0))continue;c[aa>>2]=(c[aa>>2]|0)+(c[ia>>2]|0);continue}c[la>>2]=1;if((c[oa>>2]|0)<(c[(c[K>>2]|0)+(c[ea>>2]<<2)>>2]|0))Da=c[oa>>2]|0;else Da=c[(c[K>>2]|0)+(c[ea>>2]<<2)>>2]|0;c[aa>>2]=(c[aa>>2]|0)+Da}B=c[na>>2]|0;if((c[aa>>2]|0)>(c[L>>2]|0))c[ca>>2]=B;else c[ba>>2]=B;c[da>>2]=(c[da>>2]|0)+1}c[aa>>2]=0;c[la>>2]=0;c[ea>>2]=c[F>>2];while(1){da=c[ea>>2]|0;c[ea>>2]=da+-1;if((da|0)<=(c[E>>2]|0))break;c[pa>>2]=(c[(c[H>>2]|0)+(c[ea>>2]<<2)>>2]|0)+((_(c[ba>>2]|0,c[(c[I>>2]|0)+(c[ea>>2]<<2)>>2]|0)|0)>>6);do if(!((c[la>>2]|0)!=0?1:(c[pa>>2]|0)>=(c[(c[J>>2]|0)+(c[ea>>2]<<2)>>2]|0)))if((c[pa>>2]|0)>=(c[ia>>2]|0)){c[pa>>2]=c[ia>>2];break}else{c[pa>>2]=0;break}else c[la>>2]=1;while(0);if((c[pa>>2]|0)<(c[(c[K>>2]|0)+(c[ea>>2]<<2)>>2]|0))Ea=c[pa>>2]|0;else Ea=c[(c[K>>2]|0)+(c[ea>>2]<<2)>>2]|0;c[pa>>2]=Ea;c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]=c[pa>>2];c[aa>>2]=(c[aa>>2]|0)+(c[pa>>2]|0)}c[ha>>2]=c[F>>2];while(1){c[ea>>2]=(c[ha>>2]|0)-1;if((c[ea>>2]|0)<=(c[G>>2]|0)){Fa=29;break}c[ja>>2]=(c[L>>2]|0)-(c[aa>>2]|0);c[ka>>2]=ye(c[ja>>2]|0,(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ha>>2]<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[E>>2]<<1)>>1]|0)|0)|0;pa=_((b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ha>>2]<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[E>>2]<<1)>>1]|0)|0,c[ka>>2]|0)|0;c[ja>>2]=(c[ja>>2]|0)-pa;if(((c[ja>>2]|0)-((b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ea>>2]<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[E>>2]<<1)>>1]|0))|0)>0)Ga=(c[ja>>2]|0)-((b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ea>>2]<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[E>>2]<<1)>>1]|0))|0;else Ga=0;c[sa>>2]=Ga;c[qa>>2]=(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ha>>2]<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ea>>2]<<1)>>1]|0);pa=(c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]|0)+(_(c[ka>>2]|0,c[qa>>2]|0)|0)|0;c[ra>>2]=pa+(c[sa>>2]|0);if((c[(c[J>>2]|0)+(c[ea>>2]<<2)>>2]|0)>((c[ia>>2]|0)+8|0))Ha=c[(c[J>>2]|0)+(c[ea>>2]<<2)>>2]|0;else Ha=(c[ia>>2]|0)+8|0;if((c[ra>>2]|0)>=(Ha|0)){if(!(c[Y>>2]|0)){if(ib(c[X>>2]|0,1)|0)break}else{if((c[ha>>2]|0)<=((c[E>>2]|0)+2|0)){Fa=40;break}pa=_((c[ea>>2]|0)<(c[Z>>2]|0)?7:9,c[qa>>2]|0)|0;if((c[ra>>2]|0)>(pa<<c[W>>2]<<3>>4|0)?(c[ea>>2]|0)<=(c[$>>2]|0):0){Fa=40;break}nb(c[X>>2]|0,0,1)}c[aa>>2]=(c[aa>>2]|0)+8;c[ra>>2]=(c[ra>>2]|0)-8}c[aa>>2]=(c[aa>>2]|0)-((c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]|0)+(c[P>>2]|0));if((c[P>>2]|0)>0)c[P>>2]=d[2928+((c[ea>>2]|0)-(c[E>>2]|0))>>0];c[aa>>2]=(c[aa>>2]|0)+(c[P>>2]|0);if((c[ra>>2]|0)>=(c[ia>>2]|0)){c[aa>>2]=(c[aa>>2]|0)+(c[ia>>2]|0);c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]=c[ia>>2]}else c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]=0;c[ha>>2]=(c[ha>>2]|0)+-1}if((Fa|0)==29)c[L>>2]=(c[L>>2]|0)+(c[N>>2]|0);else if((Fa|0)==40)nb(c[X>>2]|0,1,1);do if((c[P>>2]|0)>0){if(!(c[Y>>2]|0)){Fa=c[E>>2]|0;N=Fa+(kb(c[X>>2]|0,(c[ha>>2]|0)+1-(c[E>>2]|0)|0)|0)|0;c[c[O>>2]>>2]=N;break}if((c[c[O>>2]>>2]|0)<(c[ha>>2]|0))Ia=c[c[O>>2]>>2]|0;else Ia=c[ha>>2]|0;c[c[O>>2]>>2]=Ia;ob(c[X>>2]|0,(c[c[O>>2]>>2]|0)-(c[E>>2]|0)|0,(c[ha>>2]|0)+1-(c[E>>2]|0)|0)}else c[c[O>>2]>>2]=0;while(0);if((c[c[O>>2]>>2]|0)<=(c[E>>2]|0)){c[L>>2]=(c[L>>2]|0)+(c[R>>2]|0);c[R>>2]=0}do if((c[R>>2]|0)>0){Ia=c[X>>2]|0;if(c[Y>>2]|0){nb(Ia,c[c[Q>>2]>>2]|0,1);break}else{P=ib(Ia,1)|0;c[c[Q>>2]>>2]=P;break}}else c[c[Q>>2]>>2]=0;while(0);c[ja>>2]=(c[L>>2]|0)-(c[aa>>2]|0);c[ka>>2]=ye(c[ja>>2]|0,(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ha>>2]<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[E>>2]<<1)>>1]|0)|0)|0;aa=_((b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ha>>2]<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[E>>2]<<1)>>1]|0)|0,c[ka>>2]|0)|0;c[ja>>2]=(c[ja>>2]|0)-aa;c[ea>>2]=c[E>>2];while(1){if((c[ea>>2]|0)>=(c[ha>>2]|0))break;aa=_(c[ka>>2]|0,(b[(c[(c[D>>2]|0)+32>>2]|0)+((c[ea>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ea>>2]<<1)>>1]|0)|0)|0;L=(c[S>>2]|0)+(c[ea>>2]<<2)|0;c[L>>2]=(c[L>>2]|0)+aa;c[ea>>2]=(c[ea>>2]|0)+1}c[ea>>2]=c[E>>2];while(1){if((c[ea>>2]|0)>=(c[ha>>2]|0))break;if((c[ja>>2]|0)<((b[(c[(c[D>>2]|0)+32>>2]|0)+((c[ea>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ea>>2]<<1)>>1]|0)|0))Ja=c[ja>>2]|0;else Ja=(b[(c[(c[D>>2]|0)+32>>2]|0)+((c[ea>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ea>>2]<<1)>>1]|0)|0;c[ta>>2]=Ja;ka=(c[S>>2]|0)+(c[ea>>2]<<2)|0;c[ka>>2]=(c[ka>>2]|0)+(c[ta>>2]|0);c[ja>>2]=(c[ja>>2]|0)-(c[ta>>2]|0);c[ea>>2]=(c[ea>>2]|0)+1}c[ma>>2]=0;c[ea>>2]=c[E>>2];while(1){if((c[ea>>2]|0)>=(c[ha>>2]|0))break;c[ua>>2]=(b[(c[(c[D>>2]|0)+32>>2]|0)+((c[ea>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[D>>2]|0)+32>>2]|0)+(c[ea>>2]<<1)>>1]|0);c[va>>2]=c[ua>>2]<<c[W>>2];c[Aa>>2]=(c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]|0)+(c[ma>>2]|0);E=c[Aa>>2]|0;if((c[va>>2]|0)>1){if((E-(c[(c[K>>2]|0)+(c[ea>>2]<<2)>>2]|0)|0)>0)Ka=(c[Aa>>2]|0)-(c[(c[K>>2]|0)+(c[ea>>2]<<2)>>2]|0)|0;else Ka=0;c[za>>2]=Ka;c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]=(c[Aa>>2]|0)-(c[za>>2]|0);ta=_(c[V>>2]|0,c[va>>2]|0)|0;if((c[V>>2]|0)==2&(c[va>>2]|0)>2?(c[c[Q>>2]>>2]|0)==0:0)La=(c[ea>>2]|0)<(c[c[O>>2]>>2]|0);else La=0;c[wa>>2]=ta+(La?1:0);c[ya>>2]=_(c[wa>>2]|0,(b[(c[(c[D>>2]|0)+56>>2]|0)+(c[ea>>2]<<1)>>1]|0)+(c[fa>>2]|0)|0)|0;c[xa>>2]=(c[ya>>2]>>1)-((c[wa>>2]|0)*21|0);if((c[va>>2]|0)==2)c[xa>>2]=(c[xa>>2]|0)+(c[wa>>2]<<3>>2);if(((c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]|0)+(c[xa>>2]|0)|0)>=(c[wa>>2]<<1<<3|0)){if(((c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]|0)+(c[xa>>2]|0)|0)<((c[wa>>2]|0)*3<<3|0))c[xa>>2]=(c[xa>>2]|0)+(c[ya>>2]>>3)}else c[xa>>2]=(c[xa>>2]|0)+(c[ya>>2]>>2);if(0>((c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]|0)+(c[xa>>2]|0)+(c[wa>>2]<<2)|0))Ma=0;else Ma=(c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]|0)+(c[xa>>2]|0)+(c[wa>>2]<<2)|0;c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]=Ma;ta=(ye(c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0,c[wa>>2]|0)|0)>>>3;c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]=ta;ta=_(c[V>>2]|0,c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0)|0;if((ta|0)>(c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]>>3|0))c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]=c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]>>c[ga>>2]>>3;if((c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0)<8)Na=c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0;else Na=8;c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]=Na;ta=_(c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0,c[wa>>2]<<3)|0;c[(c[U>>2]|0)+(c[ea>>2]<<2)>>2]=(ta|0)>=((c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]|0)+(c[xa>>2]|0)|0)&1;ta=(_(c[V>>2]|0,c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0)|0)<<3;ja=(c[S>>2]|0)+(c[ea>>2]<<2)|0;c[ja>>2]=(c[ja>>2]|0)-ta}else{if(0>(E-(c[V>>2]<<3)|0))Oa=0;else Oa=(c[Aa>>2]|0)-(c[V>>2]<<3)|0;c[za>>2]=Oa;c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]=(c[Aa>>2]|0)-(c[za>>2]|0);c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]=0;c[(c[U>>2]|0)+(c[ea>>2]<<2)>>2]=1}if((c[za>>2]|0)>0){if((c[za>>2]>>(c[ga>>2]|0)+3|0)<(8-(c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0)|0))Pa=c[za>>2]>>(c[ga>>2]|0)+3;else Pa=8-(c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0)|0;c[Ba>>2]=Pa;E=(c[T>>2]|0)+(c[ea>>2]<<2)|0;c[E>>2]=(c[E>>2]|0)+(c[Ba>>2]|0);c[Ca>>2]=(_(c[Ba>>2]|0,c[V>>2]|0)|0)<<3;c[(c[U>>2]|0)+(c[ea>>2]<<2)>>2]=(c[Ca>>2]|0)>=((c[za>>2]|0)-(c[ma>>2]|0)|0)&1;c[za>>2]=(c[za>>2]|0)-(c[Ca>>2]|0)}c[ma>>2]=c[za>>2];c[ea>>2]=(c[ea>>2]|0)+1}c[c[M>>2]>>2]=c[ma>>2];while(1){if((c[ea>>2]|0)>=(c[F>>2]|0))break;c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]=c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]>>c[ga>>2]>>3;c[(c[S>>2]|0)+(c[ea>>2]<<2)>>2]=0;c[(c[U>>2]|0)+(c[ea>>2]<<2)>>2]=(c[(c[T>>2]|0)+(c[ea>>2]<<2)>>2]|0)<1&1;c[ea>>2]=(c[ea>>2]|0)+1}i=C;return c[ha>>2]|0}function yd(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;j=i;i=i+64|0;k=j+44|0;l=j+36|0;m=j+12|0;n=j+8|0;o=j+32|0;p=j+40|0;q=j+48|0;r=j+16|0;s=j;t=j+24|0;u=j+4|0;v=j+28|0;w=j+20|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;c[v>>2]=0;if((c[p>>2]|0)==0?1:(c[o>>2]<<1|0)>=(c[l>>2]|0)){i=j;return}c[w>>2]=c[5216+((c[p>>2]|0)-1<<2)>>2];g[t>>2]=+(c[l>>2]|0)*1.0/+((c[l>>2]|0)+(_(c[w>>2]|0,c[o>>2]|0)|0)|0);g[u>>2]=+g[t>>2]*+g[t>>2]*.5;g[r>>2]=+Q(+(+g[u>>2]*1.5707963705062866));g[s>>2]=+Q(+((1.0-+g[u>>2])*1.5707963705062866));a:do if((c[l>>2]|0)>=(c[n>>2]<<3|0)){c[v>>2]=1;while(1){u=_(c[v>>2]|0,c[v>>2]|0)|0;t=_(u+(c[v>>2]|0)|0,c[n>>2]|0)|0;if((t+(c[n>>2]>>2)|0)>=(c[l>>2]|0))break a;c[v>>2]=(c[v>>2]|0)+1}}while(0);c[l>>2]=we(c[l>>2]|0,c[n>>2]|0)|0;c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[n>>2]|0))break;if((c[m>>2]|0)>=0){t=(c[k>>2]|0)+((_(c[q>>2]|0,c[l>>2]|0)|0)<<2)|0;xe(t,c[l>>2]|0,1,+g[r>>2],-+g[s>>2]);if(c[v>>2]|0){t=(c[k>>2]|0)+((_(c[q>>2]|0,c[l>>2]|0)|0)<<2)|0;xe(t,c[l>>2]|0,c[v>>2]|0,+g[s>>2],-+g[r>>2])}}else{if(c[v>>2]|0){t=(c[k>>2]|0)+((_(c[q>>2]|0,c[l>>2]|0)|0)<<2)|0;xe(t,c[l>>2]|0,c[v>>2]|0,+g[s>>2],+g[r>>2])}t=(c[k>>2]|0)+((_(c[q>>2]|0,c[l>>2]|0)|0)<<2)|0;xe(t,c[l>>2]|0,1,+g[r>>2],+g[s>>2])}c[q>>2]=(c[q>>2]|0)+1}i=j;return}function zd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;e=i;i=i+48|0;f=e+28|0;g=e+16|0;h=e+4|0;j=e+8|0;k=e+32|0;l=e;m=e+12|0;n=e+24|0;o=e+20|0;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;if((c[j>>2]|0)<=1){c[f>>2]=1;p=c[f>>2]|0;i=e;return p|0}c[l>>2]=we(c[h>>2]|0,c[j>>2]|0)|0;c[k>>2]=0;c[m>>2]=0;do{c[o>>2]=0;c[n>>2]=0;do{h=_(c[m>>2]|0,c[l>>2]|0)|0;c[o>>2]=c[o>>2]|c[(c[g>>2]|0)+(h+(c[n>>2]|0)<<2)>>2];h=(c[n>>2]|0)+1|0;c[n>>2]=h}while((h|0)<(c[l>>2]|0));c[k>>2]=c[k>>2]|((c[o>>2]|0)!=0&1)<<c[m>>2];h=(c[m>>2]|0)+1|0;c[m>>2]=h}while((h|0)<(c[j>>2]|0));c[f>>2]=c[k>>2];p=c[f>>2]|0;i=e;return p|0}function Ad(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=+e;f=+f;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;h=i;i=i+32|0;j=h+4|0;k=h+16|0;l=h+8|0;m=h+20|0;n=h+28|0;o=h;p=h+12|0;q=h+24|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;g[m>>2]=e;g[n>>2]=f;g[p>>2]=+g[m>>2];f=1.0/+O(+(+g[p>>2]));g[q>>2]=f*+g[n>>2];c[o>>2]=0;do{g[(c[k>>2]|0)+(c[o>>2]<<2)>>2]=+g[q>>2]*+(c[(c[j>>2]|0)+(c[o>>2]<<2)>>2]|0);n=(c[o>>2]|0)+1|0;c[o>>2]=n}while((n|0)<(c[l>>2]|0));i=h;return}function Bd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0.0;e=i;i=i+32|0;f=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[f>>2]=a;c[h>>2]=b;c[j>>2]=d;g[l>>2]=0.0;c[k>>2]=0;while(1){m=+g[l>>2];if((c[k>>2]|0)>=(c[j>>2]|0))break;g[l>>2]=m+ +g[(c[f>>2]|0)+(c[k>>2]<<2)>>2]*+g[(c[h>>2]|0)+(c[k>>2]<<2)>>2];c[k>>2]=(c[k>>2]|0)+1}i=e;return +m}function Cd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;g=i;i=i+48|0;h=g+28|0;j=g+16|0;k=g+4|0;l=g+8|0;m=g+32|0;n=g;o=g+12|0;p=g+24|0;q=g+20|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[q>>2]=255;while(1){if((c[q>>2]|0)<=(c[l>>2]|0))break;c[q>>2]=c[q>>2]>>1}c[n>>2]=c[c[m>>2]>>2];c[o>>2]=0;while(1){r=c[n>>2]|0;if((c[o>>2]|0)>=(c[l>>2]|0))break;c[n>>2]=907633515+(_(r,196314165)|0);c[p>>2]=c[n>>2]>>24&c[q>>2];f=_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]>>16,(c[k>>2]>>4&65535)<<16>>16)|0;e=f+((_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]&65535,(c[k>>2]>>4&65535)<<16>>16)|0)>>16)|0;if((e+(_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]|0,(c[k>>2]>>4>>15)+1>>1)|0)|0)<=32767){e=_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]>>16,(c[k>>2]>>4&65535)<<16>>16)|0;f=e+((_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]&65535,(c[k>>2]>>4&65535)<<16>>16)|0)>>16)|0;if((f+(_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]|0,(c[k>>2]>>4>>15)+1>>1)|0)|0)<-32768)s=-32768;else{f=_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]>>16,(c[k>>2]>>4&65535)<<16>>16)|0;e=f+((_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]&65535,(c[k>>2]>>4&65535)<<16>>16)|0)>>16)|0;s=e+(_(c[(c[j>>2]|0)+(c[p>>2]<<2)>>2]|0,(c[k>>2]>>4>>15)+1>>1)|0)|0}}else s=32767;c[(c[h>>2]|0)+(c[o>>2]<<2)>>2]=(s&65535)<<16>>16;c[o>>2]=(c[o>>2]|0)+1}c[c[m>>2]>>2]=r;i=g;return}function Dd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;d=i;i=i+48|0;e=d+28|0;f=d+16|0;g=d+4|0;h=d+8|0;j=d+32|0;k=d;l=d+12|0;m=d+24|0;n=d+20|0;c[f>>2]=a;c[g>>2]=b;b=c[f>>2]|0;c[h>>2]=(ve((c[f>>2]|0)>0?b:0-b|0)|0)-1;c[l>>2]=c[f>>2]<<c[h>>2];c[k>>2]=536870911/(c[l>>2]>>16|0)|0;c[n>>2]=c[k>>2]<<16;f=_(c[l>>2]>>16,(c[k>>2]&65535)<<16>>16)|0;c[m>>2]=536870912-(f+((_(c[l>>2]&65535,(c[k>>2]&65535)<<16>>16)|0)>>16))<<3;l=_(c[m>>2]>>16,(c[k>>2]&65535)<<16>>16)|0;f=(c[n>>2]|0)+(l+((_(c[m>>2]&65535,(c[k>>2]&65535)<<16>>16)|0)>>16))|0;c[n>>2]=f+(_(c[m>>2]|0,(c[k>>2]>>15)+1>>1)|0);c[j>>2]=61-(c[h>>2]|0)-(c[g>>2]|0);g=c[j>>2]|0;if((c[j>>2]|0)>0)if((g|0)<32){c[e>>2]=c[n>>2]>>c[j>>2];o=c[e>>2]|0;i=d;return o|0}else{c[e>>2]=0;o=c[e>>2]|0;i=d;return o|0}h=c[n>>2]|0;k=0-(c[j>>2]|0)|0;do if((-2147483648>>0-g|0)>(2147483647>>0-(c[j>>2]|0)|0)){if((h|0)>(-2147483648>>k|0)){p=-2147483648>>0-(c[j>>2]|0);break}if((c[n>>2]|0)<(2147483647>>0-(c[j>>2]|0)|0)){p=2147483647>>0-(c[j>>2]|0);break}else{p=c[n>>2]|0;break}}else{if((h|0)>(2147483647>>k|0)){p=2147483647>>0-(c[j>>2]|0);break}if((c[n>>2]|0)<(-2147483648>>0-(c[j>>2]|0)|0)){p=-2147483648>>0-(c[j>>2]|0);break}else{p=c[n>>2]|0;break}}while(0);c[e>>2]=p<<0-(c[j>>2]|0);o=c[e>>2]|0;i=d;return o|0}function Ed(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;e=i;i=i+48|0;f=e+36|0;g=e+16|0;h=e;j=e+28|0;k=e+32|0;l=e+40|0;m=e+12|0;n=e+24|0;o=e+20|0;p=e+8|0;q=e+4|0;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;d=c[g>>2]|0;c[k>>2]=(ve((c[g>>2]|0)>0?d:0-d|0)|0)-1;c[o>>2]=c[g>>2]<<c[k>>2];g=c[h>>2]|0;c[l>>2]=(ve((c[h>>2]|0)>0?g:0-g|0)|0)-1;c[p>>2]=c[h>>2]<<c[l>>2];c[n>>2]=536870911/(c[p>>2]>>16|0)|0;h=_(c[o>>2]>>16,(c[n>>2]&65535)<<16>>16)|0;c[q>>2]=h+((_(c[o>>2]&65535,(c[n>>2]&65535)<<16>>16)|0)>>16);h=c[o>>2]|0;g=c[p>>2]|0;p=c[q>>2]|0;d=of(g|0,((g|0)<0)<<31>>31|0,p|0,((p|0)<0)<<31>>31|0)|0;p=af(d|0,C|0,32)|0;c[o>>2]=h-(p<<3);p=_(c[o>>2]>>16,(c[n>>2]&65535)<<16>>16)|0;c[q>>2]=(c[q>>2]|0)+(p+((_(c[o>>2]&65535,(c[n>>2]&65535)<<16>>16)|0)>>16));c[m>>2]=29+(c[k>>2]|0)-(c[l>>2]|0)-(c[j>>2]|0);j=c[m>>2]|0;if((c[m>>2]|0)>=0)if((j|0)<32){c[f>>2]=c[q>>2]>>c[m>>2];r=c[f>>2]|0;i=e;return r|0}else{c[f>>2]=0;r=c[f>>2]|0;i=e;return r|0}l=c[q>>2]|0;k=0-(c[m>>2]|0)|0;do if((-2147483648>>0-j|0)>(2147483647>>0-(c[m>>2]|0)|0)){if((l|0)>(-2147483648>>k|0)){s=-2147483648>>0-(c[m>>2]|0);break}if((c[q>>2]|0)<(2147483647>>0-(c[m>>2]|0)|0)){s=2147483647>>0-(c[m>>2]|0);break}else{s=c[q>>2]|0;break}}else{if((l|0)>(2147483647>>k|0)){s=2147483647>>0-(c[m>>2]|0);break}if((c[q>>2]|0)<(-2147483648>>0-(c[m>>2]|0)|0)){s=-2147483648>>0-(c[m>>2]|0);break}else{s=c[q>>2]|0;break}}while(0);c[f>>2]=s<<0-(c[m>>2]|0);r=c[f>>2]|0;i=e;return r|0}function Fd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)<(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function Gd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function Hd(e,f,g,h,j){e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;k=i;i=i+32|0;l=k+24|0;m=k+16|0;n=k+12|0;o=k+8|0;p=k+28|0;q=k;r=k+20|0;s=k+4|0;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[o>>2]=h;b[p>>1]=j;c[r>>2]=0;c[q>>2]=(b[p>>1]|0)-1;while(1){if((c[q>>2]|0)<0)break;c[s>>2]=(_((c[r>>2]&65535)<<16>>16,d[(c[n>>2]|0)+(c[q>>2]|0)>>0]|0)|0)>>8;c[r>>2]=a[(c[m>>2]|0)+(c[q>>2]|0)>>0]<<10;p=c[r>>2]|0;if((c[r>>2]|0)<=0){if((p|0)<0)c[r>>2]=(c[r>>2]|0)+102}else c[r>>2]=p-102;p=_(c[r>>2]>>16,(c[o>>2]&65535)<<16>>16)|0;c[r>>2]=(c[s>>2]|0)+(p+((_(c[r>>2]&65535,(c[o>>2]&65535)<<16>>16)|0)>>16));b[(c[l>>2]|0)+(c[q>>2]<<1)>>1]=c[r>>2];c[q>>2]=(c[q>>2]|0)+-1}i=k;return}function Id(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0;b=i;i=i+32|0;d=b+16|0;e=b+12|0;f=b+8|0;g=b+4|0;h=b;c[e>>2]=a;if((c[e>>2]|0)<=0){c[d>>2]=0;j=c[d>>2]|0;i=b;return j|0}se(c[e>>2]|0,g,h);if(c[g>>2]&1)c[f>>2]=32768;else c[f>>2]=46214;c[f>>2]=c[f>>2]>>(c[g>>2]>>1);g=_(c[f>>2]>>16,(((c[h>>2]&65535)<<16>>16)*213&65535)<<16>>16)|0;c[f>>2]=(c[f>>2]|0)+(g+((_(c[f>>2]&65535,(((c[h>>2]&65535)<<16>>16)*213&65535)<<16>>16)|0)>>16));c[d>>2]=c[f>>2];j=c[d>>2]|0;i=b;return j|0}function Jd(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0;f=i;i=i+160|0;g=f+68|0;h=f+100|0;j=f+40|0;k=f+44|0;l=f+92|0;m=f+8|0;n=f+12|0;o=f+72|0;p=f+16|0;q=f+20|0;r=f+88|0;s=f+96|0;t=f+104|0;u=f+112|0;v=f+48|0;w=f+116|0;x=f+52|0;y=f+56|0;z=f+60|0;A=f+64|0;B=f+4|0;C=f+120|0;D=f+84|0;E=f+24|0;F=f+128|0;G=f;H=f+32|0;I=f+108|0;J=f+80|0;K=f+76|0;c[g>>2]=a;c[h>>2]=d;c[j>>2]=e;c[G>>2]=(c[g>>2]|0)+4168;e=(c[(c[g>>2]|0)+2336>>2]|0)+(c[(c[g>>2]|0)+2328>>2]|0)|0;c[I>>2]=ua()|0;d=i;i=i+((1*(e<<2)|0)+15&-16)|0;e=i;i=i+((1*(c[(c[g>>2]|0)+2336>>2]<<1)|0)+15&-16)|0;c[H>>2]=c[(c[G>>2]|0)+72>>2]>>6;c[H+4>>2]=c[(c[G>>2]|0)+72+4>>2]>>6;if(c[(c[g>>2]|0)+2376>>2]|0){L=(c[G>>2]|0)+14|0;M=L+32|0;do{b[L>>1]=0;L=L+2|0}while((L|0)<(M|0))}me(w,q,x,r,(c[g>>2]|0)+4|0,H,c[(c[g>>2]|0)+2332>>2]|0,c[(c[g>>2]|0)+2324>>2]|0);a=c[(c[G>>2]|0)+84>>2]|0;if((c[w>>2]>>c[r>>2]|0)<(c[x>>2]>>c[q>>2]|0)){q=ne(0,(_(a-1|0,c[(c[G>>2]|0)+88>>2]|0)|0)-128|0)|0;c[y>>2]=(c[g>>2]|0)+4+(q<<2)}else{q=ne(0,(_(a,c[(c[G>>2]|0)+88>>2]|0)|0)-128|0)|0;c[y>>2]=(c[g>>2]|0)+4+(q<<2)}c[D>>2]=(c[G>>2]|0)+4;b[C>>1]=b[(c[G>>2]|0)+56>>1]|0;c[t>>2]=b[5192+((oe(1,c[(c[g>>2]|0)+4160>>2]|0)|0)<<1)>>1];q=(c[(c[g>>2]|0)+4164>>2]|0)==2;a=oe(1,c[(c[g>>2]|0)+4160>>2]|0)|0;if(q)c[u>>2]=b[5200+(a<<1)>>1];else c[u>>2]=b[5208+(a<<1)>>1];ec((c[G>>2]|0)+14|0,c[(c[g>>2]|0)+2340>>2]|0,64881);df(F|0,(c[G>>2]|0)+14|0,c[(c[g>>2]|0)+2340>>2]<<1|0)|0;do if(!(c[(c[g>>2]|0)+4160>>2]|0)){b[C>>1]=16384;if((c[(c[g>>2]|0)+4164>>2]|0)!=2){c[J>>2]=ic((c[G>>2]|0)+14|0,c[(c[g>>2]|0)+2340>>2]|0)|0;c[K>>2]=qe(134217728,c[J>>2]|0)|0;c[K>>2]=Md(4194304,c[K>>2]|0)|0;c[K>>2]=c[K>>2]<<3;a=_(c[K>>2]>>16,(c[u>>2]&65535)<<16>>16)|0;c[u>>2]=a+((_(c[K>>2]&65535,(c[u>>2]&65535)<<16>>16)|0)>>16)>>14;break}c[k>>2]=0;while(1){if((c[k>>2]|0)>=5)break;b[C>>1]=(b[C>>1]|0)-(b[(c[D>>2]|0)+(c[k>>2]<<1)>>1]|0);c[k>>2]=(c[k>>2]|0)+1}b[C>>1]=pe(3277,b[C>>1]|0)|0;b[C>>1]=(_(b[C>>1]|0,b[(c[G>>2]|0)+68>>1]|0)|0)>>14}while(0);c[s>>2]=c[(c[G>>2]|0)+52>>2];c[n>>2]=(c[c[G>>2]>>2]>>7)+1>>1;c[p>>2]=c[(c[g>>2]|0)+2336>>2];c[o>>2]=(c[(c[g>>2]|0)+2336>>2]|0)-(c[n>>2]|0)-(c[(c[g>>2]|0)+2340>>2]|0)-2;hc(e+(c[o>>2]<<1)|0,(c[g>>2]|0)+1348+(c[o>>2]<<1)|0,F,(c[(c[g>>2]|0)+2336>>2]|0)-(c[o>>2]|0)|0,c[(c[g>>2]|0)+2340>>2]|0);c[v>>2]=re(c[(c[G>>2]|0)+72+4>>2]|0,46)|0;c[v>>2]=(c[v>>2]|0)<1073741823?c[v>>2]|0:1073741823;c[k>>2]=(c[o>>2]|0)+(c[(c[g>>2]|0)+2340>>2]|0);while(1){if((c[k>>2]|0)>=(c[(c[g>>2]|0)+2336>>2]|0))break;K=_(c[v>>2]>>16,b[e+(c[k>>2]<<1)>>1]|0)|0;J=K+((_(c[v>>2]&65535,b[e+(c[k>>2]<<1)>>1]|0)|0)>>16)|0;c[d+(c[k>>2]<<2)>>2]=J;c[k>>2]=(c[k>>2]|0)+1}c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[(c[g>>2]|0)+2324>>2]|0))break;c[z>>2]=d+((c[p>>2]|0)-(c[n>>2]|0)+2<<2);c[k>>2]=0;while(1){if((c[k>>2]|0)>=(c[(c[g>>2]|0)+2332>>2]|0))break;c[B>>2]=2;e=_(c[c[z>>2]>>2]>>16,b[c[D>>2]>>1]|0)|0;c[B>>2]=(c[B>>2]|0)+(e+((_(c[c[z>>2]>>2]&65535,b[c[D>>2]>>1]|0)|0)>>16));e=_(c[(c[z>>2]|0)+-4>>2]>>16,b[(c[D>>2]|0)+2>>1]|0)|0;c[B>>2]=(c[B>>2]|0)+(e+((_(c[(c[z>>2]|0)+-4>>2]&65535,b[(c[D>>2]|0)+2>>1]|0)|0)>>16));e=_(c[(c[z>>2]|0)+-8>>2]>>16,b[(c[D>>2]|0)+4>>1]|0)|0;c[B>>2]=(c[B>>2]|0)+(e+((_(c[(c[z>>2]|0)+-8>>2]&65535,b[(c[D>>2]|0)+4>>1]|0)|0)>>16));e=_(c[(c[z>>2]|0)+-12>>2]>>16,b[(c[D>>2]|0)+6>>1]|0)|0;c[B>>2]=(c[B>>2]|0)+(e+((_(c[(c[z>>2]|0)+-12>>2]&65535,b[(c[D>>2]|0)+6>>1]|0)|0)>>16));e=_(c[(c[z>>2]|0)+-16>>2]>>16,b[(c[D>>2]|0)+8>>1]|0)|0;c[B>>2]=(c[B>>2]|0)+(e+((_(c[(c[z>>2]|0)+-16>>2]&65535,b[(c[D>>2]|0)+8>>1]|0)|0)>>16));c[z>>2]=(c[z>>2]|0)+4;c[s>>2]=907633515+(_(c[s>>2]|0,196314165)|0);c[o>>2]=c[s>>2]>>25&127;e=_(c[(c[y>>2]|0)+(c[o>>2]<<2)>>2]>>16,b[C>>1]|0)|0;v=(c[B>>2]|0)+(e+((_(c[(c[y>>2]|0)+(c[o>>2]<<2)>>2]&65535,b[C>>1]|0)|0)>>16))<<2;c[d+(c[p>>2]<<2)>>2]=v;c[p>>2]=(c[p>>2]|0)+1;c[k>>2]=(c[k>>2]|0)+1}c[l>>2]=0;while(1){if((c[l>>2]|0)>=5)break;v=(_((c[t>>2]&65535)<<16>>16,b[(c[D>>2]|0)+(c[l>>2]<<1)>>1]|0)|0)>>15&65535;b[(c[D>>2]|0)+(c[l>>2]<<1)>>1]=v;c[l>>2]=(c[l>>2]|0)+1}b[C>>1]=(_(b[C>>1]|0,(c[u>>2]&65535)<<16>>16)|0)>>15;c[c[G>>2]>>2]=(c[c[G>>2]>>2]|0)+(((c[c[G>>2]>>2]>>16)*655|0)+((c[c[G>>2]>>2]&65535)*655>>16));v=qe(c[c[G>>2]>>2]|0,((c[(c[g>>2]|0)+2316>>2]&65535)<<16>>16)*18<<8)|0;c[c[G>>2]>>2]=v;c[n>>2]=(c[c[G>>2]>>2]>>7)+1>>1;c[m>>2]=(c[m>>2]|0)+1}c[E>>2]=d+((c[(c[g>>2]|0)+2336>>2]|0)-16<<2);L=c[E>>2]|0;d=(c[g>>2]|0)+1284|0;M=L+64|0;do{c[L>>2]=c[d>>2];L=L+4|0;d=d+4|0}while((L|0)<(M|0));c[k>>2]=0;while(1){N=c[g>>2]|0;if((c[k>>2]|0)>=(c[(c[g>>2]|0)+2328>>2]|0))break;c[A>>2]=c[N+2340>>2]>>1;m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-1<<2)>>2]>>16,b[F>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-1<<2)>>2]&65535,b[F>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-2<<2)>>2]>>16,b[F+2>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-2<<2)>>2]&65535,b[F+2>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-3<<2)>>2]>>16,b[F+4>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-3<<2)>>2]&65535,b[F+4>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-4<<2)>>2]>>16,b[F+6>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-4<<2)>>2]&65535,b[F+6>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-5<<2)>>2]>>16,b[F+8>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-5<<2)>>2]&65535,b[F+8>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-6<<2)>>2]>>16,b[F+10>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-6<<2)>>2]&65535,b[F+10>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-7<<2)>>2]>>16,b[F+12>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-7<<2)>>2]&65535,b[F+12>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-8<<2)>>2]>>16,b[F+14>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-8<<2)>>2]&65535,b[F+14>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-9<<2)>>2]>>16,b[F+16>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-9<<2)>>2]&65535,b[F+16>>1]|0)|0)>>16));m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-10<<2)>>2]>>16,b[F+18>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-10<<2)>>2]&65535,b[F+18>>1]|0)|0)>>16));c[l>>2]=10;while(1){if((c[l>>2]|0)>=(c[(c[g>>2]|0)+2340>>2]|0))break;m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-(c[l>>2]|0)-1<<2)>>2]>>16,b[F+(c[l>>2]<<1)>>1]|0)|0;c[A>>2]=(c[A>>2]|0)+(m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)-(c[l>>2]|0)-1<<2)>>2]&65535,b[F+(c[l>>2]<<1)>>1]|0)|0)>>16));c[l>>2]=(c[l>>2]|0)+1}c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]=(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0)+(c[A>>2]<<4);m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;u=m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;if(((u+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1|0)<=32767){u=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;m=u+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;if(((m+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1|0)<-32768)O=-32768;else{m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;u=m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;O=(u+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1}}else O=32767;if((O|0)<=32767){u=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;m=u+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;if(((m+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1|0)<=32767){m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;u=m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;if(((u+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1|0)<-32768)P=-32768;else{u=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;m=u+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;P=(m+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1}}else P=32767;if((P|0)>=-32768){m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;u=m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;if(((u+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1|0)<=32767){u=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;m=u+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;if(((m+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1|0)<-32768)Q=-32768;else{m=_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]>>16,(c[H+4>>2]&65535)<<16>>16)|0;u=m+((_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]&65535,(c[H+4>>2]&65535)<<16>>16)|0)>>16)|0;Q=(u+(_(c[(c[E>>2]|0)+(16+(c[k>>2]|0)<<2)>>2]|0,(c[H+4>>2]>>15)+1>>1)|0)>>7)+1>>1}}else Q=32767}else Q=-32768}else Q=32767;b[(c[j>>2]|0)+(c[k>>2]<<1)>>1]=Q;c[k>>2]=(c[k>>2]|0)+1}L=N+1284|0;d=(c[E>>2]|0)+(c[(c[g>>2]|0)+2328>>2]<<2)|0;M=L+64|0;do{c[L>>2]=c[d>>2];L=L+4|0;d=d+4|0}while((L|0)<(M|0));c[(c[G>>2]|0)+52>>2]=c[s>>2];b[(c[G>>2]|0)+56>>1]=b[C>>1]|0;c[k>>2]=0;while(1){if((c[k>>2]|0)>=4)break;c[(c[h>>2]|0)+(c[k>>2]<<2)>>2]=c[n>>2];c[k>>2]=(c[k>>2]|0)+1}ka(c[I>>2]|0);i=f;return}function Kd(d,e){d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;f=i;i=i+48|0;g=f+36|0;h=f+16|0;j=f;k=f+28|0;l=f+32|0;m=f+40|0;n=f+12|0;o=f+24|0;p=f+20|0;q=f+8|0;r=f+4|0;c[g>>2]=d;c[h>>2]=e;c[n>>2]=(c[g>>2]|0)+4168;c[(c[g>>2]|0)+4164>>2]=a[(c[g>>2]|0)+2736+29>>0];c[j>>2]=0;a:do if((a[(c[g>>2]|0)+2736+29>>0]|0)==2){c[m>>2]=0;while(1){e=_(c[m>>2]|0,c[(c[g>>2]|0)+2332>>2]|0)|0;if((e|0)>=(c[(c[h>>2]|0)+((c[(c[g>>2]|0)+2324>>2]|0)-1<<2)>>2]|0))break;if((c[m>>2]|0)==(c[(c[g>>2]|0)+2324>>2]|0))break;c[k>>2]=0;c[l>>2]=0;while(1){if((c[l>>2]|0)>=5)break;c[k>>2]=(c[k>>2]|0)+(b[(c[h>>2]|0)+96+((((c[(c[g>>2]|0)+2324>>2]|0)-1-(c[m>>2]|0)|0)*5|0)+(c[l>>2]|0)<<1)>>1]|0);c[l>>2]=(c[l>>2]|0)+1}if((c[k>>2]|0)>(c[j>>2]|0)){c[j>>2]=c[k>>2];e=(c[n>>2]|0)+4|0;d=(c[h>>2]|0)+96+((((c[(c[g>>2]|0)+2324>>2]|0)-1-(c[m>>2]|0)&65535)<<16>>16)*5<<1)|0;b[e>>1]=b[d>>1]|0;b[e+2>>1]=b[d+2>>1]|0;b[e+4>>1]=b[d+4>>1]|0;b[e+6>>1]=b[d+6>>1]|0;b[e+8>>1]=b[d+8>>1]|0;c[c[n>>2]>>2]=c[(c[h>>2]|0)+((c[(c[g>>2]|0)+2324>>2]|0)-1-(c[m>>2]|0)<<2)>>2]<<8}c[m>>2]=(c[m>>2]|0)+1}d=(c[n>>2]|0)+4|0;b[d>>1]=0;b[d+2>>1]=0;b[d+4>>1]=0;b[d+6>>1]=0;b[d+8>>1]=0;b[(c[n>>2]|0)+4+4>>1]=c[j>>2];if((c[j>>2]|0)<11469){c[p>>2]=11744256;c[o>>2]=(c[p>>2]|0)/(((c[j>>2]|0)>1?c[j>>2]|0:1)|0)|0;c[l>>2]=0;while(1){if((c[l>>2]|0)>=5)break a;d=(_(b[(c[n>>2]|0)+4+(c[l>>2]<<1)>>1]|0,(c[o>>2]&65535)<<16>>16)|0)>>10&65535;b[(c[n>>2]|0)+4+(c[l>>2]<<1)>>1]=d;c[l>>2]=(c[l>>2]|0)+1}}if((c[j>>2]|0)>15565){c[r>>2]=255016960;c[q>>2]=(c[r>>2]|0)/(((c[j>>2]|0)>1?c[j>>2]|0:1)|0)|0;c[l>>2]=0;while(1){if((c[l>>2]|0)>=5)break a;d=(_(b[(c[n>>2]|0)+4+(c[l>>2]<<1)>>1]|0,(c[q>>2]&65535)<<16>>16)|0)>>14&65535;b[(c[n>>2]|0)+4+(c[l>>2]<<1)>>1]=d;c[l>>2]=(c[l>>2]|0)+1}}}else{c[c[n>>2]>>2]=((c[(c[g>>2]|0)+2316>>2]&65535)<<16>>16)*18<<8;d=(c[n>>2]|0)+4|0;b[d>>1]=0;b[d+2>>1]=0;b[d+4>>1]=0;b[d+6>>1]=0;b[d+8>>1]=0}while(0);df((c[n>>2]|0)+14|0,(c[h>>2]|0)+32+32|0,c[(c[g>>2]|0)+2340>>2]<<1|0)|0;b[(c[n>>2]|0)+68>>1]=c[(c[h>>2]|0)+136>>2];l=(c[n>>2]|0)+72|0;q=(c[h>>2]|0)+16+((c[(c[g>>2]|0)+2324>>2]|0)-2<<2)|0;c[l>>2]=c[q>>2];c[l+4>>2]=c[q+4>>2];c[(c[n>>2]|0)+88>>2]=c[(c[g>>2]|0)+2332>>2];c[(c[n>>2]|0)+84>>2]=c[(c[g>>2]|0)+2324>>2];i=f;return}function Ld(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b;c[d>>2]=a;if(!(c[d>>2]|0)){e=32;i=b;return e|0}e=32-(32-(aa(c[d>>2]|0)|0))|0;i=b;return e|0}function Md(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function Nd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0;b=i;i=i+32|0;d=b+16|0;e=b+12|0;f=b+8|0;g=b+4|0;h=b;c[e>>2]=a;if((c[e>>2]|0)<=0){c[d>>2]=0;j=c[d>>2]|0;i=b;return j|0}ke(c[e>>2]|0,g,h);if(c[g>>2]&1)c[f>>2]=32768;else c[f>>2]=46214;c[f>>2]=c[f>>2]>>(c[g>>2]>>1);g=_(c[f>>2]>>16,(((c[h>>2]&65535)<<16>>16)*213&65535)<<16>>16)|0;c[f>>2]=(c[f>>2]|0)+(g+((_(c[f>>2]&65535,(((c[h>>2]&65535)<<16>>16)*213&65535)<<16>>16)|0)>>16));c[d>>2]=c[f>>2];j=c[d>>2]|0;i=b;return j|0}function Od(a,e,f,g,h){a=a|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0;j=i;i=i+32|0;k=j+16|0;l=j+12|0;m=j+8|0;n=j+4|0;o=j;c[k>>2]=a;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[o>>2]=h;if((c[n>>2]|0)>0){h=(jb(c[m>>2]|0,(c[o>>2]|0)+(d[1472+(c[n>>2]|0)>>0]|0)|0,8)|0)&65535;b[c[k>>2]>>1]=h;b[c[l>>2]>>1]=(c[n>>2]|0)-(b[c[k>>2]>>1]|0);i=j;return}else{b[c[k>>2]>>1]=0;b[c[l>>2]>>1]=0;i=j;return}}function Pd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0;d=i;i=i+64|0;e=d+44|0;f=d+36|0;g=d+12|0;h=d+8|0;j=d+32|0;k=d+40|0;l=d+48|0;m=d+16|0;n=d;o=d+24|0;p=d+4|0;q=d+28|0;r=d+20|0;c[f>>2]=a;c[g>>2]=b;c[r>>2]=(c[f>>2]|0)+((c[g>>2]&1)<<6);c[l>>2]=1073741824;c[h>>2]=(c[g>>2]|0)-1;while(1){if((c[h>>2]|0)<=0)break;if((c[(c[r>>2]|0)+(c[h>>2]<<2)>>2]|0)>16773022){s=5;break}if((c[(c[r>>2]|0)+(c[h>>2]<<2)>>2]|0)<-16773022){s=5;break}c[m>>2]=0-(c[(c[r>>2]|0)+(c[h>>2]<<2)>>2]<<7);g=c[m>>2]|0;b=c[m>>2]|0;a=of(g|0,((g|0)<0)<<31>>31|0,b|0,((b|0)<0)<<31>>31|0)|0;b=af(a|0,C|0,32)|0;c[n>>2]=1073741824-b;b=c[n>>2]|0;c[k>>2]=32-(ie((c[n>>2]|0)>0?b:0-b|0)|0);c[o>>2]=je(c[n>>2]|0,(c[k>>2]|0)+30|0)|0;b=c[l>>2]|0;a=c[n>>2]|0;g=of(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;a=af(g|0,C|0,32)|0;c[l>>2]=a<<2;c[q>>2]=c[r>>2];c[r>>2]=(c[f>>2]|0)+((c[h>>2]&1)<<6);c[j>>2]=0;while(1){if((c[j>>2]|0)>=(c[h>>2]|0))break;a=c[(c[q>>2]|0)+(c[j>>2]<<2)>>2]|0;g=c[(c[q>>2]|0)+((c[h>>2]|0)-(c[j>>2]|0)-1<<2)>>2]|0;b=c[m>>2]|0;t=of(g|0,((g|0)<0)<<31>>31|0,b|0,((b|0)<0)<<31>>31|0)|0;b=af(t|0,C|0,30)|0;t=ef(b|0,C|0,1,0)|0;b=af(t|0,C|0,1)|0;c[p>>2]=a-b;b=(c[k>>2]|0)==1;a=c[p>>2]|0;t=c[o>>2]|0;g=of(a|0,((a|0)<0)<<31>>31|0,t|0,((t|0)<0)<<31>>31|0)|0;t=C;if(b){b=af(g|0,t|0,1)|0;a=C;u=c[p>>2]|0;v=c[o>>2]|0;w=of(u|0,((u|0)<0)<<31>>31|0,v|0,((v|0)<0)<<31>>31|0)|0;v=ef(b|0,a|0,w&1|0,0)|0;x=v;y=C}else{v=af(g|0,t|0,(c[k>>2]|0)-1|0)|0;t=ef(v|0,C|0,1,0)|0;v=af(t|0,C|0,1)|0;x=v;y=C}c[(c[r>>2]|0)+(c[j>>2]<<2)>>2]=x;c[j>>2]=(c[j>>2]|0)+1}c[h>>2]=(c[h>>2]|0)+-1}if((s|0)==5){c[e>>2]=0;z=c[e>>2]|0;i=d;return z|0}if((c[c[r>>2]>>2]|0)<=16773022?(c[c[r>>2]>>2]|0)>=-16773022:0){c[m>>2]=0-(c[c[r>>2]>>2]<<7);r=c[m>>2]|0;s=c[m>>2]|0;m=of(r|0,((r|0)<0)<<31>>31|0,s|0,((s|0)<0)<<31>>31|0)|0;s=af(m|0,C|0,32)|0;c[n>>2]=1073741824-s;s=c[l>>2]|0;m=c[n>>2]|0;n=of(s|0,((s|0)<0)<<31>>31|0,m|0,((m|0)<0)<<31>>31|0)|0;m=af(n|0,C|0,32)|0;c[l>>2]=m<<2;c[e>>2]=c[l>>2];z=c[e>>2]|0;i=d;return z|0}c[e>>2]=0;z=c[e>>2]|0;i=d;return z|0}function Qd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[c[f>>2]>>2]=65536;c[(c[f>>2]|0)+4>>2]=0-(c[c[g>>2]>>2]|0);c[j>>2]=1;while(1){if((c[j>>2]|0)>=(c[h>>2]|0))break;c[l>>2]=c[(c[g>>2]|0)+(c[j>>2]<<1<<2)>>2];d=c[(c[f>>2]|0)+((c[j>>2]|0)-1<<2)>>2]<<1;b=c[l>>2]|0;a=c[(c[f>>2]|0)+(c[j>>2]<<2)>>2]|0;m=of(b|0,((b|0)<0)<<31>>31|0,a|0,((a|0)<0)<<31>>31|0)|0;a=af(m|0,C|0,15)|0;m=ef(a|0,C|0,1,0)|0;a=af(m|0,C|0,1)|0;c[(c[f>>2]|0)+((c[j>>2]|0)+1<<2)>>2]=d-a;c[k>>2]=c[j>>2];while(1){if((c[k>>2]|0)<=1)break;a=c[(c[f>>2]|0)+((c[k>>2]|0)-2<<2)>>2]|0;d=c[l>>2]|0;m=c[(c[f>>2]|0)+((c[k>>2]|0)-1<<2)>>2]|0;b=of(d|0,((d|0)<0)<<31>>31|0,m|0,((m|0)<0)<<31>>31|0)|0;m=af(b|0,C|0,15)|0;b=ef(m|0,C|0,1,0)|0;m=af(b|0,C|0,1)|0;b=(c[f>>2]|0)+(c[k>>2]<<2)|0;c[b>>2]=(c[b>>2]|0)+(a-m);c[k>>2]=(c[k>>2]|0)+-1}m=(c[f>>2]|0)+4|0;c[m>>2]=(c[m>>2]|0)-(c[l>>2]|0);c[j>>2]=(c[j>>2]|0)+1}i=e;return}function Rd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function Sd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)<(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0} +function Ia(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function Ja(){return i|0}function Ka(a){a=a|0;i=a}function La(a,b){a=a|0;b=b|0;i=a;j=b}function Ma(a,b){a=a|0;b=b|0;if(!n){n=a;o=b}}function Na(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Oa(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Pa(a){a=a|0;C=a}function Qa(){return C|0}function Ra(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=(_(1664525,c[d>>2]|0)|0)+1013904223|0;i=b;return a|0}function Sa(a,d,e,f,h,j,k,l,m){a=a|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0.0;n=i;i=i+80|0;o=n+68|0;p=n+44|0;q=n+24|0;r=n+32|0;s=n+12|0;t=n+16|0;u=n+48|0;v=n+56|0;w=n+64|0;x=n+72|0;y=n+36|0;z=n+8|0;A=n;B=n+4|0;C=n+40|0;D=n+20|0;E=n+52|0;F=n+28|0;G=n+60|0;c[o>>2]=a;c[p>>2]=d;c[q>>2]=e;c[r>>2]=f;c[s>>2]=h;c[t>>2]=j;c[u>>2]=k;c[v>>2]=l;c[w>>2]=m;c[C>>2]=c[(c[o>>2]|0)+32>>2];c[y>>2]=_(c[u>>2]|0,c[(c[o>>2]|0)+44>>2]|0)|0;c[z>>2]=_(c[u>>2]|0,b[(c[C>>2]|0)+(c[t>>2]<<1)>>1]|0)|0;if((c[v>>2]|0)!=1){if((c[z>>2]|0)<((c[y>>2]|0)/(c[v>>2]|0)|0|0))H=c[z>>2]|0;else H=(c[y>>2]|0)/(c[v>>2]|0)|0;c[z>>2]=H}if(c[w>>2]|0){c[z>>2]=0;c[t>>2]=0;c[s>>2]=0}c[A>>2]=c[q>>2];c[B>>2]=(c[p>>2]|0)+((_(c[u>>2]|0,b[(c[C>>2]|0)+(c[s>>2]<<1)>>1]|0)|0)<<2);c[x>>2]=0;while(1){if((c[x>>2]|0)>=(_(c[u>>2]|0,b[(c[C>>2]|0)+(c[s>>2]<<1)>>1]|0)|0))break;p=c[A>>2]|0;c[A>>2]=p+4;g[p>>2]=0.0;c[x>>2]=(c[x>>2]|0)+1}c[x>>2]=c[s>>2];while(1){if((c[x>>2]|0)>=(c[t>>2]|0))break;c[D>>2]=_(c[u>>2]|0,b[(c[C>>2]|0)+(c[x>>2]<<1)>>1]|0)|0;c[E>>2]=_(c[u>>2]|0,b[(c[C>>2]|0)+((c[x>>2]|0)+1<<1)>>1]|0)|0;g[G>>2]=+g[(c[r>>2]|0)+(c[x>>2]<<2)>>2]+ +g[40+(c[x>>2]<<2)>>2];g[F>>2]=+X(+(+g[G>>2]*.6931471805599453));do{s=c[B>>2]|0;c[B>>2]=s+4;I=+g[s>>2]*+g[F>>2];s=c[A>>2]|0;c[A>>2]=s+4;g[s>>2]=I;s=(c[D>>2]|0)+1|0;c[D>>2]=s}while((s|0)<(c[E>>2]|0));c[x>>2]=(c[x>>2]|0)+1}bf((c[q>>2]|0)+(c[z>>2]<<2)|0,0,(c[y>>2]|0)-(c[z>>2]|0)<<2|0)|0;i=n;return}function Ta(a,e,f,h,j,k,l,m,n,o,p,q,r){a=a|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0;r=r|0;var s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0.0,W=0.0,Y=0.0;s=i;i=i+112|0;t=s+100|0;u=s+92|0;v=s+44|0;w=s+48|0;x=s+84|0;y=s+16|0;z=s+20|0;A=s+24|0;B=s+28|0;C=s+32|0;D=s+80|0;E=s+88|0;F=s+96|0;G=s+104|0;H=s+52|0;I=s+56|0;J=s+60|0;K=s+64|0;L=s+68|0;M=s+12|0;N=s+8|0;P=s+72|0;Q=s+36|0;R=s+76|0;S=s+4|0;T=s;U=s+40|0;c[t>>2]=a;c[u>>2]=e;c[v>>2]=f;c[w>>2]=h;c[x>>2]=j;c[y>>2]=k;c[z>>2]=l;c[A>>2]=m;c[B>>2]=n;c[C>>2]=o;c[D>>2]=p;c[E>>2]=q;c[F>>2]=r;c[H>>2]=c[z>>2];while(1){if((c[H>>2]|0)>=(c[A>>2]|0))break;c[K>>2]=(b[(c[(c[t>>2]|0)+32>>2]|0)+((c[H>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[t>>2]|0)+32>>2]|0)+(c[H>>2]<<1)>>1]|0);z=Rc(1+(c[(c[E>>2]|0)+(c[H>>2]<<2)>>2]|0)|0,(b[(c[(c[t>>2]|0)+32>>2]|0)+((c[H>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[t>>2]|0)+32>>2]|0)+(c[H>>2]<<1)>>1]|0)|0)|0;c[N>>2]=z>>>(c[w>>2]|0);g[L>>2]=+X(+(+(c[N>>2]|0)*-.125*.6931471805599453))*.5;g[M>>2]=1.0/+O(+(+(c[K>>2]<<c[w>>2]|0)));c[G>>2]=0;do{c[U>>2]=0;z=_(c[G>>2]|0,c[(c[t>>2]|0)+8>>2]|0)|0;g[Q>>2]=+g[(c[C>>2]|0)+(z+(c[H>>2]|0)<<2)>>2];z=_(c[G>>2]|0,c[(c[t>>2]|0)+8>>2]|0)|0;g[R>>2]=+g[(c[D>>2]|0)+(z+(c[H>>2]|0)<<2)>>2];if((c[x>>2]|0)==1){if(+g[Q>>2]>+g[(c[C>>2]|0)+((c[(c[t>>2]|0)+8>>2]|0)+(c[H>>2]|0)<<2)>>2])V=+g[Q>>2];else V=+g[(c[C>>2]|0)+((c[(c[t>>2]|0)+8>>2]|0)+(c[H>>2]|0)<<2)>>2];g[Q>>2]=V;if(+g[R>>2]>+g[(c[D>>2]|0)+((c[(c[t>>2]|0)+8>>2]|0)+(c[H>>2]|0)<<2)>>2])W=+g[R>>2];else W=+g[(c[D>>2]|0)+((c[(c[t>>2]|0)+8>>2]|0)+(c[H>>2]|0)<<2)>>2];g[R>>2]=W}z=_(c[G>>2]|0,c[(c[t>>2]|0)+8>>2]|0)|0;g[S>>2]=+g[(c[B>>2]|0)+(z+(c[H>>2]|0)<<2)>>2]-(+g[Q>>2]<+g[R>>2]?+g[Q>>2]:+g[R>>2]);g[S>>2]=0.0>+g[S>>2]?0.0:+g[S>>2];g[T>>2]=+X(+(-+g[S>>2]*.6931471805599453))*2.0;if((c[w>>2]|0)==3)g[T>>2]=+g[T>>2]*1.4142135381698608;g[T>>2]=+g[L>>2]<+g[T>>2]?+g[L>>2]:+g[T>>2];g[T>>2]=+g[T>>2]*+g[M>>2];z=(c[u>>2]|0)+((_(c[G>>2]|0,c[y>>2]|0)|0)<<2)|0;c[P>>2]=z+(b[(c[(c[t>>2]|0)+32>>2]|0)+(c[H>>2]<<1)>>1]<<c[w>>2]<<2);c[J>>2]=0;while(1){if((c[J>>2]|0)>=(1<<c[w>>2]|0))break;z=_(c[H>>2]|0,c[x>>2]|0)|0;if(!(d[(c[v>>2]|0)+(z+(c[G>>2]|0))>>0]&1<<c[J>>2])){c[I>>2]=0;while(1){if((c[I>>2]|0)>=(c[K>>2]|0))break;c[F>>2]=Ra(c[F>>2]|0)|0;Y=+g[T>>2];g[(c[P>>2]|0)+((c[I>>2]<<c[w>>2])+(c[J>>2]|0)<<2)>>2]=(c[F>>2]&32768|0)!=0?Y:-Y;c[I>>2]=(c[I>>2]|0)+1}c[U>>2]=1}c[J>>2]=(c[J>>2]|0)+1}if(c[U>>2]|0)Ib(c[P>>2]|0,c[K>>2]<<c[w>>2],1.0);z=(c[G>>2]|0)+1|0;c[G>>2]=z}while((z|0)<(c[x>>2]|0));c[H>>2]=(c[H>>2]|0)+1}i=s;return}function Ua(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0;e=i;i=i+32|0;f=e+8|0;h=e+16|0;j=e+20|0;k=e+24|0;l=e+4|0;m=e;n=e+12|0;c[f>>2]=a;c[h>>2]=b;c[j>>2]=d;c[h>>2]=c[h>>2]>>1;c[k>>2]=0;while(1){if((c[k>>2]|0)>=(c[j>>2]|0))break;c[l>>2]=0;while(1){if((c[l>>2]|0)>=(c[h>>2]|0))break;d=_(c[j>>2]<<1,c[l>>2]|0)|0;g[m>>2]=+g[(c[f>>2]|0)+(d+(c[k>>2]|0)<<2)>>2]*.7071067690849304;d=_(c[j>>2]|0,(c[l>>2]<<1)+1|0)|0;g[n>>2]=+g[(c[f>>2]|0)+(d+(c[k>>2]|0)<<2)>>2]*.7071067690849304;d=_(c[j>>2]<<1,c[l>>2]|0)|0;g[(c[f>>2]|0)+(d+(c[k>>2]|0)<<2)>>2]=+g[m>>2]+ +g[n>>2];d=_(c[j>>2]|0,(c[l>>2]<<1)+1|0)|0;g[(c[f>>2]|0)+(d+(c[k>>2]|0)<<2)>>2]=+g[m>>2]-+g[n>>2];c[l>>2]=(c[l>>2]|0)+1}c[k>>2]=(c[k>>2]|0)+1}i=e;return}function Va(e,f,h,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z){e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0;r=r|0;s=s|0;t=t|0;u=u|0;v=v|0;w=w|0;x=x|0;y=y|0;z=z|0;var A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0;A=i;i=i+240|0;B=A+96|0;C=A+92|0;D=A+84|0;E=A+200|0;F=A+224|0;G=A+216|0;H=A+20|0;I=A+24|0;J=A+28|0;K=A+32|0;L=A+36|0;M=A+40|0;N=A+44|0;O=A+48|0;P=A+52|0;Q=A+56|0;R=A+60|0;S=A+64|0;T=A+68|0;U=A+72|0;V=A+196|0;W=A+204|0;X=A+212|0;Y=A+220|0;Z=A+228|0;$=A+232|0;aa=A+100|0;ba=A+104|0;ca=A+108|0;da=A+112|0;ea=A+116|0;fa=A+120|0;ga=A+124|0;ha=A+128|0;ia=A+168|0;ja=A+172|0;la=A+176|0;ma=A+180|0;na=A+184|0;oa=A+188|0;pa=A+16|0;qa=A+8|0;ra=A;sa=A+12|0;ta=A+4|0;va=A+192|0;wa=A+76|0;xa=A+80|0;ya=A+208|0;za=A+88|0;c[B>>2]=e;c[C>>2]=f;c[D>>2]=h;c[E>>2]=j;c[F>>2]=k;c[G>>2]=l;c[H>>2]=m;c[I>>2]=n;c[J>>2]=o;c[K>>2]=p;c[L>>2]=q;c[M>>2]=r;c[N>>2]=s;c[O>>2]=t;c[P>>2]=u;c[Q>>2]=v;c[R>>2]=w;c[S>>2]=x;c[T>>2]=y;c[U>>2]=z;c[X>>2]=c[(c[C>>2]|0)+32>>2];c[da>>2]=1;c[ea>>2]=(c[G>>2]|0)!=0?2:1;c[ga>>2]=((c[B>>2]|0)!=0^1)&1;c[ba>>2]=1<<c[S>>2];c[aa>>2]=(c[K>>2]|0)!=0?c[ba>>2]|0:1;c[fa>>2]=_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[D>>2]<<1)>>1]|0)|0;K=_(c[ba>>2]|0,b[(c[X>>2]|0)+((c[(c[C>>2]|0)+8>>2]|0)-1<<1)>>1]|0)|0;z=_(c[ea>>2]|0,K-(c[fa>>2]|0)|0)|0;c[ia>>2]=ua()|0;K=i;i=i+((1*(z<<2)|0)+15&-16)|0;c[Y>>2]=K;K=(c[Y>>2]|0)+((_(c[ba>>2]|0,b[(c[X>>2]|0)+((c[(c[C>>2]|0)+8>>2]|0)-1<<1)>>1]|0)|0)<<2)|0;c[Z>>2]=K+(0-(c[fa>>2]|0)<<2);c[$>>2]=(c[F>>2]|0)+((_(c[ba>>2]|0,b[(c[X>>2]|0)+((c[(c[C>>2]|0)+8>>2]|0)-1<<1)>>1]|0)|0)<<2);c[ca>>2]=0;c[ha+32>>2]=c[I>>2];c[ha+24>>2]=c[R>>2];c[ha>>2]=c[B>>2];c[ha+12>>2]=c[N>>2];c[ha+4>>2]=c[C>>2];c[ha+36>>2]=c[c[U>>2]>>2];c[ha+16>>2]=c[L>>2];c[V>>2]=c[D>>2];while(1){if((c[V>>2]|0)>=(c[E>>2]|0))break;c[oa>>2]=-1;c[ra>>2]=0;c[ha+8>>2]=c[V>>2];c[va>>2]=(c[V>>2]|0)==((c[E>>2]|0)-1|0)&1;c[pa>>2]=(c[F>>2]|0)+((_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0)<<2);if(c[G>>2]|0)c[qa>>2]=(c[G>>2]|0)+((_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0)<<2);else c[qa>>2]=0;B=_(c[ba>>2]|0,b[(c[X>>2]|0)+((c[V>>2]|0)+1<<1)>>1]|0)|0;c[ma>>2]=B-(_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0);c[ja>>2]=db(c[R>>2]|0)|0;if((c[V>>2]|0)!=(c[D>>2]|0))c[Q>>2]=(c[Q>>2]|0)-(c[ja>>2]|0);c[W>>2]=(c[P>>2]|0)-(c[ja>>2]|0)-1;c[ha+28>>2]=c[W>>2];if((c[V>>2]|0)<=((c[T>>2]|0)-1|0)){if(3<((c[T>>2]|0)-(c[V>>2]|0)|0))Aa=3;else Aa=(c[T>>2]|0)-(c[V>>2]|0)|0;c[na>>2]=Sc(c[Q>>2]|0,Aa)|0;if(((c[W>>2]|0)+1|0)<((c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[na>>2]|0)|0))Ba=(c[W>>2]|0)+1|0;else Ba=(c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[na>>2]|0)|0;do if(16383>=(Ba|0))if(((c[W>>2]|0)+1|0)<((c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[na>>2]|0)|0)){Ca=(c[W>>2]|0)+1|0;break}else{Ca=(c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[na>>2]|0)|0;break}else Ca=16383;while(0);do if(0<=(Ca|0)){if(((c[W>>2]|0)+1|0)<((c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[na>>2]|0)|0))Da=(c[W>>2]|0)+1|0;else Da=(c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[na>>2]|0)|0;if(16383>=(Da|0))if(((c[W>>2]|0)+1|0)<((c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[na>>2]|0)|0)){Ea=(c[W>>2]|0)+1|0;break}else{Ea=(c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[na>>2]|0)|0;break}else Ea=16383}else Ea=0;while(0);c[la>>2]=Ea}else c[la>>2]=0;if(((c[ga>>2]|0)!=0?(B=_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0,(B-(c[ma>>2]|0)|0)>=(_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[D>>2]<<1)>>1]|0)|0)):0)?(c[da>>2]|0)!=0|(c[ca>>2]|0)==0:0)c[ca>>2]=c[V>>2];c[ra>>2]=c[(c[O>>2]|0)+(c[V>>2]<<2)>>2];c[ha+20>>2]=c[ra>>2];if((c[V>>2]|0)>=(c[(c[C>>2]|0)+12>>2]|0)){c[pa>>2]=c[Y>>2];if(c[G>>2]|0)c[qa>>2]=c[Y>>2];c[$>>2]=0}if((c[V>>2]|0)==((c[E>>2]|0)-1|0))c[$>>2]=0;if((c[ca>>2]|0)!=0?(c[L>>2]|0)!=3|(c[aa>>2]|0)>1|(c[ra>>2]|0)<0:0){B=_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[ca>>2]<<1)>>1]|0)|0;if(0>(B-(c[fa>>2]|0)-(c[ma>>2]|0)|0))Fa=0;else{B=_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[ca>>2]<<1)>>1]|0)|0;Fa=B-(c[fa>>2]|0)-(c[ma>>2]|0)|0}c[oa>>2]=Fa;c[wa>>2]=c[ca>>2];do{B=c[ba>>2]|0;I=(c[wa>>2]|0)+-1|0;c[wa>>2]=I;K=_(B,b[(c[X>>2]|0)+(I<<1)>>1]|0)|0}while((K|0)>((c[oa>>2]|0)+(c[fa>>2]|0)|0));c[xa>>2]=(c[ca>>2]|0)-1;do{K=c[ba>>2]|0;I=(c[xa>>2]|0)+1|0;c[xa>>2]=I;B=_(K,b[(c[X>>2]|0)+(I<<1)>>1]|0)|0}while((B|0)<((c[oa>>2]|0)+(c[fa>>2]|0)+(c[ma>>2]|0)|0));c[ta>>2]=0;c[sa>>2]=0;c[ya>>2]=c[wa>>2];do{B=(_(c[ya>>2]|0,c[ea>>2]|0)|0)+0|0;c[sa>>2]=c[sa>>2]|d[(c[H>>2]|0)+B>>0];B=_(c[ya>>2]|0,c[ea>>2]|0)|0;c[ta>>2]=c[ta>>2]|d[(c[H>>2]|0)+(B+(c[ea>>2]|0)-1)>>0];B=(c[ya>>2]|0)+1|0;c[ya>>2]=B}while((B|0)<(c[xa>>2]|0))}else{B=(1<<c[aa>>2])-1|0;c[ta>>2]=B;c[sa>>2]=B}a:do if(((c[M>>2]|0)!=0?(c[V>>2]|0)==(c[N>>2]|0):0)?(c[M>>2]=0,(c[ga>>2]|0)!=0):0){c[za>>2]=0;while(1){B=_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0;if((c[za>>2]|0)>=(B-(c[fa>>2]|0)|0))break a;g[(c[Y>>2]|0)+(c[za>>2]<<2)>>2]=(+g[(c[Y>>2]|0)+(c[za>>2]<<2)>>2]+ +g[(c[Z>>2]|0)+(c[za>>2]<<2)>>2])*.5;c[za>>2]=(c[za>>2]|0)+1}}while(0);if(c[M>>2]|0){if((c[oa>>2]|0)!=-1)Ga=(c[Y>>2]|0)+(c[oa>>2]<<2)|0;else Ga=0;if(c[va>>2]|0)Ha=0;else{B=(c[Y>>2]|0)+((_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0)<<2)|0;Ha=B+(0-(c[fa>>2]|0)<<2)|0}c[sa>>2]=Tc(ha,c[pa>>2]|0,c[ma>>2]|0,(c[la>>2]|0)/2|0,c[aa>>2]|0,Ga,c[S>>2]|0,Ha,1.0,c[$>>2]|0,c[sa>>2]|0)|0;if((c[oa>>2]|0)!=-1)Ia=(c[Z>>2]|0)+(c[oa>>2]<<2)|0;else Ia=0;if(c[va>>2]|0)Ja=0;else{B=(c[Z>>2]|0)+((_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0)<<2)|0;Ja=B+(0-(c[fa>>2]|0)<<2)|0}c[ta>>2]=Tc(ha,c[qa>>2]|0,c[ma>>2]|0,(c[la>>2]|0)/2|0,c[aa>>2]|0,Ia,c[S>>2]|0,Ja,1.0,c[$>>2]|0,c[ta>>2]|0)|0}else{B=c[pa>>2]|0;if(c[qa>>2]|0){if((c[oa>>2]|0)!=-1)Ka=(c[Y>>2]|0)+(c[oa>>2]<<2)|0;else Ka=0;if(c[va>>2]|0)La=0;else{I=(c[Y>>2]|0)+((_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0)<<2)|0;La=I+(0-(c[fa>>2]|0)<<2)|0}c[sa>>2]=Uc(ha,B,c[qa>>2]|0,c[ma>>2]|0,c[la>>2]|0,c[aa>>2]|0,Ka,c[S>>2]|0,La,c[$>>2]|0,c[sa>>2]|c[ta>>2])|0}else{if((c[oa>>2]|0)!=-1)Ma=(c[Y>>2]|0)+(c[oa>>2]<<2)|0;else Ma=0;if(c[va>>2]|0)Na=0;else{I=(c[Y>>2]|0)+((_(c[ba>>2]|0,b[(c[X>>2]|0)+(c[V>>2]<<1)>>1]|0)|0)<<2)|0;Na=I+(0-(c[fa>>2]|0)<<2)|0}c[sa>>2]=Tc(ha,B,c[ma>>2]|0,c[la>>2]|0,c[aa>>2]|0,Ma,c[S>>2]|0,Na,1.0,c[$>>2]|0,c[sa>>2]|c[ta>>2])|0}c[ta>>2]=c[sa>>2]}B=(_(c[V>>2]|0,c[ea>>2]|0)|0)+0|0;a[(c[H>>2]|0)+B>>0]=c[sa>>2];B=_(c[V>>2]|0,c[ea>>2]|0)|0;a[(c[H>>2]|0)+(B+(c[ea>>2]|0)-1)>>0]=c[ta>>2];c[Q>>2]=(c[Q>>2]|0)+((c[(c[J>>2]|0)+(c[V>>2]<<2)>>2]|0)+(c[ja>>2]|0));c[da>>2]=(c[la>>2]|0)>(c[ma>>2]<<3|0)&1;c[V>>2]=(c[V>>2]|0)+1}c[c[U>>2]>>2]=c[ha+36>>2];ka(c[ia>>2]|0);i=A;return}function Wa(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;a=c[d>>2]|0;if((a|0)==8e3)c[e>>2]=6;else if((a|0)==48e3)c[e>>2]=1;else if((a|0)==24e3)c[e>>2]=2;else if((a|0)==16e3)c[e>>2]=3;else if((a|0)==12e3)c[e>>2]=4;else c[e>>2]=0;i=b;return c[e>>2]|0}function Xa(a,b,d,e,f,h,j,k,l,m,n){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=+h;j=+j;k=k|0;l=l|0;m=m|0;n=n|0;var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;o=i;i=i+96|0;p=o+44|0;q=o+40|0;r=o+4|0;s=o+84|0;t=o;u=o+16|0;v=o+20|0;w=o+24|0;x=o+64|0;y=o+72|0;z=o+80|0;A=o+88|0;B=o+92|0;C=o+48|0;D=o+52|0;E=o+56|0;F=o+8|0;G=o+60|0;H=o+28|0;I=o+12|0;J=o+32|0;K=o+68|0;L=o+36|0;M=o+76|0;c[p>>2]=a;c[q>>2]=b;c[r>>2]=d;c[s>>2]=e;c[t>>2]=f;g[u>>2]=h;g[v>>2]=j;c[w>>2]=k;c[x>>2]=l;c[y>>2]=m;c[z>>2]=n;if(+g[u>>2]==0.0&+g[v>>2]==0.0){if((c[q>>2]|0)==(c[p>>2]|0)){i=o;return}ff(c[p>>2]|0,c[q>>2]|0,(c[t>>2]<<2)+0|0)|0;i=o;return}g[B>>2]=+g[u>>2]*+g[2376+((c[w>>2]|0)*12|0)>>2];g[C>>2]=+g[u>>2]*+g[2376+((c[w>>2]|0)*12|0)+4>>2];g[D>>2]=+g[u>>2]*+g[2376+((c[w>>2]|0)*12|0)+8>>2];g[E>>2]=+g[v>>2]*+g[2376+((c[x>>2]|0)*12|0)>>2];g[F>>2]=+g[v>>2]*+g[2376+((c[x>>2]|0)*12|0)+4>>2];g[G>>2]=+g[v>>2]*+g[2376+((c[x>>2]|0)*12|0)+8>>2];g[I>>2]=+g[(c[q>>2]|0)+(0-(c[s>>2]|0)+1<<2)>>2];g[J>>2]=+g[(c[q>>2]|0)+(0-(c[s>>2]|0)<<2)>>2];g[K>>2]=+g[(c[q>>2]|0)+(0-(c[s>>2]|0)-1<<2)>>2];g[L>>2]=+g[(c[q>>2]|0)+(0-(c[s>>2]|0)-2<<2)>>2];if((+g[u>>2]==+g[v>>2]?(c[r>>2]|0)==(c[s>>2]|0):0)?(c[w>>2]|0)==(c[x>>2]|0):0)c[z>>2]=0;c[A>>2]=0;while(1){if((c[A>>2]|0)>=(c[z>>2]|0))break;g[H>>2]=+g[(c[q>>2]|0)+((c[A>>2]|0)-(c[s>>2]|0)+2<<2)>>2];g[M>>2]=+g[(c[y>>2]|0)+(c[A>>2]<<2)>>2]*+g[(c[y>>2]|0)+(c[A>>2]<<2)>>2];g[(c[p>>2]|0)+(c[A>>2]<<2)>>2]=+g[(c[q>>2]|0)+(c[A>>2]<<2)>>2]+(1.0-+g[M>>2])*+g[B>>2]*+g[(c[q>>2]|0)+((c[A>>2]|0)-(c[r>>2]|0)<<2)>>2]+(1.0-+g[M>>2])*+g[C>>2]*(+g[(c[q>>2]|0)+((c[A>>2]|0)-(c[r>>2]|0)+1<<2)>>2]+ +g[(c[q>>2]|0)+((c[A>>2]|0)-(c[r>>2]|0)-1<<2)>>2])+(1.0-+g[M>>2])*+g[D>>2]*(+g[(c[q>>2]|0)+((c[A>>2]|0)-(c[r>>2]|0)+2<<2)>>2]+ +g[(c[q>>2]|0)+((c[A>>2]|0)-(c[r>>2]|0)-2<<2)>>2])+ +g[M>>2]*+g[E>>2]*+g[J>>2]+ +g[M>>2]*+g[F>>2]*(+g[I>>2]+ +g[K>>2])+ +g[M>>2]*+g[G>>2]*(+g[H>>2]+ +g[L>>2]);g[L>>2]=+g[K>>2];g[K>>2]=+g[J>>2];g[J>>2]=+g[I>>2];g[I>>2]=+g[H>>2];c[A>>2]=(c[A>>2]|0)+1}if(!(+g[v>>2]==0.0)){Vc((c[p>>2]|0)+(c[A>>2]<<2)|0,(c[q>>2]|0)+(c[A>>2]<<2)|0,c[s>>2]|0,(c[t>>2]|0)-(c[A>>2]|0)|0,+g[E>>2],+g[F>>2],+g[G>>2]);i=o;return}if((c[q>>2]|0)==(c[p>>2]|0)){i=o;return}ff((c[p>>2]|0)+(c[z>>2]<<2)|0,(c[q>>2]|0)+(c[z>>2]<<2)|0,((c[t>>2]|0)-(c[z>>2]|0)<<2)+0|0)|0;i=o;return}function Ya(a,e,f,g){a=a|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0;h=i;i=i+32|0;j=h+20|0;k=h+16|0;l=h+12|0;m=h+8|0;n=h+4|0;o=h;c[j>>2]=a;c[k>>2]=e;c[l>>2]=f;c[m>>2]=g;c[n>>2]=0;while(1){if((c[n>>2]|0)>=(c[(c[j>>2]|0)+8>>2]|0))break;c[o>>2]=(b[(c[(c[j>>2]|0)+32>>2]|0)+((c[n>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[j>>2]|0)+32>>2]|0)+(c[n>>2]<<1)>>1]|0)<<c[l>>2];g=_(c[(c[j>>2]|0)+8>>2]|0,(c[l>>2]<<1)+(c[m>>2]|0)-1|0)|0;f=_((d[(c[(c[j>>2]|0)+92+12>>2]|0)+(g+(c[n>>2]|0))>>0]|0)+64|0,c[m>>2]|0)|0;g=(_(f,c[o>>2]|0)|0)>>2;c[(c[k>>2]|0)+(c[n>>2]<<2)>>2]=g;c[n>>2]=(c[n>>2]|0)+1}i=h;return}function Za(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=ub(48e3,960,0)|0;a=Wc(c[e>>2]|0,c[d>>2]|0)|0;i=b;return a|0}function _a(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;d=c[g>>2]|0;b=ub(48e3,960,0)|0;c[k>>2]=Xc(d,b,c[j>>2]|0)|0;if(c[k>>2]|0){c[f>>2]=c[k>>2];l=c[f>>2]|0;i=e;return l|0}k=Wa(c[h>>2]|0)|0;c[(c[g>>2]|0)+16>>2]=k;if(!(c[(c[g>>2]|0)+16>>2]|0)){c[f>>2]=-1;l=c[f>>2]|0;i=e;return l|0}else{c[f>>2]=0;l=c[f>>2]|0;i=e;return l|0}return 0}function $a(a,d,e,f,h,j,k){a=a|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0.0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0.0,Ca=0.0,Da=0;l=i;i=i+288|0;m=l+164|0;n=l+148|0;o=l+4|0;p=l+8|0;q=l+144|0;r=l+272|0;s=l+160|0;t=l+24|0;u=l+28|0;v=l+32|0;w=l+36|0;x=l+40|0;y=l+44|0;z=l+48|0;A=l+96|0;B=l+104|0;C=l+112|0;D=l+116|0;E=l+120|0;F=l+124|0;G=l+128|0;H=l+132|0;I=l+136|0;J=l+140|0;K=l+244|0;L=l+252|0;M=l+260|0;N=l+268|0;O=l+276|0;P=l+280|0;Q=l+168|0;R=l+172|0;S=l+176|0;T=l+180|0;U=l+184|0;V=l+188|0;W=l+192|0;X=l+196|0;Y=l+200|0;Z=l+204|0;$=l+208|0;aa=l+212|0;ba=l+216|0;ca=l+220|0;da=l+224|0;ea=l+228|0;fa=l+232|0;ga=l+236|0;ha=l+16|0;ia=l;ja=l+12|0;la=l+240|0;ma=l+248|0;na=l+152|0;oa=l+256|0;pa=l+20|0;qa=l+156|0;ra=l+264|0;c[n>>2]=a;c[o>>2]=d;c[p>>2]=e;c[q>>2]=f;c[r>>2]=h;c[s>>2]=j;c[t>>2]=k;c[K>>2]=c[(c[n>>2]|0)+8>>2];c[U>>2]=0;c[V>>2]=0;c[ba>>2]=0;c[da>>2]=c[(c[n>>2]|0)+12>>2];c[ea>>2]=c[c[n>>2]>>2];c[fa>>2]=c[(c[ea>>2]|0)+8>>2];c[ga>>2]=c[(c[ea>>2]|0)+4>>2];c[ha>>2]=c[(c[ea>>2]|0)+32>>2];c[N>>2]=c[(c[n>>2]|0)+20>>2];c[O>>2]=c[(c[n>>2]|0)+24>>2];c[r>>2]=_(c[r>>2]|0,c[(c[n>>2]|0)+16>>2]|0)|0;c[C>>2]=(c[n>>2]|0)+84+((_(2048+(c[ga>>2]|0)|0,c[K>>2]|0)|0)<<2);c[D>>2]=(c[C>>2]|0)+((c[K>>2]|0)*24<<2);c[E>>2]=(c[D>>2]|0)+(c[fa>>2]<<1<<2);c[F>>2]=(c[E>>2]|0)+(c[fa>>2]<<1<<2);c[G>>2]=(c[F>>2]|0)+(c[fa>>2]<<1<<2);c[L>>2]=0;while(1){if((c[L>>2]|0)>(c[(c[ea>>2]|0)+36>>2]|0))break;if((c[(c[ea>>2]|0)+44>>2]<<c[L>>2]|0)==(c[r>>2]|0))break;c[L>>2]=(c[L>>2]|0)+1}if((c[L>>2]|0)>(c[(c[ea>>2]|0)+36>>2]|0)){c[m>>2]=-1;sa=c[m>>2]|0;i=l;return sa|0}c[M>>2]=1<<c[L>>2];if((c[p>>2]|0)<0|(c[p>>2]|0)>1275|(c[q>>2]|0)==0){c[m>>2]=-1;sa=c[m>>2]|0;i=l;return sa|0}c[w>>2]=_(c[M>>2]|0,c[(c[ea>>2]|0)+44>>2]|0)|0;c[u>>2]=0;do{C=(c[n>>2]|0)+84+((_(c[u>>2]|0,2048+(c[ga>>2]|0)|0)|0)<<2)|0;c[A+(c[u>>2]<<2)>>2]=C;c[B+(c[u>>2]<<2)>>2]=(c[A+(c[u>>2]<<2)>>2]|0)+8192+(0-(c[w>>2]|0)<<2);C=(c[u>>2]|0)+1|0;c[u>>2]=C}while((C|0)<(c[K>>2]|0));c[P>>2]=c[O>>2];if((c[P>>2]|0)>(c[(c[ea>>2]|0)+12>>2]|0))c[P>>2]=c[(c[ea>>2]|0)+12>>2];if((c[o>>2]|0)==0|(c[p>>2]|0)<=1){Yc(c[n>>2]|0,c[w>>2]|0,c[L>>2]|0);Zc(B,c[q>>2]|0,c[w>>2]|0,c[K>>2]|0,c[(c[n>>2]|0)+16>>2]|0,(c[ea>>2]|0)+16|0,(c[n>>2]|0)+76|0,c[t>>2]|0);c[m>>2]=(c[r>>2]|0)/(c[(c[n>>2]|0)+16>>2]|0)|0;sa=c[m>>2]|0;i=l;return sa|0}if(!(c[s>>2]|0)){eb(z,c[o>>2]|0,c[p>>2]|0);c[s>>2]=z}a:do if((c[da>>2]|0)==1){c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[fa>>2]|0))break a;if(+g[(c[D>>2]|0)+(c[v>>2]<<2)>>2]>+g[(c[D>>2]|0)+((c[fa>>2]|0)+(c[v>>2]|0)<<2)>>2])ta=+g[(c[D>>2]|0)+(c[v>>2]<<2)>>2];else ta=+g[(c[D>>2]|0)+((c[fa>>2]|0)+(c[v>>2]|0)<<2)>>2];g[(c[D>>2]|0)+(c[v>>2]<<2)>>2]=ta;c[v>>2]=(c[v>>2]|0)+1}}while(0);c[W>>2]=c[p>>2]<<3;c[Y>>2]=_c(c[s>>2]|0)|0;do if((c[Y>>2]|0)<(c[W>>2]|0))if((c[Y>>2]|0)==1){c[ca>>2]=ib(c[s>>2]|0,15)|0;break}else{c[ca>>2]=0;break}else c[ca>>2]=1;while(0);if(c[ca>>2]|0){c[Y>>2]=c[p>>2]<<3;z=c[Y>>2]|0;o=z-(_c(c[s>>2]|0)|0)|0;z=(c[s>>2]|0)+20|0;c[z>>2]=(c[z>>2]|0)+o}g[T>>2]=0.0;c[S>>2]=0;c[$>>2]=0;if((c[N>>2]|0)==0?((c[Y>>2]|0)+16|0)<=(c[W>>2]|0):0){if(ib(c[s>>2]|0,1)|0){c[ja>>2]=kb(c[s>>2]|0,6)|0;o=16<<c[ja>>2];c[S>>2]=o+(lb(c[s>>2]|0,4+(c[ja>>2]|0)|0)|0)-1;c[ia>>2]=lb(c[s>>2]|0,3)|0;ja=(_c(c[s>>2]|0)|0)+2|0;if((ja|0)<=(c[W>>2]|0))c[$>>2]=jb(c[s>>2]|0,2416,2)|0;g[T>>2]=+((c[ia>>2]|0)+1|0)*.09375}c[Y>>2]=_c(c[s>>2]|0)|0}if((c[L>>2]|0)>0?((c[Y>>2]|0)+3|0)<=(c[W>>2]|0):0){c[I>>2]=ib(c[s>>2]|0,3)|0;c[Y>>2]=_c(c[s>>2]|0)|0}else c[I>>2]=0;if(c[I>>2]|0)c[H>>2]=c[M>>2];else c[H>>2]=0;if(((c[Y>>2]|0)+3|0)<=(c[W>>2]|0))va=ib(c[s>>2]|0,3)|0;else va=0;c[J>>2]=va;Cb(c[ea>>2]|0,c[N>>2]|0,c[O>>2]|0,c[D>>2]|0,c[J>>2]|0,c[s>>2]|0,c[da>>2]|0,c[L>>2]|0);J=c[fa>>2]|0;c[la>>2]=ua()|0;va=i;i=i+((1*(J<<2)|0)+15&-16)|0;$c(c[N>>2]|0,c[O>>2]|0,c[I>>2]|0,va,c[L>>2]|0,c[s>>2]|0);c[Y>>2]=_c(c[s>>2]|0)|0;c[x>>2]=2;if(((c[Y>>2]|0)+4|0)<=(c[W>>2]|0))c[x>>2]=jb(c[s>>2]|0,2424,5)|0;J=i;i=i+((1*(c[fa>>2]<<2)|0)+15&-16)|0;Ya(c[ea>>2]|0,J,c[L>>2]|0,c[da>>2]|0);ia=i;i=i+((1*(c[fa>>2]<<2)|0)+15&-16)|0;c[Z>>2]=6;c[W>>2]=c[W>>2]<<3;c[Y>>2]=db(c[s>>2]|0)|0;c[v>>2]=c[N>>2];while(1){if((c[v>>2]|0)>=(c[O>>2]|0))break;ja=_(c[da>>2]|0,(b[(c[ha>>2]|0)+((c[v>>2]|0)+1<<1)>>1]|0)-(b[(c[ha>>2]|0)+(c[v>>2]<<1)>>1]|0)|0)|0;c[ma>>2]=ja<<c[L>>2];ja=c[ma>>2]|0;if((c[ma>>2]<<3|0)<((48>(c[ma>>2]|0)?48:c[ma>>2]|0)|0))wa=ja<<3;else wa=48>(ja|0)?48:c[ma>>2]|0;c[na>>2]=wa;c[oa>>2]=c[Z>>2];c[pa>>2]=0;while(1){if(((c[Y>>2]|0)+(c[oa>>2]<<3)|0)>=(c[W>>2]|0))break;if((c[pa>>2]|0)>=(c[J+(c[v>>2]<<2)>>2]|0))break;c[qa>>2]=ib(c[s>>2]|0,c[oa>>2]|0)|0;c[Y>>2]=db(c[s>>2]|0)|0;if(!(c[qa>>2]|0))break;c[pa>>2]=(c[pa>>2]|0)+(c[na>>2]|0);c[W>>2]=(c[W>>2]|0)-(c[na>>2]|0);c[oa>>2]=1}c[ia+(c[v>>2]<<2)>>2]=c[pa>>2];if((c[pa>>2]|0)>0)c[Z>>2]=2>((c[Z>>2]|0)-1|0)?2:(c[Z>>2]|0)-1|0;c[v>>2]=(c[v>>2]|0)+1}Z=i;i=i+((1*(c[fa>>2]<<2)|0)+15&-16)|0;if(((c[Y>>2]|0)+48|0)<=(c[W>>2]|0))xa=jb(c[s>>2]|0,2432,7)|0;else xa=5;c[R>>2]=xa;xa=c[p>>2]<<3<<3;c[y>>2]=xa-(db(c[s>>2]|0)|0)-1;if((c[I>>2]|0)!=0&(c[L>>2]|0)>=2)ya=(c[y>>2]|0)>=((c[L>>2]|0)+2<<3|0);else ya=0;c[aa>>2]=ya?8:0;c[y>>2]=(c[y>>2]|0)-(c[aa>>2]|0);ya=i;i=i+((1*(c[fa>>2]<<2)|0)+15&-16)|0;xa=i;i=i+((1*(c[fa>>2]<<2)|0)+15&-16)|0;c[Q>>2]=Fb(c[ea>>2]|0,c[N>>2]|0,c[O>>2]|0,ia,J,c[R>>2]|0,U,V,c[y>>2]|0,X,ya,Z,xa,c[da>>2]|0,c[L>>2]|0,c[s>>2]|0,0,0,0)|0;Db(c[ea>>2]|0,c[N>>2]|0,c[O>>2]|0,c[D>>2]|0,Z,c[s>>2]|0,c[da>>2]|0);c[u>>2]=0;do{ff(c[A+(c[u>>2]<<2)>>2]|0,(c[A+(c[u>>2]<<2)>>2]|0)+(c[w>>2]<<2)|0,(2048-(c[w>>2]|0)+((c[ga>>2]|0)/2|0)<<2)+0|0)|0;y=(c[u>>2]|0)+1|0;c[u>>2]=y}while((y|0)<(c[K>>2]|0));A=_(c[da>>2]|0,c[fa>>2]|0)|0;y=i;i=i+((1*A|0)+15&-16)|0;A=(_(c[da>>2]|0,c[w>>2]|0)|0)<<2;R=i;i=i+((1*A|0)+15&-16)|0;Va(0,c[ea>>2]|0,c[N>>2]|0,c[O>>2]|0,R,(c[da>>2]|0)==2?R+(c[w>>2]<<2)|0:0,y,0,ya,c[H>>2]|0,c[x>>2]|0,c[V>>2]|0,c[U>>2]|0,va,(c[p>>2]<<6)-(c[aa>>2]|0)|0,c[X>>2]|0,c[s>>2]|0,c[L>>2]|0,c[Q>>2]|0,(c[n>>2]|0)+36|0);if((c[aa>>2]|0)>0)c[ba>>2]=lb(c[s>>2]|0,1)|0;aa=c[ea>>2]|0;Q=c[N>>2]|0;X=c[O>>2]|0;va=c[D>>2]|0;U=c[p>>2]<<3;V=U-(_c(c[s>>2]|0)|0)|0;Eb(aa,Q,X,va,Z,xa,V,c[s>>2]|0,c[da>>2]|0);if(c[ba>>2]|0)Ta(c[ea>>2]|0,R,y,c[L>>2]|0,c[da>>2]|0,c[w>>2]|0,c[N>>2]|0,c[O>>2]|0,c[D>>2]|0,c[E>>2]|0,c[F>>2]|0,ya,c[(c[n>>2]|0)+36>>2]|0);b:do if(c[ca>>2]|0){c[v>>2]=0;while(1){if((c[v>>2]|0)>=(_(c[da>>2]|0,c[fa>>2]|0)|0))break b;g[(c[D>>2]|0)+(c[v>>2]<<2)>>2]=-28.0;c[v>>2]=(c[v>>2]|0)+1}}while(0);ad(c[ea>>2]|0,R,B,c[D>>2]|0,c[N>>2]|0,c[P>>2]|0,c[da>>2]|0,c[K>>2]|0,c[I>>2]|0,c[L>>2]|0,c[(c[n>>2]|0)+16>>2]|0,c[ca>>2]|0);c[u>>2]=0;do{if((c[(c[n>>2]|0)+52>>2]|0)>15)za=c[(c[n>>2]|0)+52>>2]|0;else za=15;c[(c[n>>2]|0)+52>>2]=za;if((c[(c[n>>2]|0)+56>>2]|0)>15)Aa=c[(c[n>>2]|0)+56>>2]|0;else Aa=15;c[(c[n>>2]|0)+56>>2]=Aa;Xa(c[B+(c[u>>2]<<2)>>2]|0,c[B+(c[u>>2]<<2)>>2]|0,c[(c[n>>2]|0)+56>>2]|0,c[(c[n>>2]|0)+52>>2]|0,c[(c[ea>>2]|0)+44>>2]|0,+g[(c[n>>2]|0)+64>>2],+g[(c[n>>2]|0)+60>>2],c[(c[n>>2]|0)+72>>2]|0,c[(c[n>>2]|0)+68>>2]|0,c[(c[ea>>2]|0)+60>>2]|0,c[ga>>2]|0);if(c[L>>2]|0)Xa((c[B+(c[u>>2]<<2)>>2]|0)+(c[(c[ea>>2]|0)+44>>2]<<2)|0,(c[B+(c[u>>2]<<2)>>2]|0)+(c[(c[ea>>2]|0)+44>>2]<<2)|0,c[(c[n>>2]|0)+52>>2]|0,c[S>>2]|0,(c[w>>2]|0)-(c[(c[ea>>2]|0)+44>>2]|0)|0,+g[(c[n>>2]|0)+60>>2],+g[T>>2],c[(c[n>>2]|0)+68>>2]|0,c[$>>2]|0,c[(c[ea>>2]|0)+60>>2]|0,c[ga>>2]|0);ca=(c[u>>2]|0)+1|0;c[u>>2]=ca}while((ca|0)<(c[K>>2]|0));c[(c[n>>2]|0)+56>>2]=c[(c[n>>2]|0)+52>>2];g[(c[n>>2]|0)+64>>2]=+g[(c[n>>2]|0)+60>>2];c[(c[n>>2]|0)+72>>2]=c[(c[n>>2]|0)+68>>2];c[(c[n>>2]|0)+52>>2]=c[S>>2];g[(c[n>>2]|0)+60>>2]=+g[T>>2];c[(c[n>>2]|0)+68>>2]=c[$>>2];if(c[L>>2]|0){c[(c[n>>2]|0)+56>>2]=c[(c[n>>2]|0)+52>>2];g[(c[n>>2]|0)+64>>2]=+g[(c[n>>2]|0)+60>>2];c[(c[n>>2]|0)+72>>2]=c[(c[n>>2]|0)+68>>2]}if((c[da>>2]|0)==1)df((c[D>>2]|0)+(c[fa>>2]<<2)|0,c[D>>2]|0,(c[fa>>2]<<2)+0|0)|0;c:do if(c[I>>2]|0){c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[fa>>2]<<1|0))break c;da=c[v>>2]|0;if(+g[(c[E>>2]|0)+(c[v>>2]<<2)>>2]<+g[(c[D>>2]|0)+(c[v>>2]<<2)>>2])Ba=+g[(c[E>>2]|0)+(da<<2)>>2];else Ba=+g[(c[D>>2]|0)+(da<<2)>>2];g[(c[E>>2]|0)+(c[v>>2]<<2)>>2]=Ba;c[v>>2]=(c[v>>2]|0)+1}}else{df(c[F>>2]|0,c[E>>2]|0,(c[fa>>2]<<1<<2)+0|0)|0;df(c[E>>2]|0,c[D>>2]|0,(c[fa>>2]<<1<<2)+0|0)|0;c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[fa>>2]<<1|0))break c;da=c[v>>2]|0;if(+g[(c[G>>2]|0)+(c[v>>2]<<2)>>2]+ +(c[M>>2]|0)*1.0000000474974513e-03<+g[(c[D>>2]|0)+(c[v>>2]<<2)>>2])Ca=+g[(c[G>>2]|0)+(da<<2)>>2]+ +(c[M>>2]|0)*1.0000000474974513e-03;else Ca=+g[(c[D>>2]|0)+(da<<2)>>2];g[(c[G>>2]|0)+(c[v>>2]<<2)>>2]=Ca;c[v>>2]=(c[v>>2]|0)+1}}while(0);c[u>>2]=0;do{c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[N>>2]|0))break;G=_(c[u>>2]|0,c[fa>>2]|0)|0;g[(c[D>>2]|0)+(G+(c[v>>2]|0)<<2)>>2]=0.0;G=_(c[u>>2]|0,c[fa>>2]|0)|0;g[(c[F>>2]|0)+(G+(c[v>>2]|0)<<2)>>2]=-28.0;G=_(c[u>>2]|0,c[fa>>2]|0)|0;g[(c[E>>2]|0)+(G+(c[v>>2]|0)<<2)>>2]=-28.0;c[v>>2]=(c[v>>2]|0)+1}c[v>>2]=c[O>>2];while(1){Da=c[u>>2]|0;if((c[v>>2]|0)>=(c[fa>>2]|0))break;G=_(Da,c[fa>>2]|0)|0;g[(c[D>>2]|0)+(G+(c[v>>2]|0)<<2)>>2]=0.0;G=_(c[u>>2]|0,c[fa>>2]|0)|0;g[(c[F>>2]|0)+(G+(c[v>>2]|0)<<2)>>2]=-28.0;G=_(c[u>>2]|0,c[fa>>2]|0)|0;g[(c[E>>2]|0)+(G+(c[v>>2]|0)<<2)>>2]=-28.0;c[v>>2]=(c[v>>2]|0)+1}G=Da+1|0;c[u>>2]=G}while((G|0)<2);c[(c[n>>2]|0)+36>>2]=c[(c[s>>2]|0)+28>>2];Zc(B,c[q>>2]|0,c[w>>2]|0,c[K>>2]|0,c[(c[n>>2]|0)+16>>2]|0,(c[ea>>2]|0)+16|0,(c[n>>2]|0)+76|0,c[t>>2]|0);c[(c[n>>2]|0)+48>>2]=0;t=_c(c[s>>2]|0)|0;if((t|0)>(c[p>>2]<<3|0)){c[m>>2]=-3;c[ra>>2]=1}else{if(bd(c[s>>2]|0)|0)c[(c[n>>2]|0)+40>>2]=1;c[m>>2]=(c[r>>2]|0)/(c[(c[n>>2]|0)+16>>2]|0)|0;c[ra>>2]=1}ka(c[la>>2]|0);sa=c[m>>2]|0;i=l;return sa|0}function ab(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;e=i;i=i+96|0;f=e+32|0;h=e+24|0;j=e+44|0;k=e+64|0;l=e+12|0;m=e+40|0;n=e+48|0;o=e+56|0;p=e+80|0;q=e+84|0;r=e+8|0;s=e+4|0;t=e;u=e+36|0;v=e+16|0;w=e+20|0;x=e+52|0;y=e+28|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;a:do switch(c[j>>2]|0){case 10010:{d=(c[k>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[k>>2]=d+4;c[l>>2]=b;if((c[l>>2]|0)>=0?(c[l>>2]|0)<(c[(c[c[h>>2]>>2]|0)+8>>2]|0):0){c[(c[h>>2]|0)+20>>2]=c[l>>2];z=24}else z=25;break}case 10012:{b=(c[k>>2]|0)+(4-1)&~(4-1);d=c[b>>2]|0;c[k>>2]=b+4;c[m>>2]=d;if((c[m>>2]|0)>=1?(c[m>>2]|0)<=(c[(c[c[h>>2]>>2]|0)+8>>2]|0):0){c[(c[h>>2]|0)+24>>2]=c[m>>2];z=24}else z=25;break}case 4028:{c[r>>2]=(c[h>>2]|0)+84+((_(2048+(c[(c[h>>2]|0)+4>>2]|0)|0,c[(c[h>>2]|0)+8>>2]|0)|0)<<2);c[s>>2]=(c[r>>2]|0)+((c[(c[h>>2]|0)+8>>2]|0)*24<<2);c[t>>2]=(c[s>>2]|0)+(c[(c[c[h>>2]>>2]|0)+8>>2]<<1<<2);c[u>>2]=(c[t>>2]|0)+(c[(c[c[h>>2]>>2]|0)+8>>2]<<1<<2);bf((c[h>>2]|0)+36|0,0,(Wc(c[c[h>>2]>>2]|0,c[(c[h>>2]|0)+8>>2]|0)|0)-((c[h>>2]|0)+36-(c[h>>2]|0))|0)|0;c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[(c[c[h>>2]>>2]|0)+8>>2]<<1|0)){z=24;break a}g[(c[u>>2]|0)+(c[q>>2]<<2)>>2]=-28.0;g[(c[t>>2]|0)+(c[q>>2]<<2)>>2]=-28.0;c[q>>2]=(c[q>>2]|0)+1}break}case 4033:{d=(c[k>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[k>>2]=d+4;c[v>>2]=b;if(!(c[v>>2]|0))z=25;else{c[c[v>>2]>>2]=c[(c[h>>2]|0)+52>>2];z=24}break}case 10015:{b=(c[k>>2]|0)+(4-1)&~(4-1);d=c[b>>2]|0;c[k>>2]=b+4;c[w>>2]=d;if(!(c[w>>2]|0))z=25;else{c[c[w>>2]>>2]=c[c[h>>2]>>2];z=24}break}case 10016:{d=(c[k>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[k>>2]=d+4;c[x>>2]=b;c[(c[h>>2]|0)+28>>2]=c[x>>2];z=24;break}case 4031:{b=(c[k>>2]|0)+(4-1)&~(4-1);d=c[b>>2]|0;c[k>>2]=b+4;c[y>>2]=d;if(!(c[y>>2]|0))z=25;else{c[c[y>>2]>>2]=c[(c[h>>2]|0)+36>>2];z=24}break}case 10008:{d=(c[k>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[k>>2]=d+4;c[n>>2]=b;if((c[n>>2]|0)<1|(c[n>>2]|0)>2)z=25;else{c[(c[h>>2]|0)+12>>2]=c[n>>2];z=24}break}case 10007:{b=(c[k>>2]|0)+(4-1)&~(4-1);d=c[b>>2]|0;c[k>>2]=b+4;c[o>>2]=d;if(!(c[o>>2]|0))z=25;else{c[c[o>>2]>>2]=c[(c[h>>2]|0)+40>>2];c[(c[h>>2]|0)+40>>2]=0;z=24}break}case 4027:{d=(c[k>>2]|0)+(4-1)&~(4-1);b=c[d>>2]|0;c[k>>2]=d+4;c[p>>2]=b;if(!(c[p>>2]|0))z=25;else{c[c[p>>2]>>2]=(c[(c[h>>2]|0)+4>>2]|0)/(c[(c[h>>2]|0)+16>>2]|0)|0;z=24}break}default:{c[f>>2]=-5;A=c[f>>2]|0;i=e;return A|0}}while(0);if((z|0)==24){c[f>>2]=0;A=c[f>>2]|0;i=e;return A|0}else if((z|0)==25){c[f>>2]=-1;A=c[f>>2]|0;i=e;return A|0}return 0}function bb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;f=i;i=i+16|0;g=f+12|0;h=f+8|0;j=f+4|0;k=f;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;e=c[k>>2]|0;k=cd(c[h>>2]|0,c[g>>2]|0)|0;ob(e,k,(c[(c[2448+(((c[h>>2]|0)<(c[j>>2]|0)?c[h>>2]|0:c[j>>2]|0)<<2)>>2]|0)+(((c[h>>2]|0)>(c[j>>2]|0)?c[h>>2]|0:c[j>>2]|0)<<2)>>2]|0)+(c[(c[2448+(((c[h>>2]|0)<((c[j>>2]|0)+1|0)?c[h>>2]|0:(c[j>>2]|0)+1|0)<<2)>>2]|0)+(((c[h>>2]|0)>((c[j>>2]|0)+1|0)?c[h>>2]|0:(c[j>>2]|0)+1|0)<<2)>>2]|0)|0);i=f;return}function cb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0.0;f=i;i=i+16|0;g=f+12|0;h=f+8|0;j=f+4|0;k=f;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;e=c[h>>2]|0;d=c[j>>2]|0;b=kb(c[k>>2]|0,(c[(c[2448+(((c[h>>2]|0)<(c[j>>2]|0)?c[h>>2]|0:c[j>>2]|0)<<2)>>2]|0)+(((c[h>>2]|0)>(c[j>>2]|0)?c[h>>2]|0:c[j>>2]|0)<<2)>>2]|0)+(c[(c[2448+(((c[h>>2]|0)<((c[j>>2]|0)+1|0)?c[h>>2]|0:(c[j>>2]|0)+1|0)<<2)>>2]|0)+(((c[h>>2]|0)>((c[j>>2]|0)+1|0)?c[h>>2]|0:(c[j>>2]|0)+1|0)<<2)>>2]|0)|0)|0;l=+dd(e,d,b,c[g>>2]|0);i=f;return +l}function db(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;b=i;i=i+32|0;d=b+16|0;e=b+12|0;f=b+8|0;g=b+4|0;h=b;c[d>>2]=a;c[e>>2]=c[(c[d>>2]|0)+20>>2]<<3;c[g>>2]=32-(aa(c[(c[d>>2]|0)+28>>2]|0)|0);c[f>>2]=(c[(c[d>>2]|0)+28>>2]|0)>>>((c[g>>2]|0)-16|0);c[h>>2]=((c[f>>2]|0)>>>12)-8;c[h>>2]=(c[h>>2]|0)+((c[f>>2]|0)>>>0>(c[2512+(c[h>>2]<<2)>>2]|0)>>>0&1);c[g>>2]=(c[g>>2]<<3)+(c[h>>2]|0);i=b;return (c[e>>2]|0)-(c[g>>2]|0)|0}function eb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[c[f>>2]>>2]=c[g>>2];c[(c[f>>2]|0)+4>>2]=c[h>>2];c[(c[f>>2]|0)+8>>2]=0;c[(c[f>>2]|0)+12>>2]=0;c[(c[f>>2]|0)+16>>2]=0;c[(c[f>>2]|0)+20>>2]=9;c[(c[f>>2]|0)+24>>2]=0;c[(c[f>>2]|0)+28>>2]=128;h=ed(c[f>>2]|0)|0;c[(c[f>>2]|0)+40>>2]=h;c[(c[f>>2]|0)+32>>2]=(c[(c[f>>2]|0)+28>>2]|0)-1-(c[(c[f>>2]|0)+40>>2]>>1);c[(c[f>>2]|0)+44>>2]=0;fd(c[f>>2]|0);i=e;return}function fb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[e>>2]=a;c[f>>2]=b;b=gd(c[(c[e>>2]|0)+28>>2]|0,c[f>>2]|0)|0;c[(c[e>>2]|0)+36>>2]=b;c[g>>2]=((c[(c[e>>2]|0)+32>>2]|0)>>>0)/((c[(c[e>>2]|0)+36>>2]|0)>>>0)|0;i=d;return (c[f>>2]|0)-((c[g>>2]|0)+1+((c[f>>2]|0)-((c[g>>2]|0)+1)&0-((c[f>>2]|0)>>>0<((c[g>>2]|0)+1|0)>>>0&1)))|0}function gb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[e>>2]=a;c[f>>2]=b;c[(c[e>>2]|0)+36>>2]=(c[(c[e>>2]|0)+28>>2]|0)>>>(c[f>>2]|0);c[g>>2]=((c[(c[e>>2]|0)+32>>2]|0)>>>0)/((c[(c[e>>2]|0)+36>>2]|0)>>>0)|0;i=d;return (1<<c[f>>2])-((c[g>>2]|0)+1+((1<<c[f>>2])-((c[g>>2]|0)+1)&0-(1<<c[f>>2]>>>0<((c[g>>2]|0)+1|0)>>>0&1)))|0}function hb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[l>>2]=_(c[(c[g>>2]|0)+36>>2]|0,(c[k>>2]|0)-(c[j>>2]|0)|0)|0;k=(c[g>>2]|0)+32|0;c[k>>2]=(c[k>>2]|0)-(c[l>>2]|0);k=c[g>>2]|0;if((c[h>>2]|0)>>>0>0){m=_(c[k+36>>2]|0,(c[j>>2]|0)-(c[h>>2]|0)|0)|0;n=c[g>>2]|0;o=n+28|0;c[o>>2]=m;p=c[g>>2]|0;fd(p);i=f;return}else{m=(c[k+28>>2]|0)-(c[l>>2]|0)|0;n=c[g>>2]|0;o=n+28|0;c[o>>2]=m;p=c[g>>2]|0;fd(p);i=f;return}}function ib(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;d=i;i=i+32|0;e=d+20|0;f=d+16|0;g=d+12|0;h=d+8|0;j=d+4|0;k=d;c[e>>2]=a;c[f>>2]=b;c[g>>2]=c[(c[e>>2]|0)+28>>2];c[h>>2]=c[(c[e>>2]|0)+32>>2];c[j>>2]=(c[g>>2]|0)>>>(c[f>>2]|0);c[k>>2]=(c[h>>2]|0)>>>0<(c[j>>2]|0)>>>0&1;if(!(c[k>>2]|0))c[(c[e>>2]|0)+32>>2]=(c[h>>2]|0)-(c[j>>2]|0);if(c[k>>2]|0){l=c[j>>2]|0;m=c[e>>2]|0;n=m+28|0;c[n>>2]=l;o=c[e>>2]|0;fd(o);p=c[k>>2]|0;i=d;return p|0}else{l=(c[g>>2]|0)-(c[j>>2]|0)|0;m=c[e>>2]|0;n=m+28|0;c[n>>2]=l;o=c[e>>2]|0;fd(o);p=c[k>>2]|0;i=d;return p|0}return 0}function jb(a,b,e){a=a|0;b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;f=i;i=i+32|0;g=f+4|0;h=f+16|0;j=f+8|0;k=f+20|0;l=f+28|0;m=f;n=f+12|0;o=f+24|0;c[g>>2]=a;c[h>>2]=b;c[j>>2]=e;c[m>>2]=c[(c[g>>2]|0)+28>>2];c[l>>2]=c[(c[g>>2]|0)+32>>2];c[k>>2]=(c[m>>2]|0)>>>(c[j>>2]|0);c[o>>2]=-1;do{c[n>>2]=c[m>>2];j=c[k>>2]|0;e=(c[o>>2]|0)+1|0;c[o>>2]=e;c[m>>2]=_(j,d[(c[h>>2]|0)+e>>0]|0)|0}while((c[l>>2]|0)>>>0<(c[m>>2]|0)>>>0);c[(c[g>>2]|0)+32>>2]=(c[l>>2]|0)-(c[m>>2]|0);c[(c[g>>2]|0)+28>>2]=(c[n>>2]|0)-(c[m>>2]|0);fd(c[g>>2]|0);i=f;return c[o>>2]|0}function kb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;d=i;i=i+32|0;e=d+8|0;f=d+16|0;g=d+20|0;h=d+24|0;j=d+4|0;k=d;l=d+12|0;c[f>>2]=a;c[g>>2]=b;c[g>>2]=(c[g>>2]|0)+-1;c[k>>2]=32-(aa(c[g>>2]|0)|0);if((c[k>>2]|0)<=8){c[g>>2]=(c[g>>2]|0)+1;c[j>>2]=fb(c[f>>2]|0,c[g>>2]|0)|0;hb(c[f>>2]|0,c[j>>2]|0,(c[j>>2]|0)+1|0,c[g>>2]|0);c[e>>2]=c[j>>2];m=c[e>>2]|0;i=d;return m|0}c[k>>2]=(c[k>>2]|0)-8;c[h>>2]=((c[g>>2]|0)>>>(c[k>>2]|0))+1;c[j>>2]=fb(c[f>>2]|0,c[h>>2]|0)|0;hb(c[f>>2]|0,c[j>>2]|0,(c[j>>2]|0)+1|0,c[h>>2]|0);h=c[j>>2]<<c[k>>2];c[l>>2]=h|(lb(c[f>>2]|0,c[k>>2]|0)|0);if((c[l>>2]|0)>>>0<=(c[g>>2]|0)>>>0){c[e>>2]=c[l>>2];m=c[e>>2]|0;i=d;return m|0}else{c[(c[f>>2]|0)+44>>2]=1;c[e>>2]=c[g>>2];m=c[e>>2]|0;i=d;return m|0}return 0}function lb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;d=i;i=i+32|0;e=d+16|0;f=d+12|0;g=d+8|0;h=d+4|0;j=d;c[e>>2]=a;c[f>>2]=b;c[g>>2]=c[(c[e>>2]|0)+12>>2];c[h>>2]=c[(c[e>>2]|0)+16>>2];if((c[h>>2]|0)>>>0<(c[f>>2]|0)>>>0)do{b=hd(c[e>>2]|0)|0;c[g>>2]=c[g>>2]|b<<c[h>>2];c[h>>2]=(c[h>>2]|0)+8}while((c[h>>2]|0)<=24);c[j>>2]=c[g>>2]&(1<<c[f>>2])-1;c[g>>2]=(c[g>>2]|0)>>>(c[f>>2]|0);c[h>>2]=(c[h>>2]|0)-(c[f>>2]|0);c[(c[e>>2]|0)+12>>2]=c[g>>2];c[(c[e>>2]|0)+16>>2]=c[h>>2];h=(c[e>>2]|0)+20|0;c[h>>2]=(c[h>>2]|0)+(c[f>>2]|0);i=d;return c[j>>2]|0}function mb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;c[l>>2]=id(c[(c[g>>2]|0)+28>>2]|0,c[k>>2]|0)|0;if((c[h>>2]|0)>>>0>0){e=(c[(c[g>>2]|0)+28>>2]|0)-(_(c[l>>2]|0,(c[k>>2]|0)-(c[h>>2]|0)|0)|0)|0;d=(c[g>>2]|0)+32|0;c[d>>2]=(c[d>>2]|0)+e;e=_(c[l>>2]|0,(c[j>>2]|0)-(c[h>>2]|0)|0)|0;c[(c[g>>2]|0)+28>>2]=e;m=c[g>>2]|0;jd(m);i=f;return}else{e=_(c[l>>2]|0,(c[k>>2]|0)-(c[j>>2]|0)|0)|0;j=(c[g>>2]|0)+28|0;c[j>>2]=(c[j>>2]|0)-e;m=c[g>>2]|0;jd(m);i=f;return}}function nb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[j>>2]=c[(c[f>>2]|0)+28>>2];c[l>>2]=c[(c[f>>2]|0)+32>>2];c[k>>2]=(c[j>>2]|0)>>>(c[h>>2]|0);c[j>>2]=(c[j>>2]|0)-(c[k>>2]|0);if(c[g>>2]|0)c[(c[f>>2]|0)+32>>2]=(c[l>>2]|0)+(c[j>>2]|0);c[(c[f>>2]|0)+28>>2]=(c[g>>2]|0)!=0?c[k>>2]|0:c[j>>2]|0;jd(c[f>>2]|0);i=e;return}function ob(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[h>>2]=(c[h>>2]|0)+-1;c[l>>2]=32-(aa(c[h>>2]|0)|0);if((c[l>>2]|0)>8){c[l>>2]=(c[l>>2]|0)-8;c[j>>2]=((c[h>>2]|0)>>>(c[l>>2]|0))+1;c[k>>2]=(c[g>>2]|0)>>>(c[l>>2]|0);mb(c[f>>2]|0,c[k>>2]|0,(c[k>>2]|0)+1|0,c[j>>2]|0);pb(c[f>>2]|0,c[g>>2]&(1<<c[l>>2])-1,c[l>>2]|0);i=e;return}else{mb(c[f>>2]|0,c[g>>2]|0,(c[g>>2]|0)+1|0,(c[h>>2]|0)+1|0);i=e;return}}function pb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[j>>2]=c[(c[f>>2]|0)+12>>2];c[k>>2]=c[(c[f>>2]|0)+16>>2];if(((c[k>>2]|0)+(c[h>>2]|0)|0)>>>0>32)do{d=kd(c[f>>2]|0,c[j>>2]&255)|0;b=(c[f>>2]|0)+44|0;c[b>>2]=c[b>>2]|d;c[j>>2]=(c[j>>2]|0)>>>8;c[k>>2]=(c[k>>2]|0)-8}while((c[k>>2]|0)>=8);c[j>>2]=c[j>>2]|c[g>>2]<<c[k>>2];c[k>>2]=(c[k>>2]|0)+(c[h>>2]|0);c[(c[f>>2]|0)+12>>2]=c[j>>2];c[(c[f>>2]|0)+16>>2]=c[k>>2];k=(c[f>>2]|0)+20|0;c[k>>2]=(c[k>>2]|0)+(c[h>>2]|0);i=e;return}function qb(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;e=i;i=i+80|0;f=e+60|0;g=e+48|0;h=e+4|0;j=e+8|0;k=e+64|0;l=e;m=e+16|0;n=e+56|0;o=e+52|0;c[f>>2]=a;c[g>>2]=d;if((c[(c[f>>2]|0)+8>>2]|0)>0)p=c[(c[f>>2]|0)+8>>2]|0;else p=0;c[o>>2]=p;c[m>>2]=1;c[l>>2]=0;do{c[k>>2]=b[(c[f>>2]|0)+12+(c[l>>2]<<1<<1)>>1];c[j>>2]=b[(c[f>>2]|0)+12+((c[l>>2]<<1)+1<<1)>>1];p=_(c[m+(c[l>>2]<<2)>>2]|0,c[k>>2]|0)|0;c[m+((c[l>>2]|0)+1<<2)>>2]=p;c[l>>2]=(c[l>>2]|0)+1}while((c[j>>2]|0)!=1);c[j>>2]=b[(c[f>>2]|0)+12+((c[l>>2]<<1)-1<<1)>>1];c[n>>2]=(c[l>>2]|0)-1;while(1){if((c[n>>2]|0)<0)break;if(c[n>>2]|0)c[h>>2]=b[(c[f>>2]|0)+12+((c[n>>2]<<1)-1<<1)>>1];else c[h>>2]=1;l=b[(c[f>>2]|0)+12+(c[n>>2]<<1<<1)>>1]|0;if((l|0)==2)md(c[g>>2]|0,c[j>>2]|0,c[m+(c[n>>2]<<2)>>2]|0);else if((l|0)==4)nd(c[g>>2]|0,c[m+(c[n>>2]<<2)>>2]<<c[o>>2],c[f>>2]|0,c[j>>2]|0,c[m+(c[n>>2]<<2)>>2]|0,c[h>>2]|0);else if((l|0)==3)od(c[g>>2]|0,c[m+(c[n>>2]<<2)>>2]<<c[o>>2],c[f>>2]|0,c[j>>2]|0,c[m+(c[n>>2]<<2)>>2]|0,c[h>>2]|0);else if((l|0)==5)pd(c[g>>2]|0,c[m+(c[n>>2]<<2)>>2]<<c[o>>2],c[f>>2]|0,c[j>>2]|0,c[m+(c[n>>2]<<2)>>2]|0,c[h>>2]|0);c[j>>2]=c[h>>2];c[n>>2]=(c[n>>2]|0)+-1}i=e;return}function rb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;e=i;i=i+32|0;f=e+8|0;g=e+16|0;h=e+20|0;j=e+24|0;k=e+4|0;l=e;m=e+12|0;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[j>>2]=0;c[l>>2]=gb(c[f>>2]|0,15)|0;c[k>>2]=0;do if((c[l>>2]|0)>>>0>=(c[g>>2]|0)>>>0){c[j>>2]=(c[j>>2]|0)+1;c[k>>2]=c[g>>2];c[g>>2]=(qd(c[g>>2]|0,c[h>>2]|0)|0)+1;while(1){if((c[g>>2]|0)>>>0>1)n=(c[l>>2]|0)>>>0>=((c[k>>2]|0)+(c[g>>2]<<1)|0)>>>0;else n=0;o=c[g>>2]|0;if(!n)break;c[g>>2]=o<<1;c[k>>2]=(c[k>>2]|0)+(c[g>>2]|0);c[g>>2]=(_((c[g>>2]|0)-2|0,c[h>>2]|0)|0)>>>15;c[g>>2]=(c[g>>2]|0)+1;c[j>>2]=(c[j>>2]|0)+1}if(o>>>0<=1){c[m>>2]=((c[l>>2]|0)-(c[k>>2]|0)|0)>>>1;c[j>>2]=(c[j>>2]|0)+(c[m>>2]|0);c[k>>2]=(c[k>>2]|0)+(c[m>>2]<<1)}if((c[l>>2]|0)>>>0<((c[k>>2]|0)+(c[g>>2]|0)|0)>>>0){c[j>>2]=0-(c[j>>2]|0);break}else{c[k>>2]=(c[k>>2]|0)+(c[g>>2]|0);break}}while(0);l=c[f>>2]|0;f=c[k>>2]|0;if(((c[k>>2]|0)+(c[g>>2]|0)|0)>>>0>=32768){p=32768;hb(l,f,p,32768);q=c[j>>2]|0;i=e;return q|0}p=(c[k>>2]|0)+(c[g>>2]|0)|0;hb(l,f,p,32768);q=c[j>>2]|0;i=e;return q|0}function sb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;b=i;i=i+32|0;d=b+16|0;e=b+12|0;f=b+8|0;g=b+4|0;h=b;c[d>>2]=a;c[f>>2]=0;c[g>>2]=32-(aa(c[d>>2]|0)|0)-1>>1;c[e>>2]=1<<c[g>>2];do{c[h>>2]=(c[f>>2]<<1)+(c[e>>2]|0)<<c[g>>2];if((c[h>>2]|0)>>>0<=(c[d>>2]|0)>>>0){c[f>>2]=(c[f>>2]|0)+(c[e>>2]|0);c[d>>2]=(c[d>>2]|0)-(c[h>>2]|0)}c[e>>2]=(c[e>>2]|0)>>>1;c[g>>2]=(c[g>>2]|0)+-1}while((c[g>>2]|0)>=0);i=b;return c[f>>2]|0}function tb(a,d,e,f,h,j,k){a=a|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0.0;l=i;i=i+144|0;m=l+132|0;n=l+108|0;o=l+8|0;p=l+56|0;q=l+64|0;r=l+16|0;s=l+20|0;t=l+24|0;u=l+28|0;v=l+32|0;w=l+36|0;x=l+40|0;y=l+44|0;z=l+104|0;A=l+112|0;B=l+120|0;C=l+128|0;D=l+136|0;E=l+68|0;F=l+72|0;G=l+76|0;H=l+80|0;I=l+84|0;J=l+88|0;K=l+92|0;L=l+12|0;M=l+4|0;N=l;O=l+96|0;P=l+48|0;Q=l+100|0;R=l+52|0;S=l+116|0;T=l+60|0;U=l+124|0;c[m>>2]=a;c[n>>2]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=h;c[r>>2]=j;c[s>>2]=k;c[u>>2]=c[c[m>>2]>>2];c[x>>2]=c[(c[m>>2]|0)+24>>2];c[t>>2]=0;while(1){V=c[u>>2]>>1;if((c[t>>2]|0)>=(c[r>>2]|0))break;c[u>>2]=V;c[x>>2]=(c[x>>2]|0)+(c[u>>2]<<2);c[t>>2]=(c[t>>2]|0)+1}c[v>>2]=V;c[w>>2]=c[u>>2]>>2;c[y>>2]=c[n>>2];c[z>>2]=(c[n>>2]|0)+((_(c[s>>2]|0,(c[v>>2]|0)-1|0)|0)<<2);c[A>>2]=(c[o>>2]|0)+(c[q>>2]>>1<<2);c[B>>2]=c[x>>2];c[C>>2]=c[(c[(c[m>>2]|0)+8+(c[r>>2]<<2)>>2]|0)+44>>2];c[t>>2]=0;while(1){if((c[t>>2]|0)>=(c[w>>2]|0))break;n=c[C>>2]|0;c[C>>2]=n+2;c[D>>2]=b[n>>1];g[E>>2]=+g[c[z>>2]>>2]*+g[(c[B>>2]|0)+(c[t>>2]<<2)>>2]+ +g[c[y>>2]>>2]*+g[(c[B>>2]|0)+((c[w>>2]|0)+(c[t>>2]|0)<<2)>>2];g[F>>2]=+g[c[y>>2]>>2]*+g[(c[B>>2]|0)+(c[t>>2]<<2)>>2]-+g[c[z>>2]>>2]*+g[(c[B>>2]|0)+((c[w>>2]|0)+(c[t>>2]|0)<<2)>>2];g[(c[A>>2]|0)+((c[D>>2]<<1)+1<<2)>>2]=+g[E>>2];g[(c[A>>2]|0)+(c[D>>2]<<1<<2)>>2]=+g[F>>2];c[y>>2]=(c[y>>2]|0)+(c[s>>2]<<1<<2);c[z>>2]=(c[z>>2]|0)+(0-(c[s>>2]<<1)<<2);c[t>>2]=(c[t>>2]|0)+1}qb(c[(c[m>>2]|0)+8+(c[r>>2]<<2)>>2]|0,(c[o>>2]|0)+(c[q>>2]>>1<<2)|0);c[G>>2]=(c[o>>2]|0)+(c[q>>2]>>1<<2);c[H>>2]=(c[o>>2]|0)+(c[q>>2]>>1<<2)+(c[v>>2]<<2)+-8;c[I>>2]=c[x>>2];c[t>>2]=0;while(1){if((c[t>>2]|0)>=((c[w>>2]|0)+1>>1|0))break;g[J>>2]=+g[(c[G>>2]|0)+4>>2];g[K>>2]=+g[c[G>>2]>>2];g[N>>2]=+g[(c[I>>2]|0)+(c[t>>2]<<2)>>2];g[O>>2]=+g[(c[I>>2]|0)+((c[w>>2]|0)+(c[t>>2]|0)<<2)>>2];g[L>>2]=+g[J>>2]*+g[N>>2]+ +g[K>>2]*+g[O>>2];g[M>>2]=+g[J>>2]*+g[O>>2]-+g[K>>2]*+g[N>>2];g[J>>2]=+g[(c[H>>2]|0)+4>>2];g[K>>2]=+g[c[H>>2]>>2];g[c[G>>2]>>2]=+g[L>>2];g[(c[H>>2]|0)+4>>2]=+g[M>>2];g[N>>2]=+g[(c[I>>2]|0)+((c[w>>2]|0)-(c[t>>2]|0)-1<<2)>>2];g[O>>2]=+g[(c[I>>2]|0)+((c[v>>2]|0)-(c[t>>2]|0)-1<<2)>>2];g[L>>2]=+g[J>>2]*+g[N>>2]+ +g[K>>2]*+g[O>>2];g[M>>2]=+g[J>>2]*+g[O>>2]-+g[K>>2]*+g[N>>2];g[c[H>>2]>>2]=+g[L>>2];g[(c[G>>2]|0)+4>>2]=+g[M>>2];c[G>>2]=(c[G>>2]|0)+8;c[H>>2]=(c[H>>2]|0)+-8;c[t>>2]=(c[t>>2]|0)+1}c[P>>2]=(c[o>>2]|0)+(c[q>>2]<<2)+-4;c[Q>>2]=c[o>>2];c[R>>2]=c[p>>2];c[S>>2]=(c[p>>2]|0)+(c[q>>2]<<2)+-4;c[t>>2]=0;while(1){if((c[t>>2]|0)>=((c[q>>2]|0)/2|0|0))break;g[T>>2]=+g[c[P>>2]>>2];g[U>>2]=+g[c[Q>>2]>>2];W=+g[c[S>>2]>>2]*+g[U>>2]-+g[c[R>>2]>>2]*+g[T>>2];p=c[Q>>2]|0;c[Q>>2]=p+4;g[p>>2]=W;W=+g[c[R>>2]>>2]*+g[U>>2]+ +g[c[S>>2]>>2]*+g[T>>2];p=c[P>>2]|0;c[P>>2]=p+-4;g[p>>2]=W;c[R>>2]=(c[R>>2]|0)+4;c[S>>2]=(c[S>>2]|0)+-4;c[t>>2]=(c[t>>2]|0)+1}i=l;return}function ub(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=0;a:while(1){if((c[k>>2]|0)>=1){m=12;break}c[l>>2]=0;while(1){if((c[l>>2]|0)>=4)break;if((c[g>>2]|0)==(c[c[2544+(c[k>>2]<<2)>>2]>>2]|0)?(c[h>>2]<<c[l>>2]|0)==(_(c[(c[2544+(c[k>>2]<<2)>>2]|0)+44>>2]|0,c[(c[2544+(c[k>>2]<<2)>>2]|0)+40>>2]|0)|0):0){m=7;break a}c[l>>2]=(c[l>>2]|0)+1}c[k>>2]=(c[k>>2]|0)+1}if((m|0)==7){if(c[j>>2]|0)c[c[j>>2]>>2]=0;c[f>>2]=c[2544+(c[k>>2]<<2)>>2];n=c[f>>2]|0;i=e;return n|0}else if((m|0)==12){if(c[j>>2]|0)c[c[j>>2]>>2]=-1;c[f>>2]=0;n=c[f>>2]|0;i=e;return n|0}return 0}function vb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+112|0;j=h+4|0;k=h+48|0;l=h+84|0;m=h;n=h+80|0;o=h+88|0;p=h+92|0;q=h+72|0;r=h+56|0;s=h+8|0;t=h+28|0;u=h+76|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;g[q>>2]=1.0;c[s>>2]=0;c[s+4>>2]=0;c[s+8>>2]=0;c[s+12>>2]=0;c[s+16>>2]=0;g[u>>2]=.800000011920929;c[o>>2]=1;while(1){if((c[o>>2]|0)>=(c[l>>2]>>1|0))break;g[(c[k>>2]|0)+(c[o>>2]<<2)>>2]=((+g[(c[c[j>>2]>>2]|0)+((c[o>>2]<<1)-1<<2)>>2]+ +g[(c[c[j>>2]>>2]|0)+((c[o>>2]<<1)+1<<2)>>2])*.5+ +g[(c[c[j>>2]>>2]|0)+(c[o>>2]<<1<<2)>>2])*.5;c[o>>2]=(c[o>>2]|0)+1}g[c[k>>2]>>2]=(+g[(c[c[j>>2]>>2]|0)+4>>2]*.5+ +g[c[c[j>>2]>>2]>>2])*.5;if((c[m>>2]|0)==2){c[o>>2]=1;while(1){if((c[o>>2]|0)>=(c[l>>2]>>1|0))break;m=(c[k>>2]|0)+(c[o>>2]<<2)|0;g[m>>2]=+g[m>>2]+((+g[(c[(c[j>>2]|0)+4>>2]|0)+((c[o>>2]<<1)-1<<2)>>2]+ +g[(c[(c[j>>2]|0)+4>>2]|0)+((c[o>>2]<<1)+1<<2)>>2])*.5+ +g[(c[(c[j>>2]|0)+4>>2]|0)+(c[o>>2]<<1<<2)>>2])*.5;c[o>>2]=(c[o>>2]|0)+1}m=c[k>>2]|0;g[m>>2]=+g[m>>2]+(+g[(c[(c[j>>2]|0)+4>>2]|0)+4>>2]*.5+ +g[c[(c[j>>2]|0)+4>>2]>>2])*.5}Bb(c[k>>2]|0,p,0,0,4,c[l>>2]>>1,c[n>>2]|0)|0;g[p>>2]=+g[p>>2]*1.000100016593933;c[o>>2]=1;while(1){if((c[o>>2]|0)>4)break;n=p+(c[o>>2]<<2)|0;g[n>>2]=+g[n>>2]-+g[p+(c[o>>2]<<2)>>2]*(+(c[o>>2]|0)*.00800000037997961)*(+(c[o>>2]|0)*.00800000037997961);c[o>>2]=(c[o>>2]|0)+1}yb(r,p,4);c[o>>2]=0;while(1){if((c[o>>2]|0)>=4)break;g[q>>2]=+g[q>>2]*.8999999761581421;g[r+(c[o>>2]<<2)>>2]=+g[r+(c[o>>2]<<2)>>2]*+g[q>>2];c[o>>2]=(c[o>>2]|0)+1}g[t>>2]=+g[r>>2]+.800000011920929;g[t+4>>2]=+g[r+4>>2]+ +g[u>>2]*+g[r>>2];g[t+8>>2]=+g[r+8>>2]+ +g[u>>2]*+g[r+4>>2];g[t+12>>2]=+g[r+12>>2]+ +g[u>>2]*+g[r+8>>2];g[t+16>>2]=+g[u>>2]*+g[r+12>>2];rd(c[k>>2]|0,t,c[k>>2]|0,c[l>>2]>>1,s);i=h;return}function wb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;h=i;i=i+48|0;j=h+4|0;k=h+32|0;l=h+8|0;m=h+36|0;n=h+44|0;o=h;p=h+16|0;q=h+40|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=0;while(1){if((c[o>>2]|0)>=((c[n>>2]|0)-3|0))break;c[p>>2]=0;c[p+4>>2]=0;c[p+8>>2]=0;c[p+12>>2]=0;sd(c[j>>2]|0,(c[k>>2]|0)+(c[o>>2]<<2)|0,p,c[m>>2]|0);g[(c[l>>2]|0)+(c[o>>2]<<2)>>2]=+g[p>>2];g[(c[l>>2]|0)+((c[o>>2]|0)+1<<2)>>2]=+g[p+4>>2];g[(c[l>>2]|0)+((c[o>>2]|0)+2<<2)>>2]=+g[p+8>>2];g[(c[l>>2]|0)+((c[o>>2]|0)+3<<2)>>2]=+g[p+12>>2];c[o>>2]=(c[o>>2]|0)+4}while(1){if((c[o>>2]|0)>=(c[n>>2]|0))break;g[q>>2]=+td(c[j>>2]|0,(c[k>>2]|0)+(c[o>>2]<<2)|0,c[m>>2]|0);g[(c[l>>2]|0)+(c[o>>2]<<2)>>2]=+g[q>>2];c[o>>2]=(c[o>>2]|0)+1}i=h;return}function xb(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;j=i;i=i+80|0;k=j+16|0;l=j+32|0;m=j+52|0;n=j+60|0;o=j+40|0;p=j+56|0;q=j+64|0;r=j+68|0;s=j+8|0;t=j+36|0;u=j+20|0;v=j;w=j+24|0;x=j+44|0;y=j+28|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[j+48>>2]=h;c[s>>2]=0;c[s+4>>2]=0;c[r>>2]=(c[m>>2]|0)+(c[n>>2]|0);h=c[m>>2]>>2;c[u>>2]=ua()|0;f=i;i=i+((1*(h<<2)|0)+15&-16)|0;h=i;i=i+((1*(c[r>>2]>>2<<2)|0)+15&-16)|0;e=i;i=i+((1*(c[n>>2]>>1<<2)|0)+15&-16)|0;c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[m>>2]>>2|0))break;g[f+(c[q>>2]<<2)>>2]=+g[(c[k>>2]|0)+(c[q>>2]<<1<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[r>>2]>>2|0))break;g[h+(c[q>>2]<<2)>>2]=+g[(c[l>>2]|0)+(c[q>>2]<<1<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}wb(f,h,e,c[m>>2]>>2,c[n>>2]>>2);ud(e,h,c[m>>2]>>2,c[n>>2]>>2,s);c[p>>2]=0;while(1){if((c[p>>2]|0)>=(c[n>>2]>>1|0))break;g[e+(c[p>>2]<<2)>>2]=0.0;if(!((N((c[p>>2]|0)-(c[s>>2]<<1)|0)|0)>2?(N((c[p>>2]|0)-(c[s+4>>2]<<1)|0)|0)>2:0)){g[v>>2]=+td(c[k>>2]|0,(c[l>>2]|0)+(c[p>>2]<<2)|0,c[m>>2]>>1);g[e+(c[p>>2]<<2)>>2]=-1.0>+g[v>>2]?-1.0:+g[v>>2]}c[p>>2]=(c[p>>2]|0)+1}ud(e,c[l>>2]|0,c[m>>2]>>1,c[n>>2]>>1,s);if((c[s>>2]|0)>0?(c[s>>2]|0)<((c[n>>2]>>1)-1|0):0){g[w>>2]=+g[e+((c[s>>2]|0)-1<<2)>>2];g[x>>2]=+g[e+(c[s>>2]<<2)>>2];g[y>>2]=+g[e+((c[s>>2]|0)+1<<2)>>2];if(+g[y>>2]-+g[w>>2]>(+g[x>>2]-+g[w>>2])*.699999988079071){c[t>>2]=1;z=c[s>>2]|0;A=z<<1;B=c[t>>2]|0;C=A-B|0;D=c[o>>2]|0;c[D>>2]=C;E=c[u>>2]|0;ka(E|0);i=j;return}if(+g[w>>2]-+g[y>>2]>(+g[x>>2]-+g[y>>2])*.699999988079071){c[t>>2]=-1;z=c[s>>2]|0;A=z<<1;B=c[t>>2]|0;C=A-B|0;D=c[o>>2]|0;c[D>>2]=C;E=c[u>>2]|0;ka(E|0);i=j;return}else{c[t>>2]=0;z=c[s>>2]|0;A=z<<1;B=c[t>>2]|0;C=A-B|0;D=c[o>>2]|0;c[D>>2]=C;E=c[u>>2]|0;ka(E|0);i=j;return}}c[t>>2]=0;z=c[s>>2]|0;A=z<<1;B=c[t>>2]|0;C=A-B|0;D=c[o>>2]|0;c[D>>2]=C;E=c[u>>2]|0;ka(E|0);i=j;return}function yb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;e=i;i=i+48|0;f=e+36|0;h=e+16|0;j=e;k=e+28|0;l=e+32|0;m=e+40|0;n=e+12|0;o=e+24|0;p=e+20|0;q=e+8|0;r=e+4|0;c[f>>2]=a;c[h>>2]=b;c[j>>2]=d;g[n>>2]=+g[c[h>>2]>>2];c[o>>2]=c[f>>2];c[k>>2]=0;while(1){if((c[k>>2]|0)>=(c[j>>2]|0))break;g[(c[o>>2]|0)+(c[k>>2]<<2)>>2]=0.0;c[k>>2]=(c[k>>2]|0)+1}if(!(+g[c[h>>2]>>2]!=0.0)){i=e;return}c[k>>2]=0;while(1){if((c[k>>2]|0)>=(c[j>>2]|0)){s=15;break}g[p>>2]=0.0;c[l>>2]=0;while(1){if((c[l>>2]|0)>=(c[k>>2]|0))break;g[p>>2]=+g[p>>2]+ +g[(c[o>>2]|0)+(c[l>>2]<<2)>>2]*+g[(c[h>>2]|0)+((c[k>>2]|0)-(c[l>>2]|0)<<2)>>2];c[l>>2]=(c[l>>2]|0)+1}g[p>>2]=+g[p>>2]+ +g[(c[h>>2]|0)+((c[k>>2]|0)+1<<2)>>2];g[m>>2]=-(+g[p>>2]/+g[n>>2]);g[(c[o>>2]|0)+(c[k>>2]<<2)>>2]=+g[m>>2];c[l>>2]=0;while(1){if((c[l>>2]|0)>=((c[k>>2]|0)+1>>1|0))break;g[q>>2]=+g[(c[o>>2]|0)+(c[l>>2]<<2)>>2];g[r>>2]=+g[(c[o>>2]|0)+((c[k>>2]|0)-1-(c[l>>2]|0)<<2)>>2];g[(c[o>>2]|0)+(c[l>>2]<<2)>>2]=+g[q>>2]+ +g[m>>2]*+g[r>>2];g[(c[o>>2]|0)+((c[k>>2]|0)-1-(c[l>>2]|0)<<2)>>2]=+g[r>>2]+ +g[m>>2]*+g[q>>2];c[l>>2]=(c[l>>2]|0)+1}g[n>>2]=+g[n>>2]-+g[m>>2]*+g[m>>2]*+g[n>>2];if(+g[n>>2]<+g[c[h>>2]>>2]*1.0000000474974513e-03){s=15;break}c[k>>2]=(c[k>>2]|0)+1}if((s|0)==15){i=e;return}}function zb(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;j=i;i=i+64|0;k=j+48|0;l=j+28|0;m=j;n=j+40|0;o=j+44|0;p=j+52|0;q=j+24|0;r=j+36|0;s=j+32|0;t=j+8|0;u=j+4|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;h=c[o>>2]|0;c[s>>2]=ua()|0;f=i;i=i+((1*(h<<2)|0)+15&-16)|0;h=i;i=i+((1*((c[n>>2]|0)+(c[o>>2]|0)<<2)|0)+15&-16)|0;c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;g[f+(c[q>>2]<<2)>>2]=+g[(c[l>>2]|0)+((c[o>>2]|0)-(c[q>>2]|0)-1<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;g[h+(c[q>>2]<<2)>>2]=+g[(c[p>>2]|0)+((c[o>>2]|0)-(c[q>>2]|0)-1<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[n>>2]|0))break;g[h+((c[q>>2]|0)+(c[o>>2]|0)<<2)>>2]=+g[(c[k>>2]|0)+(c[q>>2]<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;g[(c[p>>2]|0)+(c[q>>2]<<2)>>2]=+g[(c[k>>2]|0)+((c[n>>2]|0)-(c[q>>2]|0)-1<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}c[q>>2]=0;while(1){if((c[q>>2]|0)>=((c[n>>2]|0)-3|0))break;c[t>>2]=0;c[t+4>>2]=0;c[t+8>>2]=0;c[t+12>>2]=0;vd(f,h+(c[q>>2]<<2)|0,t,c[o>>2]|0);g[(c[m>>2]|0)+(c[q>>2]<<2)>>2]=+g[(c[k>>2]|0)+(c[q>>2]<<2)>>2]+ +g[t>>2];g[(c[m>>2]|0)+((c[q>>2]|0)+1<<2)>>2]=+g[(c[k>>2]|0)+((c[q>>2]|0)+1<<2)>>2]+ +g[t+4>>2];g[(c[m>>2]|0)+((c[q>>2]|0)+2<<2)>>2]=+g[(c[k>>2]|0)+((c[q>>2]|0)+2<<2)>>2]+ +g[t+8>>2];g[(c[m>>2]|0)+((c[q>>2]|0)+3<<2)>>2]=+g[(c[k>>2]|0)+((c[q>>2]|0)+3<<2)>>2]+ +g[t+12>>2];c[q>>2]=(c[q>>2]|0)+4}while(1){if((c[q>>2]|0)>=(c[n>>2]|0))break;g[u>>2]=0.0;c[r>>2]=0;while(1){if((c[r>>2]|0)>=(c[o>>2]|0))break;g[u>>2]=+g[u>>2]+ +g[f+(c[r>>2]<<2)>>2]*+g[h+((c[q>>2]|0)+(c[r>>2]|0)<<2)>>2];c[r>>2]=(c[r>>2]|0)+1}g[(c[m>>2]|0)+(c[q>>2]<<2)>>2]=+g[(c[k>>2]|0)+(c[q>>2]<<2)>>2]+ +g[u>>2];c[q>>2]=(c[q>>2]|0)+1}ka(c[s>>2]|0);i=j;return}function Ab(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;j=i;i=i+64|0;k=j+48|0;l=j+28|0;m=j;n=j+40|0;o=j+44|0;p=j+52|0;q=j+24|0;r=j+36|0;s=j+32|0;t=j+8|0;u=j+4|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;h=c[o>>2]|0;c[s>>2]=ua()|0;f=i;i=i+((1*(h<<2)|0)+15&-16)|0;h=i;i=i+((1*((c[n>>2]|0)+(c[o>>2]|0)<<2)|0)+15&-16)|0;c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;g[f+(c[q>>2]<<2)>>2]=+g[(c[l>>2]|0)+((c[o>>2]|0)-(c[q>>2]|0)-1<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;g[h+(c[q>>2]<<2)>>2]=-+g[(c[p>>2]|0)+((c[o>>2]|0)-(c[q>>2]|0)-1<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}while(1){if((c[q>>2]|0)>=((c[n>>2]|0)+(c[o>>2]|0)|0))break;g[h+(c[q>>2]<<2)>>2]=0.0;c[q>>2]=(c[q>>2]|0)+1}c[q>>2]=0;while(1){if((c[q>>2]|0)>=((c[n>>2]|0)-3|0))break;g[t>>2]=+g[(c[k>>2]|0)+(c[q>>2]<<2)>>2];g[t+4>>2]=+g[(c[k>>2]|0)+((c[q>>2]|0)+1<<2)>>2];g[t+8>>2]=+g[(c[k>>2]|0)+((c[q>>2]|0)+2<<2)>>2];g[t+12>>2]=+g[(c[k>>2]|0)+((c[q>>2]|0)+3<<2)>>2];vd(f,h+(c[q>>2]<<2)|0,t,c[o>>2]|0);g[h+((c[q>>2]|0)+(c[o>>2]|0)<<2)>>2]=-+g[t>>2];g[(c[m>>2]|0)+(c[q>>2]<<2)>>2]=+g[t>>2];g[t+4>>2]=+g[t+4>>2]+ +g[h+((c[q>>2]|0)+(c[o>>2]|0)<<2)>>2]*+g[c[l>>2]>>2];g[h+((c[q>>2]|0)+(c[o>>2]|0)+1<<2)>>2]=-+g[t+4>>2];g[(c[m>>2]|0)+((c[q>>2]|0)+1<<2)>>2]=+g[t+4>>2];g[t+8>>2]=+g[t+8>>2]+ +g[h+((c[q>>2]|0)+(c[o>>2]|0)+1<<2)>>2]*+g[c[l>>2]>>2];g[t+8>>2]=+g[t+8>>2]+ +g[h+((c[q>>2]|0)+(c[o>>2]|0)<<2)>>2]*+g[(c[l>>2]|0)+4>>2];g[h+((c[q>>2]|0)+(c[o>>2]|0)+2<<2)>>2]=-+g[t+8>>2];g[(c[m>>2]|0)+((c[q>>2]|0)+2<<2)>>2]=+g[t+8>>2];g[t+12>>2]=+g[t+12>>2]+ +g[h+((c[q>>2]|0)+(c[o>>2]|0)+2<<2)>>2]*+g[c[l>>2]>>2];g[t+12>>2]=+g[t+12>>2]+ +g[h+((c[q>>2]|0)+(c[o>>2]|0)+1<<2)>>2]*+g[(c[l>>2]|0)+4>>2];g[t+12>>2]=+g[t+12>>2]+ +g[h+((c[q>>2]|0)+(c[o>>2]|0)<<2)>>2]*+g[(c[l>>2]|0)+8>>2];g[h+((c[q>>2]|0)+(c[o>>2]|0)+3<<2)>>2]=-+g[t+12>>2];g[(c[m>>2]|0)+((c[q>>2]|0)+3<<2)>>2]=+g[t+12>>2];c[q>>2]=(c[q>>2]|0)+4}while(1){if((c[q>>2]|0)>=(c[n>>2]|0))break;g[u>>2]=+g[(c[k>>2]|0)+(c[q>>2]<<2)>>2];c[r>>2]=0;while(1){if((c[r>>2]|0)>=(c[o>>2]|0))break;g[u>>2]=+g[u>>2]-+g[f+(c[r>>2]<<2)>>2]*+g[h+((c[q>>2]|0)+(c[r>>2]|0)<<2)>>2];c[r>>2]=(c[r>>2]|0)+1}g[h+((c[q>>2]|0)+(c[o>>2]|0)<<2)>>2]=+g[u>>2];g[(c[m>>2]|0)+(c[q>>2]<<2)>>2]=+g[u>>2];c[q>>2]=(c[q>>2]|0)+1}c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;g[(c[p>>2]|0)+(c[q>>2]<<2)>>2]=+g[(c[m>>2]|0)+((c[n>>2]|0)-(c[q>>2]|0)-1<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}ka(c[s>>2]|0);i=j;return}function Bb(a,b,d,e,f,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0.0;k=i;i=i+64|0;l=k+52|0;m=k+44|0;n=k+24|0;o=k+20|0;p=k+12|0;q=k+40|0;r=k+56|0;s=k+28|0;t=k+8|0;u=k+4|0;v=k+32|0;w=k;x=k+16|0;y=k+36|0;c[l>>2]=a;c[m>>2]=b;c[n>>2]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=h;c[k+48>>2]=j;c[u>>2]=(c[q>>2]|0)-(c[p>>2]|0);j=c[q>>2]|0;c[x>>2]=ua()|0;h=i;i=i+((1*(j<<2)|0)+15&-16)|0;if(!(c[o>>2]|0))c[w>>2]=c[l>>2];else{c[s>>2]=0;while(1){if((c[s>>2]|0)>=(c[q>>2]|0))break;g[h+(c[s>>2]<<2)>>2]=+g[(c[l>>2]|0)+(c[s>>2]<<2)>>2];c[s>>2]=(c[s>>2]|0)+1}c[s>>2]=0;while(1){if((c[s>>2]|0)>=(c[o>>2]|0))break;g[h+(c[s>>2]<<2)>>2]=+g[(c[l>>2]|0)+(c[s>>2]<<2)>>2]*+g[(c[n>>2]|0)+(c[s>>2]<<2)>>2];g[h+((c[q>>2]|0)-(c[s>>2]|0)-1<<2)>>2]=+g[(c[l>>2]|0)+((c[q>>2]|0)-(c[s>>2]|0)-1<<2)>>2]*+g[(c[n>>2]|0)+(c[s>>2]<<2)>>2];c[s>>2]=(c[s>>2]|0)+1}c[w>>2]=h}c[v>>2]=0;wb(c[w>>2]|0,c[w>>2]|0,c[m>>2]|0,c[u>>2]|0,(c[p>>2]|0)+1|0);c[t>>2]=0;while(1){if((c[t>>2]|0)>(c[p>>2]|0))break;c[s>>2]=(c[t>>2]|0)+(c[u>>2]|0);g[r>>2]=0.0;while(1){z=+g[r>>2];if((c[s>>2]|0)>=(c[q>>2]|0))break;g[r>>2]=z+ +g[(c[w>>2]|0)+(c[s>>2]<<2)>>2]*+g[(c[w>>2]|0)+((c[s>>2]|0)-(c[t>>2]|0)<<2)>>2];c[s>>2]=(c[s>>2]|0)+1}h=(c[m>>2]|0)+(c[t>>2]<<2)|0;g[h>>2]=+g[h>>2]+z;c[t>>2]=(c[t>>2]|0)+1}t=c[v>>2]|0;c[y>>2]=1;ka(c[x>>2]|0);i=k;return t|0}function Cb(a,b,e,f,h,j,k,l){a=a|0;b=b|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0.0;m=i;i=i+96|0;n=m+36|0;o=m+24|0;p=m+20|0;q=m+72|0;r=m+32|0;s=m+16|0;t=m+52|0;u=m+60|0;v=m+68|0;w=m+76|0;x=m+80|0;y=m+40|0;z=m+8|0;A=m;B=m+4|0;C=m+48|0;D=m+56|0;E=m+28|0;F=m+64|0;G=m+12|0;c[n>>2]=a;c[o>>2]=b;c[p>>2]=e;c[q>>2]=f;c[r>>2]=h;c[s>>2]=j;c[t>>2]=k;c[u>>2]=l;c[v>>2]=2552+((c[u>>2]|0)*84|0)+((c[r>>2]|0)*42|0);c[y>>2]=0;c[y+4>>2]=0;if(c[r>>2]|0){g[z>>2]=0.0;g[A>>2]=.149993896484375}else{g[A>>2]=+g[2904+(c[u>>2]<<2)>>2];g[z>>2]=+g[2888+(c[u>>2]<<2)>>2]}c[B>>2]=c[(c[s>>2]|0)+4>>2]<<3;c[w>>2]=c[o>>2];while(1){if((c[w>>2]|0)>=(c[p>>2]|0))break;c[x>>2]=0;do{c[C>>2]=wd(c[s>>2]|0)|0;do if(((c[B>>2]|0)-(c[C>>2]|0)|0)<15){if(((c[B>>2]|0)-(c[C>>2]|0)|0)>=2){c[D>>2]=jb(c[s>>2]|0,2920,2)|0;c[D>>2]=c[D>>2]>>1^0-(c[D>>2]&1);break}if(((c[B>>2]|0)-(c[C>>2]|0)|0)>=1){c[D>>2]=0-(ib(c[s>>2]|0,1)|0);break}else{c[D>>2]=-1;break}}else{c[G>>2]=((c[w>>2]|0)<20?c[w>>2]|0:20)<<1;c[D>>2]=rb(c[s>>2]|0,(d[(c[v>>2]|0)+(c[G>>2]|0)>>0]|0)<<7,(d[(c[v>>2]|0)+((c[G>>2]|0)+1)>>0]|0)<<6)|0}while(0);g[E>>2]=+(c[D>>2]|0);o=(c[w>>2]|0)+(_(c[x>>2]|0,c[(c[n>>2]|0)+8>>2]|0)|0)|0;if(-9.0>+g[(c[q>>2]|0)+(o<<2)>>2])H=-9.0;else{o=(c[w>>2]|0)+(_(c[x>>2]|0,c[(c[n>>2]|0)+8>>2]|0)|0)|0;H=+g[(c[q>>2]|0)+(o<<2)>>2]}o=(c[w>>2]|0)+(_(c[x>>2]|0,c[(c[n>>2]|0)+8>>2]|0)|0)|0;g[(c[q>>2]|0)+(o<<2)>>2]=H;o=(c[w>>2]|0)+(_(c[x>>2]|0,c[(c[n>>2]|0)+8>>2]|0)|0)|0;g[F>>2]=+g[z>>2]*+g[(c[q>>2]|0)+(o<<2)>>2]+ +g[y+(c[x>>2]<<2)>>2]+ +g[E>>2];o=(c[w>>2]|0)+(_(c[x>>2]|0,c[(c[n>>2]|0)+8>>2]|0)|0)|0;g[(c[q>>2]|0)+(o<<2)>>2]=+g[F>>2];g[y+(c[x>>2]<<2)>>2]=+g[y+(c[x>>2]<<2)>>2]+ +g[E>>2]-+g[A>>2]*+g[E>>2];o=(c[x>>2]|0)+1|0;c[x>>2]=o}while((o|0)<(c[t>>2]|0));c[w>>2]=(c[w>>2]|0)+1}i=m;return}function Db(a,b,d,e,f,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;k=i;i=i+48|0;l=k+36|0;m=k+16|0;n=k;o=k+28|0;p=k+32|0;q=k+40|0;r=k+12|0;s=k+24|0;t=k+20|0;u=k+8|0;v=k+4|0;c[l>>2]=a;c[m>>2]=b;c[n>>2]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=h;c[r>>2]=j;c[s>>2]=c[m>>2];while(1){if((c[s>>2]|0)>=(c[n>>2]|0))break;if((c[(c[p>>2]|0)+(c[s>>2]<<2)>>2]|0)>0){c[t>>2]=0;do{c[u>>2]=lb(c[q>>2]|0,c[(c[p>>2]|0)+(c[s>>2]<<2)>>2]|0)|0;g[v>>2]=(+(c[u>>2]|0)+.5)*+(1<<14-(c[(c[p>>2]|0)+(c[s>>2]<<2)>>2]|0)|0)*.00006103515625-.5;m=(c[s>>2]|0)+(_(c[t>>2]|0,c[(c[l>>2]|0)+8>>2]|0)|0)|0;j=(c[o>>2]|0)+(m<<2)|0;g[j>>2]=+g[j>>2]+ +g[v>>2];j=(c[t>>2]|0)+1|0;c[t>>2]=j}while((j|0)<(c[r>>2]|0))}c[s>>2]=(c[s>>2]|0)+1}i=k;return}function Eb(a,b,d,e,f,h,j,k,l){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;m=i;i=i+64|0;n=m+24|0;o=m+20|0;p=m+44|0;q=m+36|0;r=m+32|0;s=m+40|0;t=m+48|0;u=m+52|0;v=m+8|0;w=m+4|0;x=m+28|0;y=m+12|0;z=m;A=m+16|0;c[n>>2]=a;c[o>>2]=b;c[p>>2]=d;c[q>>2]=e;c[r>>2]=f;c[s>>2]=h;c[t>>2]=j;c[u>>2]=k;c[v>>2]=l;c[x>>2]=0;while(1){if((c[x>>2]|0)>=2)break;c[w>>2]=c[o>>2];while(1){if((c[w>>2]|0)>=(c[p>>2]|0))break;if((c[t>>2]|0)<(c[v>>2]|0))break;if((c[(c[r>>2]|0)+(c[w>>2]<<2)>>2]|0)<8?(c[(c[s>>2]|0)+(c[w>>2]<<2)>>2]|0)==(c[x>>2]|0):0){c[y>>2]=0;do{c[z>>2]=lb(c[u>>2]|0,1)|0;g[A>>2]=(+(c[z>>2]|0)-.5)*+(1<<14-(c[(c[r>>2]|0)+(c[w>>2]<<2)>>2]|0)-1|0)*.00006103515625;l=(c[w>>2]|0)+(_(c[y>>2]|0,c[(c[n>>2]|0)+8>>2]|0)|0)|0;k=(c[q>>2]|0)+(l<<2)|0;g[k>>2]=+g[k>>2]+ +g[A>>2];c[t>>2]=(c[t>>2]|0)+-1;k=(c[y>>2]|0)+1|0;c[y>>2]=k}while((k|0)<(c[v>>2]|0))}c[w>>2]=(c[w>>2]|0)+1}c[x>>2]=(c[x>>2]|0)+1}i=m;return}function Fb(a,e,f,g,h,j,k,l,m,n,o,p,q,r,s,t,u,v,w){a=a|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;p=p|0;q=q|0;r=r|0;s=s|0;t=t|0;u=u|0;v=v|0;w=w|0;var x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0;x=i;i=i+160|0;y=x+72|0;z=x+56|0;A=x+4|0;B=x+52|0;C=x+140|0;D=x+68|0;E=x+20|0;F=x+24|0;G=x+28|0;H=x+32|0;I=x+36|0;J=x+40|0;K=x+44|0;L=x+48|0;M=x+112|0;N=x+120|0;O=x+128|0;P=x+136|0;Q=x+144|0;R=x+148|0;S=x+76|0;T=x+80|0;U=x+84|0;V=x+88|0;W=x+92|0;X=x+96|0;Y=x+100|0;Z=x+104|0;$=x+12|0;aa=x;ba=x+8|0;ca=x+108|0;da=x+116|0;ea=x+60|0;fa=x+124|0;ga=x+16|0;ha=x+64|0;ia=x+132|0;c[y>>2]=a;c[z>>2]=e;c[A>>2]=f;c[B>>2]=g;c[C>>2]=h;c[D>>2]=j;c[E>>2]=k;c[F>>2]=l;c[G>>2]=m;c[H>>2]=n;c[I>>2]=o;c[J>>2]=p;c[K>>2]=q;c[L>>2]=r;c[M>>2]=s;c[N>>2]=t;c[O>>2]=u;c[P>>2]=v;c[Q>>2]=w;c[G>>2]=(c[G>>2]|0)>0?c[G>>2]|0:0;c[T>>2]=c[(c[y>>2]|0)+8>>2];c[W>>2]=c[z>>2];c[X>>2]=(c[G>>2]|0)>=8?8:0;c[G>>2]=(c[G>>2]|0)-(c[X>>2]|0);c[Z>>2]=0;c[Y>>2]=0;do if((c[L>>2]|0)==2){c[Y>>2]=d[2928+((c[A>>2]|0)-(c[z>>2]|0))>>0];if((c[Y>>2]|0)>(c[G>>2]|0)){c[Y>>2]=0;break}else{c[G>>2]=(c[G>>2]|0)-(c[Y>>2]|0);c[Z>>2]=(c[G>>2]|0)>=8?8:0;c[G>>2]=(c[G>>2]|0)-(c[Z>>2]|0);break}}while(0);w=c[T>>2]|0;c[$>>2]=ua()|0;v=i;i=i+((1*(w<<2)|0)+15&-16)|0;w=i;i=i+((1*(c[T>>2]<<2)|0)+15&-16)|0;u=i;i=i+((1*(c[T>>2]<<2)|0)+15&-16)|0;t=i;i=i+((1*(c[T>>2]<<2)|0)+15&-16)|0;c[U>>2]=c[z>>2];while(1){if((c[U>>2]|0)>=(c[A>>2]|0))break;if((c[L>>2]<<3|0)>(((b[(c[(c[y>>2]|0)+32>>2]|0)+((c[U>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[y>>2]|0)+32>>2]|0)+(c[U>>2]<<1)>>1]|0)|0)*3<<c[M>>2]<<3>>4|0))ja=c[L>>2]<<3;else ja=((b[(c[(c[y>>2]|0)+32>>2]|0)+((c[U>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[y>>2]|0)+32>>2]|0)+(c[U>>2]<<1)>>1]|0)|0)*3<<c[M>>2]<<3>>4;c[u+(c[U>>2]<<2)>>2]=ja;s=_(c[L>>2]|0,(b[(c[(c[y>>2]|0)+32>>2]|0)+((c[U>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[y>>2]|0)+32>>2]|0)+(c[U>>2]<<1)>>1]|0)|0)|0;r=_(s,(c[D>>2]|0)-5-(c[M>>2]|0)|0)|0;s=_(r,(c[A>>2]|0)-(c[U>>2]|0)-1|0)|0;r=(_(s,1<<(c[M>>2]|0)+3)|0)>>6;c[t+(c[U>>2]<<2)>>2]=r;if(((b[(c[(c[y>>2]|0)+32>>2]|0)+((c[U>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[y>>2]|0)+32>>2]|0)+(c[U>>2]<<1)>>1]|0)<<c[M>>2]|0)==1){r=t+(c[U>>2]<<2)|0;c[r>>2]=(c[r>>2]|0)-(c[L>>2]<<3)}c[U>>2]=(c[U>>2]|0)+1}c[R>>2]=1;c[S>>2]=(c[(c[y>>2]|0)+48>>2]|0)-1;do{c[aa>>2]=0;c[ba>>2]=0;c[ca>>2]=(c[R>>2]|0)+(c[S>>2]|0)>>1;c[U>>2]=c[A>>2];while(1){D=c[U>>2]|0;c[U>>2]=D+-1;if((D|0)<=(c[z>>2]|0))break;c[ea>>2]=(b[(c[(c[y>>2]|0)+32>>2]|0)+((c[U>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[y>>2]|0)+32>>2]|0)+(c[U>>2]<<1)>>1]|0);D=_(c[L>>2]|0,c[ea>>2]|0)|0;ja=_(c[ca>>2]|0,c[T>>2]|0)|0;r=_(D,d[(c[(c[y>>2]|0)+52>>2]|0)+(ja+(c[U>>2]|0))>>0]|0)|0;c[da>>2]=r<<c[M>>2]>>2;if((c[da>>2]|0)>0){if(0>((c[da>>2]|0)+(c[t+(c[U>>2]<<2)>>2]|0)|0))la=0;else la=(c[da>>2]|0)+(c[t+(c[U>>2]<<2)>>2]|0)|0;c[da>>2]=la}c[da>>2]=(c[da>>2]|0)+(c[(c[B>>2]|0)+(c[U>>2]<<2)>>2]|0);if(!((c[aa>>2]|0)!=0?1:(c[da>>2]|0)>=(c[u+(c[U>>2]<<2)>>2]|0))){if((c[da>>2]|0)<(c[L>>2]<<3|0))continue;c[ba>>2]=(c[ba>>2]|0)+(c[L>>2]<<3);continue}c[aa>>2]=1;if((c[da>>2]|0)<(c[(c[C>>2]|0)+(c[U>>2]<<2)>>2]|0))ma=c[da>>2]|0;else ma=c[(c[C>>2]|0)+(c[U>>2]<<2)>>2]|0;c[ba>>2]=(c[ba>>2]|0)+ma}r=c[ca>>2]|0;if((c[ba>>2]|0)>(c[G>>2]|0))c[S>>2]=r-1;else c[R>>2]=r+1}while((c[R>>2]|0)<=(c[S>>2]|0));ba=c[R>>2]|0;c[R>>2]=ba+-1;c[S>>2]=ba;c[U>>2]=c[z>>2];while(1){if((c[U>>2]|0)>=(c[A>>2]|0))break;c[ha>>2]=(b[(c[(c[y>>2]|0)+32>>2]|0)+((c[U>>2]|0)+1<<1)>>1]|0)-(b[(c[(c[y>>2]|0)+32>>2]|0)+(c[U>>2]<<1)>>1]|0);ba=_(c[L>>2]|0,c[ha>>2]|0)|0;ca=_(c[R>>2]|0,c[T>>2]|0)|0;ma=_(ba,d[(c[(c[y>>2]|0)+52>>2]|0)+(ca+(c[U>>2]|0))>>0]|0)|0;c[fa>>2]=ma<<c[M>>2]>>2;if((c[S>>2]|0)>=(c[(c[y>>2]|0)+48>>2]|0))na=c[(c[C>>2]|0)+(c[U>>2]<<2)>>2]|0;else{ma=_(c[L>>2]|0,c[ha>>2]|0)|0;ca=_(c[S>>2]|0,c[T>>2]|0)|0;ba=_(ma,d[(c[(c[y>>2]|0)+52>>2]|0)+(ca+(c[U>>2]|0))>>0]|0)|0;na=ba<<c[M>>2]>>2}c[ga>>2]=na;if((c[fa>>2]|0)>0){if(0>((c[fa>>2]|0)+(c[t+(c[U>>2]<<2)>>2]|0)|0))oa=0;else oa=(c[fa>>2]|0)+(c[t+(c[U>>2]<<2)>>2]|0)|0;c[fa>>2]=oa}if((c[ga>>2]|0)>0){if(0>((c[ga>>2]|0)+(c[t+(c[U>>2]<<2)>>2]|0)|0))pa=0;else pa=(c[ga>>2]|0)+(c[t+(c[U>>2]<<2)>>2]|0)|0;c[ga>>2]=pa}if((c[R>>2]|0)>0)c[fa>>2]=(c[fa>>2]|0)+(c[(c[B>>2]|0)+(c[U>>2]<<2)>>2]|0);c[ga>>2]=(c[ga>>2]|0)+(c[(c[B>>2]|0)+(c[U>>2]<<2)>>2]|0);if((c[(c[B>>2]|0)+(c[U>>2]<<2)>>2]|0)>0)c[W>>2]=c[U>>2];if(0>((c[ga>>2]|0)-(c[fa>>2]|0)|0))qa=0;else qa=(c[ga>>2]|0)-(c[fa>>2]|0)|0;c[ga>>2]=qa;c[v+(c[U>>2]<<2)>>2]=c[fa>>2];c[w+(c[U>>2]<<2)>>2]=c[ga>>2];c[U>>2]=(c[U>>2]|0)+1}c[V>>2]=xd(c[y>>2]|0,c[z>>2]|0,c[A>>2]|0,c[W>>2]|0,v,w,u,c[C>>2]|0,c[G>>2]|0,c[H>>2]|0,c[X>>2]|0,c[E>>2]|0,c[Y>>2]|0,c[F>>2]|0,c[Z>>2]|0,c[I>>2]|0,c[J>>2]|0,c[K>>2]|0,c[L>>2]|0,c[M>>2]|0,c[N>>2]|0,c[O>>2]|0,c[P>>2]|0,c[Q>>2]|0)|0;Q=c[V>>2]|0;c[ia>>2]=1;ka(c[$>>2]|0);i=x;return Q|0}function Gb(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0;j=i;i=i+96|0;k=j+84|0;l=j;m=j+4|0;n=j+40|0;o=j+76|0;p=j+16|0;q=j+20|0;r=j+24|0;s=j+64|0;t=j+72|0;u=j+80|0;v=j+88|0;w=j+44|0;x=j+48|0;y=j+52|0;z=j+8|0;A=j+56|0;B=j+28|0;C=j+60|0;D=j+12|0;E=j+32|0;F=j+68|0;G=j+36|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;h=c[l>>2]|0;c[y>>2]=ua()|0;f=i;i=i+((1*(h<<2)|0)+15&-16)|0;h=i;i=i+((1*(c[l>>2]<<2)|0)+15&-16)|0;e=i;i=i+((1*(c[l>>2]<<2)|0)+15&-16)|0;yd(c[k>>2]|0,c[l>>2]|0,1,c[o>>2]|0,c[m>>2]|0,c[n>>2]|0);g[u>>2]=0.0;c[r>>2]=0;do{n=e+(c[r>>2]<<2)|0;if(+g[(c[k>>2]|0)+(c[r>>2]<<2)>>2]>0.0)g[n>>2]=1.0;else{g[n>>2]=-1.0;g[(c[k>>2]|0)+(c[r>>2]<<2)>>2]=-+g[(c[k>>2]|0)+(c[r>>2]<<2)>>2]}c[h+(c[r>>2]<<2)>>2]=0;g[f+(c[r>>2]<<2)>>2]=0.0;n=(c[r>>2]|0)+1|0;c[r>>2]=n}while((n|0)<(c[l>>2]|0));g[w>>2]=0.0;g[v>>2]=0.0;c[t>>2]=c[m>>2];if((c[m>>2]|0)>(c[l>>2]>>1|0)){c[r>>2]=0;do{g[u>>2]=+g[u>>2]+ +g[(c[k>>2]|0)+(c[r>>2]<<2)>>2];n=(c[r>>2]|0)+1|0;c[r>>2]=n}while((n|0)<(c[l>>2]|0));if(!(+g[u>>2]>1.0000000036274937e-15&+g[u>>2]<64.0)){g[c[k>>2]>>2]=1.0;c[r>>2]=1;do{g[(c[k>>2]|0)+(c[r>>2]<<2)>>2]=0.0;n=(c[r>>2]|0)+1|0;c[r>>2]=n}while((n|0)<(c[l>>2]|0));g[u>>2]=1.0}g[z>>2]=+((c[m>>2]|0)-1|0)*(1.0/+g[u>>2]);c[r>>2]=0;do{u=~~+M(+(+g[z>>2]*+g[(c[k>>2]|0)+(c[r>>2]<<2)>>2]));c[h+(c[r>>2]<<2)>>2]=u;g[f+(c[r>>2]<<2)>>2]=+(c[h+(c[r>>2]<<2)>>2]|0);g[w>>2]=+g[w>>2]+ +g[f+(c[r>>2]<<2)>>2]*+g[f+(c[r>>2]<<2)>>2];g[v>>2]=+g[v>>2]+ +g[(c[k>>2]|0)+(c[r>>2]<<2)>>2]*+g[f+(c[r>>2]<<2)>>2];u=f+(c[r>>2]<<2)|0;g[u>>2]=+g[u>>2]*2.0;c[t>>2]=(c[t>>2]|0)-(c[h+(c[r>>2]<<2)>>2]|0);u=(c[r>>2]|0)+1|0;c[r>>2]=u}while((u|0)<(c[l>>2]|0))}if((c[t>>2]|0)>((c[l>>2]|0)+3|0)){g[A>>2]=+(c[t>>2]|0);g[w>>2]=+g[w>>2]+ +g[A>>2]*+g[A>>2];g[w>>2]=+g[w>>2]+ +g[A>>2]*+g[f>>2];c[h>>2]=(c[h>>2]|0)+(c[t>>2]|0);c[t>>2]=0}g[s>>2]=1.0;c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[t>>2]|0))break;g[C>>2]=-999999986991104.0;g[D>>2]=0.0;c[B>>2]=0;g[w>>2]=+g[w>>2]+1.0;c[r>>2]=0;do{g[E>>2]=+g[v>>2]+ +g[(c[k>>2]|0)+(c[r>>2]<<2)>>2];g[F>>2]=+g[w>>2]+ +g[f+(c[r>>2]<<2)>>2];g[E>>2]=+g[E>>2]*+g[E>>2];if(+g[D>>2]*+g[E>>2]>+g[F>>2]*+g[C>>2]){g[D>>2]=+g[F>>2];g[C>>2]=+g[E>>2];c[B>>2]=c[r>>2]}A=(c[r>>2]|0)+1|0;c[r>>2]=A}while((A|0)<(c[l>>2]|0));g[v>>2]=+g[v>>2]+ +g[(c[k>>2]|0)+(c[B>>2]<<2)>>2];g[w>>2]=+g[w>>2]+ +g[f+(c[B>>2]<<2)>>2];A=f+(c[B>>2]<<2)|0;g[A>>2]=+g[A>>2]+ +g[s>>2]*2.0;A=h+(c[B>>2]<<2)|0;c[A>>2]=(c[A>>2]|0)+1;c[q>>2]=(c[q>>2]|0)+1}c[r>>2]=0;do{g[(c[k>>2]|0)+(c[r>>2]<<2)>>2]=+g[e+(c[r>>2]<<2)>>2]*+g[(c[k>>2]|0)+(c[r>>2]<<2)>>2];if(+g[e+(c[r>>2]<<2)>>2]<0.0)c[h+(c[r>>2]<<2)>>2]=0-(c[h+(c[r>>2]<<2)>>2]|0);q=(c[r>>2]|0)+1|0;c[r>>2]=q}while((q|0)<(c[l>>2]|0));bb(h,c[l>>2]|0,c[m>>2]|0,c[p>>2]|0);c[x>>2]=zd(h,c[l>>2]|0,c[o>>2]|0)|0;o=c[x>>2]|0;c[G>>2]=1;ka(c[y>>2]|0);i=j;return o|0}function Hb(a,b,d,e,f,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;j=+j;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;k=i;i=i+48|0;l=k+36|0;m=k+16|0;n=k;o=k+28|0;p=k+32|0;q=k+40|0;r=k+12|0;s=k+24|0;t=k+20|0;u=k+8|0;c[l>>2]=a;c[m>>2]=b;c[n>>2]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=h;g[r>>2]=j;h=c[m>>2]|0;c[u>>2]=ua()|0;f=i;i=i+((1*(h<<2)|0)+15&-16)|0;g[s>>2]=+cb(f,c[m>>2]|0,c[n>>2]|0,c[q>>2]|0);Ad(f,c[l>>2]|0,c[m>>2]|0,+g[s>>2],+g[r>>2]);yd(c[l>>2]|0,c[m>>2]|0,-1,c[p>>2]|0,c[n>>2]|0,c[o>>2]|0);c[t>>2]=zd(f,c[m>>2]|0,c[p>>2]|0)|0;p=c[t>>2]|0;c[k+4>>2]=1;ka(c[u>>2]|0);i=k;return p|0}function Ib(a,b,d){a=a|0;b=b|0;d=+d;var e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;e=i;i=i+32|0;f=e+4|0;h=e+16|0;j=e+8|0;k=e+20|0;l=e+28|0;m=e;n=e+12|0;o=e+24|0;c[f>>2]=a;c[h>>2]=b;g[j>>2]=d;g[l>>2]=+Bd(c[f>>2]|0,c[f>>2]|0,c[h>>2]|0)+1.0000000036274937e-15;g[n>>2]=+g[l>>2];d=1.0/+O(+(+g[n>>2]));g[m>>2]=d*+g[j>>2];c[o>>2]=c[f>>2];c[k>>2]=0;while(1){if((c[k>>2]|0)>=(c[h>>2]|0))break;g[c[o>>2]>>2]=+g[m>>2]*+g[c[o>>2]>>2];c[o>>2]=(c[o>>2]|0)+4;c[k>>2]=(c[k>>2]|0)+1}i=e;return}function Jb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0.0;f=i;i=i+48|0;h=f+4|0;j=f+16|0;k=f+36|0;l=f;m=f+32|0;n=f+40|0;o=f+44|0;p=f+24|0;q=f+20|0;r=f+8|0;s=f+12|0;t=f+28|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;g[r>>2]=1.0000000036274937e-15;g[q>>2]=1.0000000036274937e-15;a:do if(c[k>>2]|0){c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[l>>2]|0))break a;g[s>>2]=+g[(c[h>>2]|0)+(c[m>>2]<<2)>>2]+ +g[(c[j>>2]|0)+(c[m>>2]<<2)>>2];g[t>>2]=+g[(c[h>>2]|0)+(c[m>>2]<<2)>>2]-+g[(c[j>>2]|0)+(c[m>>2]<<2)>>2];g[q>>2]=+g[q>>2]+ +g[s>>2]*+g[s>>2];g[r>>2]=+g[r>>2]+ +g[t>>2]*+g[t>>2];c[m>>2]=(c[m>>2]|0)+1}}else{u=+Bd(c[h>>2]|0,c[h>>2]|0,c[l>>2]|0);g[q>>2]=+g[q>>2]+u;u=+Bd(c[j>>2]|0,c[j>>2]|0,c[l>>2]|0);g[r>>2]=+g[r>>2]+u}while(0);g[o>>2]=+O(+(+g[q>>2]));g[p>>2]=+O(+(+g[r>>2]));c[n>>2]=~~+M(+(+W(+(+g[p>>2]),+(+g[o>>2]))*10430.3818359375+.5));i=f;return c[n>>2]|0}function Kb(a){a=a|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[e>>2]=a;c[g>>2]=32767/((c[(c[e>>2]|0)+2340>>2]|0)+1|0)|0;c[h>>2]=0;c[f>>2]=0;while(1){if((c[f>>2]|0)>=(c[(c[e>>2]|0)+2340>>2]|0))break;c[h>>2]=(c[h>>2]|0)+(c[g>>2]|0);b[(c[e>>2]|0)+2772+1280+(c[f>>2]<<1)>>1]=c[h>>2];c[f>>2]=(c[f>>2]|0)+1}c[(c[e>>2]|0)+2772+1376>>2]=0;c[(c[e>>2]|0)+2772+1380>>2]=3176576;i=d;return}function Lb(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;g=i;i=i+80|0;h=g;j=g+16|0;k=g+4|0;l=g+8|0;m=g+32|0;n=g+36|0;o=g+12|0;p=g+24|0;q=g+40|0;r=g+28|0;s=g+20|0;c[h>>2]=a;c[j>>2]=d;c[k>>2]=e;c[l>>2]=f;c[r>>2]=(c[h>>2]|0)+2772;if((c[(c[h>>2]|0)+2316>>2]|0)!=(c[(c[r>>2]|0)+1384>>2]|0)){Kb(c[h>>2]|0);c[(c[r>>2]|0)+1384>>2]=c[(c[h>>2]|0)+2316>>2]}a:do if((c[(c[h>>2]|0)+4160>>2]|0)==0?(c[(c[h>>2]|0)+4164>>2]|0)==0:0){c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[(c[h>>2]|0)+2340>>2]|0))break;f=(c[r>>2]|0)+1280+(c[m>>2]<<1)|0;b[f>>1]=(b[f>>1]|0)+((((b[(c[h>>2]|0)+2344+(c[m>>2]<<1)>>1]|0)-(b[(c[r>>2]|0)+1280+(c[m>>2]<<1)>>1]|0)>>16)*16348|0)+(((b[(c[h>>2]|0)+2344+(c[m>>2]<<1)>>1]|0)-(b[(c[r>>2]|0)+1280+(c[m>>2]<<1)>>1]|0)&65535)*16348>>16));c[m>>2]=(c[m>>2]|0)+1}c[p>>2]=0;c[n>>2]=0;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[(c[h>>2]|0)+2324>>2]|0))break;if((c[(c[j>>2]|0)+16+(c[m>>2]<<2)>>2]|0)>(c[p>>2]|0)){c[p>>2]=c[(c[j>>2]|0)+16+(c[m>>2]<<2)>>2];c[n>>2]=c[m>>2]}c[m>>2]=(c[m>>2]|0)+1}ff((c[r>>2]|0)+(c[(c[h>>2]|0)+2332>>2]<<2)|0,c[r>>2]|0,(_((c[(c[h>>2]|0)+2324>>2]|0)-1|0,c[(c[h>>2]|0)+2332>>2]|0)|0)<<2|0)|0;f=_(c[n>>2]|0,c[(c[h>>2]|0)+2332>>2]|0)|0;df(c[r>>2]|0,(c[h>>2]|0)+4+(f<<2)|0,c[(c[h>>2]|0)+2332>>2]<<2|0)|0;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[(c[h>>2]|0)+2324>>2]|0))break a;f=(c[r>>2]|0)+1376|0;c[f>>2]=(c[f>>2]|0)+((((c[(c[j>>2]|0)+16+(c[m>>2]<<2)>>2]|0)-(c[(c[r>>2]|0)+1376>>2]|0)>>16)*4634|0)+(((c[(c[j>>2]|0)+16+(c[m>>2]<<2)>>2]|0)-(c[(c[r>>2]|0)+1376>>2]|0)&65535)*4634>>16));c[m>>2]=(c[m>>2]|0)+1}}while(0);if(!(c[(c[h>>2]|0)+4160>>2]|0)){bf((c[r>>2]|0)+1312|0,0,c[(c[h>>2]|0)+2340>>2]<<2|0)|0;i=g;return}j=(c[l>>2]|0)+16|0;c[s>>2]=ua()|0;n=i;i=i+((1*(j<<2)|0)+15&-16)|0;Cd(n+64|0,c[r>>2]|0,c[(c[r>>2]|0)+1376>>2]|0,c[l>>2]|0,(c[r>>2]|0)+1380|0);jc(q,(c[r>>2]|0)+1280|0,c[(c[h>>2]|0)+2340>>2]|0);j=n;p=(c[r>>2]|0)+1312|0;f=j+64|0;do{c[j>>2]=c[p>>2];j=j+4|0;p=p+4|0}while((j|0)<(f|0));c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[l>>2]|0))break;c[o>>2]=c[(c[h>>2]|0)+2340>>2]>>1;e=_(c[n+(16+(c[m>>2]|0)-1<<2)>>2]>>16,b[q>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-1<<2)>>2]&65535,b[q>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-2<<2)>>2]>>16,b[q+2>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-2<<2)>>2]&65535,b[q+2>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-3<<2)>>2]>>16,b[q+4>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-3<<2)>>2]&65535,b[q+4>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-4<<2)>>2]>>16,b[q+6>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-4<<2)>>2]&65535,b[q+6>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-5<<2)>>2]>>16,b[q+8>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-5<<2)>>2]&65535,b[q+8>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-6<<2)>>2]>>16,b[q+10>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-6<<2)>>2]&65535,b[q+10>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-7<<2)>>2]>>16,b[q+12>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-7<<2)>>2]&65535,b[q+12>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-8<<2)>>2]>>16,b[q+14>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-8<<2)>>2]&65535,b[q+14>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-9<<2)>>2]>>16,b[q+16>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-9<<2)>>2]&65535,b[q+16>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-10<<2)>>2]>>16,b[q+18>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-10<<2)>>2]&65535,b[q+18>>1]|0)|0)>>16));if((c[(c[h>>2]|0)+2340>>2]|0)==16){e=_(c[n+(16+(c[m>>2]|0)-11<<2)>>2]>>16,b[q+20>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-11<<2)>>2]&65535,b[q+20>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-12<<2)>>2]>>16,b[q+22>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-12<<2)>>2]&65535,b[q+22>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-13<<2)>>2]>>16,b[q+24>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-13<<2)>>2]&65535,b[q+24>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-14<<2)>>2]>>16,b[q+26>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-14<<2)>>2]&65535,b[q+26>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-15<<2)>>2]>>16,b[q+28>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-15<<2)>>2]&65535,b[q+28>>1]|0)|0)>>16));e=_(c[n+(16+(c[m>>2]|0)-16<<2)>>2]>>16,b[q+30>>1]|0)|0;c[o>>2]=(c[o>>2]|0)+(e+((_(c[n+(16+(c[m>>2]|0)-16<<2)>>2]&65535,b[q+30>>1]|0)|0)>>16))}c[n+(16+(c[m>>2]|0)<<2)>>2]=(c[n+(16+(c[m>>2]|0)<<2)>>2]|0)+(c[o>>2]<<4);if(((b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]|0)+((c[o>>2]>>5)+1>>1)|0)<=32767)if(((b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]|0)+((c[o>>2]>>5)+1>>1)|0)<-32768)t=-32768;else t=(b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]|0)+((c[o>>2]>>5)+1>>1)|0;else t=32767;b[(c[k>>2]|0)+(c[m>>2]<<1)>>1]=t;c[m>>2]=(c[m>>2]|0)+1}j=(c[r>>2]|0)+1312|0;p=n+(c[l>>2]<<2)|0;f=j+64|0;do{c[j>>2]=c[p>>2];j=j+4|0;p=p+4|0}while((j|0)<(f|0));ka(c[s>>2]|0);i=g;return}function Mb(d,e,f,g,h,j){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;k=i;i=i+48|0;l=k+12|0;m=k+16|0;n=k+28|0;o=k+4|0;p=k+32|0;q=k+36|0;r=k+40|0;s=k+24|0;t=k+20|0;u=k+44|0;v=k;w=k+8|0;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[p>>2]=h;c[q>>2]=j;a[u+1>>0]=0;c[v>>2]=c[m>>2];c[r>>2]=(((c[p>>2]|0)+(c[o>>2]<<1)&65535)<<16>>16)*7;c[w>>2]=1496+(c[r>>2]|0);c[n>>2]=(c[n>>2]|0)+8>>4;c[r>>2]=0;while(1){if((c[r>>2]|0)>=(c[n>>2]|0))break;c[t>>2]=c[(c[q>>2]|0)+(c[r>>2]<<2)>>2];a:do if((c[t>>2]|0)>0){a[u>>0]=a[(c[w>>2]|0)+((c[t>>2]&31|0)<6?c[t>>2]&31:6)>>0]|0;c[s>>2]=0;while(1){if((c[s>>2]|0)>=16)break a;if((b[(c[v>>2]|0)+(c[s>>2]<<1)>>1]|0)>0){o=((jb(c[l>>2]|0,u,8)|0)<<1)-1|0;p=(c[v>>2]|0)+(c[s>>2]<<1)|0;b[p>>1]=_(b[p>>1]|0,o)|0}c[s>>2]=(c[s>>2]|0)+1}}while(0);c[v>>2]=(c[v>>2]|0)+32;c[r>>2]=(c[r>>2]|0)+1}i=k;return}function Nb(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;bf(c[d>>2]|0,0,4260)|0;c[(c[d>>2]|0)+2376>>2]=1;c[c[d>>2]>>2]=65536;Kb(c[d>>2]|0);Zb(c[d>>2]|0);i=b;return 0}function Ob(d,e,f,g){d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;h=i;i=i+144|0;j=h+48|0;k=h+40|0;l=h;m=h+84|0;n=h+4|0;o=h+16|0;p=h+20|0;q=h+24|0;r=h+28|0;s=h+72|0;t=h+80|0;u=h+88|0;v=h+92|0;w=h+96|0;x=h+104|0;y=h+56|0;z=h+60|0;A=h+8|0;B=h+64|0;C=h+12|0;D=h+32|0;E=h+68|0;F=h+36|0;G=h+76|0;H=h+44|0;I=h+52|0;c[j>>2]=d;c[k>>2]=e;c[l>>2]=f;c[m>>2]=g;c[p>>2]=0;g=c[(c[j>>2]|0)+2336>>2]|0;c[I>>2]=ua()|0;f=i;i=i+((1*(g<<1)|0)+15&-16)|0;g=i;i=i+((1*((c[(c[j>>2]|0)+2336>>2]|0)+(c[(c[j>>2]|0)+2328>>2]|0)<<2)|0)+15&-16)|0;e=i;i=i+((1*(c[(c[j>>2]|0)+2332>>2]<<2)|0)+15&-16)|0;d=i;i=i+((1*((c[(c[j>>2]|0)+2332>>2]|0)+16<<2)|0)+15&-16)|0;c[E>>2]=b[456+(a[(c[j>>2]|0)+2736+29>>0]>>1<<2)+(a[(c[j>>2]|0)+2736+30>>0]<<1)>>1];if((a[(c[j>>2]|0)+2736+31>>0]|0)<4)c[s>>2]=1;else c[s>>2]=0;c[D>>2]=a[(c[j>>2]|0)+2736+34>>0];c[n>>2]=0;while(1){if((c[n>>2]|0)>=(c[(c[j>>2]|0)+2328>>2]|0))break;c[D>>2]=907633515+(_(c[D>>2]|0,196314165)|0);c[(c[j>>2]|0)+4+(c[n>>2]<<2)>>2]=b[(c[m>>2]|0)+(c[n>>2]<<1)>>1]<<14;J=(c[j>>2]|0)+4+(c[n>>2]<<2)|0;K=c[J>>2]|0;if((c[(c[j>>2]|0)+4+(c[n>>2]<<2)>>2]|0)<=0){if((K|0)<0){L=(c[j>>2]|0)+4+(c[n>>2]<<2)|0;c[L>>2]=(c[L>>2]|0)+1280}}else c[J>>2]=K-1280;K=(c[j>>2]|0)+4+(c[n>>2]<<2)|0;c[K>>2]=(c[K>>2]|0)+(c[E>>2]<<4);if((c[D>>2]|0)<0)c[(c[j>>2]|0)+4+(c[n>>2]<<2)>>2]=0-(c[(c[j>>2]|0)+4+(c[n>>2]<<2)>>2]|0);c[D>>2]=(c[D>>2]|0)+(b[(c[m>>2]|0)+(c[n>>2]<<1)>>1]|0);c[n>>2]=(c[n>>2]|0)+1}m=d;D=(c[j>>2]|0)+1284|0;E=m+64|0;do{c[m>>2]=c[D>>2];m=m+4|0;D=D+4|0}while((m|0)<(E|0));c[G>>2]=(c[j>>2]|0)+4;c[w>>2]=c[l>>2];c[r>>2]=c[(c[j>>2]|0)+2336>>2];c[o>>2]=0;while(1){if((c[o>>2]|0)>=(c[(c[j>>2]|0)+2324>>2]|0))break;c[H>>2]=e;c[u>>2]=(c[k>>2]|0)+32+(c[o>>2]>>1<<5);df(x|0,c[u>>2]|0,c[(c[j>>2]|0)+2340>>2]<<1|0)|0;c[v>>2]=(c[k>>2]|0)+96+((c[o>>2]|0)*5<<1);c[t>>2]=a[(c[j>>2]|0)+2736+29>>0];c[A>>2]=c[(c[k>>2]|0)+16+(c[o>>2]<<2)>>2]>>6;c[B>>2]=Dd(c[(c[k>>2]|0)+16+(c[o>>2]<<2)>>2]|0,47)|0;a:do if((c[(c[k>>2]|0)+16+(c[o>>2]<<2)>>2]|0)!=(c[c[j>>2]>>2]|0)){c[C>>2]=Ed(c[c[j>>2]>>2]|0,c[(c[k>>2]|0)+16+(c[o>>2]<<2)>>2]|0,16)|0;c[n>>2]=0;while(1){if((c[n>>2]|0)>=16)break a;K=_(c[C>>2]>>16,(c[d+(c[n>>2]<<2)>>2]&65535)<<16>>16)|0;J=K+((_(c[C>>2]&65535,(c[d+(c[n>>2]<<2)>>2]&65535)<<16>>16)|0)>>16)|0;K=J+(_(c[C>>2]|0,(c[d+(c[n>>2]<<2)>>2]>>15)+1>>1)|0)|0;c[d+(c[n>>2]<<2)>>2]=K;c[n>>2]=(c[n>>2]|0)+1}}else c[C>>2]=65536;while(0);c[c[j>>2]>>2]=c[(c[k>>2]|0)+16+(c[o>>2]<<2)>>2];if(((c[(c[j>>2]|0)+4160>>2]|0)!=0?(c[(c[j>>2]|0)+4164>>2]|0)==2:0)?((c[o>>2]|0)<2?(a[(c[j>>2]|0)+2736+29>>0]|0)!=2:0):0){K=c[v>>2]|0;b[K>>1]=0;b[K+2>>1]=0;b[K+4>>1]=0;b[K+6>>1]=0;b[K+8>>1]=0;b[(c[v>>2]|0)+4>>1]=4096;c[t>>2]=2;c[(c[k>>2]|0)+(c[o>>2]<<2)>>2]=c[(c[j>>2]|0)+2308>>2]}b:do if((c[t>>2]|0)==2){c[p>>2]=c[(c[k>>2]|0)+(c[o>>2]<<2)>>2];if((c[o>>2]|0)!=0?!((c[o>>2]|0)==2&(c[s>>2]|0)!=0):0){if((c[C>>2]|0)==65536)break;c[n>>2]=0;while(1){if((c[n>>2]|0)>=((c[p>>2]|0)+2|0))break b;K=_(c[C>>2]>>16,(c[g+((c[r>>2]|0)-(c[n>>2]|0)-1<<2)>>2]&65535)<<16>>16)|0;J=K+((_(c[C>>2]&65535,(c[g+((c[r>>2]|0)-(c[n>>2]|0)-1<<2)>>2]&65535)<<16>>16)|0)>>16)|0;K=J+(_(c[C>>2]|0,(c[g+((c[r>>2]|0)-(c[n>>2]|0)-1<<2)>>2]>>15)+1>>1)|0)|0;c[g+((c[r>>2]|0)-(c[n>>2]|0)-1<<2)>>2]=K;c[n>>2]=(c[n>>2]|0)+1}}c[q>>2]=(c[(c[j>>2]|0)+2336>>2]|0)-(c[p>>2]|0)-(c[(c[j>>2]|0)+2340>>2]|0)-2;if((c[o>>2]|0)==2)df((c[j>>2]|0)+1348+(c[(c[j>>2]|0)+2336>>2]<<1)|0,c[l>>2]|0,c[(c[j>>2]|0)+2332>>2]<<1<<1|0)|0;K=(c[q>>2]|0)+(_(c[o>>2]|0,c[(c[j>>2]|0)+2332>>2]|0)|0)|0;hc(f+(c[q>>2]<<1)|0,(c[j>>2]|0)+1348+(K<<1)|0,c[u>>2]|0,(c[(c[j>>2]|0)+2336>>2]|0)-(c[q>>2]|0)|0,c[(c[j>>2]|0)+2340>>2]|0);if(!(c[o>>2]|0)){K=_(c[B>>2]>>16,(c[(c[k>>2]|0)+136>>2]&65535)<<16>>16)|0;c[B>>2]=K+((_(c[B>>2]&65535,(c[(c[k>>2]|0)+136>>2]&65535)<<16>>16)|0)>>16)<<2}c[n>>2]=0;while(1){if((c[n>>2]|0)>=((c[p>>2]|0)+2|0))break b;K=_(c[B>>2]>>16,b[f+((c[(c[j>>2]|0)+2336>>2]|0)-(c[n>>2]|0)-1<<1)>>1]|0)|0;J=K+((_(c[B>>2]&65535,b[f+((c[(c[j>>2]|0)+2336>>2]|0)-(c[n>>2]|0)-1<<1)>>1]|0)|0)>>16)|0;c[g+((c[r>>2]|0)-(c[n>>2]|0)-1<<2)>>2]=J;c[n>>2]=(c[n>>2]|0)+1}}while(0);c:do if((c[t>>2]|0)==2){c[F>>2]=g+((c[r>>2]|0)-(c[p>>2]|0)+2<<2);c[n>>2]=0;while(1){if((c[n>>2]|0)>=(c[(c[j>>2]|0)+2332>>2]|0))break c;c[y>>2]=2;J=_(c[c[F>>2]>>2]>>16,b[c[v>>2]>>1]|0)|0;c[y>>2]=(c[y>>2]|0)+(J+((_(c[c[F>>2]>>2]&65535,b[c[v>>2]>>1]|0)|0)>>16));J=_(c[(c[F>>2]|0)+-4>>2]>>16,b[(c[v>>2]|0)+2>>1]|0)|0;c[y>>2]=(c[y>>2]|0)+(J+((_(c[(c[F>>2]|0)+-4>>2]&65535,b[(c[v>>2]|0)+2>>1]|0)|0)>>16));J=_(c[(c[F>>2]|0)+-8>>2]>>16,b[(c[v>>2]|0)+4>>1]|0)|0;c[y>>2]=(c[y>>2]|0)+(J+((_(c[(c[F>>2]|0)+-8>>2]&65535,b[(c[v>>2]|0)+4>>1]|0)|0)>>16));J=_(c[(c[F>>2]|0)+-12>>2]>>16,b[(c[v>>2]|0)+6>>1]|0)|0;c[y>>2]=(c[y>>2]|0)+(J+((_(c[(c[F>>2]|0)+-12>>2]&65535,b[(c[v>>2]|0)+6>>1]|0)|0)>>16));J=_(c[(c[F>>2]|0)+-16>>2]>>16,b[(c[v>>2]|0)+8>>1]|0)|0;c[y>>2]=(c[y>>2]|0)+(J+((_(c[(c[F>>2]|0)+-16>>2]&65535,b[(c[v>>2]|0)+8>>1]|0)|0)>>16));c[F>>2]=(c[F>>2]|0)+4;c[(c[H>>2]|0)+(c[n>>2]<<2)>>2]=(c[(c[G>>2]|0)+(c[n>>2]<<2)>>2]|0)+(c[y>>2]<<1);c[g+(c[r>>2]<<2)>>2]=c[(c[H>>2]|0)+(c[n>>2]<<2)>>2]<<1;c[r>>2]=(c[r>>2]|0)+1;c[n>>2]=(c[n>>2]|0)+1}}else c[H>>2]=c[G>>2];while(0);c[n>>2]=0;while(1){if((c[n>>2]|0)>=(c[(c[j>>2]|0)+2332>>2]|0))break;c[z>>2]=c[(c[j>>2]|0)+2340>>2]>>1;J=_(c[d+(16+(c[n>>2]|0)-1<<2)>>2]>>16,b[x>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-1<<2)>>2]&65535,b[x>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-2<<2)>>2]>>16,b[x+2>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-2<<2)>>2]&65535,b[x+2>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-3<<2)>>2]>>16,b[x+4>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-3<<2)>>2]&65535,b[x+4>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-4<<2)>>2]>>16,b[x+6>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-4<<2)>>2]&65535,b[x+6>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-5<<2)>>2]>>16,b[x+8>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-5<<2)>>2]&65535,b[x+8>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-6<<2)>>2]>>16,b[x+10>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-6<<2)>>2]&65535,b[x+10>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-7<<2)>>2]>>16,b[x+12>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-7<<2)>>2]&65535,b[x+12>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-8<<2)>>2]>>16,b[x+14>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-8<<2)>>2]&65535,b[x+14>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-9<<2)>>2]>>16,b[x+16>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-9<<2)>>2]&65535,b[x+16>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-10<<2)>>2]>>16,b[x+18>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-10<<2)>>2]&65535,b[x+18>>1]|0)|0)>>16));if((c[(c[j>>2]|0)+2340>>2]|0)==16){J=_(c[d+(16+(c[n>>2]|0)-11<<2)>>2]>>16,b[x+20>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-11<<2)>>2]&65535,b[x+20>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-12<<2)>>2]>>16,b[x+22>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-12<<2)>>2]&65535,b[x+22>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-13<<2)>>2]>>16,b[x+24>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-13<<2)>>2]&65535,b[x+24>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-14<<2)>>2]>>16,b[x+26>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-14<<2)>>2]&65535,b[x+26>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-15<<2)>>2]>>16,b[x+28>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-15<<2)>>2]&65535,b[x+28>>1]|0)|0)>>16));J=_(c[d+(16+(c[n>>2]|0)-16<<2)>>2]>>16,b[x+30>>1]|0)|0;c[z>>2]=(c[z>>2]|0)+(J+((_(c[d+(16+(c[n>>2]|0)-16<<2)>>2]&65535,b[x+30>>1]|0)|0)>>16))}c[d+(16+(c[n>>2]|0)<<2)>>2]=(c[(c[H>>2]|0)+(c[n>>2]<<2)>>2]|0)+(c[z>>2]<<4);J=_(c[d+(16+(c[n>>2]|0)<<2)>>2]>>16,(c[A>>2]&65535)<<16>>16)|0;K=J+((_(c[d+(16+(c[n>>2]|0)<<2)>>2]&65535,(c[A>>2]&65535)<<16>>16)|0)>>16)|0;if(((K+(_(c[d+(16+(c[n>>2]|0)<<2)>>2]|0,(c[A>>2]>>15)+1>>1)|0)>>7)+1>>1|0)<=32767){K=_(c[d+(16+(c[n>>2]|0)<<2)>>2]>>16,(c[A>>2]&65535)<<16>>16)|0;J=K+((_(c[d+(16+(c[n>>2]|0)<<2)>>2]&65535,(c[A>>2]&65535)<<16>>16)|0)>>16)|0;if(((J+(_(c[d+(16+(c[n>>2]|0)<<2)>>2]|0,(c[A>>2]>>15)+1>>1)|0)>>7)+1>>1|0)<-32768)M=-32768;else{J=_(c[d+(16+(c[n>>2]|0)<<2)>>2]>>16,(c[A>>2]&65535)<<16>>16)|0;K=J+((_(c[d+(16+(c[n>>2]|0)<<2)>>2]&65535,(c[A>>2]&65535)<<16>>16)|0)>>16)|0;M=(K+(_(c[d+(16+(c[n>>2]|0)<<2)>>2]|0,(c[A>>2]>>15)+1>>1)|0)>>7)+1>>1}}else M=32767;b[(c[w>>2]|0)+(c[n>>2]<<1)>>1]=M;c[n>>2]=(c[n>>2]|0)+1}m=d;D=d+(c[(c[j>>2]|0)+2332>>2]<<2)|0;E=m+64|0;do{c[m>>2]=c[D>>2];m=m+4|0;D=D+4|0}while((m|0)<(E|0));c[G>>2]=(c[G>>2]|0)+(c[(c[j>>2]|0)+2332>>2]<<2);c[w>>2]=(c[w>>2]|0)+(c[(c[j>>2]|0)+2332>>2]<<1);c[o>>2]=(c[o>>2]|0)+1}m=(c[j>>2]|0)+1284|0;D=d;E=m+64|0;do{c[m>>2]=c[D>>2];m=m+4|0;D=D+4|0}while((m|0)<(E|0));ka(c[I>>2]|0);i=h;return}function Pb(b,d,e,f,g,h){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;j=i;i=i+192|0;k=j+172|0;l=j+152|0;m=j;n=j+164|0;o=j+168|0;p=j+176|0;q=j+148|0;r=j+160|0;s=j+156|0;t=j+8|0;u=j+4|0;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[p>>2]=h;c[s>>2]=0;c[q>>2]=c[(c[k>>2]|0)+2328>>2];c[t+136>>2]=0;do if(!(c[o>>2]|0))v=4;else{if((c[o>>2]|0)==2?(c[(c[k>>2]|0)+2420+(c[(c[k>>2]|0)+2388>>2]<<2)>>2]|0)==1:0){v=4;break}_b(c[k>>2]|0,t,c[m>>2]|0,1)}while(0);if((v|0)==4){v=(c[q>>2]|0)+16-1&-16;c[u>>2]=ua()|0;h=i;i=i+((1*(v<<1)|0)+15&-16)|0;Rb(c[k>>2]|0,c[l>>2]|0,c[(c[k>>2]|0)+2388>>2]|0,c[o>>2]|0,c[p>>2]|0);Sb(c[l>>2]|0,h,a[(c[k>>2]|0)+2736+29>>0]|0,a[(c[k>>2]|0)+2736+30>>0]|0,c[(c[k>>2]|0)+2328>>2]|0);Qb(c[k>>2]|0,t,c[p>>2]|0);Ob(c[k>>2]|0,t,c[m>>2]|0,h);_b(c[k>>2]|0,t,c[m>>2]|0,0);c[(c[k>>2]|0)+4160>>2]=0;c[(c[k>>2]|0)+4164>>2]=a[(c[k>>2]|0)+2736+29>>0];c[(c[k>>2]|0)+2376>>2]=0;ka(c[u>>2]|0)}c[r>>2]=(c[(c[k>>2]|0)+2336>>2]|0)-(c[(c[k>>2]|0)+2328>>2]|0);ff((c[k>>2]|0)+1348|0,(c[k>>2]|0)+1348+(c[(c[k>>2]|0)+2328>>2]<<1)|0,c[r>>2]<<1|0)|0;df((c[k>>2]|0)+1348+(c[r>>2]<<1)|0,c[m>>2]|0,c[(c[k>>2]|0)+2328>>2]<<1|0)|0;$b(c[k>>2]|0,c[m>>2]|0,c[q>>2]|0);Lb(c[k>>2]|0,t,c[m>>2]|0,c[q>>2]|0);c[(c[k>>2]|0)+2308>>2]=c[t+((c[(c[k>>2]|0)+2324>>2]|0)-1<<2)>>2];c[c[n>>2]>>2]=c[q>>2];i=j;return c[s>>2]|0}function Qb(d,e,f){d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;g=i;i=i+96|0;h=g+4|0;j=g+16|0;k=g+12|0;l=g+8|0;m=g+24|0;n=g;o=g+32|0;p=g+64|0;q=g+20|0;c[h>>2]=d;c[j>>2]=e;c[k>>2]=f;Xb((c[j>>2]|0)+16|0,(c[h>>2]|0)+2736|0,(c[h>>2]|0)+2312|0,(c[k>>2]|0)==2&1,c[(c[h>>2]|0)+2324>>2]|0);Yb(o,(c[h>>2]|0)+2736+8|0,c[(c[h>>2]|0)+2732>>2]|0);jc((c[j>>2]|0)+32+32|0,o,c[(c[h>>2]|0)+2340>>2]|0);if((c[(c[h>>2]|0)+2376>>2]|0)==1)a[(c[h>>2]|0)+2736+31>>0]=4;if((a[(c[h>>2]|0)+2736+31>>0]|0)<4){c[l>>2]=0;while(1){if((c[l>>2]|0)>=(c[(c[h>>2]|0)+2340>>2]|0))break;k=(b[(c[h>>2]|0)+2344+(c[l>>2]<<1)>>1]|0)+((_(a[(c[h>>2]|0)+2736+31>>0]|0,(b[o+(c[l>>2]<<1)>>1]|0)-(b[(c[h>>2]|0)+2344+(c[l>>2]<<1)>>1]|0)|0)|0)>>2)&65535;b[p+(c[l>>2]<<1)>>1]=k;c[l>>2]=(c[l>>2]|0)+1}jc((c[j>>2]|0)+32|0,p,c[(c[h>>2]|0)+2340>>2]|0)}else df((c[j>>2]|0)+32|0,(c[j>>2]|0)+32+32|0,c[(c[h>>2]|0)+2340>>2]<<1|0)|0;df((c[h>>2]|0)+2344|0,o|0,c[(c[h>>2]|0)+2340>>2]<<1|0)|0;if(c[(c[h>>2]|0)+4160>>2]|0){ec((c[j>>2]|0)+32|0,c[(c[h>>2]|0)+2340>>2]|0,63570);ec((c[j>>2]|0)+32+32|0,c[(c[h>>2]|0)+2340>>2]|0,63570)}if((a[(c[h>>2]|0)+2736+29>>0]|0)!=2){bf(c[j>>2]|0,0,c[(c[h>>2]|0)+2324>>2]<<2|0)|0;bf((c[j>>2]|0)+96|0,0,(c[(c[h>>2]|0)+2324>>2]|0)*5<<1|0)|0;a[(c[h>>2]|0)+2736+32>>0]=0;c[(c[j>>2]|0)+136>>2]=0;i=g;return}fc(b[(c[h>>2]|0)+2736+26>>1]|0,a[(c[h>>2]|0)+2736+28>>0]|0,c[j>>2]|0,c[(c[h>>2]|0)+2316>>2]|0,c[(c[h>>2]|0)+2324>>2]|0);c[q>>2]=c[240+(a[(c[h>>2]|0)+2736+32>>0]<<2)>>2];c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[(c[h>>2]|0)+2324>>2]|0))break;c[n>>2]=a[(c[h>>2]|0)+2736+4+(c[m>>2]|0)>>0];c[l>>2]=0;while(1){if((c[l>>2]|0)>=5)break;b[(c[j>>2]|0)+96+(((c[m>>2]|0)*5|0)+(c[l>>2]|0)<<1)>>1]=a[(c[q>>2]|0)+(((c[n>>2]|0)*5|0)+(c[l>>2]|0))>>0]<<7;c[l>>2]=(c[l>>2]|0)+1}c[m>>2]=(c[m>>2]|0)+1}c[n>>2]=a[(c[h>>2]|0)+2736+33>>0];c[(c[j>>2]|0)+136>>2]=b[464+(c[n>>2]<<1)>>1];i=g;return}function Rb(d,e,f,g,h){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0;j=i;i=i+96|0;k=j+36|0;l=j+4|0;m=j+28|0;n=j+16|0;o=j+32|0;p=j;q=j+12|0;r=j+24|0;s=j+20|0;t=j+8|0;u=j+40|0;v=j+72|0;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[o>>2]=h;if((c[n>>2]|0)==0?(c[(c[k>>2]|0)+2404+(c[m>>2]<<2)>>2]|0)==0:0)c[r>>2]=jb(c[l>>2]|0,440,8)|0;else c[r>>2]=(jb(c[l>>2]|0,432,8)|0)+2;a[(c[k>>2]|0)+2736+29>>0]=c[r>>2]>>1;a[(c[k>>2]|0)+2736+30>>0]=c[r>>2]&1;m=c[l>>2]|0;if((c[o>>2]|0)==2){n=(jb(m,168,8)|0)&255;a[(c[k>>2]|0)+2736>>0]=n}else{n=(jb(m,144+(a[(c[k>>2]|0)+2736+29>>0]<<3)|0,8)|0)<<3&255;a[(c[k>>2]|0)+2736>>0]=n;n=((jb(c[l>>2]|0,504,8)|0)&255)<<24>>24;m=(c[k>>2]|0)+2736|0;a[m>>0]=(a[m>>0]|0)+n}c[p>>2]=1;while(1){w=c[l>>2]|0;if((c[p>>2]|0)>=(c[(c[k>>2]|0)+2324>>2]|0))break;n=(jb(w,168,8)|0)&255;a[(c[k>>2]|0)+2736+(c[p>>2]|0)>>0]=n;c[p>>2]=(c[p>>2]|0)+1}n=_(a[(c[k>>2]|0)+2736+29>>0]>>1,b[c[(c[k>>2]|0)+2732>>2]>>1]|0)|0;m=(jb(w,(c[(c[(c[k>>2]|0)+2732>>2]|0)+12>>2]|0)+n|0,8)|0)&255;a[(c[k>>2]|0)+2736+8>>0]=m;bc(u,v,c[(c[k>>2]|0)+2732>>2]|0,a[(c[k>>2]|0)+2736+8>>0]|0);c[p>>2]=0;while(1){if((c[p>>2]|0)>=(b[(c[(c[k>>2]|0)+2732>>2]|0)+2>>1]|0))break;c[r>>2]=jb(c[l>>2]|0,(c[(c[(c[k>>2]|0)+2732>>2]|0)+24>>2]|0)+(b[u+(c[p>>2]<<1)>>1]|0)|0,8)|0;if(c[r>>2]|0){if((c[r>>2]|0)==8){v=jb(c[l>>2]|0,512,8)|0;c[r>>2]=(c[r>>2]|0)+v}}else{v=jb(c[l>>2]|0,512,8)|0;c[r>>2]=(c[r>>2]|0)-v}a[(c[k>>2]|0)+2736+8+((c[p>>2]|0)+1)>>0]=(c[r>>2]|0)-4;c[p>>2]=(c[p>>2]|0)+1}if((c[(c[k>>2]|0)+2324>>2]|0)==4){p=(jb(c[l>>2]|0,448,8)|0)&255;a[(c[k>>2]|0)+2736+31>>0]=p}else a[(c[k>>2]|0)+2736+31>>0]=4;if((a[(c[k>>2]|0)+2736+29>>0]|0)!=2){x=c[k>>2]|0;y=x+2736|0;z=y+29|0;A=a[z>>0]|0;B=A<<24>>24;C=c[k>>2]|0;D=C+2396|0;c[D>>2]=B;E=c[l>>2]|0;F=jb(E,480,8)|0;G=F&255;H=c[k>>2]|0;I=H+2736|0;J=I+34|0;a[J>>0]=G;i=j;return}c[s>>2]=1;if(((c[o>>2]|0)==2?(c[(c[k>>2]|0)+2396>>2]|0)==2:0)?(c[t>>2]=((jb(c[l>>2]|0,552,8)|0)&65535)<<16>>16,(c[t>>2]|0)>0):0){c[t>>2]=(c[t>>2]|0)-9;b[(c[k>>2]|0)+2736+26>>1]=(b[(c[k>>2]|0)+2400>>1]|0)+(c[t>>2]|0);c[s>>2]=0}if(c[s>>2]|0){s=((jb(c[l>>2]|0,520,8)|0)&65535)<<16>>16;t=(_(s,c[(c[k>>2]|0)+2316>>2]>>1)|0)&65535;b[(c[k>>2]|0)+2736+26>>1]=t;t=((jb(c[l>>2]|0,c[(c[k>>2]|0)+2380>>2]|0,8)|0)&65535)<<16>>16;s=(c[k>>2]|0)+2736+26|0;b[s>>1]=(b[s>>1]|0)+t}b[(c[k>>2]|0)+2400>>1]=b[(c[k>>2]|0)+2736+26>>1]|0;t=(jb(c[l>>2]|0,c[(c[k>>2]|0)+2384>>2]|0,8)|0)&255;a[(c[k>>2]|0)+2736+28>>0]=t;t=(jb(c[l>>2]|0,216,8)|0)&255;a[(c[k>>2]|0)+2736+32>>0]=t;c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[(c[k>>2]|0)+2324>>2]|0))break;t=(jb(c[l>>2]|0,c[224+(a[(c[k>>2]|0)+2736+32>>0]<<2)>>2]|0,8)|0)&255;a[(c[k>>2]|0)+2736+4+(c[q>>2]|0)>>0]=t;c[q>>2]=(c[q>>2]|0)+1}if(!(c[o>>2]|0)){o=(jb(c[l>>2]|0,424,8)|0)&255;a[(c[k>>2]|0)+2736+33>>0]=o;x=c[k>>2]|0;y=x+2736|0;z=y+29|0;A=a[z>>0]|0;B=A<<24>>24;C=c[k>>2]|0;D=C+2396|0;c[D>>2]=B;E=c[l>>2]|0;F=jb(E,480,8)|0;G=F&255;H=c[k>>2]|0;I=H+2736|0;J=I+34|0;a[J>>0]=G;i=j;return}else{a[(c[k>>2]|0)+2736+33>>0]=0;x=c[k>>2]|0;y=x+2736|0;z=y+29|0;A=a[z>>0]|0;B=A<<24>>24;C=c[k>>2]|0;D=C+2396|0;c[D>>2]=B;E=c[l>>2]|0;F=jb(E,480,8)|0;G=F&255;H=c[k>>2]|0;I=H+2736|0;J=I+34|0;a[J>>0]=G;i=j;return}}function Sb(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;h=i;i=i+224|0;j=h+84|0;k=h+180|0;l=h+200|0;m=h+208|0;n=h+188|0;o=h+196|0;p=h+204|0;q=h+212|0;r=h+216|0;s=h+80|0;t=h+184|0;u=h+88|0;v=h;w=h+96|0;x=h+192|0;y=h+176|0;c[j>>2]=a;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[u>>2]=jb(c[j>>2]|0,840+((c[l>>2]>>1)*9|0)|0,8)|0;c[r>>2]=c[n>>2]>>4;if((c[r>>2]<<4|0)<(c[n>>2]|0))c[r>>2]=(c[r>>2]|0)+1;c[y>>2]=656+((c[u>>2]|0)*18|0);c[o>>2]=0;while(1){if((c[o>>2]|0)>=(c[r>>2]|0))break;c[w+(c[o>>2]<<2)>>2]=0;u=jb(c[j>>2]|0,c[y>>2]|0,8)|0;c[v+(c[o>>2]<<2)>>2]=u;while(1){z=c[o>>2]|0;if((c[v+(c[o>>2]<<2)>>2]|0)!=17)break;u=w+(z<<2)|0;c[u>>2]=(c[u>>2]|0)+1;u=jb(c[j>>2]|0,818+((c[w+(c[o>>2]<<2)>>2]|0)==10&1)|0,8)|0;c[v+(c[o>>2]<<2)>>2]=u}c[o>>2]=z+1}c[o>>2]=0;while(1){if((c[o>>2]|0)>=(c[r>>2]|0))break;z=(c[k>>2]|0)+((c[o>>2]&65535)<<16>>16<<4<<1)|0;if((c[v+(c[o>>2]<<2)>>2]|0)>0)ac(z,c[j>>2]|0,c[v+(c[o>>2]<<2)>>2]|0);else{y=z;z=y+32|0;do{b[y>>1]=0;y=y+2|0}while((y|0)<(z|0))}c[o>>2]=(c[o>>2]|0)+1}c[o>>2]=0;while(1){if((c[o>>2]|0)>=(c[r>>2]|0))break;if((c[w+(c[o>>2]<<2)>>2]|0)>0){c[t>>2]=c[w+(c[o>>2]<<2)>>2];c[x>>2]=(c[k>>2]|0)+((c[o>>2]&65535)<<16>>16<<4<<1);c[q>>2]=0;while(1){if((c[q>>2]|0)>=16)break;c[s>>2]=b[(c[x>>2]|0)+(c[q>>2]<<1)>>1];c[p>>2]=0;while(1){A=c[s>>2]|0;if((c[p>>2]|0)>=(c[t>>2]|0))break;c[s>>2]=A<<1;y=jb(c[j>>2]|0,416,8)|0;c[s>>2]=(c[s>>2]|0)+y;c[p>>2]=(c[p>>2]|0)+1}b[(c[x>>2]|0)+(c[q>>2]<<1)>>1]=A;c[q>>2]=(c[q>>2]|0)+1}y=v+(c[o>>2]<<2)|0;c[y>>2]=c[y>>2]|c[t>>2]<<5}c[o>>2]=(c[o>>2]|0)+1}Mb(c[j>>2]|0,c[k>>2]|0,c[n>>2]|0,c[l>>2]|0,c[m>>2]|0,v);i=h;return}function Tb(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[g>>2]=b;c[h>>2]=d;c[j>>2]=e;c[l>>2]=0;c[(c[g>>2]|0)+2332>>2]=((c[h>>2]&65535)<<16>>16)*5;c[k>>2]=_((c[(c[g>>2]|0)+2324>>2]&65535)<<16>>16,(c[(c[g>>2]|0)+2332>>2]&65535)<<16>>16)|0;if(!((c[(c[g>>2]|0)+2316>>2]|0)==(c[h>>2]|0)?(c[(c[g>>2]|0)+2320>>2]|0)==(c[j>>2]|0):0)){e=mc((c[g>>2]|0)+2432|0,((c[h>>2]&65535)<<16>>16)*1e3|0,c[j>>2]|0,0)|0;c[l>>2]=(c[l>>2]|0)+e;c[(c[g>>2]|0)+2320>>2]=c[j>>2]}if((c[(c[g>>2]|0)+2316>>2]|0)==(c[h>>2]|0)?(c[k>>2]|0)==(c[(c[g>>2]|0)+2328>>2]|0):0){m=c[l>>2]|0;i=f;return m|0}j=(c[(c[g>>2]|0)+2324>>2]|0)==4;e=(c[g>>2]|0)+2384|0;do if((c[h>>2]|0)==8)if(j){c[e>>2]=616;break}else{c[e>>2]=648;break}else if(j){c[e>>2]=576;break}else{c[e>>2]=632;break}while(0);if((c[(c[g>>2]|0)+2316>>2]|0)!=(c[h>>2]|0)){c[(c[g>>2]|0)+2336>>2]=((c[h>>2]&65535)<<16>>16)*20;e=(c[g>>2]|0)+2340|0;if((c[h>>2]|0)==8|(c[h>>2]|0)==12){c[e>>2]=10;c[(c[g>>2]|0)+2732>>2]=256}else{c[e>>2]=16;c[(c[g>>2]|0)+2732>>2]=296}do if((c[h>>2]|0)!=16){if((c[h>>2]|0)==12){c[(c[g>>2]|0)+2380>>2]=496;break}if((c[h>>2]|0)==8)c[(c[g>>2]|0)+2380>>2]=480}else c[(c[g>>2]|0)+2380>>2]=504;while(0);c[(c[g>>2]|0)+2376>>2]=1;c[(c[g>>2]|0)+2308>>2]=100;a[(c[g>>2]|0)+2312>>0]=10;c[(c[g>>2]|0)+4164>>2]=0;bf((c[g>>2]|0)+1348|0,0,960)|0;e=(c[g>>2]|0)+1284|0;j=e+64|0;do{c[e>>2]=0;e=e+4|0}while((e|0)<(j|0))}c[(c[g>>2]|0)+2316>>2]=c[h>>2];c[(c[g>>2]|0)+2328>>2]=c[k>>2];m=c[l>>2]|0;i=f;return m|0}function Ub(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=0;c[c[d>>2]>>2]=8544;i=b;return c[e>>2]|0}function Vb(a){a=a|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[e>>2]=a;c[g>>2]=0;c[h>>2]=c[e>>2];c[f>>2]=0;while(1){if((c[f>>2]|0)>=2)break;c[g>>2]=Nb((c[h>>2]|0)+((c[f>>2]|0)*4260|0)|0)|0;c[f>>2]=(c[f>>2]|0)+1}f=(c[e>>2]|0)+8520|0;b[f>>1]=0;b[f+2>>1]=0;b[f+4>>1]=0;b[f+6>>1]=0;b[f+8>>1]=0;b[f+10>>1]=0;c[(c[e>>2]|0)+8540>>2]=0;i=d;return c[g>>2]|0}function Wb(d,e,f,g,h,j,k){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0;l=i;i=i+784|0;m=l+64|0;n=l+48|0;o=l+44|0;p=l+108|0;q=l+100|0;r=l+16|0;s=l+20|0;t=l+24|0;u=l+28|0;v=l+32|0;w=l+36|0;x=l+96|0;y=l+104|0;z=l+112|0;A=l+120|0;B=l+128|0;C=l+68|0;D=l+72|0;E=l+76|0;F=l+80|0;G=l+84|0;H=l+12|0;I=l+8|0;J=l+136|0;K=l+4|0;L=l;M=l+40|0;N=l+92|0;O=l+52|0;P=l+88|0;c[n>>2]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=g;c[r>>2]=h;c[s>>2]=j;c[t>>2]=k;c[w>>2]=0;c[x>>2]=0;c[B>>2]=0;c[B+4>>2]=0;c[D>>2]=c[n>>2];c[E>>2]=c[D>>2];a:do if(c[q>>2]|0){c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[(c[o>>2]|0)+4>>2]|0))break a;c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2388>>2]=0;c[v>>2]=(c[v>>2]|0)+1}}while(0);if((c[(c[o>>2]|0)+4>>2]|0)>(c[(c[D>>2]|0)+8536>>2]|0)){q=Nb((c[E>>2]|0)+4260|0)|0;c[x>>2]=(c[x>>2]|0)+q}if((c[(c[o>>2]|0)+4>>2]|0)==1?(c[(c[D>>2]|0)+8536>>2]|0)==2:0)Q=(c[(c[o>>2]|0)+12>>2]|0)==((c[(c[E>>2]|0)+2316>>2]|0)*1e3|0);else Q=0;c[G>>2]=Q&1;b:do if(!(c[(c[E>>2]|0)+2388>>2]|0)){c[v>>2]=0;c:while(1){if((c[v>>2]|0)>=(c[(c[o>>2]|0)+4>>2]|0))break b;do if(!(c[(c[o>>2]|0)+16>>2]|0)){c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]=1;c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2324>>2]=2}else{if((c[(c[o>>2]|0)+16>>2]|0)==10){c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]=1;c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2324>>2]=2;break}if((c[(c[o>>2]|0)+16>>2]|0)==20){c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]=1;c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2324>>2]=4;break}if((c[(c[o>>2]|0)+16>>2]|0)==40){c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]=2;c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2324>>2]=4;break}if((c[(c[o>>2]|0)+16>>2]|0)!=60){R=23;break c}c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]=3;c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2324>>2]=4}while(0);c[I>>2]=(c[(c[o>>2]|0)+12>>2]>>10)+1;if((c[I>>2]|0)!=8&(c[I>>2]|0)!=12&(c[I>>2]|0)!=16){R=25;break}Q=Tb((c[E>>2]|0)+((c[v>>2]|0)*4260|0)|0,c[I>>2]|0,c[(c[o>>2]|0)+8>>2]|0)|0;c[x>>2]=(c[x>>2]|0)+Q;c[v>>2]=(c[v>>2]|0)+1}if((R|0)==23){c[m>>2]=-203;S=c[m>>2]|0;i=l;return S|0}else if((R|0)==25){c[m>>2]=-200;S=c[m>>2]|0;i=l;return S|0}}while(0);do if((c[c[o>>2]>>2]|0)==2?(c[(c[o>>2]|0)+4>>2]|0)==2:0){if((c[(c[D>>2]|0)+8532>>2]|0)!=1?(c[(c[D>>2]|0)+8536>>2]|0)!=1:0)break;I=(c[D>>2]|0)+8520|0;b[I>>1]=0;b[I+2>>1]=0;I=(c[D>>2]|0)+8520+8|0;b[I>>1]=0;b[I+2>>1]=0;df((c[E>>2]|0)+4260+2432|0,(c[E>>2]|0)+2432|0,300)|0}while(0);c[(c[D>>2]|0)+8532>>2]=c[c[o>>2]>>2];c[(c[D>>2]|0)+8536>>2]=c[(c[o>>2]|0)+4>>2];if((c[(c[o>>2]|0)+8>>2]|0)<=48e3?(c[(c[o>>2]|0)+8>>2]|0)>=8e3:0){d:do if((c[p>>2]|0)!=1?(c[(c[E>>2]|0)+2388>>2]|0)==0:0){c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[(c[o>>2]|0)+4>>2]|0))break;c[u>>2]=0;while(1){I=(c[u>>2]|0)<(c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]|0);T=ib(c[r>>2]|0,1)|0;if(!I)break;c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2404+(c[u>>2]<<2)>>2]=T;c[u>>2]=(c[u>>2]|0)+1}c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2416>>2]=T;c[v>>2]=(c[v>>2]|0)+1}c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[(c[o>>2]|0)+4>>2]|0))break;I=(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2420|0;c[I>>2]=0;c[I+4>>2]=0;c[I+8>>2]=0;e:do if(c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2416>>2]|0){if((c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]|0)==1){c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2420>>2]=1;break}c[z>>2]=(jb(c[r>>2]|0,c[408+((c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]|0)-2<<2)>>2]|0,8)|0)+1;c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2392>>2]|0))break e;c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2420+(c[u>>2]<<2)>>2]=c[z>>2]>>c[u>>2]&1;c[u>>2]=(c[u>>2]|0)+1}}while(0);c[v>>2]=(c[v>>2]|0)+1}if(!(c[p>>2]|0)){c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[(c[E>>2]|0)+2392>>2]|0))break d;c[v>>2]=0;while(1){U=c[u>>2]|0;if((c[v>>2]|0)>=(c[(c[o>>2]|0)+4>>2]|0))break;if(c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2420+(U<<2)>>2]|0){do if((c[v>>2]|0)==0?(c[(c[o>>2]|0)+4>>2]|0)==2:0){vc(c[r>>2]|0,B);if(c[(c[E>>2]|0)+4260+2420+(c[u>>2]<<2)>>2]|0)break;wc(c[r>>2]|0,w)}while(0);do if((c[u>>2]|0)>0){if(!(c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2420+((c[u>>2]|0)-1<<2)>>2]|0)){R=64;break}c[K>>2]=2}else R=64;while(0);if((R|0)==64){R=0;c[K>>2]=0}Rb((c[E>>2]|0)+((c[v>>2]|0)*4260|0)|0,c[r>>2]|0,c[u>>2]|0,1,c[K>>2]|0);Sb(c[r>>2]|0,J,a[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2736+29>>0]|0,a[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2736+30>>0]|0,c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2328>>2]|0)}c[v>>2]=(c[v>>2]|0)+1}c[u>>2]=U+1}}}while(0);f:do if((c[(c[o>>2]|0)+4>>2]|0)==2){do if(c[p>>2]|0){if((c[p>>2]|0)==2?(c[(c[E>>2]|0)+2420+(c[(c[E>>2]|0)+2388>>2]<<2)>>2]|0)==1:0)break;c[v>>2]=0;while(1){if((c[v>>2]|0)>=2)break f;c[B+(c[v>>2]<<2)>>2]=b[(c[D>>2]|0)+8520+(c[v>>2]<<1)>>1];c[v>>2]=(c[v>>2]|0)+1}}while(0);vc(c[r>>2]|0,B);if(!((c[p>>2]|0)==0?(c[(c[E>>2]|0)+4260+2404+(c[(c[E>>2]|0)+2388>>2]<<2)>>2]|0)==0:0))R=74;do if((R|0)==74){if((c[p>>2]|0)==2?(c[(c[E>>2]|0)+4260+2420+(c[(c[E>>2]|0)+2388>>2]<<2)>>2]|0)==0:0)break;c[w>>2]=0;break f}while(0);wc(c[r>>2]|0,w)}while(0);if(((c[w>>2]|0)==0?(c[(c[o>>2]|0)+4>>2]|0)==2:0)?(c[(c[D>>2]|0)+8540>>2]|0)==1:0){bf((c[D>>2]|0)+4260+1348|0,0,960)|0;R=(c[D>>2]|0)+4260+1284|0;U=R+64|0;do{c[R>>2]=0;R=R+4|0}while((R|0)<(U|0));c[(c[D>>2]|0)+4260+2308>>2]=100;a[(c[D>>2]|0)+4260+2312>>0]=10;c[(c[D>>2]|0)+4260+4164>>2]=0;c[(c[D>>2]|0)+4260+2376>>2]=1}R=_(c[(c[o>>2]|0)+12>>2]|0,c[(c[o>>2]|0)+4>>2]|0)|0;c[H>>2]=(R|0)<(_(c[(c[o>>2]|0)+8>>2]|0,c[c[o>>2]>>2]|0)|0)&1;if(c[H>>2]|0)V=1;else V=_(c[(c[o>>2]|0)+4>>2]|0,(c[(c[E>>2]|0)+2328>>2]|0)+2|0)|0;c[L>>2]=ua()|0;R=i;i=i+((1*(V<<1)|0)+15&-16)|0;if(c[H>>2]|0){c[A>>2]=c[s>>2];c[A+4>>2]=(c[s>>2]|0)+(c[(c[E>>2]|0)+2328>>2]<<1)+4}else{c[A>>2]=R;c[A+4>>2]=R+(c[(c[E>>2]|0)+2328>>2]<<1)+4}if(!(c[p>>2]|0))c[F>>2]=((c[w>>2]|0)!=0^1)&1;else{if(c[(c[D>>2]|0)+8540>>2]|0)if((c[p>>2]|0)==2?(c[(c[o>>2]|0)+4>>2]|0)==2:0)W=(c[(c[E>>2]|0)+4260+2420+(c[(c[E>>2]|0)+4260+2388>>2]<<2)>>2]|0)==1;else W=0;else W=1;c[F>>2]=W&1}c[v>>2]=0;while(1){if((c[v>>2]|0)>=(c[(c[o>>2]|0)+4>>2]|0))break;if((c[v>>2]|0)==0|(c[F>>2]|0)!=0){c[M>>2]=(c[(c[E>>2]|0)+2388>>2]|0)-(c[v>>2]|0);g:do if((c[M>>2]|0)<=0)c[N>>2]=0;else{if((c[p>>2]|0)==2){c[N>>2]=(c[(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2420+((c[M>>2]|0)-1<<2)>>2]|0)!=0?2:0;break}do if((c[v>>2]|0)>0){if(!(c[(c[D>>2]|0)+8540>>2]|0))break;c[N>>2]=1;break g}while(0);c[N>>2]=2}while(0);W=Pb((c[E>>2]|0)+((c[v>>2]|0)*4260|0)|0,c[r>>2]|0,(c[A+(c[v>>2]<<2)>>2]|0)+4|0,y,c[p>>2]|0,c[N>>2]|0)|0;c[x>>2]=(c[x>>2]|0)+W}else bf((c[A+(c[v>>2]<<2)>>2]|0)+4|0,0,c[y>>2]<<1|0)|0;W=(c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2388|0;c[W>>2]=(c[W>>2]|0)+1;c[v>>2]=(c[v>>2]|0)+1}if((c[c[o>>2]>>2]|0)==2?(c[(c[o>>2]|0)+4>>2]|0)==2:0)cc((c[D>>2]|0)+8520|0,c[A>>2]|0,c[A+4>>2]|0,B,c[(c[E>>2]|0)+2316>>2]|0,c[y>>2]|0);else{B=c[A>>2]|0;N=(c[D>>2]|0)+8520+4|0;b[B>>1]=b[N>>1]|0;b[B+2>>1]=b[N+2>>1]|0;N=(c[D>>2]|0)+8520+4|0;B=(c[A>>2]|0)+(c[y>>2]<<1)|0;b[N>>1]=b[B>>1]|0;b[N+2>>1]=b[B+2>>1]|0}B=_(c[y>>2]|0,c[(c[o>>2]|0)+8>>2]|0)|0;c[c[t>>2]>>2]=(B|0)/(((c[(c[E>>2]|0)+2316>>2]&65535)<<16>>16)*1e3|0)|0;if((c[c[o>>2]>>2]|0)==2)X=c[c[t>>2]>>2]|0;else X=1;B=i;i=i+((1*(X<<1)|0)+15&-16)|0;if((c[c[o>>2]>>2]|0)==2)c[C>>2]=B;else c[C>>2]=c[s>>2];if(c[H>>2]|0)Y=_(c[(c[o>>2]|0)+4>>2]|0,(c[(c[E>>2]|0)+2328>>2]|0)+2|0)|0;else Y=1;B=i;i=i+((1*(Y<<1)|0)+15&-16)|0;if(c[H>>2]|0){H=(_(c[(c[o>>2]|0)+4>>2]|0,(c[(c[E>>2]|0)+2328>>2]|0)+2|0)|0)<<1;df(B|0,c[s>>2]|0,H+0|0)|0;c[A>>2]=B;c[A+4>>2]=B+(c[(c[E>>2]|0)+2328>>2]<<1)+4}c[v>>2]=0;while(1){B=c[o>>2]|0;if((c[c[o>>2]>>2]|0)<(c[(c[o>>2]|0)+4>>2]|0))Z=c[B>>2]|0;else Z=c[B+4>>2]|0;if((c[v>>2]|0)>=(Z|0))break;B=nc((c[E>>2]|0)+((c[v>>2]|0)*4260|0)+2432|0,c[C>>2]|0,(c[A+(c[v>>2]<<2)>>2]|0)+2|0,c[y>>2]|0)|0;c[x>>2]=(c[x>>2]|0)+B;h:do if((c[c[o>>2]>>2]|0)==2){c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[c[t>>2]>>2]|0))break h;b[(c[s>>2]|0)+((c[v>>2]|0)+(c[u>>2]<<1)<<1)>>1]=b[(c[C>>2]|0)+(c[u>>2]<<1)>>1]|0;c[u>>2]=(c[u>>2]|0)+1}}while(0);c[v>>2]=(c[v>>2]|0)+1}i:do if((c[c[o>>2]>>2]|0)==2){if((c[(c[o>>2]|0)+4>>2]|0)!=1)break;if(c[G>>2]|0){v=nc((c[E>>2]|0)+4260+2432|0,c[C>>2]|0,(c[A>>2]|0)+2|0,c[y>>2]|0)|0;c[x>>2]=(c[x>>2]|0)+v;c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[c[t>>2]>>2]|0))break i;b[(c[s>>2]|0)+(1+(c[u>>2]<<1)<<1)>>1]=b[(c[C>>2]|0)+(c[u>>2]<<1)>>1]|0;c[u>>2]=(c[u>>2]|0)+1}}else{c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[c[t>>2]>>2]|0))break i;b[(c[s>>2]|0)+(1+(c[u>>2]<<1)<<1)>>1]=b[(c[s>>2]|0)+(0+(c[u>>2]<<1)<<1)>>1]|0;c[u>>2]=(c[u>>2]|0)+1}}}while(0);if((c[(c[E>>2]|0)+4164>>2]|0)==2){c[O>>2]=c[738];c[O+4>>2]=c[739];c[O+8>>2]=c[740];s=_(c[(c[E>>2]|0)+2308>>2]|0,c[O+((c[(c[E>>2]|0)+2316>>2]|0)-8>>2<<2)>>2]|0)|0;c[(c[o>>2]|0)+20>>2]=s}else c[(c[o>>2]|0)+20>>2]=0;j:do if((c[p>>2]|0)==1){c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[(c[D>>2]|0)+8536>>2]|0))break j;a[(c[D>>2]|0)+((c[u>>2]|0)*4260|0)+2312>>0]=10;c[u>>2]=(c[u>>2]|0)+1}}else c[(c[D>>2]|0)+8540>>2]=c[w>>2];while(0);c[m>>2]=c[x>>2];c[P>>2]=1;ka(c[L>>2]|0);S=c[m>>2]|0;i=l;return S|0}c[x>>2]=-200;c[m>>2]=c[x>>2];S=c[m>>2]|0;i=l;return S|0}function Xb(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;h=i;i=i+32|0;j=h+4|0;k=h+16|0;l=h+8|0;m=h+20|0;n=h+28|0;o=h;p=h+12|0;q=h+24|0;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[o>>2]=0;while(1){if((c[o>>2]|0)>=(c[n>>2]|0))break;g=a[(c[k>>2]|0)+(c[o>>2]|0)>>0]|0;do if(!((c[o>>2]|0)==0&(c[m>>2]|0)==0)){c[p>>2]=g+-4;c[q>>2]=8+(a[c[l>>2]>>0]|0);f=c[p>>2]|0;if((c[p>>2]|0)>(c[q>>2]|0)){e=c[l>>2]|0;a[e>>0]=(a[e>>0]|0)+((f<<1)-(c[q>>2]|0));break}else{e=c[l>>2]|0;a[e>>0]=(a[e>>0]|0)+f;break}}else{f=(Gd(g,(a[c[l>>2]>>0]|0)-16|0)|0)&255;a[c[l>>2]>>0]=f}while(0);if((a[c[l>>2]>>0]|0)<=63)if((a[c[l>>2]>>0]|0)<0)r=0;else r=a[c[l>>2]>>0]|0;else r=63;a[c[l>>2]>>0]=r;g=gc(Fd(((a[c[l>>2]>>0]<<16>>16)*29|0)+((a[c[l>>2]>>0]<<16>>16)*7281>>16)+2090|0,3967)|0)|0;c[(c[j>>2]|0)+(c[o>>2]<<2)>>2]=g;c[o>>2]=(c[o>>2]|0)+1}i=h;return}function Yb(e,f,g){e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+144|0;j=h+24|0;k=h+16|0;l=h+12|0;m=h+8|0;n=h+128|0;o=h+32|0;p=h+64|0;q=h+96|0;r=h+20|0;s=h;t=h+4|0;c[j>>2]=e;c[k>>2]=f;c[l>>2]=g;g=_(a[c[k>>2]>>0]|0,b[(c[l>>2]|0)+2>>1]|0)|0;c[t>>2]=(c[(c[l>>2]|0)+8>>2]|0)+g;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(b[(c[l>>2]|0)+2>>1]|0))break;b[(c[j>>2]|0)+(c[m>>2]<<1)>>1]=d[(c[t>>2]|0)+(c[m>>2]|0)>>0]<<7;c[m>>2]=(c[m>>2]|0)+1}bc(o,n,c[l>>2]|0,a[c[k>>2]>>0]|0);Hd(p,(c[k>>2]|0)+1|0,n,b[(c[l>>2]|0)+4>>1]|0,b[(c[l>>2]|0)+2>>1]|0);lc(q,c[j>>2]|0,b[(c[l>>2]|0)+2>>1]|0);c[m>>2]=0;while(1){if((c[m>>2]|0)>=(b[(c[l>>2]|0)+2>>1]|0))break;c[r>>2]=Id(b[q+(c[m>>2]<<1)>>1]<<16)|0;c[s>>2]=(b[(c[j>>2]|0)+(c[m>>2]<<1)>>1]|0)+((b[p+(c[m>>2]<<1)>>1]<<14|0)/(c[r>>2]|0)|0);if((c[s>>2]|0)>32767)u=32767;else u=(c[s>>2]|0)<0?0:c[s>>2]|0;b[(c[j>>2]|0)+(c[m>>2]<<1)>>1]=u;c[m>>2]=(c[m>>2]|0)+1}kc(c[j>>2]|0,c[(c[l>>2]|0)+32>>2]|0,b[(c[l>>2]|0)+2>>1]|0);i=h;return}function Zb(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;c[(c[d>>2]|0)+4168>>2]=c[(c[d>>2]|0)+2328>>2]<<7;c[(c[d>>2]|0)+4168+72>>2]=65536;c[(c[d>>2]|0)+4168+72+4>>2]=65536;c[(c[d>>2]|0)+4168+88>>2]=20;c[(c[d>>2]|0)+4168+84>>2]=2;i=b;return}function _b(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;f=i;i=i+16|0;g=f+12|0;h=f+8|0;j=f+4|0;k=f;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=e;if((c[(c[g>>2]|0)+2316>>2]|0)!=(c[(c[g>>2]|0)+4168+80>>2]|0)){Zb(c[g>>2]|0);c[(c[g>>2]|0)+4168+80>>2]=c[(c[g>>2]|0)+2316>>2]}e=c[g>>2]|0;d=c[h>>2]|0;if(c[k>>2]|0){Jd(e,d,c[j>>2]|0);j=(c[g>>2]|0)+4160|0;c[j>>2]=(c[j>>2]|0)+1;i=f;return}else{Kd(e,d);i=f;return}}function $b(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;f=i;i=i+48|0;g=f+36|0;h=f+16|0;j=f;k=f+28|0;l=f+32|0;m=f+40|0;n=f+12|0;o=f+24|0;p=f+20|0;q=f+8|0;r=f+4|0;c[g>>2]=a;c[h>>2]=d;c[j>>2]=e;c[n>>2]=(c[g>>2]|0)+4168;if(c[(c[g>>2]|0)+4160>>2]|0){uc((c[n>>2]|0)+60|0,(c[n>>2]|0)+64|0,c[h>>2]|0,c[j>>2]|0);c[(c[n>>2]|0)+48>>2]=1;i=f;return}a:do if(c[(c[g>>2]|0)+4168+48>>2]|0){uc(m,l,c[h>>2]|0,c[j>>2]|0);if((c[l>>2]|0)<=(c[(c[n>>2]|0)+64>>2]|0)){if((c[l>>2]|0)<(c[(c[n>>2]|0)+64>>2]|0))c[m>>2]=c[m>>2]>>(c[(c[n>>2]|0)+64>>2]|0)-(c[l>>2]|0)}else c[(c[n>>2]|0)+60>>2]=c[(c[n>>2]|0)+60>>2]>>(c[l>>2]|0)-(c[(c[n>>2]|0)+64>>2]|0);if((c[m>>2]|0)>(c[(c[n>>2]|0)+60>>2]|0)){c[p>>2]=Ld(c[(c[n>>2]|0)+60>>2]|0)|0;c[p>>2]=(c[p>>2]|0)-1;c[(c[n>>2]|0)+60>>2]=c[(c[n>>2]|0)+60>>2]<<c[p>>2];e=c[m>>2]|0;c[m>>2]=e>>(Md(24-(c[p>>2]|0)|0,0)|0);c[o>>2]=(c[(c[n>>2]|0)+60>>2]|0)/(((c[m>>2]|0)>1?c[m>>2]|0:1)|0)|0;c[q>>2]=(Nd(c[o>>2]|0)|0)<<4;c[r>>2]=(65536-(c[q>>2]|0)|0)/(c[j>>2]|0)|0;c[r>>2]=c[r>>2]<<2;c[k>>2]=0;while(1){if((c[k>>2]|0)>=(c[j>>2]|0))break a;e=_(c[q>>2]>>16,b[(c[h>>2]|0)+(c[k>>2]<<1)>>1]|0)|0;d=e+((_(c[q>>2]&65535,b[(c[h>>2]|0)+(c[k>>2]<<1)>>1]|0)|0)>>16)&65535;b[(c[h>>2]|0)+(c[k>>2]<<1)>>1]=d;c[q>>2]=(c[q>>2]|0)+(c[r>>2]|0);if((c[q>>2]|0)>65536)break a;c[k>>2]=(c[k>>2]|0)+1}}}while(0);c[(c[n>>2]|0)+48>>2]=0;i=f;return}function ac(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+48|0;g=f+8|0;h=f+4|0;j=f;k=f+40|0;l=f+32|0;m=f+16|0;c[g>>2]=a;c[h>>2]=d;c[j>>2]=e;Od(k,k+2|0,c[h>>2]|0,c[j>>2]|0,1320);Od(l,l+2|0,c[h>>2]|0,b[k>>1]|0,1168);Od(m,m+2|0,c[h>>2]|0,b[l>>1]|0,1016);Od(c[g>>2]|0,(c[g>>2]|0)+2|0,c[h>>2]|0,b[m>>1]|0,864);Od((c[g>>2]|0)+4|0,(c[g>>2]|0)+6|0,c[h>>2]|0,b[m+2>>1]|0,864);Od(m+4|0,m+6|0,c[h>>2]|0,b[l+2>>1]|0,1016);Od((c[g>>2]|0)+8|0,(c[g>>2]|0)+10|0,c[h>>2]|0,b[m+4>>1]|0,864);Od((c[g>>2]|0)+12|0,(c[g>>2]|0)+14|0,c[h>>2]|0,b[m+6>>1]|0,864);Od(l+4|0,l+6|0,c[h>>2]|0,b[k+2>>1]|0,1168);Od(m+8|0,m+10|0,c[h>>2]|0,b[l+4>>1]|0,1016);Od((c[g>>2]|0)+16|0,(c[g>>2]|0)+18|0,c[h>>2]|0,b[m+8>>1]|0,864);Od((c[g>>2]|0)+20|0,(c[g>>2]|0)+22|0,c[h>>2]|0,b[m+10>>1]|0,864);Od(m+12|0,m+14|0,c[h>>2]|0,b[l+6>>1]|0,1016);Od((c[g>>2]|0)+24|0,(c[g>>2]|0)+26|0,c[h>>2]|0,b[m+12>>1]|0,864);Od((c[g>>2]|0)+28|0,(c[g>>2]|0)+30|0,c[h>>2]|0,b[m+14>>1]|0,864);i=f;return}function bc(e,f,g,h){e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=i;i=i+32|0;k=j+4|0;l=j+12|0;m=j+8|0;n=j+20|0;o=j;p=j+24|0;q=j+16|0;c[k>>2]=e;c[l>>2]=f;c[m>>2]=g;c[n>>2]=h;h=(_(c[n>>2]|0,b[(c[m>>2]|0)+2>>1]|0)|0)/2|0;c[q>>2]=(c[(c[m>>2]|0)+20>>2]|0)+h;c[o>>2]=0;while(1){if((c[o>>2]|0)>=(b[(c[m>>2]|0)+2>>1]|0))break;h=c[q>>2]|0;c[q>>2]=h+1;a[p>>0]=a[h>>0]|0;b[(c[k>>2]|0)+(c[o>>2]<<1)>>1]=((d[p>>0]>>1&7)<<16>>16)*9;h=(c[o>>2]|0)+(_(d[p>>0]&1,(b[(c[m>>2]|0)+2>>1]|0)-1|0)|0)|0;a[(c[l>>2]|0)+(c[o>>2]|0)>>0]=a[(c[(c[m>>2]|0)+16>>2]|0)+h>>0]|0;b[(c[k>>2]|0)+((c[o>>2]|0)+1<<1)>>1]=((d[p>>0]>>5&7)<<16>>16)*9;h=(c[o>>2]|0)+(_(d[p>>0]>>4&1,(b[(c[m>>2]|0)+2>>1]|0)-1|0)|0)+1|0;a[(c[l>>2]|0)+((c[o>>2]|0)+1)>>0]=a[(c[(c[m>>2]|0)+16>>2]|0)+h>>0]|0;c[o>>2]=(c[o>>2]|0)+2}i=j;return}function cc(a,d,e,f,g,h){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;j=i;i=i+64|0;k=j+24|0;l=j+20|0;m=j+44|0;n=j+36|0;o=j+32|0;p=j+40|0;q=j+48|0;r=j+52|0;s=j+8|0;t=j+4|0;u=j+28|0;v=j+12|0;w=j;x=j+16|0;c[k>>2]=a;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[p>>2]=h;h=c[l>>2]|0;g=(c[k>>2]|0)+4|0;b[h>>1]=b[g>>1]|0;b[h+2>>1]=b[g+2>>1]|0;g=c[m>>2]|0;h=(c[k>>2]|0)+8|0;b[g>>1]=b[h>>1]|0;b[g+2>>1]=b[h+2>>1]|0;h=(c[k>>2]|0)+4|0;g=(c[l>>2]|0)+(c[p>>2]<<1)|0;b[h>>1]=b[g>>1]|0;b[h+2>>1]=b[g+2>>1]|0;g=(c[k>>2]|0)+8|0;h=(c[m>>2]|0)+(c[p>>2]<<1)|0;b[g>>1]=b[h>>1]|0;b[g+2>>1]=b[h+2>>1]|0;c[w>>2]=b[c[k>>2]>>1];c[x>>2]=b[(c[k>>2]|0)+2>>1];c[r>>2]=65536/(c[o>>2]<<3|0)|0;c[s>>2]=((_(((c[c[n>>2]>>2]|0)-(b[c[k>>2]>>1]|0)&65535)<<16>>16,(c[r>>2]&65535)<<16>>16)|0)>>15)+1>>1;c[t>>2]=((_(((c[(c[n>>2]|0)+4>>2]|0)-(b[(c[k>>2]|0)+2>>1]|0)&65535)<<16>>16,(c[r>>2]&65535)<<16>>16)|0)>>15)+1>>1;c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]<<3|0))break;c[w>>2]=(c[w>>2]|0)+(c[s>>2]|0);c[x>>2]=(c[x>>2]|0)+(c[t>>2]|0);c[u>>2]=(b[(c[l>>2]|0)+(c[q>>2]<<1)>>1]|0)+(b[(c[l>>2]|0)+((c[q>>2]|0)+2<<1)>>1]|0)+(b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]<<1)<<9;r=_(c[u>>2]>>16,(c[w>>2]&65535)<<16>>16)|0;c[u>>2]=(b[(c[m>>2]|0)+((c[q>>2]|0)+1<<1)>>1]<<8)+(r+((_(c[u>>2]&65535,(c[w>>2]&65535)<<16>>16)|0)>>16));r=_(b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]<<11>>16,(c[x>>2]&65535)<<16>>16)|0;c[u>>2]=(c[u>>2]|0)+(r+((_(b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]<<11&65535,(c[x>>2]&65535)<<16>>16)|0)>>16));if(((c[u>>2]>>7)+1>>1|0)<=32767)if(((c[u>>2]>>7)+1>>1|0)<-32768)y=-32768;else y=(c[u>>2]>>7)+1>>1;else y=32767;b[(c[m>>2]|0)+((c[q>>2]|0)+1<<1)>>1]=y;c[q>>2]=(c[q>>2]|0)+1}c[w>>2]=c[c[n>>2]>>2];c[x>>2]=c[(c[n>>2]|0)+4>>2];c[q>>2]=c[o>>2]<<3;while(1){if((c[q>>2]|0)>=(c[p>>2]|0))break;c[u>>2]=(b[(c[l>>2]|0)+(c[q>>2]<<1)>>1]|0)+(b[(c[l>>2]|0)+((c[q>>2]|0)+2<<1)>>1]|0)+(b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]<<1)<<9;o=_(c[u>>2]>>16,(c[w>>2]&65535)<<16>>16)|0;c[u>>2]=(b[(c[m>>2]|0)+((c[q>>2]|0)+1<<1)>>1]<<8)+(o+((_(c[u>>2]&65535,(c[w>>2]&65535)<<16>>16)|0)>>16));o=_(b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]<<11>>16,(c[x>>2]&65535)<<16>>16)|0;c[u>>2]=(c[u>>2]|0)+(o+((_(b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]<<11&65535,(c[x>>2]&65535)<<16>>16)|0)>>16));if(((c[u>>2]>>7)+1>>1|0)<=32767)if(((c[u>>2]>>7)+1>>1|0)<-32768)z=-32768;else z=(c[u>>2]>>7)+1>>1;else z=32767;b[(c[m>>2]|0)+((c[q>>2]|0)+1<<1)>>1]=z;c[q>>2]=(c[q>>2]|0)+1}b[c[k>>2]>>1]=c[c[n>>2]>>2];b[(c[k>>2]|0)+2>>1]=c[(c[n>>2]|0)+4>>2];c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[p>>2]|0))break;c[u>>2]=(b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]|0)+(b[(c[m>>2]|0)+((c[q>>2]|0)+1<<1)>>1]|0);c[v>>2]=(b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]|0)-(b[(c[m>>2]|0)+((c[q>>2]|0)+1<<1)>>1]|0);if((c[u>>2]|0)>32767)A=32767;else A=(c[u>>2]|0)<-32768?-32768:c[u>>2]|0;b[(c[l>>2]|0)+((c[q>>2]|0)+1<<1)>>1]=A;if((c[v>>2]|0)>32767)B=32767;else B=(c[v>>2]|0)<-32768?-32768:c[v>>2]|0;b[(c[m>>2]|0)+((c[q>>2]|0)+1<<1)>>1]=B;c[q>>2]=(c[q>>2]|0)+1}i=j;return}function dc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[k>>2]=(c[h>>2]|0)-65536;c[j>>2]=0;while(1){l=c[h>>2]>>16;if((c[j>>2]|0)>=((c[g>>2]|0)-1|0))break;d=_(l,(c[(c[f>>2]|0)+(c[j>>2]<<2)>>2]&65535)<<16>>16)|0;b=d+((_(c[h>>2]&65535,(c[(c[f>>2]|0)+(c[j>>2]<<2)>>2]&65535)<<16>>16)|0)>>16)|0;d=b+(_(c[h>>2]|0,(c[(c[f>>2]|0)+(c[j>>2]<<2)>>2]>>15)+1>>1)|0)|0;c[(c[f>>2]|0)+(c[j>>2]<<2)>>2]=d;d=((_(c[h>>2]|0,c[k>>2]|0)|0)>>15)+1>>1;c[h>>2]=(c[h>>2]|0)+d;c[j>>2]=(c[j>>2]|0)+1}j=_(l,(c[(c[f>>2]|0)+((c[g>>2]|0)-1<<2)>>2]&65535)<<16>>16)|0;l=j+((_(c[h>>2]&65535,(c[(c[f>>2]|0)+((c[g>>2]|0)-1<<2)>>2]&65535)<<16>>16)|0)>>16)|0;j=l+(_(c[h>>2]|0,(c[(c[f>>2]|0)+((c[g>>2]|0)-1<<2)>>2]>>15)+1>>1)|0)|0;c[(c[f>>2]|0)+((c[g>>2]|0)-1<<2)>>2]=j;i=e;return}function ec(a,d,e){a=a|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[g>>2]=a;c[h>>2]=d;c[j>>2]=e;c[l>>2]=(c[j>>2]|0)-65536;c[k>>2]=0;while(1){m=c[j>>2]|0;if((c[k>>2]|0)>=((c[h>>2]|0)-1|0))break;e=((_(m,b[(c[g>>2]|0)+(c[k>>2]<<1)>>1]|0)|0)>>15)+1>>1&65535;b[(c[g>>2]|0)+(c[k>>2]<<1)>>1]=e;e=((_(c[j>>2]|0,c[l>>2]|0)|0)>>15)+1>>1;c[j>>2]=(c[j>>2]|0)+e;c[k>>2]=(c[k>>2]|0)+1}k=((_(m,b[(c[g>>2]|0)+((c[h>>2]|0)-1<<1)>>1]|0)|0)>>15)+1>>1&65535;b[(c[g>>2]|0)+((c[h>>2]|0)-1<<1)>>1]=k;i=f;return}function fc(d,e,f,g,h){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;j=i;i=i+48|0;k=j+36|0;l=j+38|0;m=j+8|0;n=j+20|0;o=j+28|0;p=j+32|0;q=j+12|0;r=j+24|0;s=j+4|0;t=j;u=j+16|0;b[k>>1]=d;a[l>>0]=e;c[m>>2]=f;c[n>>2]=g;c[o>>2]=h;h=(c[o>>2]|0)==4;do if((c[n>>2]|0)==8)if(h){c[u>>2]=1840;c[t>>2]=11;break}else{c[u>>2]=1808;c[t>>2]=3;break}else if(h){c[u>>2]=1888;c[t>>2]=34;break}else{c[u>>2]=1816;c[t>>2]=12;break}while(0);c[r>>2]=(c[n>>2]&65535)<<16>>16<<1;c[s>>2]=((c[n>>2]&65535)<<16>>16)*18;c[p>>2]=(c[r>>2]|0)+(b[k>>1]|0);c[q>>2]=0;while(1){if((c[q>>2]|0)>=(c[o>>2]|0))break;k=_(c[q>>2]|0,c[t>>2]|0)|0;c[(c[m>>2]|0)+(c[q>>2]<<2)>>2]=(c[p>>2]|0)+(a[(c[u>>2]|0)+(k+(a[l>>0]|0))>>0]|0);k=c[(c[m>>2]|0)+(c[q>>2]<<2)>>2]|0;do if((c[r>>2]|0)>(c[s>>2]|0)){if((k|0)>(c[r>>2]|0)){v=c[r>>2]|0;break}if((c[(c[m>>2]|0)+(c[q>>2]<<2)>>2]|0)<(c[s>>2]|0)){v=c[s>>2]|0;break}else{v=c[(c[m>>2]|0)+(c[q>>2]<<2)>>2]|0;break}}else{if((k|0)>(c[s>>2]|0)){v=c[s>>2]|0;break}if((c[(c[m>>2]|0)+(c[q>>2]<<2)>>2]|0)<(c[r>>2]|0)){v=c[r>>2]|0;break}else{v=c[(c[m>>2]|0)+(c[q>>2]<<2)>>2]|0;break}}while(0);c[(c[m>>2]|0)+(c[q>>2]<<2)>>2]=v;c[q>>2]=(c[q>>2]|0)+1}i=j;return}function gc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0;b=i;i=i+16|0;d=b+12|0;e=b+8|0;f=b+4|0;g=b;c[e>>2]=a;if((c[e>>2]|0)<0){c[d>>2]=0;h=c[d>>2]|0;i=b;return h|0}if((c[e>>2]|0)>=3967){c[d>>2]=2147483647;h=c[d>>2]|0;i=b;return h|0}c[f>>2]=1<<(c[e>>2]>>7);c[g>>2]=c[e>>2]&127;a=c[f>>2]|0;j=c[f>>2]|0;if((c[e>>2]|0)<2048){e=_((_((c[g>>2]&65535)<<16>>16,(128-(c[g>>2]|0)&65535)<<16>>16)|0)>>16,-174)|0;c[f>>2]=a+((_(j,(c[g>>2]|0)+(e+((_((_((c[g>>2]&65535)<<16>>16,(128-(c[g>>2]|0)&65535)<<16>>16)|0)&65535,-174)|0)>>16))|0)|0)>>7)}else{e=_((_((c[g>>2]&65535)<<16>>16,(128-(c[g>>2]|0)&65535)<<16>>16)|0)>>16,-174)|0;c[f>>2]=a+(_(j>>7,(c[g>>2]|0)+(e+((_((_((c[g>>2]&65535)<<16>>16,(128-(c[g>>2]|0)&65535)<<16>>16)|0)&65535,-174)|0)>>16))|0)|0)}c[d>>2]=c[f>>2];h=c[d>>2]|0;i=b;return h|0}function hc(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;h=i;i=i+48|0;j=h;k=h+16|0;l=h+28|0;m=h+4|0;n=h+32|0;o=h+36|0;p=h+12|0;q=h+24|0;r=h+20|0;s=h+8|0;c[j>>2]=a;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[p>>2]=c[n>>2];while(1){if((c[p>>2]|0)>=(c[m>>2]|0))break;c[s>>2]=(c[k>>2]|0)+((c[p>>2]|0)-1<<1);c[q>>2]=_(b[c[s>>2]>>1]|0,b[c[l>>2]>>1]|0)|0;c[q>>2]=(c[q>>2]|0)+(_(b[(c[s>>2]|0)+-2>>1]|0,b[(c[l>>2]|0)+2>>1]|0)|0);c[q>>2]=(c[q>>2]|0)+(_(b[(c[s>>2]|0)+-4>>1]|0,b[(c[l>>2]|0)+4>>1]|0)|0);c[q>>2]=(c[q>>2]|0)+(_(b[(c[s>>2]|0)+-6>>1]|0,b[(c[l>>2]|0)+6>>1]|0)|0);c[q>>2]=(c[q>>2]|0)+(_(b[(c[s>>2]|0)+-8>>1]|0,b[(c[l>>2]|0)+8>>1]|0)|0);c[q>>2]=(c[q>>2]|0)+(_(b[(c[s>>2]|0)+-10>>1]|0,b[(c[l>>2]|0)+10>>1]|0)|0);c[o>>2]=6;while(1){if((c[o>>2]|0)>=(c[n>>2]|0))break;c[q>>2]=(c[q>>2]|0)+(_(b[(c[s>>2]|0)+(0-(c[o>>2]|0)<<1)>>1]|0,b[(c[l>>2]|0)+(c[o>>2]<<1)>>1]|0)|0);c[q>>2]=(c[q>>2]|0)+(_(b[(c[s>>2]|0)+(0-(c[o>>2]|0)-1<<1)>>1]|0,b[(c[l>>2]|0)+((c[o>>2]|0)+1<<1)>>1]|0)|0);c[o>>2]=(c[o>>2]|0)+2}c[q>>2]=(b[(c[s>>2]|0)+2>>1]<<12)-(c[q>>2]|0);c[r>>2]=(c[q>>2]>>11)+1>>1;if((c[r>>2]|0)>32767)t=32767;else t=(c[r>>2]|0)<-32768?-32768:c[r>>2]|0;b[(c[j>>2]|0)+(c[p>>2]<<1)>>1]=t;c[p>>2]=(c[p>>2]|0)+1}bf(c[j>>2]|0,0,c[n>>2]<<1|0)|0;i=h;return}function ic(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;e=i;i=i+160|0;f=e+136|0;g=e+144|0;h=e+148|0;j=e+152|0;k=e+8|0;l=e;m=e+140|0;c[g>>2]=a;c[h>>2]=d;c[m>>2]=0;c[l>>2]=k+((c[h>>2]&1)<<6);c[j>>2]=0;while(1){if((c[j>>2]|0)>=(c[h>>2]|0))break;c[m>>2]=(c[m>>2]|0)+(b[(c[g>>2]|0)+(c[j>>2]<<1)>>1]|0);c[(c[l>>2]|0)+(c[j>>2]<<2)>>2]=b[(c[g>>2]|0)+(c[j>>2]<<1)>>1]<<12;c[j>>2]=(c[j>>2]|0)+1}if((c[m>>2]|0)>=4096){c[f>>2]=0;n=c[f>>2]|0;i=e;return n|0}else{c[f>>2]=Pd(k,c[h>>2]|0)|0;n=c[f>>2]|0;i=e;return n|0}return 0}function jc(a,e,f){a=a|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;g=i;i=i+272|0;h=g+264|0;j=g+48|0;k=g+24|0;l=g+36|0;m=g+224|0;n=g+16|0;o=g+20|0;p=g+120|0;q=g+188|0;r=g+228|0;s=g+268|0;t=g+40|0;u=g+44|0;v=g+8|0;w=g;x=g+4|0;y=g+56|0;z=g+28|0;A=g+184|0;B=g+12|0;C=g+32|0;c[h>>2]=a;c[j>>2]=e;c[k>>2]=f;c[B>>2]=0;c[l>>2]=(c[k>>2]|0)==16?2968:2984;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;c[u>>2]=b[(c[j>>2]|0)+(c[m>>2]<<1)>>1]>>8;c[v>>2]=(b[(c[j>>2]|0)+(c[m>>2]<<1)>>1]|0)-(c[u>>2]<<8);c[w>>2]=b[1544+(c[u>>2]<<1)>>1];c[x>>2]=(b[1544+((c[u>>2]|0)+1<<1)>>1]|0)-(c[w>>2]|0);f=((c[w>>2]<<8)+(_(c[x>>2]|0,c[v>>2]|0)|0)>>3)+1>>1;c[p+(d[(c[l>>2]|0)+(c[m>>2]|0)>>0]<<2)>>2]=f;c[m>>2]=(c[m>>2]|0)+1}c[o>>2]=c[k>>2]>>1;Qd(q,p,c[o>>2]|0);Qd(r,p+4|0,c[o>>2]|0);c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[o>>2]|0))break;c[s>>2]=(c[q+((c[m>>2]|0)+1<<2)>>2]|0)+(c[q+(c[m>>2]<<2)>>2]|0);c[t>>2]=(c[r+((c[m>>2]|0)+1<<2)>>2]|0)-(c[r+(c[m>>2]<<2)>>2]|0);c[y+(c[m>>2]<<2)>>2]=0-(c[t>>2]|0)-(c[s>>2]|0);c[y+((c[k>>2]|0)-(c[m>>2]|0)-1<<2)>>2]=(c[t>>2]|0)-(c[s>>2]|0);c[m>>2]=(c[m>>2]|0)+1}c[n>>2]=0;while(1){if((c[n>>2]|0)>=10)break;c[z>>2]=0;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;s=c[y+(c[m>>2]<<2)>>2]|0;c[A>>2]=(c[y+(c[m>>2]<<2)>>2]|0)>0?s:0-s|0;if((c[A>>2]|0)>(c[z>>2]|0)){c[z>>2]=c[A>>2];c[B>>2]=c[m>>2]}c[m>>2]=(c[m>>2]|0)+1}c[z>>2]=(c[z>>2]>>4)+1>>1;if((c[z>>2]|0)<=32767)break;c[z>>2]=(c[z>>2]|0)<163838?c[z>>2]|0:163838;c[C>>2]=65470-(((c[z>>2]|0)-32767<<14|0)/((_(c[z>>2]|0,(c[B>>2]|0)+1|0)|0)>>2|0)|0);dc(y,c[k>>2]|0,c[C>>2]|0);c[n>>2]=(c[n>>2]|0)+1}C=(c[n>>2]|0)==10;c[m>>2]=0;a:do if(C)while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break a;if(((c[y+(c[m>>2]<<2)>>2]>>4)+1>>1|0)<=32767)if(((c[y+(c[m>>2]<<2)>>2]>>4)+1>>1|0)<-32768)D=-32768;else D=(c[y+(c[m>>2]<<2)>>2]>>4)+1>>1;else D=32767;b[(c[h>>2]|0)+(c[m>>2]<<1)>>1]=D;c[y+(c[m>>2]<<2)>>2]=b[(c[h>>2]|0)+(c[m>>2]<<1)>>1]<<5;c[m>>2]=(c[m>>2]|0)+1}else while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break a;b[(c[h>>2]|0)+(c[m>>2]<<1)>>1]=(c[y+(c[m>>2]<<2)>>2]>>4)+1>>1;c[m>>2]=(c[m>>2]|0)+1}while(0);c[n>>2]=0;while(1){if((c[n>>2]|0)>=16){E=31;break}if((ic(c[h>>2]|0,c[k>>2]|0)|0)>=107374){E=31;break}dc(y,c[k>>2]|0,65536-(2<<c[n>>2])|0);c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;b[(c[h>>2]|0)+(c[m>>2]<<1)>>1]=(c[y+(c[m>>2]<<2)>>2]>>4)+1>>1;c[m>>2]=(c[m>>2]|0)+1}c[n>>2]=(c[n>>2]|0)+1}if((E|0)==31){i=g;return}} +function Td(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function Ud(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)<(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function Vd(a,d,e,f,g,h,j){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;k=i;i=i+48|0;l=k;m=k+8|0;n=k+36|0;o=k+16|0;p=k+32|0;q=k+40|0;r=k+44|0;s=k+24|0;t=k+20|0;u=k+12|0;v=k+4|0;w=k+28|0;c[l>>2]=a;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=g;c[q>>2]=h;c[r>>2]=j;j=c[o>>2]|0;if((j|0)==18){c[s>>2]=0;while(1){if((c[s>>2]|0)>=(c[q>>2]|0))break;c[u>>2]=(c[m>>2]|0)+(c[s>>2]>>16<<2);o=_((c[s>>2]&65535)>>16,(c[p>>2]&65535)<<16>>16)|0;c[v>>2]=o+((_(c[s>>2]&65535,(c[p>>2]&65535)<<16>>16)|0)>>16);c[w>>2]=(c[n>>2]|0)+((c[v>>2]|0)*9<<1);o=_(c[c[u>>2]>>2]>>16,b[c[w>>2]>>1]|0)|0;c[t>>2]=o+((_(c[c[u>>2]>>2]&65535,b[c[w>>2]>>1]|0)|0)>>16);o=_(c[(c[u>>2]|0)+4>>2]>>16,b[(c[w>>2]|0)+2>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+4>>2]&65535,b[(c[w>>2]|0)+2>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+8>>2]>>16,b[(c[w>>2]|0)+4>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+8>>2]&65535,b[(c[w>>2]|0)+4>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+12>>2]>>16,b[(c[w>>2]|0)+6>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+12>>2]&65535,b[(c[w>>2]|0)+6>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+16>>2]>>16,b[(c[w>>2]|0)+8>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+16>>2]&65535,b[(c[w>>2]|0)+8>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+20>>2]>>16,b[(c[w>>2]|0)+10>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+20>>2]&65535,b[(c[w>>2]|0)+10>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+24>>2]>>16,b[(c[w>>2]|0)+12>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+24>>2]&65535,b[(c[w>>2]|0)+12>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+28>>2]>>16,b[(c[w>>2]|0)+14>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+28>>2]&65535,b[(c[w>>2]|0)+14>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+32>>2]>>16,b[(c[w>>2]|0)+16>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+32>>2]&65535,b[(c[w>>2]|0)+16>>1]|0)|0)>>16));c[w>>2]=(c[n>>2]|0)+(((c[p>>2]|0)-1-(c[v>>2]|0)|0)*9<<1);o=_(c[(c[u>>2]|0)+68>>2]>>16,b[c[w>>2]>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+68>>2]&65535,b[c[w>>2]>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+64>>2]>>16,b[(c[w>>2]|0)+2>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+64>>2]&65535,b[(c[w>>2]|0)+2>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+60>>2]>>16,b[(c[w>>2]|0)+4>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+60>>2]&65535,b[(c[w>>2]|0)+4>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+56>>2]>>16,b[(c[w>>2]|0)+6>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+56>>2]&65535,b[(c[w>>2]|0)+6>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+52>>2]>>16,b[(c[w>>2]|0)+8>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+52>>2]&65535,b[(c[w>>2]|0)+8>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+48>>2]>>16,b[(c[w>>2]|0)+10>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+48>>2]&65535,b[(c[w>>2]|0)+10>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+44>>2]>>16,b[(c[w>>2]|0)+12>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+44>>2]&65535,b[(c[w>>2]|0)+12>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+40>>2]>>16,b[(c[w>>2]|0)+14>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+40>>2]&65535,b[(c[w>>2]|0)+14>>1]|0)|0)>>16));o=_(c[(c[u>>2]|0)+36>>2]>>16,b[(c[w>>2]|0)+16>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(o+((_(c[(c[u>>2]|0)+36>>2]&65535,b[(c[w>>2]|0)+16>>1]|0)|0)>>16));if(((c[t>>2]>>5)+1>>1|0)<=32767)if(((c[t>>2]>>5)+1>>1|0)<-32768)x=-32768;else x=(c[t>>2]>>5)+1>>1;else x=32767;o=c[l>>2]|0;c[l>>2]=o+2;b[o>>1]=x;c[s>>2]=(c[s>>2]|0)+(c[r>>2]|0)}y=c[l>>2]|0;i=k;return y|0}else if((j|0)==24){c[s>>2]=0;while(1){if((c[s>>2]|0)>=(c[q>>2]|0))break;c[u>>2]=(c[m>>2]|0)+(c[s>>2]>>16<<2);x=_((c[c[u>>2]>>2]|0)+(c[(c[u>>2]|0)+92>>2]|0)>>16,b[c[n>>2]>>1]|0)|0;c[t>>2]=x+((_((c[c[u>>2]>>2]|0)+(c[(c[u>>2]|0)+92>>2]|0)&65535,b[c[n>>2]>>1]|0)|0)>>16);x=_((c[(c[u>>2]|0)+4>>2]|0)+(c[(c[u>>2]|0)+88>>2]|0)>>16,b[(c[n>>2]|0)+2>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+4>>2]|0)+(c[(c[u>>2]|0)+88>>2]|0)&65535,b[(c[n>>2]|0)+2>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+8>>2]|0)+(c[(c[u>>2]|0)+84>>2]|0)>>16,b[(c[n>>2]|0)+4>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+8>>2]|0)+(c[(c[u>>2]|0)+84>>2]|0)&65535,b[(c[n>>2]|0)+4>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+12>>2]|0)+(c[(c[u>>2]|0)+80>>2]|0)>>16,b[(c[n>>2]|0)+6>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+12>>2]|0)+(c[(c[u>>2]|0)+80>>2]|0)&65535,b[(c[n>>2]|0)+6>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+16>>2]|0)+(c[(c[u>>2]|0)+76>>2]|0)>>16,b[(c[n>>2]|0)+8>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+16>>2]|0)+(c[(c[u>>2]|0)+76>>2]|0)&65535,b[(c[n>>2]|0)+8>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+20>>2]|0)+(c[(c[u>>2]|0)+72>>2]|0)>>16,b[(c[n>>2]|0)+10>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+20>>2]|0)+(c[(c[u>>2]|0)+72>>2]|0)&65535,b[(c[n>>2]|0)+10>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+24>>2]|0)+(c[(c[u>>2]|0)+68>>2]|0)>>16,b[(c[n>>2]|0)+12>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+24>>2]|0)+(c[(c[u>>2]|0)+68>>2]|0)&65535,b[(c[n>>2]|0)+12>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+28>>2]|0)+(c[(c[u>>2]|0)+64>>2]|0)>>16,b[(c[n>>2]|0)+14>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+28>>2]|0)+(c[(c[u>>2]|0)+64>>2]|0)&65535,b[(c[n>>2]|0)+14>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+32>>2]|0)+(c[(c[u>>2]|0)+60>>2]|0)>>16,b[(c[n>>2]|0)+16>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+32>>2]|0)+(c[(c[u>>2]|0)+60>>2]|0)&65535,b[(c[n>>2]|0)+16>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+36>>2]|0)+(c[(c[u>>2]|0)+56>>2]|0)>>16,b[(c[n>>2]|0)+18>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+36>>2]|0)+(c[(c[u>>2]|0)+56>>2]|0)&65535,b[(c[n>>2]|0)+18>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+40>>2]|0)+(c[(c[u>>2]|0)+52>>2]|0)>>16,b[(c[n>>2]|0)+20>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+40>>2]|0)+(c[(c[u>>2]|0)+52>>2]|0)&65535,b[(c[n>>2]|0)+20>>1]|0)|0)>>16));x=_((c[(c[u>>2]|0)+44>>2]|0)+(c[(c[u>>2]|0)+48>>2]|0)>>16,b[(c[n>>2]|0)+22>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(x+((_((c[(c[u>>2]|0)+44>>2]|0)+(c[(c[u>>2]|0)+48>>2]|0)&65535,b[(c[n>>2]|0)+22>>1]|0)|0)>>16));if(((c[t>>2]>>5)+1>>1|0)<=32767)if(((c[t>>2]>>5)+1>>1|0)<-32768)z=-32768;else z=(c[t>>2]>>5)+1>>1;else z=32767;x=c[l>>2]|0;c[l>>2]=x+2;b[x>>1]=z;c[s>>2]=(c[s>>2]|0)+(c[r>>2]|0)}y=c[l>>2]|0;i=k;return y|0}else if((j|0)==36){c[s>>2]=0;while(1){if((c[s>>2]|0)>=(c[q>>2]|0))break;c[u>>2]=(c[m>>2]|0)+(c[s>>2]>>16<<2);j=_((c[c[u>>2]>>2]|0)+(c[(c[u>>2]|0)+140>>2]|0)>>16,b[c[n>>2]>>1]|0)|0;c[t>>2]=j+((_((c[c[u>>2]>>2]|0)+(c[(c[u>>2]|0)+140>>2]|0)&65535,b[c[n>>2]>>1]|0)|0)>>16);j=_((c[(c[u>>2]|0)+4>>2]|0)+(c[(c[u>>2]|0)+136>>2]|0)>>16,b[(c[n>>2]|0)+2>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+4>>2]|0)+(c[(c[u>>2]|0)+136>>2]|0)&65535,b[(c[n>>2]|0)+2>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+8>>2]|0)+(c[(c[u>>2]|0)+132>>2]|0)>>16,b[(c[n>>2]|0)+4>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+8>>2]|0)+(c[(c[u>>2]|0)+132>>2]|0)&65535,b[(c[n>>2]|0)+4>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+12>>2]|0)+(c[(c[u>>2]|0)+128>>2]|0)>>16,b[(c[n>>2]|0)+6>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+12>>2]|0)+(c[(c[u>>2]|0)+128>>2]|0)&65535,b[(c[n>>2]|0)+6>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+16>>2]|0)+(c[(c[u>>2]|0)+124>>2]|0)>>16,b[(c[n>>2]|0)+8>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+16>>2]|0)+(c[(c[u>>2]|0)+124>>2]|0)&65535,b[(c[n>>2]|0)+8>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+20>>2]|0)+(c[(c[u>>2]|0)+120>>2]|0)>>16,b[(c[n>>2]|0)+10>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+20>>2]|0)+(c[(c[u>>2]|0)+120>>2]|0)&65535,b[(c[n>>2]|0)+10>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+24>>2]|0)+(c[(c[u>>2]|0)+116>>2]|0)>>16,b[(c[n>>2]|0)+12>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+24>>2]|0)+(c[(c[u>>2]|0)+116>>2]|0)&65535,b[(c[n>>2]|0)+12>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+28>>2]|0)+(c[(c[u>>2]|0)+112>>2]|0)>>16,b[(c[n>>2]|0)+14>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+28>>2]|0)+(c[(c[u>>2]|0)+112>>2]|0)&65535,b[(c[n>>2]|0)+14>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+32>>2]|0)+(c[(c[u>>2]|0)+108>>2]|0)>>16,b[(c[n>>2]|0)+16>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+32>>2]|0)+(c[(c[u>>2]|0)+108>>2]|0)&65535,b[(c[n>>2]|0)+16>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+36>>2]|0)+(c[(c[u>>2]|0)+104>>2]|0)>>16,b[(c[n>>2]|0)+18>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+36>>2]|0)+(c[(c[u>>2]|0)+104>>2]|0)&65535,b[(c[n>>2]|0)+18>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+40>>2]|0)+(c[(c[u>>2]|0)+100>>2]|0)>>16,b[(c[n>>2]|0)+20>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+40>>2]|0)+(c[(c[u>>2]|0)+100>>2]|0)&65535,b[(c[n>>2]|0)+20>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+44>>2]|0)+(c[(c[u>>2]|0)+96>>2]|0)>>16,b[(c[n>>2]|0)+22>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+44>>2]|0)+(c[(c[u>>2]|0)+96>>2]|0)&65535,b[(c[n>>2]|0)+22>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+48>>2]|0)+(c[(c[u>>2]|0)+92>>2]|0)>>16,b[(c[n>>2]|0)+24>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+48>>2]|0)+(c[(c[u>>2]|0)+92>>2]|0)&65535,b[(c[n>>2]|0)+24>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+52>>2]|0)+(c[(c[u>>2]|0)+88>>2]|0)>>16,b[(c[n>>2]|0)+26>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+52>>2]|0)+(c[(c[u>>2]|0)+88>>2]|0)&65535,b[(c[n>>2]|0)+26>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+56>>2]|0)+(c[(c[u>>2]|0)+84>>2]|0)>>16,b[(c[n>>2]|0)+28>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+56>>2]|0)+(c[(c[u>>2]|0)+84>>2]|0)&65535,b[(c[n>>2]|0)+28>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+60>>2]|0)+(c[(c[u>>2]|0)+80>>2]|0)>>16,b[(c[n>>2]|0)+30>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+60>>2]|0)+(c[(c[u>>2]|0)+80>>2]|0)&65535,b[(c[n>>2]|0)+30>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+64>>2]|0)+(c[(c[u>>2]|0)+76>>2]|0)>>16,b[(c[n>>2]|0)+32>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+64>>2]|0)+(c[(c[u>>2]|0)+76>>2]|0)&65535,b[(c[n>>2]|0)+32>>1]|0)|0)>>16));j=_((c[(c[u>>2]|0)+68>>2]|0)+(c[(c[u>>2]|0)+72>>2]|0)>>16,b[(c[n>>2]|0)+34>>1]|0)|0;c[t>>2]=(c[t>>2]|0)+(j+((_((c[(c[u>>2]|0)+68>>2]|0)+(c[(c[u>>2]|0)+72>>2]|0)&65535,b[(c[n>>2]|0)+34>>1]|0)|0)>>16));if(((c[t>>2]>>5)+1>>1|0)<=32767)if(((c[t>>2]>>5)+1>>1|0)<-32768)A=-32768;else A=(c[t>>2]>>5)+1>>1;else A=32767;j=c[l>>2]|0;c[l>>2]=j+2;b[j>>1]=A;c[s>>2]=(c[s>>2]|0)+(c[r>>2]|0)}y=c[l>>2]|0;i=k;return y|0}else{y=c[l>>2]|0;i=k;return y|0}return 0}function Wd(a,d,e,f){a=a|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;g=i;i=i+32|0;h=g+4|0;j=g+16|0;k=g+8|0;l=g+20|0;m=g+28|0;n=g;o=g+12|0;p=g+24|0;c[h>>2]=a;c[j>>2]=d;c[k>>2]=e;c[l>>2]=f;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;c[p>>2]=(((c[m>>2]&65535)>>16)*12|0)+((c[m>>2]&65535)*12>>16);c[o>>2]=(c[j>>2]|0)+(c[m>>2]>>16<<1);c[n>>2]=_(b[c[o>>2]>>1]|0,b[2280+(c[p>>2]<<3)>>1]|0)|0;c[n>>2]=(c[n>>2]|0)+(_(b[(c[o>>2]|0)+2>>1]|0,b[2280+(c[p>>2]<<3)+2>>1]|0)|0);c[n>>2]=(c[n>>2]|0)+(_(b[(c[o>>2]|0)+4>>1]|0,b[2280+(c[p>>2]<<3)+4>>1]|0)|0);c[n>>2]=(c[n>>2]|0)+(_(b[(c[o>>2]|0)+6>>1]|0,b[2280+(c[p>>2]<<3)+6>>1]|0)|0);c[n>>2]=(c[n>>2]|0)+(_(b[(c[o>>2]|0)+8>>1]|0,b[2280+(11-(c[p>>2]|0)<<3)+6>>1]|0)|0);c[n>>2]=(c[n>>2]|0)+(_(b[(c[o>>2]|0)+10>>1]|0,b[2280+(11-(c[p>>2]|0)<<3)+4>>1]|0)|0);c[n>>2]=(c[n>>2]|0)+(_(b[(c[o>>2]|0)+12>>1]|0,b[2280+(11-(c[p>>2]|0)<<3)+2>>1]|0)|0);c[n>>2]=(c[n>>2]|0)+(_(b[(c[o>>2]|0)+14>>1]|0,b[2280+(11-(c[p>>2]|0)<<3)>>1]|0)|0);if(((c[n>>2]>>14)+1>>1|0)<=32767)if(((c[n>>2]>>14)+1>>1|0)<-32768)q=-32768;else q=(c[n>>2]>>14)+1>>1;else q=32767;f=c[h>>2]|0;c[h>>2]=f+2;b[f>>1]=q;c[m>>2]=(c[m>>2]|0)+(c[l>>2]|0)}i=g;return c[h>>2]|0}function Xd(a,e,f){a=a|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0;g=i;i=i+16|0;h=g+12|0;j=g+8|0;k=g+4|0;l=g;c[j>>2]=a;c[k>>2]=e;c[l>>2]=f;if((c[k>>2]|0)<1){b[c[l>>2]>>1]=-1;c[h>>2]=-1;m=c[h>>2]|0;i=g;return m|0}if((d[c[j>>2]>>0]|0|0)<252){b[c[l>>2]>>1]=d[c[j>>2]>>0]|0;c[h>>2]=1;m=c[h>>2]|0;i=g;return m|0}if((c[k>>2]|0)<2){b[c[l>>2]>>1]=-1;c[h>>2]=-1;m=c[h>>2]|0;i=g;return m|0}else{b[c[l>>2]>>1]=((d[(c[j>>2]|0)+1>>0]|0)<<2)+(d[c[j>>2]>>0]|0);c[h>>2]=2;m=c[h>>2]|0;i=g;return m|0}return 0}function Yd(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;i=b;return (c[d>>2]|0)+4-1&-4|0}function Zd(d,e,f,h,j,k){d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0;l=i;i=i+320|0;m=l;n=l+72|0;o=l+48|0;p=l+40|0;q=l+24|0;r=l+8|0;s=l+16|0;t=l+56|0;u=l+80|0;v=l+64|0;w=l+32|0;x=l+100|0;y=l+96|0;z=l+88|0;A=l+84|0;B=l+256|0;C=l+252|0;D=l+220|0;E=l+200|0;F=l+192|0;G=l+172|0;H=l+168|0;I=l+160|0;J=l+112|0;K=l+272|0;L=l+284|0;M=l+292|0;N=l+300|0;O=l+304|0;P=l+180|0;Q=l+184|0;R=l+280|0;S=l+288|0;T=l+296|0;U=l+248|0;V=l+216|0;W=l+204|0;Y=l+208|0;Z=l+212|0;$=l+188|0;aa=l+228|0;ba=l+232|0;ca=l+276|0;da=l+164|0;ea=l+236|0;fa=l+240|0;ga=l+244|0;ha=l+92|0;ia=l+104|0;ja=l+260|0;la=l+308|0;ma=l+196|0;na=l+268|0;oa=l+224|0;pa=l+312|0;qa=l+108|0;ra=l+176|0;sa=l+264|0;c[y>>2]=d;c[z>>2]=e;c[A>>2]=f;c[B>>2]=h;c[C>>2]=j;c[D>>2]=k;c[H>>2]=0;c[I>>2]=0;c[O>>2]=0;c[S>>2]=0;c[U>>2]=0;c[V>>2]=0;c[W>>2]=0;c[da>>2]=0;c[E>>2]=(c[y>>2]|0)+(c[(c[y>>2]|0)+4>>2]|0);c[F>>2]=(c[y>>2]|0)+(c[c[y>>2]>>2]|0);c[ba>>2]=(c[(c[y>>2]|0)+12>>2]|0)/50|0;c[aa>>2]=c[ba>>2]>>1;c[$>>2]=c[aa>>2]>>1;c[Z>>2]=c[$>>2]>>1;if((c[C>>2]|0)<(c[Z>>2]|0)){c[x>>2]=-2;ta=c[x>>2]|0;i=l;return ta|0}if((c[C>>2]|0)<(((c[(c[y>>2]|0)+12>>2]|0)/25|0)*3|0))va=c[C>>2]|0;else va=((c[(c[y>>2]|0)+12>>2]|0)/25|0)*3|0;c[C>>2]=va;if((c[A>>2]|0)<=1){c[z>>2]=0;if((c[C>>2]|0)<(c[(c[y>>2]|0)+60>>2]|0))wa=c[C>>2]|0;else wa=c[(c[y>>2]|0)+60>>2]|0;c[C>>2]=wa}do if(!(c[z>>2]|0)){c[Q>>2]=c[C>>2];c[R>>2]=c[(c[y>>2]|0)+56>>2];if(!(c[R>>2]|0)){c[G>>2]=0;while(1){if((c[G>>2]|0)>=(_(c[Q>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0))break;g[(c[B>>2]|0)+(c[G>>2]<<2)>>2]=0.0;c[G>>2]=(c[G>>2]|0)+1}c[x>>2]=c[Q>>2];ta=c[x>>2]|0;i=l;return ta|0}if((c[Q>>2]|0)>(c[ba>>2]|0)){while(1){c[fa>>2]=Zd(c[y>>2]|0,0,0,c[B>>2]|0,(c[Q>>2]|0)<(c[ba>>2]|0)?c[Q>>2]|0:c[ba>>2]|0,0)|0;xa=c[fa>>2]|0;if((c[fa>>2]|0)<0){ya=20;break}wa=_(xa,c[(c[y>>2]|0)+8>>2]|0)|0;c[B>>2]=(c[B>>2]|0)+(wa<<2);c[Q>>2]=(c[Q>>2]|0)-(c[fa>>2]|0);if((c[Q>>2]|0)<=0){ya=22;break}}if((ya|0)==20){c[x>>2]=xa;ta=c[x>>2]|0;i=l;return ta|0}else if((ya|0)==22){c[x>>2]=c[C>>2];ta=c[x>>2]|0;i=l;return ta|0}}if((c[Q>>2]|0)<(c[ba>>2]|0)){if((c[Q>>2]|0)>(c[aa>>2]|0)){c[Q>>2]=c[aa>>2];break}if(((c[R>>2]|0)!=1e3?(c[Q>>2]|0)>(c[$>>2]|0):0)?(c[Q>>2]|0)<(c[aa>>2]|0):0)c[Q>>2]=c[$>>2]}}else{c[Q>>2]=c[(c[y>>2]|0)+60>>2];c[R>>2]=c[(c[y>>2]|0)+52>>2];eb(J,c[z>>2]|0,c[A>>2]|0)}while(0);c[ea>>2]=0;c[M>>2]=1;c[N>>2]=1;do if((c[z>>2]|0)!=0?(c[(c[y>>2]|0)+56>>2]|0)>0:0){if(!(((c[R>>2]|0)==1002?(c[(c[y>>2]|0)+56>>2]|0)!=1002:0)?(c[(c[y>>2]|0)+64>>2]|0)==0:0)){if((c[R>>2]|0)==1002)break;if((c[(c[y>>2]|0)+56>>2]|0)!=1002)break}c[S>>2]=1;ya=_(c[$>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0;if((c[R>>2]|0)==1002){c[N>>2]=ya;break}else{c[M>>2]=ya;break}}while(0);ya=c[N>>2]|0;c[ga>>2]=ua()|0;N=i;i=i+((1*(ya<<2)|0)+15&-16)|0;if((c[S>>2]|0)!=0&(c[R>>2]|0)==1002){c[O>>2]=N;Zd(c[y>>2]|0,0,0,c[O>>2]|0,(c[$>>2]|0)<(c[Q>>2]|0)?c[$>>2]|0:c[Q>>2]|0,0)|0}a:do if((c[Q>>2]|0)>(c[C>>2]|0)){c[x>>2]=-1;c[ha>>2]=1}else{c[C>>2]=c[Q>>2];if((c[R>>2]|0)==1002|(c[ea>>2]|0)!=0)za=1;else za=_((c[aa>>2]|0)>(c[C>>2]|0)?c[aa>>2]|0:c[C>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0;c[L>>2]=za;N=i;i=i+((1*(c[L>>2]<<1)|0)+15&-16)|0;b:do if((c[R>>2]|0)!=1002){c[la>>2]=N;if((c[(c[y>>2]|0)+56>>2]|0)==1002)Vb(c[E>>2]|0)|0;if(10>(((c[Q>>2]|0)*1e3|0)/(c[(c[y>>2]|0)+12>>2]|0)|0|0))Aa=10;else Aa=((c[Q>>2]|0)*1e3|0)/(c[(c[y>>2]|0)+12>>2]|0)|0;c[(c[y>>2]|0)+16+16>>2]=Aa;do if(c[z>>2]|0){c[(c[y>>2]|0)+16+4>>2]=c[(c[y>>2]|0)+44>>2];ya=c[y>>2]|0;if((c[R>>2]|0)!=1e3){c[ya+16+12>>2]=16e3;break}xa=c[y>>2]|0;if((c[ya+48>>2]|0)==1101){c[xa+16+12>>2]=8e3;break}if((c[xa+48>>2]|0)==1102){c[(c[y>>2]|0)+16+12>>2]=12e3;break}else{c[(c[y>>2]|0)+16+12>>2]=16e3;break}}while(0);c[ia>>2]=(c[z>>2]|0)==0?1:c[D>>2]<<1;c[ja>>2]=0;c:while(1){c[ma>>2]=(c[ja>>2]|0)==0&1;c[H>>2]=Wb(c[E>>2]|0,(c[y>>2]|0)+16|0,c[ia>>2]|0,c[ma>>2]|0,J,c[la>>2]|0,K)|0;d:do if(c[H>>2]|0){if(!(c[ia>>2]|0))break c;c[K>>2]=c[C>>2];c[G>>2]=0;while(1){if((c[G>>2]|0)>=(_(c[C>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0))break d;b[(c[la>>2]|0)+(c[G>>2]<<1)>>1]=0;c[G>>2]=(c[G>>2]|0)+1}}while(0);xa=_(c[K>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0;c[la>>2]=(c[la>>2]|0)+(xa<<1);c[ja>>2]=(c[ja>>2]|0)+(c[K>>2]|0);if((c[ja>>2]|0)>=(c[C>>2]|0))break b}c[x>>2]=-3;c[ha>>2]=1;break a}while(0);c[T>>2]=0;if((c[D>>2]|0)==0&(c[R>>2]|0)!=1002&(c[z>>2]|0)!=0?(xa=(ge(J)|0)+17|0,(xa+(((c[(c[y>>2]|0)+52>>2]|0)==1001&1)*20|0)|0)<=(c[A>>2]<<3|0)):0){if((c[R>>2]|0)==1001)c[U>>2]=ib(J,12)|0;else c[U>>2]=1;if(c[U>>2]|0){c[W>>2]=ib(J,1)|0;if((c[R>>2]|0)==1001)Ba=(kb(J,256)|0)+2|0;else{xa=c[A>>2]|0;Ba=xa-((ge(J)|0)+7>>3)|0}c[V>>2]=Ba;c[A>>2]=(c[A>>2]|0)-(c[V>>2]|0);xa=c[A>>2]<<3;if((xa|0)<(ge(J)|0)){c[A>>2]=0;c[V>>2]=0;c[U>>2]=0}xa=J+4|0;c[xa>>2]=(c[xa>>2]|0)-(c[V>>2]|0)}}if((c[R>>2]|0)!=1002)c[T>>2]=17;c[na>>2]=21;switch(c[(c[y>>2]|0)+48>>2]|0){case 1101:{c[na>>2]=13;break}case 1103:case 1102:{c[na>>2]=17;break}case 1104:{c[na>>2]=19;break}case 1105:{c[na>>2]=21;break}default:{}}xa=c[F>>2]|0;c[w>>2]=c[na>>2];ab(xa,10012,w)|0;xa=c[F>>2]|0;c[v>>2]=c[(c[y>>2]|0)+44>>2];ab(xa,10008,v)|0;if(c[U>>2]|0){c[S>>2]=0;c[M>>2]=1}xa=i;i=i+((1*(c[M>>2]<<2)|0)+15&-16)|0;if((c[S>>2]|0)!=0&(c[R>>2]|0)!=1002){c[O>>2]=xa;Zd(c[y>>2]|0,0,0,c[O>>2]|0,(c[$>>2]|0)<(c[Q>>2]|0)?c[$>>2]|0:c[Q>>2]|0,0)|0}if(c[U>>2]|0)Ca=_(c[$>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0;else Ca=1;c[P>>2]=Ca;xa=i;i=i+((1*(c[P>>2]<<2)|0)+15&-16)|0;if((c[U>>2]|0)!=0&(c[W>>2]|0)!=0){ya=c[F>>2]|0;c[u>>2]=0;ab(ya,10010,u)|0;$a(c[F>>2]|0,(c[z>>2]|0)+(c[A>>2]|0)|0,c[V>>2]|0,xa,c[$>>2]|0,0,0)|0;ya=c[F>>2]|0;c[t>>2]=da+(((da-da|0)/4|0)<<2);ab(ya,4031,t)|0}ya=c[F>>2]|0;c[s>>2]=c[T>>2];ab(ya,10010,s)|0;do if((c[R>>2]|0)==1e3){a[pa>>0]=a[5184]|0;a[pa+1>>0]=a[5185]|0;e:do if(!(c[ea>>2]|0)){c[G>>2]=0;while(1){if((c[G>>2]|0)>=(_(c[C>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0))break e;g[(c[B>>2]|0)+(c[G>>2]<<2)>>2]=0.0;c[G>>2]=(c[G>>2]|0)+1}}while(0);if((c[(c[y>>2]|0)+56>>2]|0)==1001){if((c[U>>2]|0)!=0&(c[W>>2]|0)!=0?(c[(c[y>>2]|0)+64>>2]|0)!=0:0)break;ya=c[F>>2]|0;c[q>>2]=0;ab(ya,10010,q)|0;$a(c[F>>2]|0,pa,2,c[B>>2]|0,c[Z>>2]|0,0,c[ea>>2]|0)|0}}else{c[oa>>2]=(c[ba>>2]|0)<(c[C>>2]|0)?c[ba>>2]|0:c[C>>2]|0;do if((c[R>>2]|0)!=(c[(c[y>>2]|0)+56>>2]|0)){if((c[(c[y>>2]|0)+56>>2]|0)<=0)break;if(c[(c[y>>2]|0)+64>>2]|0)break;ab(c[F>>2]|0,4028,r)|0}while(0);c[I>>2]=$a(c[F>>2]|0,(c[D>>2]|0)!=0?0:c[z>>2]|0,c[A>>2]|0,c[B>>2]|0,c[oa>>2]|0,J,c[ea>>2]|0)|0}while(0);f:do if(!((c[R>>2]|0)==1002|(c[ea>>2]|0)!=0)){c[G>>2]=0;while(1){if((c[G>>2]|0)>=(_(c[C>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0))break f;g[(c[B>>2]|0)+(c[G>>2]<<2)>>2]=+g[(c[B>>2]|0)+(c[G>>2]<<2)>>2]+ +(b[N+(c[G>>2]<<1)>>1]|0)*.000030517578125;c[G>>2]=(c[G>>2]|0)+1}}while(0);N=c[F>>2]|0;c[p>>2]=qa+(((qa-qa|0)/4|0)<<2);ab(N,10015,p)|0;c[ca>>2]=c[(c[qa>>2]|0)+60>>2];if(!((c[U>>2]|0)==0|(c[W>>2]|0)!=0)){ab(c[F>>2]|0,4028,o)|0;N=c[F>>2]|0;c[n>>2]=0;ab(N,10010,n)|0;$a(c[F>>2]|0,(c[z>>2]|0)+(c[A>>2]|0)|0,c[V>>2]|0,xa,c[$>>2]|0,0,0)|0;N=c[F>>2]|0;c[m>>2]=da+(((da-da|0)/4|0)<<2);ab(N,4031,m)|0;N=(c[B>>2]|0)+((_(c[(c[y>>2]|0)+8>>2]|0,(c[C>>2]|0)-(c[Z>>2]|0)|0)|0)<<2)|0;ya=xa+((_(c[(c[y>>2]|0)+8>>2]|0,c[Z>>2]|0)|0)<<2)|0;fa=(c[B>>2]|0)+((_(c[(c[y>>2]|0)+8>>2]|0,(c[C>>2]|0)-(c[Z>>2]|0)|0)|0)<<2)|0;he(N,ya,fa,c[Z>>2]|0,c[(c[y>>2]|0)+8>>2]|0,c[ca>>2]|0,c[(c[y>>2]|0)+12>>2]|0)}if((c[U>>2]|0)!=0&(c[W>>2]|0)!=0){c[Y>>2]=0;while(1){if((c[Y>>2]|0)>=(c[(c[y>>2]|0)+8>>2]|0))break;c[G>>2]=0;while(1){if((c[G>>2]|0)>=(c[Z>>2]|0))break;fa=_(c[(c[y>>2]|0)+8>>2]|0,c[G>>2]|0)|0;ya=_(c[(c[y>>2]|0)+8>>2]|0,c[G>>2]|0)|0;g[(c[B>>2]|0)+(ya+(c[Y>>2]|0)<<2)>>2]=+g[xa+(fa+(c[Y>>2]|0)<<2)>>2];c[G>>2]=(c[G>>2]|0)+1}c[Y>>2]=(c[Y>>2]|0)+1}fa=xa+((_(c[(c[y>>2]|0)+8>>2]|0,c[Z>>2]|0)|0)<<2)|0;ya=(c[B>>2]|0)+((_(c[(c[y>>2]|0)+8>>2]|0,c[Z>>2]|0)|0)<<2)|0;N=(c[B>>2]|0)+((_(c[(c[y>>2]|0)+8>>2]|0,c[Z>>2]|0)|0)<<2)|0;he(fa,ya,N,c[Z>>2]|0,c[(c[y>>2]|0)+8>>2]|0,c[ca>>2]|0,c[(c[y>>2]|0)+12>>2]|0)}do if(c[S>>2]|0){if((c[Q>>2]|0)<(c[$>>2]|0)){he(c[O>>2]|0,c[B>>2]|0,c[B>>2]|0,c[Z>>2]|0,c[(c[y>>2]|0)+8>>2]|0,c[ca>>2]|0,c[(c[y>>2]|0)+12>>2]|0);break}c[G>>2]=0;while(1){if((c[G>>2]|0)>=(_(c[(c[y>>2]|0)+8>>2]|0,c[Z>>2]|0)|0))break;g[(c[B>>2]|0)+(c[G>>2]<<2)>>2]=+g[(c[O>>2]|0)+(c[G>>2]<<2)>>2];c[G>>2]=(c[G>>2]|0)+1}N=(c[O>>2]|0)+((_(c[(c[y>>2]|0)+8>>2]|0,c[Z>>2]|0)|0)<<2)|0;ya=(c[B>>2]|0)+((_(c[(c[y>>2]|0)+8>>2]|0,c[Z>>2]|0)|0)<<2)|0;fa=(c[B>>2]|0)+((_(c[(c[y>>2]|0)+8>>2]|0,c[Z>>2]|0)|0)<<2)|0;he(N,ya,fa,c[Z>>2]|0,c[(c[y>>2]|0)+8>>2]|0,c[ca>>2]|0,c[(c[y>>2]|0)+12>>2]|0)}while(0);g:do if(c[(c[y>>2]|0)+40>>2]|0){g[ra>>2]=+X(+(+(c[(c[y>>2]|0)+40>>2]|0)*6.488140788860619e-04*.6931471805599453));c[G>>2]=0;while(1){if((c[G>>2]|0)>=(_(c[C>>2]|0,c[(c[y>>2]|0)+8>>2]|0)|0))break g;g[sa>>2]=+g[(c[B>>2]|0)+(c[G>>2]<<2)>>2]*+g[ra>>2];g[(c[B>>2]|0)+(c[G>>2]<<2)>>2]=+g[sa>>2];c[G>>2]=(c[G>>2]|0)+1}}while(0);if((c[A>>2]|0)<=1)c[(c[y>>2]|0)+80>>2]=0;else c[(c[y>>2]|0)+80>>2]=c[J+28>>2]^c[da>>2];c[(c[y>>2]|0)+56>>2]=c[R>>2];if(c[U>>2]|0)Da=(c[W>>2]|0)!=0^1;else Da=0;c[(c[y>>2]|0)+64>>2]=Da&1;if((c[I>>2]|0)>=0)_d()|0;c[x>>2]=(c[I>>2]|0)<0?c[I>>2]|0:c[Q>>2]|0;c[ha>>2]=1}while(0);ka(c[ga>>2]|0);ta=c[x>>2]|0;i=l;return ta|0}function _d(){return 0}function $d(a){a=a|0;var b=0,e=0,f=0;b=i;i=i+16|0;e=b+4|0;f=b;c[e>>2]=a;do if(!((d[c[e>>2]>>0]|0)&128))if(((d[c[e>>2]>>0]|0)&96|0)==96){c[f>>2]=1001;break}else{c[f>>2]=1e3;break}else c[f>>2]=1002;while(0);i=b;return c[f>>2]|0}function ae(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;i=b;return (c[d>>2]|0)+4-1&-4|0}function be(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Ze(c[d>>2]|0)|0;i=b;return a|0}function ce(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;_e(c[d>>2]|0);i=b;return}function de(a,b,e,f,g,h,j,k){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0;l=i;i=i+112|0;m=l;n=l+72|0;o=l+56|0;p=l+12|0;q=l+4|0;r=l+16|0;s=l+20|0;t=l+24|0;u=l+28|0;v=l+32|0;w=l+36|0;x=l+40|0;y=l+44|0;z=l+48|0;A=l+52|0;B=l+8|0;C=l+60|0;D=l+64|0;E=l+68|0;F=l+76|0;G=l+80|0;H=l+84|0;I=l+88|0;J=l+92|0;K=l+96|0;L=l+100|0;M=l+104|0;c[o>>2]=a;c[p>>2]=b;c[q>>2]=e;c[r>>2]=f;c[s>>2]=g;c[t>>2]=h;c[u>>2]=j;c[v>>2]=k;c[C>>2]=0;k=c[o>>2]|0;c[m>>2]=w+(((w-w|0)/4|0)<<2);Qc(k,4029,m)|0;if((c[t>>2]|0)<(((c[w>>2]|0)/25|0)*3|0))N=c[t>>2]|0;else N=((c[w>>2]|0)/25|0)*3|0;c[t>>2]=N;N=c[t>>2]<<1;c[D>>2]=ua()|0;m=i;i=i+((1*(N<<2)|0)+15&-16)|0;N=c[o>>2]|0;c[B>>2]=N+(ae(268)|0);c[x>>2]=Ac(2)|0;c[y>>2]=Ac(1)|0;if(!(c[q>>2]|0))c[C>>2]=1;if((c[q>>2]|0)<0){c[n>>2]=-1;c[E>>2]=1;O=c[D>>2]|0;ka(O|0);P=c[n>>2]|0;i=l;return P|0}if((c[C>>2]|0)==0?(c[q>>2]|0)<((c[(c[o>>2]|0)+4>>2]<<1)-1|0):0){c[n>>2]=-4;c[E>>2]=1;O=c[D>>2]|0;ka(O|0);P=c[n>>2]|0;i=l;return P|0}if(!(c[C>>2]|0)){c[F>>2]=fe(c[p>>2]|0,c[q>>2]|0,c[(c[o>>2]|0)+4>>2]|0,c[w>>2]|0)|0;w=c[F>>2]|0;if((c[F>>2]|0)<0){c[n>>2]=w;c[E>>2]=1;O=c[D>>2]|0;ka(O|0);P=c[n>>2]|0;i=l;return P|0}if((w|0)>(c[t>>2]|0)){c[n>>2]=-2;c[E>>2]=1;O=c[D>>2]|0;ka(O|0);P=c[n>>2]|0;i=l;return P|0}}c[z>>2]=0;while(1){if((c[z>>2]|0)>=(c[(c[o>>2]|0)+4>>2]|0)){Q=36;break}c[G>>2]=c[B>>2];if((c[z>>2]|0)<(c[(c[o>>2]|0)+8>>2]|0))R=ae(c[x>>2]|0)|0;else R=ae(c[y>>2]|0)|0;c[B>>2]=(c[B>>2]|0)+R;if((c[C>>2]|0)==0&(c[q>>2]|0)<=0){Q=22;break}c[H>>2]=0;c[I>>2]=Cc(c[G>>2]|0,c[p>>2]|0,c[q>>2]|0,m,c[t>>2]|0,c[u>>2]|0,(c[z>>2]|0)!=((c[(c[o>>2]|0)+4>>2]|0)-1|0)&1,H,c[v>>2]|0)|0;c[p>>2]=(c[p>>2]|0)+(c[H>>2]|0);c[q>>2]=(c[q>>2]|0)-(c[H>>2]|0);S=c[I>>2]|0;if((c[I>>2]|0)<=0){Q=24;break}c[t>>2]=S;a:do if((c[z>>2]|0)<(c[(c[o>>2]|0)+8>>2]|0)){c[K>>2]=-1;while(1){w=Jc(c[o>>2]|0,c[z>>2]|0,c[K>>2]|0)|0;c[J>>2]=w;if((w|0)==-1)break;Ha[c[s>>2]&1](c[r>>2]|0,c[c[o>>2]>>2]|0,c[J>>2]|0,m,2,c[t>>2]|0);c[K>>2]=c[J>>2]}c[K>>2]=-1;while(1){w=Kc(c[o>>2]|0,c[z>>2]|0,c[K>>2]|0)|0;c[J>>2]=w;if((w|0)==-1)break a;Ha[c[s>>2]&1](c[r>>2]|0,c[c[o>>2]>>2]|0,c[J>>2]|0,m+4|0,2,c[t>>2]|0);c[K>>2]=c[J>>2]}}else{c[M>>2]=-1;while(1){w=Lc(c[o>>2]|0,c[z>>2]|0,c[M>>2]|0)|0;c[L>>2]=w;if((w|0)==-1)break a;Ha[c[s>>2]&1](c[r>>2]|0,c[c[o>>2]>>2]|0,c[L>>2]|0,m,1,c[t>>2]|0);c[M>>2]=c[L>>2]}}while(0);c[z>>2]=(c[z>>2]|0)+1}if((Q|0)==22){c[n>>2]=-3;c[E>>2]=1;O=c[D>>2]|0;ka(O|0);P=c[n>>2]|0;i=l;return P|0}else if((Q|0)==24){c[n>>2]=S;c[E>>2]=1;O=c[D>>2]|0;ka(O|0);P=c[n>>2]|0;i=l;return P|0}else if((Q|0)==36){c[A>>2]=0;while(1){if((c[A>>2]|0)>=(c[c[o>>2]>>2]|0))break;if((d[(c[o>>2]|0)+12+(c[A>>2]|0)>>0]|0|0)==255)Ha[c[s>>2]&1](c[r>>2]|0,c[c[o>>2]>>2]|0,c[A>>2]|0,0,0,c[t>>2]|0);c[A>>2]=(c[A>>2]|0)+1}c[n>>2]=c[t>>2];c[E>>2]=1;O=c[D>>2]|0;ka(O|0);P=c[n>>2]|0;i=l;return P|0}return 0}function ee(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;j=i;i=i+32|0;k=j+4|0;l=j+16|0;m=j+8|0;n=j+20|0;o=j+28|0;p=j;q=j+12|0;r=j+24|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;c[q>>2]=c[k>>2];k=(c[n>>2]|0)!=0;c[r>>2]=0;if(k){while(1){if((c[r>>2]|0)>=(c[p>>2]|0))break;k=_(c[r>>2]|0,c[o>>2]|0)|0;h=_(c[r>>2]|0,c[l>>2]|0)|0;g[(c[q>>2]|0)+(h+(c[m>>2]|0)<<2)>>2]=+g[(c[n>>2]|0)+(k<<2)>>2];c[r>>2]=(c[r>>2]|0)+1}i=j;return}else{while(1){if((c[r>>2]|0)>=(c[p>>2]|0))break;n=_(c[r>>2]|0,c[l>>2]|0)|0;g[(c[q>>2]|0)+(n+(c[m>>2]|0)<<2)>>2]=0.0;c[r>>2]=(c[r>>2]|0)+1}i=j;return}}function fe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;f=i;i=i+144|0;g=f+12|0;h=f+16|0;j=f+4|0;k=f+8|0;l=f+32|0;m=f;n=f+36|0;o=f+136|0;p=f+40|0;q=f+28|0;r=f+20|0;s=f+24|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[q>>2]=0;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0)){t=11;break}if((c[j>>2]|0)<=0){t=4;break}c[n>>2]=zc(c[h>>2]|0,c[j>>2]|0,(c[m>>2]|0)!=((c[k>>2]|0)-1|0)&1,o,0,p,0,r)|0;if((c[n>>2]|0)<0){t=6;break}c[s>>2]=Hc(c[h>>2]|0,c[r>>2]|0,c[l>>2]|0)|0;if((c[m>>2]|0)!=0?(c[q>>2]|0)!=(c[s>>2]|0):0){t=9;break}c[q>>2]=c[s>>2];c[h>>2]=(c[h>>2]|0)+(c[r>>2]|0);c[j>>2]=(c[j>>2]|0)-(c[r>>2]|0);c[m>>2]=(c[m>>2]|0)+1}if((t|0)==4){c[g>>2]=-4;u=c[g>>2]|0;i=f;return u|0}else if((t|0)==6){c[g>>2]=c[n>>2];u=c[g>>2]|0;i=f;return u|0}else if((t|0)==9){c[g>>2]=-4;u=c[g>>2]|0;i=f;return u|0}else if((t|0)==11){c[g>>2]=c[q>>2];u=c[g>>2]|0;i=f;return u|0}return 0}function ge(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=(c[(c[d>>2]|0)+20>>2]|0)-(32-(aa(c[(c[d>>2]|0)+28>>2]|0)|0))|0;i=b;return a|0}function he(a,b,d,e,f,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;k=i;i=i+48|0;l=k+36|0;m=k+16|0;n=k;o=k+28|0;p=k+32|0;q=k+40|0;r=k+12|0;s=k+24|0;t=k+20|0;u=k+8|0;v=k+4|0;c[l>>2]=a;c[m>>2]=b;c[n>>2]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=h;c[r>>2]=j;c[u>>2]=48e3/(c[r>>2]|0)|0;c[t>>2]=0;while(1){if((c[t>>2]|0)>=(c[p>>2]|0))break;c[s>>2]=0;while(1){if((c[s>>2]|0)>=(c[o>>2]|0))break;r=_(c[s>>2]|0,c[u>>2]|0)|0;j=_(c[s>>2]|0,c[u>>2]|0)|0;g[v>>2]=+g[(c[q>>2]|0)+(r<<2)>>2]*+g[(c[q>>2]|0)+(j<<2)>>2];j=_(c[s>>2]|0,c[p>>2]|0)|0;r=_(c[s>>2]|0,c[p>>2]|0)|0;h=_(c[s>>2]|0,c[p>>2]|0)|0;g[(c[n>>2]|0)+(h+(c[t>>2]|0)<<2)>>2]=+g[v>>2]*+g[(c[m>>2]|0)+(j+(c[t>>2]|0)<<2)>>2]+(1.0-+g[v>>2])*+g[(c[l>>2]|0)+(r+(c[t>>2]|0)<<2)>>2];c[s>>2]=(c[s>>2]|0)+1}c[t>>2]=(c[t>>2]|0)+1}i=k;return}function ie(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b;c[d>>2]=a;if(!(c[d>>2]|0)){e=32;i=b;return e|0}e=32-(32-(aa(c[d>>2]|0)|0))|0;i=b;return e|0}function je(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;d=i;i=i+48|0;e=d+28|0;f=d+16|0;g=d+4|0;h=d+8|0;j=d+32|0;k=d;l=d+12|0;m=d+24|0;n=d+20|0;c[f>>2]=a;c[g>>2]=b;b=c[f>>2]|0;c[h>>2]=(ie((c[f>>2]|0)>0?b:0-b|0)|0)-1;c[l>>2]=c[f>>2]<<c[h>>2];c[k>>2]=536870911/(c[l>>2]>>16|0)|0;c[n>>2]=c[k>>2]<<16;f=_(c[l>>2]>>16,(c[k>>2]&65535)<<16>>16)|0;c[m>>2]=536870912-(f+((_(c[l>>2]&65535,(c[k>>2]&65535)<<16>>16)|0)>>16))<<3;l=_(c[m>>2]>>16,(c[k>>2]&65535)<<16>>16)|0;f=(c[n>>2]|0)+(l+((_(c[m>>2]&65535,(c[k>>2]&65535)<<16>>16)|0)>>16))|0;c[n>>2]=f+(_(c[m>>2]|0,(c[k>>2]>>15)+1>>1)|0);c[j>>2]=61-(c[h>>2]|0)-(c[g>>2]|0);g=c[j>>2]|0;if((c[j>>2]|0)>0)if((g|0)<32){c[e>>2]=c[n>>2]>>c[j>>2];o=c[e>>2]|0;i=d;return o|0}else{c[e>>2]=0;o=c[e>>2]|0;i=d;return o|0}h=c[n>>2]|0;k=0-(c[j>>2]|0)|0;do if((-2147483648>>0-g|0)>(2147483647>>0-(c[j>>2]|0)|0)){if((h|0)>(-2147483648>>k|0)){p=-2147483648>>0-(c[j>>2]|0);break}if((c[n>>2]|0)<(2147483647>>0-(c[j>>2]|0)|0)){p=2147483647>>0-(c[j>>2]|0);break}else{p=c[n>>2]|0;break}}else{if((h|0)>(2147483647>>k|0)){p=2147483647>>0-(c[j>>2]|0);break}if((c[n>>2]|0)<(-2147483648>>0-(c[j>>2]|0)|0)){p=-2147483648>>0-(c[j>>2]|0);break}else{p=c[n>>2]|0;break}}while(0);c[e>>2]=p<<0-(c[j>>2]|0);o=c[e>>2]|0;i=d;return o|0}function ke(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;j=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[j>>2]=Ld(c[f>>2]|0)|0;c[c[g>>2]>>2]=c[j>>2];g=(le(c[f>>2]|0,24-(c[j>>2]|0)|0)|0)&127;c[c[h>>2]>>2]=g;i=e;return}function le(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;d=i;i=i+32|0;e=d+20|0;f=d+16|0;g=d+12|0;h=d+8|0;j=d+4|0;k=d;c[f>>2]=a;c[g>>2]=b;c[h>>2]=c[f>>2];c[j>>2]=c[g>>2];c[k>>2]=0-(c[g>>2]|0);if(!(c[g>>2]|0)){c[e>>2]=c[f>>2];l=c[e>>2]|0;i=d;return l|0}f=c[h>>2]|0;if((c[g>>2]|0)<0){c[e>>2]=f<<c[k>>2]|(c[h>>2]|0)>>>(32-(c[k>>2]|0)|0);l=c[e>>2]|0;i=d;return l|0}else{c[e>>2]=f<<32-(c[j>>2]|0)|(c[h>>2]|0)>>>(c[j>>2]|0);l=c[e>>2]|0;i=d;return l|0}return 0}function me(a,d,e,f,g,h,j,k){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;var l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;l=i;i=i+48|0;m=l+4|0;n=l+16|0;o=l+36|0;p=l;q=l+32|0;r=l+40|0;s=l+44|0;t=l+24|0;u=l+20|0;v=l+8|0;w=l+12|0;x=l+28|0;c[m>>2]=a;c[n>>2]=d;c[o>>2]=e;c[p>>2]=f;c[q>>2]=g;c[r>>2]=h;c[s>>2]=j;c[t>>2]=k;k=c[s>>2]<<1;c[x>>2]=ua()|0;j=i;i=i+((1*(k<<1)|0)+15&-16)|0;c[w>>2]=j;c[v>>2]=0;while(1){if((c[v>>2]|0)>=2)break;c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[s>>2]|0))break;k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;h=_(c[(c[q>>2]|0)+(k<<2)>>2]>>16,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]&65535)<<16>>16)|0;k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;g=h+((_(c[(c[q>>2]|0)+(k<<2)>>2]&65535,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]&65535)<<16>>16)|0)>>16)|0;k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;if((g+(_(c[(c[q>>2]|0)+(k<<2)>>2]|0,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]>>15)+1>>1)|0)>>8|0)<=32767){k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;g=_(c[(c[q>>2]|0)+(k<<2)>>2]>>16,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]&65535)<<16>>16)|0;k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;h=g+((_(c[(c[q>>2]|0)+(k<<2)>>2]&65535,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]&65535)<<16>>16)|0)>>16)|0;k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;if((h+(_(c[(c[q>>2]|0)+(k<<2)>>2]|0,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]>>15)+1>>1)|0)>>8|0)<-32768)y=-32768;else{k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;h=_(c[(c[q>>2]|0)+(k<<2)>>2]>>16,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]&65535)<<16>>16)|0;k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;g=h+((_(c[(c[q>>2]|0)+(k<<2)>>2]&65535,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]&65535)<<16>>16)|0)>>16)|0;k=(c[u>>2]|0)+(_((c[v>>2]|0)+(c[t>>2]|0)-2|0,c[s>>2]|0)|0)|0;y=g+(_(c[(c[q>>2]|0)+(k<<2)>>2]|0,(c[(c[r>>2]|0)+(c[v>>2]<<2)>>2]>>15)+1>>1)|0)>>8}}else y=32767;b[(c[w>>2]|0)+(c[u>>2]<<1)>>1]=y;c[u>>2]=(c[u>>2]|0)+1}c[w>>2]=(c[w>>2]|0)+(c[s>>2]<<1);c[v>>2]=(c[v>>2]|0)+1}uc(c[m>>2]|0,c[n>>2]|0,j,c[s>>2]|0);uc(c[o>>2]|0,c[p>>2]|0,j+(c[s>>2]<<1)|0,c[s>>2]|0);ka(c[x>>2]|0);i=l;return}function ne(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function oe(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)<(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function pe(a,c){a=a|0;c=c|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+2|0;f=d;b[e>>1]=a;b[f>>1]=c;i=d;return ((b[e>>1]|0)>(b[f>>1]|0)?b[e>>1]|0:b[f>>1]|0)&65535|0}function qe(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)<(c[f>>2]|0)?c[e>>2]|0:c[f>>2]|0)|0}function re(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;d=i;i=i+48|0;e=d+28|0;f=d+16|0;g=d+4|0;h=d+8|0;j=d+32|0;k=d;l=d+12|0;m=d+24|0;n=d+20|0;c[f>>2]=a;c[g>>2]=b;b=c[f>>2]|0;c[h>>2]=(Ld((c[f>>2]|0)>0?b:0-b|0)|0)-1;c[l>>2]=c[f>>2]<<c[h>>2];c[k>>2]=536870911/(c[l>>2]>>16|0)|0;c[n>>2]=c[k>>2]<<16;f=_(c[l>>2]>>16,(c[k>>2]&65535)<<16>>16)|0;c[m>>2]=536870912-(f+((_(c[l>>2]&65535,(c[k>>2]&65535)<<16>>16)|0)>>16))<<3;l=_(c[m>>2]>>16,(c[k>>2]&65535)<<16>>16)|0;f=(c[n>>2]|0)+(l+((_(c[m>>2]&65535,(c[k>>2]&65535)<<16>>16)|0)>>16))|0;c[n>>2]=f+(_(c[m>>2]|0,(c[k>>2]>>15)+1>>1)|0);c[j>>2]=61-(c[h>>2]|0)-(c[g>>2]|0);g=c[j>>2]|0;if((c[j>>2]|0)>0)if((g|0)<32){c[e>>2]=c[n>>2]>>c[j>>2];o=c[e>>2]|0;i=d;return o|0}else{c[e>>2]=0;o=c[e>>2]|0;i=d;return o|0}h=c[n>>2]|0;k=0-(c[j>>2]|0)|0;do if((-2147483648>>0-g|0)>(2147483647>>0-(c[j>>2]|0)|0)){if((h|0)>(-2147483648>>k|0)){p=-2147483648>>0-(c[j>>2]|0);break}if((c[n>>2]|0)<(2147483647>>0-(c[j>>2]|0)|0)){p=2147483647>>0-(c[j>>2]|0);break}else{p=c[n>>2]|0;break}}else{if((h|0)>(2147483647>>k|0)){p=2147483647>>0-(c[j>>2]|0);break}if((c[n>>2]|0)<(-2147483648>>0-(c[j>>2]|0)|0)){p=-2147483648>>0-(c[j>>2]|0);break}else{p=c[n>>2]|0;break}}while(0);c[e>>2]=p<<0-(c[j>>2]|0);o=c[e>>2]|0;i=d;return o|0}function se(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;j=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[j>>2]=te(c[f>>2]|0)|0;c[c[g>>2]>>2]=c[j>>2];g=(ue(c[f>>2]|0,24-(c[j>>2]|0)|0)|0)&127;c[c[h>>2]>>2]=g;i=e;return}function te(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b;c[d>>2]=a;if(!(c[d>>2]|0)){e=32;i=b;return e|0}e=32-(32-(aa(c[d>>2]|0)|0))|0;i=b;return e|0}function ue(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;d=i;i=i+32|0;e=d+20|0;f=d+16|0;g=d+12|0;h=d+8|0;j=d+4|0;k=d;c[f>>2]=a;c[g>>2]=b;c[h>>2]=c[f>>2];c[j>>2]=c[g>>2];c[k>>2]=0-(c[g>>2]|0);if(!(c[g>>2]|0)){c[e>>2]=c[f>>2];l=c[e>>2]|0;i=d;return l|0}f=c[h>>2]|0;if((c[g>>2]|0)<0){c[e>>2]=f<<c[k>>2]|(c[h>>2]|0)>>>(32-(c[k>>2]|0)|0);l=c[e>>2]|0;i=d;return l|0}else{c[e>>2]=f<<32-(c[j>>2]|0)|(c[h>>2]|0)>>>(c[j>>2]|0);l=c[e>>2]|0;i=d;return l|0}return 0}function ve(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b;c[d>>2]=a;if(!(c[d>>2]|0)){e=32;i=b;return e|0}e=32-(32-(aa(c[d>>2]|0)|0))|0;i=b;return e|0}function we(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>>>0)/((c[f>>2]|0)>>>0)|0|0}function xe(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=+e;f=+f;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+48|0;j=h+4|0;k=h+16|0;l=h+36|0;m=h;n=h+32|0;o=h+40|0;p=h+44|0;q=h+24|0;r=h+20|0;s=h+8|0;t=h+12|0;u=h+28|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;g[m>>2]=e;g[n>>2]=f;c[q>>2]=c[j>>2];g[p>>2]=-+g[n>>2];c[o>>2]=0;while(1){if((c[o>>2]|0)>=((c[k>>2]|0)-(c[l>>2]|0)|0))break;g[r>>2]=+g[c[q>>2]>>2];g[s>>2]=+g[(c[q>>2]|0)+(c[l>>2]<<2)>>2];g[(c[q>>2]|0)+(c[l>>2]<<2)>>2]=+g[m>>2]*+g[s>>2]+ +g[n>>2]*+g[r>>2];f=+g[m>>2]*+g[r>>2]+ +g[p>>2]*+g[s>>2];d=c[q>>2]|0;c[q>>2]=d+4;g[d>>2]=f;c[o>>2]=(c[o>>2]|0)+1}c[q>>2]=(c[j>>2]|0)+((c[k>>2]|0)-(c[l>>2]<<1)-1<<2);c[o>>2]=(c[k>>2]|0)-(c[l>>2]<<1)-1;while(1){if((c[o>>2]|0)<0)break;g[t>>2]=+g[c[q>>2]>>2];g[u>>2]=+g[(c[q>>2]|0)+(c[l>>2]<<2)>>2];g[(c[q>>2]|0)+(c[l>>2]<<2)>>2]=+g[m>>2]*+g[u>>2]+ +g[n>>2]*+g[t>>2];f=+g[m>>2]*+g[t>>2]+ +g[p>>2]*+g[u>>2];k=c[q>>2]|0;c[q>>2]=k+-4;g[k>>2]=f;c[o>>2]=(c[o>>2]|0)+-1}i=h;return}function ye(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;i=d;return ((c[e>>2]|0)>>>0)/((c[f>>2]|0)>>>0)|0|0}function ze(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[g>>2]=b;c[h>>2]=d;if(((c[(c[g>>2]|0)+24>>2]|0)+(c[(c[g>>2]|0)+8>>2]|0)|0)>>>0>=(c[(c[g>>2]|0)+4>>2]|0)>>>0){c[f>>2]=-1;j=c[f>>2]|0;i=e;return j|0}else{d=c[h>>2]&255;h=(c[g>>2]|0)+24|0;b=c[h>>2]|0;c[h>>2]=b+1;a[(c[c[g>>2]>>2]|0)+b>>0]=d;c[f>>2]=0;j=c[f>>2]|0;i=e;return j|0}return 0}function Ae(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+4112|0;f=e+4108|0;g=e+4104|0;h=e+4100|0;j=e+4096|0;k=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;vb(c[f>>2]|0,k,2048,c[g>>2]|0,c[h>>2]|0);xb(k+1440|0,k,1328,620,j,c[h>>2]|0);c[j>>2]=720-(c[j>>2]|0);i=e;return c[j>>2]|0}function Be(){return 0}function Ce(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+48|0;j=h+4|0;k=h+16|0;l=h+36|0;m=h;n=h+32|0;o=h+40|0;p=h+44|0;q=h+24|0;r=h+20|0;s=h+8|0;t=h+12|0;u=h+28|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=((c[c[j>>2]>>2]|0)!=0^1)&1;c[r>>2]=c[k>>2];c[s>>2]=c[c[j>>2]>>2];c[t>>2]=c[(c[j>>2]|0)+24>>2];c[q>>2]=(c[l>>2]|0)!=0&1;c[p>>2]=0;do{c[u>>2]=0;if((c[(c[j>>2]|0)+28>>2]|0)>=8){if(c[s>>2]|0){c[u>>2]=+g[c[r>>2]>>2]<0.0&1;pb(c[t>>2]|0,c[u>>2]|0,1)}else c[u>>2]=lb(c[t>>2]|0,1)|0;f=(c[j>>2]|0)+28|0;c[f>>2]=(c[f>>2]|0)-8;c[m>>2]=(c[m>>2]|0)-8}if(c[o>>2]|0)g[c[r>>2]>>2]=(c[u>>2]|0)!=0?-1.0:1.0;c[r>>2]=c[l>>2];f=(c[p>>2]|0)+1|0;c[p>>2]=f}while((f|0)<(1+(c[q>>2]|0)|0));if(!(c[n>>2]|0)){i=h;return 1}g[c[n>>2]>>2]=+g[c[k>>2]>>2];i=h;return 1}function De(a,d,e,f,h,j,k,l,m,n,o){a=a|0;d=d|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=m|0;n=n|0;o=o|0;var p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0;p=i;i=i+160|0;q=p+72|0;r=p+56|0;s=p+4|0;t=p+52|0;u=p+140|0;v=p+68|0;w=p+20|0;x=p+24|0;y=p+28|0;z=p+32|0;A=p+36|0;B=p+40|0;C=p+44|0;D=p+48|0;E=p+112|0;F=p+120|0;G=p+128|0;H=p+136|0;I=p+144|0;J=p+148|0;K=p+76|0;L=p+80|0;M=p+84|0;N=p+88|0;O=p+92|0;P=p+96|0;Q=p+100|0;R=p+104|0;S=p+12|0;T=p;U=p+8|0;V=p+108|0;W=p+116|0;X=p+60|0;Y=p+124|0;Z=p+16|0;$=p+64|0;aa=p+132|0;c[q>>2]=a;c[r>>2]=d;c[s>>2]=e;c[t>>2]=f;c[u>>2]=h;c[v>>2]=j;c[w>>2]=k;c[x>>2]=l;c[y>>2]=m;c[z>>2]=n;c[A>>2]=o;c[C>>2]=0;c[K>>2]=0;c[L>>2]=c[c[q>>2]>>2];c[M>>2]=c[(c[q>>2]|0)+4>>2];c[N>>2]=c[(c[q>>2]|0)+8>>2];c[O>>2]=c[(c[q>>2]|0)+12>>2];c[P>>2]=c[(c[q>>2]|0)+24>>2];c[Q>>2]=c[(c[q>>2]|0)+32>>2];c[H>>2]=(b[(c[(c[M>>2]|0)+56>>2]|0)+(c[N>>2]<<1)>>1]|0)+(c[y>>2]<<3);c[I>>2]=(c[H>>2]>>1)-(((c[z>>2]|0)!=0?(c[u>>2]|0)==2:0)?16:4);c[B>>2]=Ge(c[u>>2]|0,c[c[v>>2]>>2]|0,c[I>>2]|0,c[H>>2]|0,c[z>>2]|0)|0;if((c[z>>2]|0)!=0?(c[N>>2]|0)>=(c[O>>2]|0):0)c[B>>2]=1;if(c[L>>2]|0)c[C>>2]=Jb(c[s>>2]|0,c[t>>2]|0,c[z>>2]|0,c[u>>2]|0)|0;c[J>>2]=db(c[P>>2]|0)|0;do if((c[B>>2]|0)!=1){if(c[L>>2]|0)c[C>>2]=(_(c[C>>2]|0,c[B>>2]|0)|0)+8192>>14;do if((c[z>>2]|0)!=0&(c[u>>2]|0)>2){c[R>>2]=3;c[S>>2]=c[C>>2];c[T>>2]=(c[B>>2]|0)/2|0;O=_(c[R>>2]|0,(c[T>>2]|0)+1|0)|0;c[U>>2]=O+(c[T>>2]|0);O=c[P>>2]|0;if(c[L>>2]|0){if((c[S>>2]|0)<=(c[T>>2]|0))ba=_(c[R>>2]|0,c[S>>2]|0)|0;else ba=(c[S>>2]|0)-1-(c[T>>2]|0)+(_((c[T>>2]|0)+1|0,c[R>>2]|0)|0)|0;if((c[S>>2]|0)<=(c[T>>2]|0))ca=_(c[R>>2]|0,(c[S>>2]|0)+1|0)|0;else ca=(c[S>>2]|0)-(c[T>>2]|0)+(_((c[T>>2]|0)+1|0,c[R>>2]|0)|0)|0;mb(O,ba,ca,c[U>>2]|0);break}c[V>>2]=fb(O,c[U>>2]|0)|0;if((c[V>>2]|0)<(_((c[T>>2]|0)+1|0,c[R>>2]|0)|0))c[S>>2]=(c[V>>2]|0)/(c[R>>2]|0)|0;else c[S>>2]=(c[T>>2]|0)+1+((c[V>>2]|0)-(_((c[T>>2]|0)+1|0,c[R>>2]|0)|0));if((c[S>>2]|0)<=(c[T>>2]|0))da=_(c[R>>2]|0,c[S>>2]|0)|0;else da=(c[S>>2]|0)-1-(c[T>>2]|0)+(_((c[T>>2]|0)+1|0,c[R>>2]|0)|0)|0;if((c[S>>2]|0)<=(c[T>>2]|0))ea=_(c[R>>2]|0,(c[S>>2]|0)+1|0)|0;else ea=(c[S>>2]|0)-(c[T>>2]|0)+(_((c[T>>2]|0)+1|0,c[R>>2]|0)|0)|0;hb(c[P>>2]|0,da,ea,c[U>>2]|0);c[C>>2]=c[S>>2]}else{if((c[x>>2]|0)>1|(c[z>>2]|0)!=0){O=c[P>>2]|0;if(c[L>>2]|0){ob(O,c[C>>2]|0,(c[B>>2]|0)+1|0);break}else{c[C>>2]=kb(O,(c[B>>2]|0)+1|0)|0;break}}c[W>>2]=1;c[X>>2]=_((c[B>>2]>>1)+1|0,(c[B>>2]>>1)+1|0)|0;if(!(c[L>>2]|0)){c[Z>>2]=0;c[$>>2]=fb(c[P>>2]|0,c[X>>2]|0)|0;if((c[$>>2]|0)<((_(c[B>>2]>>1,(c[B>>2]>>1)+1|0)|0)>>1|0)){c[C>>2]=((sb((c[$>>2]<<3)+1|0)|0)-1|0)>>>1;c[W>>2]=(c[C>>2]|0)+1;c[Z>>2]=(_(c[C>>2]|0,(c[C>>2]|0)+1|0)|0)>>1}else{O=(c[B>>2]|0)+1<<1;c[C>>2]=(O-(sb(((c[X>>2]|0)-(c[$>>2]|0)-1<<3)+1|0)|0)|0)>>>1;c[W>>2]=(c[B>>2]|0)+1-(c[C>>2]|0);c[Z>>2]=(c[X>>2]|0)-((_((c[B>>2]|0)+1-(c[C>>2]|0)|0,(c[B>>2]|0)+2-(c[C>>2]|0)|0)|0)>>1)}hb(c[P>>2]|0,c[Z>>2]|0,(c[Z>>2]|0)+(c[W>>2]|0)|0,c[X>>2]|0);break}if((c[C>>2]|0)<=(c[B>>2]>>1|0))fa=(c[C>>2]|0)+1|0;else fa=(c[B>>2]|0)+1-(c[C>>2]|0)|0;c[W>>2]=fa;if((c[C>>2]|0)<=(c[B>>2]>>1|0))ga=(_(c[C>>2]|0,(c[C>>2]|0)+1|0)|0)>>1;else ga=(c[X>>2]|0)-((_((c[B>>2]|0)+1-(c[C>>2]|0)|0,(c[B>>2]|0)+2-(c[C>>2]|0)|0)|0)>>1)|0;c[Y>>2]=ga;mb(c[P>>2]|0,c[Y>>2]|0,(c[Y>>2]|0)+(c[W>>2]|0)|0,c[X>>2]|0)}while(0);c[C>>2]=Rc(c[C>>2]<<14,c[B>>2]|0)|0;if((c[L>>2]|0)!=0&(c[z>>2]|0)!=0)if(!(c[C>>2]|0)){He(c[M>>2]|0,c[s>>2]|0,c[t>>2]|0,c[Q>>2]|0,c[N>>2]|0,c[u>>2]|0);break}else{Ie(c[s>>2]|0,c[t>>2]|0,c[u>>2]|0);break}}else if(c[z>>2]|0){if(c[L>>2]|0){c[K>>2]=(c[C>>2]|0)>8192&1;a:do if(c[K>>2]|0){c[aa>>2]=0;while(1){if((c[aa>>2]|0)>=(c[u>>2]|0))break a;g[(c[t>>2]|0)+(c[aa>>2]<<2)>>2]=-+g[(c[t>>2]|0)+(c[aa>>2]<<2)>>2];c[aa>>2]=(c[aa>>2]|0)+1}}while(0);He(c[M>>2]|0,c[s>>2]|0,c[t>>2]|0,c[Q>>2]|0,c[N>>2]|0,c[u>>2]|0)}do if((c[c[v>>2]>>2]|0)>16?(c[(c[q>>2]|0)+28>>2]|0)>16:0){O=c[P>>2]|0;if(c[L>>2]|0){nb(O,c[K>>2]|0,2);break}else{c[K>>2]=ib(O,2)|0;break}}else ha=60;while(0);if((ha|0)==60)c[K>>2]=0;c[C>>2]=0}while(0);ha=db(c[P>>2]|0)|0;c[G>>2]=ha-(c[J>>2]|0);J=c[v>>2]|0;c[J>>2]=(c[J>>2]|0)-(c[G>>2]|0);if(!(c[C>>2]|0)){c[E>>2]=32767;c[F>>2]=0;J=c[A>>2]|0;c[J>>2]=c[J>>2]&(1<<c[w>>2])-1;c[D>>2]=-16384;ia=c[K>>2]|0;ja=c[r>>2]|0;c[ja>>2]=ia;ka=c[E>>2]|0;la=c[r>>2]|0;ma=la+4|0;c[ma>>2]=ka;na=c[F>>2]|0;oa=c[r>>2]|0;pa=oa+8|0;c[pa>>2]=na;qa=c[D>>2]|0;ra=c[r>>2]|0;sa=ra+12|0;c[sa>>2]=qa;ta=c[C>>2]|0;ua=c[r>>2]|0;va=ua+16|0;c[va>>2]=ta;wa=c[G>>2]|0;xa=c[r>>2]|0;ya=xa+20|0;c[ya>>2]=wa;i=p;return}if((c[C>>2]|0)==16384){c[E>>2]=0;c[F>>2]=32767;J=c[A>>2]|0;c[J>>2]=c[J>>2]&(1<<c[w>>2])-1<<c[w>>2];c[D>>2]=16384;ia=c[K>>2]|0;ja=c[r>>2]|0;c[ja>>2]=ia;ka=c[E>>2]|0;la=c[r>>2]|0;ma=la+4|0;c[ma>>2]=ka;na=c[F>>2]|0;oa=c[r>>2]|0;pa=oa+8|0;c[pa>>2]=na;qa=c[D>>2]|0;ra=c[r>>2]|0;sa=ra+12|0;c[sa>>2]=qa;ta=c[C>>2]|0;ua=c[r>>2]|0;va=ua+16|0;c[va>>2]=ta;wa=c[G>>2]|0;xa=c[r>>2]|0;ya=xa+20|0;c[ya>>2]=wa;i=p;return}else{c[E>>2]=(Je(c[C>>2]&65535)|0)<<16>>16;c[F>>2]=(Je(16384-(c[C>>2]|0)&65535)|0)<<16>>16;w=((c[u>>2]|0)-1<<7&65535)<<16>>16;c[D>>2]=16384+(_(w,((Ke(c[F>>2]|0,c[E>>2]|0)|0)&65535)<<16>>16)|0)>>15;ia=c[K>>2]|0;ja=c[r>>2]|0;c[ja>>2]=ia;ka=c[E>>2]|0;la=c[r>>2]|0;ma=la+4|0;c[ma>>2]=ka;na=c[F>>2]|0;oa=c[r>>2]|0;pa=oa+8|0;c[pa>>2]=na;qa=c[D>>2]|0;ra=c[r>>2]|0;sa=ra+12|0;c[sa>>2]=qa;ta=c[C>>2]|0;ua=c[r>>2]|0;va=ua+16|0;c[va>>2]=ta;wa=c[G>>2]|0;xa=c[r>>2]|0;ya=xa+20|0;c[ya>>2]=wa;i=p;return}}function Ee(a,b,d,e){a=a|0;b=b|0;d=+d;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;f=i;i=i+64|0;h=f+52|0;j=f+44|0;k=f+24|0;l=f+20|0;m=f+12|0;n=f+40|0;o=f+48|0;p=f+56|0;q=f+28|0;r=f+8|0;s=f+4|0;t=f+32|0;u=f;v=f+16|0;w=f+36|0;c[h>>2]=a;c[j>>2]=b;g[k>>2]=d;c[l>>2]=e;g[n>>2]=0.0;g[o>>2]=0.0;Fe(c[j>>2]|0,c[h>>2]|0,c[j>>2]|0,c[l>>2]|0,n,o);g[n>>2]=+g[k>>2]*+g[n>>2];g[r>>2]=+g[k>>2];g[p>>2]=+g[r>>2]*+g[r>>2]+ +g[o>>2]-+g[n>>2]*2.0;g[q>>2]=+g[r>>2]*+g[r>>2]+ +g[o>>2]+ +g[n>>2]*2.0;if(+g[q>>2]<6.000000284984708e-04|+g[p>>2]<6.000000284984708e-04){df(c[j>>2]|0,c[h>>2]|0,(c[l>>2]<<2)+0|0)|0;i=f;return}g[s>>2]=+g[p>>2];g[t>>2]=1.0/+O(+(+g[s>>2]));g[s>>2]=+g[q>>2];g[u>>2]=1.0/+O(+(+g[s>>2]));c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[l>>2]|0))break;g[w>>2]=+g[k>>2]*+g[(c[h>>2]|0)+(c[m>>2]<<2)>>2];g[v>>2]=+g[(c[j>>2]|0)+(c[m>>2]<<2)>>2];g[(c[h>>2]|0)+(c[m>>2]<<2)>>2]=+g[t>>2]*(+g[w>>2]-+g[v>>2]);g[(c[j>>2]|0)+(c[m>>2]<<2)>>2]=+g[u>>2]*(+g[w>>2]+ +g[v>>2]);c[m>>2]=(c[m>>2]|0)+1}i=f;return}function Fe(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0.0;j=i;i=i+48|0;k=j+28|0;l=j+16|0;m=j+4|0;n=j+8|0;o=j+32|0;p=j;q=j+12|0;r=j+24|0;s=j+20|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;g[r>>2]=0.0;g[s>>2]=0.0;c[q>>2]=0;while(1){t=+g[r>>2];if((c[q>>2]|0)>=(c[n>>2]|0))break;g[r>>2]=t+ +g[(c[k>>2]|0)+(c[q>>2]<<2)>>2]*+g[(c[l>>2]|0)+(c[q>>2]<<2)>>2];g[s>>2]=+g[s>>2]+ +g[(c[k>>2]|0)+(c[q>>2]<<2)>>2]*+g[(c[m>>2]|0)+(c[q>>2]<<2)>>2];c[q>>2]=(c[q>>2]|0)+1}g[c[o>>2]>>2]=t;g[c[p>>2]>>2]=+g[s>>2];i=j;return}function Ge(a,d,e,f,g){a=a|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;h=i;i=i+32|0;j=h+4|0;k=h+16|0;l=h+8|0;m=h+20|0;n=h+28|0;o=h;p=h+12|0;q=h+24|0;c[j>>2]=a;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[q>>2]=(c[j>>2]<<1)-1;if((c[n>>2]|0)!=0&(c[j>>2]|0)==2)c[q>>2]=(c[q>>2]|0)+-1;j=(c[k>>2]|0)+(_(c[q>>2]|0,c[l>>2]|0)|0)|0;c[p>>2]=Sc(j,c[q>>2]|0)|0;if(((c[k>>2]|0)-(c[m>>2]|0)-32|0)<(c[p>>2]|0))r=(c[k>>2]|0)-(c[m>>2]|0)-32|0;else r=c[p>>2]|0;c[p>>2]=r;c[p>>2]=64<(c[p>>2]|0)?64:c[p>>2]|0;if((c[p>>2]|0)<4){c[o>>2]=1;s=c[o>>2]|0;i=h;return s|0}else{c[o>>2]=b[25080+((c[p>>2]&7)<<1)>>1]>>14-(c[p>>2]>>3);c[o>>2]=(c[o>>2]|0)+1>>1<<1;s=c[o>>2]|0;i=h;return s|0}return 0}function He(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;j=i;i=i+64|0;k=j+52|0;l=j+44|0;m=j+24|0;n=j+20|0;o=j+12|0;p=j+40|0;q=j+48|0;r=j+56|0;s=j+28|0;t=j+8|0;u=j+4|0;v=j+32|0;w=j;x=j+16|0;y=j+36|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=d;c[n>>2]=e;c[o>>2]=f;c[p>>2]=h;c[q>>2]=c[o>>2];g[u>>2]=+g[(c[n>>2]|0)+(c[q>>2]<<2)>>2];g[v>>2]=+g[(c[n>>2]|0)+((c[q>>2]|0)+(c[(c[k>>2]|0)+8>>2]|0)<<2)>>2];g[w>>2]=+O(+(+g[u>>2]*+g[u>>2]+1.0000000036274937e-15+ +g[v>>2]*+g[v>>2]))+1.0000000036274937e-15;g[s>>2]=+g[u>>2]/+g[w>>2];g[t>>2]=+g[v>>2]/+g[w>>2];c[r>>2]=0;while(1){if((c[r>>2]|0)>=(c[p>>2]|0))break;g[y>>2]=+g[(c[l>>2]|0)+(c[r>>2]<<2)>>2];g[x>>2]=+g[(c[m>>2]|0)+(c[r>>2]<<2)>>2];g[(c[l>>2]|0)+(c[r>>2]<<2)>>2]=+g[s>>2]*+g[y>>2]+ +g[t>>2]*+g[x>>2];c[r>>2]=(c[r>>2]|0)+1}i=j;return}function Ie(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0;e=i;i=i+32|0;f=e+20|0;h=e+16|0;j=e+12|0;k=e+8|0;l=e+4|0;m=e;c[f>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=0;while(1){if((c[k>>2]|0)>=(c[j>>2]|0))break;g[m>>2]=+g[(c[f>>2]|0)+(c[k>>2]<<2)>>2]*.7071067690849304;g[l>>2]=+g[(c[h>>2]|0)+(c[k>>2]<<2)>>2]*.7071067690849304;g[(c[f>>2]|0)+(c[k>>2]<<2)>>2]=+g[m>>2]+ +g[l>>2];g[(c[h>>2]|0)+(c[k>>2]<<2)>>2]=+g[l>>2]-+g[m>>2];c[k>>2]=(c[k>>2]|0)+1}i=e;return}function Je(a){a=a|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+6|0;f=d;g=d+4|0;b[e>>1]=a;c[f>>2]=4096+(_(b[e>>1]|0,b[e>>1]|0)|0)>>13;b[g>>1]=c[f>>2];b[g>>1]=32767-(b[g>>1]|0)+(16384+(_(b[g>>1]|0,((16384+(_(b[g>>1]|0,(8277+(16384+(_(-626,b[g>>1]|0)|0)>>15)&65535)<<16>>16)|0)>>15)+-7651&65535)<<16>>16)|0)>>15);i=d;return 1+(b[g>>1]|0)&65535|0}function Ke(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[e>>2]=a;c[f>>2]=b;c[g>>2]=32-(aa(c[f>>2]|0)|0);c[h>>2]=32-(aa(c[e>>2]|0)|0);c[f>>2]=c[f>>2]<<15-(c[g>>2]|0);c[e>>2]=c[e>>2]<<15-(c[h>>2]|0);b=((c[h>>2]|0)-(c[g>>2]|0)<<11)+(16384+(_((c[e>>2]&65535)<<16>>16,((16384+(_((c[e>>2]&65535)<<16>>16,-2597)|0)>>15)+7932&65535)<<16>>16)|0)>>15)|0;e=b-(16384+(_((c[f>>2]&65535)<<16>>16,((16384+(_((c[f>>2]&65535)<<16>>16,-2597)|0)>>15)+7932&65535)<<16>>16)|0)>>15)|0;i=d;return e|0}function Le(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;f=i;i=i+48|0;h=f+28|0;j=f+16|0;k=f+4|0;l=f+8|0;m=f+32|0;n=f;o=f+12|0;p=f+24|0;q=f+20|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[o>>2]=_(c[j>>2]|0,c[k>>2]|0)|0;e=c[o>>2]|0;c[p>>2]=ua()|0;d=i;i=i+((1*(e<<2)|0)+15&-16)|0;if(c[l>>2]|0){c[q>>2]=25128+(c[k>>2]<<2)+-8;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;c[n>>2]=0;while(1){if((c[n>>2]|0)>=(c[j>>2]|0))break;l=_(c[n>>2]|0,c[k>>2]|0)|0;e=_(c[(c[q>>2]|0)+(c[m>>2]<<2)>>2]|0,c[j>>2]|0)|0;g[d+(e+(c[n>>2]|0)<<2)>>2]=+g[(c[h>>2]|0)+(l+(c[m>>2]|0)<<2)>>2];c[n>>2]=(c[n>>2]|0)+1}c[m>>2]=(c[m>>2]|0)+1}r=c[h>>2]|0;s=c[o>>2]|0;t=s<<2;u=c[h>>2]|0;v=u;w=d;x=v-w|0;y=(x|0)/4|0;z=0;A=t+z|0;df(r|0,d|0,A|0)|0;B=c[p>>2]|0;ka(B|0);i=f;return}else{c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;c[n>>2]=0;while(1){if((c[n>>2]|0)>=(c[j>>2]|0))break;q=_(c[n>>2]|0,c[k>>2]|0)|0;l=_(c[m>>2]|0,c[j>>2]|0)|0;g[d+(l+(c[n>>2]|0)<<2)>>2]=+g[(c[h>>2]|0)+(q+(c[m>>2]|0)<<2)>>2];c[n>>2]=(c[n>>2]|0)+1}c[m>>2]=(c[m>>2]|0)+1}r=c[h>>2]|0;s=c[o>>2]|0;t=s<<2;u=c[h>>2]|0;v=u;w=d;x=v-w|0;y=(x|0)/4|0;z=0;A=t+z|0;df(r|0,d|0,A|0)|0;B=c[p>>2]|0;ka(B|0);i=f;return}}function Me(a,e,f,h,j,k,l,m,n){a=a|0;e=e|0;f=f|0;h=h|0;j=j|0;k=k|0;l=l|0;m=+m;n=n|0;var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0;o=i;i=i+176|0;p=o+160|0;q=o+128|0;r=o+4|0;s=o+56|0;t=o+68|0;u=o+152|0;v=o+20|0;w=o+24|0;x=o+28|0;y=o+32|0;z=o+36|0;A=o+40|0;B=o+44|0;C=o+48|0;D=o+132|0;E=o+140|0;F=o+148|0;G=o+156|0;H=o+164|0;I=o+72|0;J=o+76|0;K=o+80|0;L=o+84|0;M=o+88|0;N=o+92|0;O=o+96|0;P=o+100|0;Q=o+12|0;R=o;S=o+8|0;T=o+104|0;U=o+52|0;V=o+136|0;W=o+60|0;X=o+144|0;Y=o+16|0;Z=o+64|0;c[p>>2]=a;c[q>>2]=e;c[r>>2]=f;c[s>>2]=h;c[t>>2]=j;c[u>>2]=k;c[v>>2]=l;g[w>>2]=m;c[x>>2]=n;c[B>>2]=0;c[C>>2]=0;c[D>>2]=c[t>>2];g[E>>2]=0.0;g[F>>2]=0.0;c[G>>2]=0;c[H>>2]=((c[c[p>>2]>>2]|0)!=0^1)&1;c[I>>2]=0;c[J>>2]=c[c[p>>2]>>2];c[K>>2]=c[(c[p>>2]|0)+4>>2];c[L>>2]=c[(c[p>>2]|0)+8>>2];c[M>>2]=c[(c[p>>2]|0)+16>>2];c[N>>2]=c[(c[p>>2]|0)+24>>2];n=_((c[v>>2]|0)+1|0,c[(c[K>>2]|0)+8>>2]|0)|0;c[y>>2]=(c[(c[K>>2]|0)+92+8>>2]|0)+(b[(c[(c[K>>2]|0)+92+4>>2]|0)+(n+(c[L>>2]|0)<<1)>>1]|0);if((c[v>>2]|0)!=-1?((c[r>>2]|0)>2?(c[s>>2]|0)>((d[(c[y>>2]|0)+(d[c[y>>2]>>0]|0)>>0]|0)+12|0):0):0){c[U>>2]=0;c[r>>2]=c[r>>2]>>1;c[I>>2]=(c[q>>2]|0)+(c[r>>2]<<2);c[v>>2]=(c[v>>2]|0)-1;if((c[t>>2]|0)==1)c[x>>2]=c[x>>2]&1|c[x>>2]<<1;c[t>>2]=(c[t>>2]|0)+1>>1;De(c[p>>2]|0,T,c[q>>2]|0,c[I>>2]|0,c[r>>2]|0,s,c[t>>2]|0,c[D>>2]|0,c[v>>2]|0,0,x);c[B>>2]=c[T+4>>2];c[C>>2]=c[T+8>>2];c[Q>>2]=c[T+12>>2];c[R>>2]=c[T+16>>2];c[S>>2]=c[T+20>>2];g[E>>2]=+(c[B>>2]|0)*.000030517578125;g[F>>2]=+(c[C>>2]|0)*.000030517578125;do if((c[D>>2]|0)>1?(c[R>>2]&16383|0)!=0:0){C=c[Q>>2]|0;if((c[R>>2]|0)>8192){c[Q>>2]=(c[Q>>2]|0)-(C>>4-(c[v>>2]|0));break}if(0<(C+(c[r>>2]<<3>>5-(c[v>>2]|0))|0))$=0;else $=(c[Q>>2]|0)+(c[r>>2]<<3>>5-(c[v>>2]|0))|0;c[Q>>2]=$}while(0);$=c[s>>2]|0;if((c[s>>2]|0)<(((c[s>>2]|0)-(c[Q>>2]|0)|0)/2|0|0))aa=$;else aa=($-(c[Q>>2]|0)|0)/2|0;if(0<=(aa|0)){aa=c[s>>2]|0;if((c[s>>2]|0)<(((c[s>>2]|0)-(c[Q>>2]|0)|0)/2|0|0))ba=aa;else ba=(aa-(c[Q>>2]|0)|0)/2|0}else ba=0;c[O>>2]=ba;c[P>>2]=(c[s>>2]|0)-(c[O>>2]|0);ba=(c[p>>2]|0)+28|0;c[ba>>2]=(c[ba>>2]|0)-(c[S>>2]|0);if(c[u>>2]|0)c[U>>2]=(c[u>>2]|0)+(c[r>>2]<<2);c[V>>2]=c[(c[p>>2]|0)+28>>2];S=c[p>>2]|0;if((c[O>>2]|0)>=(c[P>>2]|0)){c[G>>2]=Me(S,c[q>>2]|0,c[r>>2]|0,c[O>>2]|0,c[t>>2]|0,c[u>>2]|0,c[v>>2]|0,+g[w>>2]*+g[E>>2],c[x>>2]|0)|0;c[V>>2]=(c[O>>2]|0)-((c[V>>2]|0)-(c[(c[p>>2]|0)+28>>2]|0));if((c[V>>2]|0)>24&(c[R>>2]|0)!=0)c[P>>2]=(c[P>>2]|0)+((c[V>>2]|0)-24);ba=Me(c[p>>2]|0,c[I>>2]|0,c[r>>2]|0,c[P>>2]|0,c[t>>2]|0,c[U>>2]|0,c[v>>2]|0,+g[w>>2]*+g[F>>2],c[x>>2]>>c[t>>2])|0;c[G>>2]=c[G>>2]|ba<<(c[D>>2]>>1);ca=c[G>>2]|0;i=o;return ca|0}else{ba=Me(S,c[I>>2]|0,c[r>>2]|0,c[P>>2]|0,c[t>>2]|0,c[U>>2]|0,c[v>>2]|0,+g[w>>2]*+g[F>>2],c[x>>2]>>c[t>>2])|0;c[G>>2]=ba<<(c[D>>2]>>1);c[V>>2]=(c[P>>2]|0)-((c[V>>2]|0)-(c[(c[p>>2]|0)+28>>2]|0));if((c[V>>2]|0)>24&(c[R>>2]|0)!=16384)c[O>>2]=(c[O>>2]|0)+((c[V>>2]|0)-24);V=Me(c[p>>2]|0,c[q>>2]|0,c[r>>2]|0,c[O>>2]|0,c[t>>2]|0,c[u>>2]|0,c[v>>2]|0,+g[w>>2]*+g[E>>2],c[x>>2]|0)|0;c[G>>2]=c[G>>2]|V;ca=c[G>>2]|0;i=o;return ca|0}}c[z>>2]=Oe(c[K>>2]|0,c[L>>2]|0,c[v>>2]|0,c[s>>2]|0)|0;c[A>>2]=Pe(c[K>>2]|0,c[L>>2]|0,c[v>>2]|0,c[z>>2]|0)|0;s=(c[p>>2]|0)+28|0;c[s>>2]=(c[s>>2]|0)-(c[A>>2]|0);while(1){if(!((c[(c[p>>2]|0)+28>>2]|0)<0?(c[z>>2]|0)>0:0))break;s=(c[p>>2]|0)+28|0;c[s>>2]=(c[s>>2]|0)+(c[A>>2]|0);c[z>>2]=(c[z>>2]|0)+-1;c[A>>2]=Pe(c[K>>2]|0,c[L>>2]|0,c[v>>2]|0,c[z>>2]|0)|0;s=(c[p>>2]|0)+28|0;c[s>>2]=(c[s>>2]|0)-(c[A>>2]|0)}if(c[z>>2]|0){c[W>>2]=Qe(c[z>>2]|0)|0;z=c[q>>2]|0;A=c[r>>2]|0;v=c[W>>2]|0;W=c[M>>2]|0;M=c[t>>2]|0;L=c[N>>2]|0;if(c[J>>2]|0){c[G>>2]=Gb(z,A,v,W,M,L)|0;ca=c[G>>2]|0;i=o;return ca|0}else{c[G>>2]=Hb(z,A,v,W,M,L,+g[w>>2])|0;ca=c[G>>2]|0;i=o;return ca|0}}if(!(c[H>>2]|0)){ca=c[G>>2]|0;i=o;return ca|0}c[Y>>2]=(1<<c[t>>2])-1;c[x>>2]=c[x>>2]&c[Y>>2];if(!(c[x>>2]|0)){bf(c[q>>2]|0,0,c[r>>2]<<2|0)|0;ca=c[G>>2]|0;i=o;return ca|0}t=(c[u>>2]|0)==0;c[X>>2]=0;if(t){while(1){if((c[X>>2]|0)>=(c[r>>2]|0))break;t=Ra(c[(c[p>>2]|0)+36>>2]|0)|0;c[(c[p>>2]|0)+36>>2]=t;g[(c[q>>2]|0)+(c[X>>2]<<2)>>2]=+(c[(c[p>>2]|0)+36>>2]>>20|0);c[X>>2]=(c[X>>2]|0)+1}c[G>>2]=c[Y>>2]}else{while(1){if((c[X>>2]|0)>=(c[r>>2]|0))break;Y=Ra(c[(c[p>>2]|0)+36>>2]|0)|0;c[(c[p>>2]|0)+36>>2]=Y;g[Z>>2]=.00390625;m=+g[Z>>2];g[Z>>2]=(c[(c[p>>2]|0)+36>>2]&32768|0)!=0?m:-m;g[(c[q>>2]|0)+(c[X>>2]<<2)>>2]=+g[(c[u>>2]|0)+(c[X>>2]<<2)>>2]+ +g[Z>>2];c[X>>2]=(c[X>>2]|0)+1}c[G>>2]=c[x>>2]}Ib(c[q>>2]|0,c[r>>2]|0,+g[w>>2]);ca=c[G>>2]|0;i=o;return ca|0}function Ne(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;f=i;i=i+48|0;h=f+28|0;j=f+16|0;k=f+4|0;l=f+8|0;m=f+32|0;n=f;o=f+12|0;p=f+24|0;q=f+20|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[o>>2]=_(c[j>>2]|0,c[k>>2]|0)|0;e=c[o>>2]|0;c[p>>2]=ua()|0;d=i;i=i+((1*(e<<2)|0)+15&-16)|0;if(c[l>>2]|0){c[q>>2]=25128+(c[k>>2]<<2)+-8;c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;c[n>>2]=0;while(1){r=c[m>>2]|0;if((c[n>>2]|0)>=(c[j>>2]|0))break;l=_(c[(c[q>>2]|0)+(r<<2)>>2]|0,c[j>>2]|0)|0;e=_(c[n>>2]|0,c[k>>2]|0)|0;g[d+(e+(c[m>>2]|0)<<2)>>2]=+g[(c[h>>2]|0)+(l+(c[n>>2]|0)<<2)>>2];c[n>>2]=(c[n>>2]|0)+1}c[m>>2]=r+1}s=c[h>>2]|0;t=c[o>>2]|0;u=t<<2;v=c[h>>2]|0;w=v;x=d;y=w-x|0;z=(y|0)/4|0;A=0;B=u+A|0;df(s|0,d|0,B|0)|0;C=c[p>>2]|0;ka(C|0);i=f;return}else{c[m>>2]=0;while(1){if((c[m>>2]|0)>=(c[k>>2]|0))break;c[n>>2]=0;while(1){D=c[m>>2]|0;if((c[n>>2]|0)>=(c[j>>2]|0))break;r=_(D,c[j>>2]|0)|0;q=_(c[n>>2]|0,c[k>>2]|0)|0;g[d+(q+(c[m>>2]|0)<<2)>>2]=+g[(c[h>>2]|0)+(r+(c[n>>2]|0)<<2)>>2];c[n>>2]=(c[n>>2]|0)+1}c[m>>2]=D+1}s=c[h>>2]|0;t=c[o>>2]|0;u=t<<2;v=c[h>>2]|0;w=v;x=d;y=w-x|0;z=(y|0)/4|0;A=0;B=u+A|0;df(s|0,d|0,B|0)|0;C=c[p>>2]|0;ka(C|0);i=f;return}}function Oe(a,e,f,g){a=a|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+48|0;j=h;k=h+16|0;l=h+28|0;m=h+4|0;n=h+32|0;o=h+36|0;p=h+12|0;q=h+24|0;r=h+20|0;s=h+8|0;c[k>>2]=a;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[m>>2]=(c[m>>2]|0)+1;g=_(c[m>>2]|0,c[(c[k>>2]|0)+8>>2]|0)|0;c[r>>2]=(c[(c[k>>2]|0)+92+8>>2]|0)+(b[(c[(c[k>>2]|0)+92+4>>2]|0)+(g+(c[l>>2]|0)<<1)>>1]|0);c[p>>2]=0;c[q>>2]=d[c[r>>2]>>0];c[n>>2]=(c[n>>2]|0)+-1;c[o>>2]=0;while(1){if((c[o>>2]|0)>=6)break;c[s>>2]=(c[p>>2]|0)+(c[q>>2]|0)+1>>1;l=c[s>>2]|0;if((d[(c[r>>2]|0)+(c[s>>2]|0)>>0]|0)>=(c[n>>2]|0))c[q>>2]=l;else c[p>>2]=l;c[o>>2]=(c[o>>2]|0)+1}if(!(c[p>>2]|0))t=-1;else t=d[(c[r>>2]|0)+(c[p>>2]|0)>>0]|0;if(((c[n>>2]|0)-t|0)<=((d[(c[r>>2]|0)+(c[q>>2]|0)>>0]|0)-(c[n>>2]|0)|0)){c[j>>2]=c[p>>2];u=c[j>>2]|0;i=h;return u|0}else{c[j>>2]=c[q>>2];u=c[j>>2]|0;i=h;return u|0}return 0}function Pe(a,e,f,g){a=a|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0;h=i;i=i+32|0;j=h+16|0;k=h+12|0;l=h+8|0;m=h+4|0;n=h;c[j>>2]=a;c[k>>2]=e;c[l>>2]=f;c[m>>2]=g;c[l>>2]=(c[l>>2]|0)+1;g=_(c[l>>2]|0,c[(c[j>>2]|0)+8>>2]|0)|0;c[n>>2]=(c[(c[j>>2]|0)+92+8>>2]|0)+(b[(c[(c[j>>2]|0)+92+4>>2]|0)+(g+(c[k>>2]|0)<<1)>>1]|0);if(!(c[m>>2]|0)){o=0;i=h;return o|0}o=(d[(c[n>>2]|0)+(c[m>>2]|0)>>0]|0)+1|0;i=h;return o|0}function Qe(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=c[d>>2]|0;if((c[d>>2]|0)<8){e=a;i=b;return e|0}e=8+(a&7)<<(c[d>>2]>>3)-1;i=b;return e|0}function Re(){return}function Se(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,j=0.0;d=i;i=i+48|0;e=d+32|0;f=d;Ve(f,a,b);b=c[6312]|0;if((b|0)==1){c[6312]=2;h=1;i=d;return h|0}else if(!b){b=Xe(f,25264,25272,25280,25288,25296)|0;c[6314]=b;if(!b){h=0;i=d;return h|0}c[6312]=1;j=+g[6322];if(j!=0.0){c[e>>2]=~~j;Qc(b,4034,e)|0}c[6312]=1;h=1;i=d;return h|0}else{pa(c[6318]|0,48e3);h=1;i=d;return h|0}return 0}function Te(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;d=i;i=i+16|0;e=d;f=Ze((c[6318]|0)*23040|0)|0;g=Pc(c[6314]|0,a,b,f,5760,0)|0;if((g|0)<0){c[e>>2]=g;va(25304,e|0)|0;h=0;_e(f);i=d;return h|0}e=c[6320]|0;if((g|0)>(e|0)){b=g-e|0;a=c[6318]|0;j=Ze(_(b<<2,a)|0)|0;k=Ze(a<<2)|0;if((a|0)>0){l=0;do{m=_(l,b)|0;c[k+(l<<2)>>2]=j+(m<<2);n=e;do{c[j+(m+(n-e)<<2)>>2]=c[f+((_(a,n)|0)+l<<2)>>2];n=n+1|0}while((n|0)!=(g|0));l=l+1|0}while((l|0)<(a|0))}wa(k|0,a|0,b|0);_e(k);_e(j);o=c[6320]|0;p=e}else{o=e;p=g}c[6320]=o-p;h=1;_e(f);i=d;return h|0}function Ue(){return}function Ve(a,b,d){a=a|0;b=b|0;d=d|0;c[a>>2]=b;c[a+4>>2]=d;d=a+8|0;c[d>>2]=0;c[d+4>>2]=0;c[d+8>>2]=0;c[d+12>>2]=0;c[d+16>>2]=0;c[d+20>>2]=0;return}function We(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;g=i;i=i+16|0;h=g;a[h+8>>0]=0;if((e|0)<19){i=g;return 0}j=b;k=j;l=j+4|0;j=d[l>>0]|d[l+1>>0]<<8|d[l+2>>0]<<16|d[l+3>>0]<<24;l=h;c[l>>2]=d[k>>0]|d[k+1>>0]<<8|d[k+2>>0]<<16|d[k+3>>0]<<24;c[l+4>>2]=j;if(Ye(h,25336,8)|0){i=g;return 0}h=e+-1|0;if((e|0)<9){i=g;return 0}j=d[b+8>>0]|0;c[f>>2]=j;if((e|0)<10|(j&240|0)!=0){i=g;return 0}l=a[b+9>>0]|0;k=f+4|0;c[k>>2]=l&255;if(!(l<<24>>24)){i=g;return 0}m=e+-2|0;if((m|0)<=9){i=g;return 0}c[f+8>>2]=(d[b+11>>0]|0)<<8|(d[b+10>>0]|0);n=f+12|0;if((e+-4|0)<12){i=g;return 0}o=d[b+12>>0]|0;c[n>>2]=o;p=(d[b+13>>0]|0)<<8|o;c[n>>2]=p;o=(d[b+14>>0]|0)<<16|p;c[n>>2]=o;c[n>>2]=(d[b+15>>0]|0)<<24|o;if((m|0)<16){i=g;return 0}c[f+16>>2]=((d[b+17>>0]|0)<<8|(d[b+16>>0]|0))<<16>>16;if((e|0)<19){i=g;return 0}m=a[b+18>>0]|0;c[f+20>>2]=m&255;if(!(m<<24>>24)){if((l&255)>2){i=g;return 0}c[f+24>>2]=1;c[f+28>>2]=(l&255)>1&1;a[f+32>>0]=0;a[f+33>>0]=1;q=j;r=19;s=q>>>0>1;t=(r|0)==(e|0);u=t|s;v=u&1;i=g;return v|0}if((h|0)<=18){i=g;return 0}j=a[b+19>>0]|0;if(!(j<<24>>24)){i=g;return 0}l=j&255;m=f+24|0;c[m>>2]=l;if((h|0)<=19){i=g;return 0}o=a[b+20>>0]|0;n=o&255;if((o&255)>(j&255)|(n+l|0)>255){i=g;return 0}l=f+28|0;c[l>>2]=n;n=21;j=0;while(1){if((n|0)>(h|0)){w=23;break}o=a[b+n>>0]|0;a[f+32+j>>0]=o;p=n+1|0;j=j+1|0;if(!(o<<24>>24==-1?1:(o&255|0)<=((c[l>>2]|0)+(c[m>>2]|0)|0))){w=23;break}if((j|0)>=(c[k>>2]|0)){x=p;w=21;break}else n=p}if((w|0)==21){q=c[f>>2]|0;r=x;s=q>>>0>1;t=(r|0)==(e|0);u=t|s;v=u&1;i=g;return v|0}else if((w|0)==23){i=g;return 0}return 0}function Xe(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var j=0,k=0,l=0,m=0,n=0;j=i;i=i+304|0;k=j;l=j+296|0;m=j+8|0;if(!(We(c[a>>2]|0,c[a+4>>2]|0,m)|0)){n=0;i=j;return n|0}c[b>>2]=c[m+20>>2];b=c[m+4>>2]|0;c[d>>2]=b;c[e>>2]=c[m+8>>2];e=m+24|0;d=Oc(48e3,b,c[e>>2]|0,c[m+28>>2]|0,m+32|0,l)|0;if((d|0)==0|(c[l>>2]|0)!=0){n=0;i=j;return n|0}c[h>>2]=c[e>>2];e=m+16|0;m=c[e>>2]|0;do if(m){c[k>>2]=m;h=Qc(d,4034,k)|0;c[l>>2]=h;if(!h)break;else if((h|0)==-5){g[f>>2]=+P(10.0,+(+(c[e>>2]|0)/5120.0));break}else{n=0;i=j;return n|0}}while(0);n=d;i=j;return n|0}function Ye(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;if(!d){e=0;return e|0}else{f=d;g=b;h=c}while(1){c=a[g>>0]|0;b=a[h>>0]|0;if(c<<24>>24!=b<<24>>24){i=c;j=b;break}f=f+-1|0;if(!f){e=0;k=5;break}else{g=g+1|0;h=h+1|0}}if((k|0)==5)return e|0;e=(i&255)-(j&255)|0;return e|0}function Ze(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,pa=0,qa=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,Aa=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0;do if(a>>>0<245){b=a>>>0<11?16:a+11&-8;d=b>>>3;e=c[6338]|0;f=e>>>d;if(f&3){g=(f&1^1)+d|0;h=g<<1;i=25392+(h<<2)|0;j=25392+(h+2<<2)|0;h=c[j>>2]|0;k=h+8|0;l=c[k>>2]|0;do if((i|0)!=(l|0)){if(l>>>0<(c[6342]|0)>>>0)za();m=l+12|0;if((c[m>>2]|0)==(h|0)){c[m>>2]=i;c[j>>2]=l;break}else za()}else c[6338]=e&~(1<<g);while(0);l=g<<3;c[h+4>>2]=l|3;j=h+(l|4)|0;c[j>>2]=c[j>>2]|1;n=k;return n|0}j=c[6340]|0;if(b>>>0>j>>>0){if(f){l=2<<d;i=f<<d&(l|0-l);l=(i&0-i)+-1|0;i=l>>>12&16;m=l>>>i;l=m>>>5&8;o=m>>>l;m=o>>>2&4;p=o>>>m;o=p>>>1&2;q=p>>>o;p=q>>>1&1;r=(l|i|m|o|p)+(q>>>p)|0;p=r<<1;q=25392+(p<<2)|0;o=25392+(p+2<<2)|0;p=c[o>>2]|0;m=p+8|0;i=c[m>>2]|0;do if((q|0)!=(i|0)){if(i>>>0<(c[6342]|0)>>>0)za();l=i+12|0;if((c[l>>2]|0)==(p|0)){c[l>>2]=q;c[o>>2]=i;s=c[6340]|0;break}else za()}else{c[6338]=e&~(1<<r);s=j}while(0);j=r<<3;e=j-b|0;c[p+4>>2]=b|3;i=p+b|0;c[p+(b|4)>>2]=e|1;c[p+j>>2]=e;if(s){j=c[6343]|0;o=s>>>3;q=o<<1;d=25392+(q<<2)|0;f=c[6338]|0;k=1<<o;if(f&k){o=25392+(q+2<<2)|0;h=c[o>>2]|0;if(h>>>0<(c[6342]|0)>>>0)za();else{t=o;u=h}}else{c[6338]=f|k;t=25392+(q+2<<2)|0;u=d}c[t>>2]=j;c[u+12>>2]=j;c[j+8>>2]=u;c[j+12>>2]=d}c[6340]=e;c[6343]=i;n=m;return n|0}i=c[6339]|0;if(i){e=(i&0-i)+-1|0;i=e>>>12&16;d=e>>>i;e=d>>>5&8;j=d>>>e;d=j>>>2&4;q=j>>>d;j=q>>>1&2;k=q>>>j;q=k>>>1&1;f=c[25656+((e|i|d|j|q)+(k>>>q)<<2)>>2]|0;q=(c[f+4>>2]&-8)-b|0;k=f;j=f;while(1){f=c[k+16>>2]|0;if(!f){d=c[k+20>>2]|0;if(!d){v=q;w=j;break}else x=d}else x=f;f=(c[x+4>>2]&-8)-b|0;d=f>>>0<q>>>0;q=d?f:q;k=x;j=d?x:j}j=c[6342]|0;if(w>>>0<j>>>0)za();k=w+b|0;if(w>>>0>=k>>>0)za();q=c[w+24>>2]|0;m=c[w+12>>2]|0;do if((m|0)==(w|0)){p=w+20|0;r=c[p>>2]|0;if(!r){d=w+16|0;f=c[d>>2]|0;if(!f){y=0;break}else{z=f;A=d}}else{z=r;A=p}while(1){p=z+20|0;r=c[p>>2]|0;if(r){z=r;A=p;continue}p=z+16|0;r=c[p>>2]|0;if(!r){B=z;C=A;break}else{z=r;A=p}}if(C>>>0<j>>>0)za();else{c[C>>2]=0;y=B;break}}else{p=c[w+8>>2]|0;if(p>>>0<j>>>0)za();r=p+12|0;if((c[r>>2]|0)!=(w|0))za();d=m+8|0;if((c[d>>2]|0)==(w|0)){c[r>>2]=m;c[d>>2]=p;y=m;break}else za()}while(0);do if(q){m=c[w+28>>2]|0;j=25656+(m<<2)|0;if((w|0)==(c[j>>2]|0)){c[j>>2]=y;if(!y){c[6339]=c[6339]&~(1<<m);break}}else{if(q>>>0<(c[6342]|0)>>>0)za();m=q+16|0;if((c[m>>2]|0)==(w|0))c[m>>2]=y;else c[q+20>>2]=y;if(!y)break}m=c[6342]|0;if(y>>>0<m>>>0)za();c[y+24>>2]=q;j=c[w+16>>2]|0;do if(j)if(j>>>0<m>>>0)za();else{c[y+16>>2]=j;c[j+24>>2]=y;break}while(0);j=c[w+20>>2]|0;if(j)if(j>>>0<(c[6342]|0)>>>0)za();else{c[y+20>>2]=j;c[j+24>>2]=y;break}}while(0);if(v>>>0<16){q=v+b|0;c[w+4>>2]=q|3;j=w+(q+4)|0;c[j>>2]=c[j>>2]|1}else{c[w+4>>2]=b|3;c[w+(b|4)>>2]=v|1;c[w+(v+b)>>2]=v;j=c[6340]|0;if(j){q=c[6343]|0;m=j>>>3;j=m<<1;p=25392+(j<<2)|0;d=c[6338]|0;r=1<<m;if(d&r){m=25392+(j+2<<2)|0;f=c[m>>2]|0;if(f>>>0<(c[6342]|0)>>>0)za();else{D=m;E=f}}else{c[6338]=d|r;D=25392+(j+2<<2)|0;E=p}c[D>>2]=q;c[E+12>>2]=q;c[q+8>>2]=E;c[q+12>>2]=p}c[6340]=v;c[6343]=k}n=w+8|0;return n|0}else F=b}else F=b}else if(a>>>0<=4294967231){p=a+11|0;q=p&-8;j=c[6339]|0;if(j){r=0-q|0;d=p>>>8;if(d)if(q>>>0>16777215)G=31;else{p=(d+1048320|0)>>>16&8;f=d<<p;d=(f+520192|0)>>>16&4;m=f<<d;f=(m+245760|0)>>>16&2;i=14-(d|p|f)+(m<<f>>>15)|0;G=q>>>(i+7|0)&1|i<<1}else G=0;i=c[25656+(G<<2)>>2]|0;a:do if(!i){H=r;I=0;J=0;K=86}else{f=r;m=0;p=q<<((G|0)==31?0:25-(G>>>1)|0);d=i;e=0;while(1){h=c[d+4>>2]&-8;o=h-q|0;if(o>>>0<f>>>0)if((h|0)==(q|0)){L=o;M=d;N=d;K=90;break a}else{O=o;P=d}else{O=f;P=e}o=c[d+20>>2]|0;d=c[d+16+(p>>>31<<2)>>2]|0;h=(o|0)==0|(o|0)==(d|0)?m:o;if(!d){H=O;I=h;J=P;K=86;break}else{f=O;m=h;p=p<<1;e=P}}}while(0);if((K|0)==86){if((I|0)==0&(J|0)==0){i=2<<G;r=j&(i|0-i);if(!r){F=q;break}i=(r&0-r)+-1|0;r=i>>>12&16;b=i>>>r;i=b>>>5&8;k=b>>>i;b=k>>>2&4;e=k>>>b;k=e>>>1&2;p=e>>>k;e=p>>>1&1;Q=c[25656+((i|r|b|k|e)+(p>>>e)<<2)>>2]|0;R=0}else{Q=I;R=J}if(!Q){S=H;T=R}else{L=H;M=Q;N=R;K=90}}if((K|0)==90)while(1){K=0;e=(c[M+4>>2]&-8)-q|0;p=e>>>0<L>>>0;k=p?e:L;e=p?M:N;p=c[M+16>>2]|0;if(p){L=k;M=p;N=e;K=90;continue}M=c[M+20>>2]|0;if(!M){S=k;T=e;break}else{L=k;N=e;K=90}}if((T|0)!=0?S>>>0<((c[6340]|0)-q|0)>>>0:0){j=c[6342]|0;if(T>>>0<j>>>0)za();e=T+q|0;if(T>>>0>=e>>>0)za();k=c[T+24>>2]|0;p=c[T+12>>2]|0;do if((p|0)==(T|0)){b=T+20|0;r=c[b>>2]|0;if(!r){i=T+16|0;m=c[i>>2]|0;if(!m){U=0;break}else{V=m;W=i}}else{V=r;W=b}while(1){b=V+20|0;r=c[b>>2]|0;if(r){V=r;W=b;continue}b=V+16|0;r=c[b>>2]|0;if(!r){X=V;Y=W;break}else{V=r;W=b}}if(Y>>>0<j>>>0)za();else{c[Y>>2]=0;U=X;break}}else{b=c[T+8>>2]|0;if(b>>>0<j>>>0)za();r=b+12|0;if((c[r>>2]|0)!=(T|0))za();i=p+8|0;if((c[i>>2]|0)==(T|0)){c[r>>2]=p;c[i>>2]=b;U=p;break}else za()}while(0);do if(k){p=c[T+28>>2]|0;j=25656+(p<<2)|0;if((T|0)==(c[j>>2]|0)){c[j>>2]=U;if(!U){c[6339]=c[6339]&~(1<<p);break}}else{if(k>>>0<(c[6342]|0)>>>0)za();p=k+16|0;if((c[p>>2]|0)==(T|0))c[p>>2]=U;else c[k+20>>2]=U;if(!U)break}p=c[6342]|0;if(U>>>0<p>>>0)za();c[U+24>>2]=k;j=c[T+16>>2]|0;do if(j)if(j>>>0<p>>>0)za();else{c[U+16>>2]=j;c[j+24>>2]=U;break}while(0);j=c[T+20>>2]|0;if(j)if(j>>>0<(c[6342]|0)>>>0)za();else{c[U+20>>2]=j;c[j+24>>2]=U;break}}while(0);b:do if(S>>>0>=16){c[T+4>>2]=q|3;c[T+(q|4)>>2]=S|1;c[T+(S+q)>>2]=S;k=S>>>3;if(S>>>0<256){j=k<<1;p=25392+(j<<2)|0;b=c[6338]|0;i=1<<k;if(b&i){k=25392+(j+2<<2)|0;r=c[k>>2]|0;if(r>>>0<(c[6342]|0)>>>0)za();else{Z=k;_=r}}else{c[6338]=b|i;Z=25392+(j+2<<2)|0;_=p}c[Z>>2]=e;c[_+12>>2]=e;c[T+(q+8)>>2]=_;c[T+(q+12)>>2]=p;break}p=S>>>8;if(p)if(S>>>0>16777215)$=31;else{j=(p+1048320|0)>>>16&8;i=p<<j;p=(i+520192|0)>>>16&4;b=i<<p;i=(b+245760|0)>>>16&2;r=14-(p|j|i)+(b<<i>>>15)|0;$=S>>>(r+7|0)&1|r<<1}else $=0;r=25656+($<<2)|0;c[T+(q+28)>>2]=$;c[T+(q+20)>>2]=0;c[T+(q+16)>>2]=0;i=c[6339]|0;b=1<<$;if(!(i&b)){c[6339]=i|b;c[r>>2]=e;c[T+(q+24)>>2]=r;c[T+(q+12)>>2]=e;c[T+(q+8)>>2]=e;break}b=c[r>>2]|0;c:do if((c[b+4>>2]&-8|0)!=(S|0)){r=S<<(($|0)==31?0:25-($>>>1)|0);i=b;while(1){j=i+16+(r>>>31<<2)|0;p=c[j>>2]|0;if(!p){aa=j;ba=i;break}if((c[p+4>>2]&-8|0)==(S|0)){ca=p;break c}else{r=r<<1;i=p}}if(aa>>>0<(c[6342]|0)>>>0)za();else{c[aa>>2]=e;c[T+(q+24)>>2]=ba;c[T+(q+12)>>2]=e;c[T+(q+8)>>2]=e;break b}}else ca=b;while(0);b=ca+8|0;i=c[b>>2]|0;r=c[6342]|0;if(i>>>0>=r>>>0&ca>>>0>=r>>>0){c[i+12>>2]=e;c[b>>2]=e;c[T+(q+8)>>2]=i;c[T+(q+12)>>2]=ca;c[T+(q+24)>>2]=0;break}else za()}else{i=S+q|0;c[T+4>>2]=i|3;b=T+(i+4)|0;c[b>>2]=c[b>>2]|1}while(0);n=T+8|0;return n|0}else F=q}else F=q}else F=-1;while(0);T=c[6340]|0;if(T>>>0>=F>>>0){S=T-F|0;ca=c[6343]|0;if(S>>>0>15){c[6343]=ca+F;c[6340]=S;c[ca+(F+4)>>2]=S|1;c[ca+T>>2]=S;c[ca+4>>2]=F|3}else{c[6340]=0;c[6343]=0;c[ca+4>>2]=T|3;S=ca+(T+4)|0;c[S>>2]=c[S>>2]|1}n=ca+8|0;return n|0}ca=c[6341]|0;if(ca>>>0>F>>>0){S=ca-F|0;c[6341]=S;ca=c[6344]|0;c[6344]=ca+F;c[ca+(F+4)>>2]=S|1;c[ca+4>>2]=F|3;n=ca+8|0;return n|0}do if(!(c[6456]|0)){ca=ra(30)|0;if(!(ca+-1&ca)){c[6458]=ca;c[6457]=ca;c[6459]=-1;c[6460]=-1;c[6461]=0;c[6449]=0;c[6456]=(Ba(0)|0)&-16^1431655768;break}else za()}while(0);ca=F+48|0;S=c[6458]|0;T=F+47|0;ba=S+T|0;aa=0-S|0;S=ba&aa;if(S>>>0<=F>>>0){n=0;return n|0}$=c[6448]|0;if(($|0)!=0?(_=c[6446]|0,Z=_+S|0,Z>>>0<=_>>>0|Z>>>0>$>>>0):0){n=0;return n|0}d:do if(!(c[6449]&4)){$=c[6344]|0;e:do if($){Z=25800;while(1){_=c[Z>>2]|0;if(_>>>0<=$>>>0?(U=Z+4|0,(_+(c[U>>2]|0)|0)>>>0>$>>>0):0){da=Z;ea=U;break}Z=c[Z+8>>2]|0;if(!Z){K=174;break e}}Z=ba-(c[6341]|0)&aa;if(Z>>>0<2147483647){U=oa(Z|0)|0;_=(U|0)==((c[da>>2]|0)+(c[ea>>2]|0)|0);X=_?Z:0;if(_)if((U|0)==(-1|0))fa=X;else{ga=U;ha=X;K=194;break d}else{ia=U;ja=Z;ka=X;K=184}}else fa=0}else K=174;while(0);do if((K|0)==174){$=oa(0)|0;if(($|0)!=(-1|0)){q=$;X=c[6457]|0;Z=X+-1|0;if(!(Z&q))la=S;else la=S-q+(Z+q&0-X)|0;X=c[6446]|0;q=X+la|0;if(la>>>0>F>>>0&la>>>0<2147483647){Z=c[6448]|0;if((Z|0)!=0?q>>>0<=X>>>0|q>>>0>Z>>>0:0){fa=0;break}Z=oa(la|0)|0;q=(Z|0)==($|0);X=q?la:0;if(q){ga=$;ha=X;K=194;break d}else{ia=Z;ja=la;ka=X;K=184}}else fa=0}else fa=0}while(0);f:do if((K|0)==184){X=0-ja|0;do if(ca>>>0>ja>>>0&(ja>>>0<2147483647&(ia|0)!=(-1|0))?(Z=c[6458]|0,$=T-ja+Z&0-Z,$>>>0<2147483647):0)if((oa($|0)|0)==(-1|0)){oa(X|0)|0;fa=ka;break f}else{ma=$+ja|0;break}else ma=ja;while(0);if((ia|0)==(-1|0))fa=ka;else{ga=ia;ha=ma;K=194;break d}}while(0);c[6449]=c[6449]|4;na=fa;K=191}else{na=0;K=191}while(0);if((((K|0)==191?S>>>0<2147483647:0)?(fa=oa(S|0)|0,S=oa(0)|0,fa>>>0<S>>>0&((fa|0)!=(-1|0)&(S|0)!=(-1|0))):0)?(ma=S-fa|0,S=ma>>>0>(F+40|0)>>>0,S):0){ga=fa;ha=S?ma:na;K=194}if((K|0)==194){na=(c[6446]|0)+ha|0;c[6446]=na;if(na>>>0>(c[6447]|0)>>>0)c[6447]=na;na=c[6344]|0;g:do if(na){ma=25800;do{S=c[ma>>2]|0;fa=ma+4|0;ia=c[fa>>2]|0;if((ga|0)==(S+ia|0)){pa=S;qa=fa;sa=ia;ta=ma;K=204;break}ma=c[ma+8>>2]|0}while((ma|0)!=0);if(((K|0)==204?(c[ta+12>>2]&8|0)==0:0)?na>>>0<ga>>>0&na>>>0>=pa>>>0:0){c[qa>>2]=sa+ha;ma=(c[6341]|0)+ha|0;ia=na+8|0;fa=(ia&7|0)==0?0:0-ia&7;ia=ma-fa|0;c[6344]=na+fa;c[6341]=ia;c[na+(fa+4)>>2]=ia|1;c[na+(ma+4)>>2]=40;c[6345]=c[6460];break}ma=c[6342]|0;if(ga>>>0<ma>>>0){c[6342]=ga;ua=ga}else ua=ma;ma=ga+ha|0;ia=25800;while(1){if((c[ia>>2]|0)==(ma|0)){va=ia;wa=ia;K=212;break}ia=c[ia+8>>2]|0;if(!ia){xa=25800;break}}if((K|0)==212)if(!(c[wa+12>>2]&8)){c[va>>2]=ga;ia=wa+4|0;c[ia>>2]=(c[ia>>2]|0)+ha;ia=ga+8|0;ma=(ia&7|0)==0?0:0-ia&7;ia=ga+(ha+8)|0;fa=(ia&7|0)==0?0:0-ia&7;ia=ga+(fa+ha)|0;S=ma+F|0;ka=ga+S|0;ja=ia-(ga+ma)-F|0;c[ga+(ma+4)>>2]=F|3;h:do if((ia|0)!=(na|0)){if((ia|0)==(c[6343]|0)){T=(c[6340]|0)+ja|0;c[6340]=T;c[6343]=ka;c[ga+(S+4)>>2]=T|1;c[ga+(T+S)>>2]=T;break}T=ha+4|0;ca=c[ga+(T+fa)>>2]|0;if((ca&3|0)==1){la=ca&-8;ea=ca>>>3;i:do if(ca>>>0>=256){da=c[ga+((fa|24)+ha)>>2]|0;aa=c[ga+(ha+12+fa)>>2]|0;do if((aa|0)==(ia|0)){ba=fa|16;X=ga+(T+ba)|0;$=c[X>>2]|0;if(!$){Z=ga+(ba+ha)|0;ba=c[Z>>2]|0;if(!ba){Aa=0;break}else{Ca=ba;Da=Z}}else{Ca=$;Da=X}while(1){X=Ca+20|0;$=c[X>>2]|0;if($){Ca=$;Da=X;continue}X=Ca+16|0;$=c[X>>2]|0;if(!$){Ea=Ca;Fa=Da;break}else{Ca=$;Da=X}}if(Fa>>>0<ua>>>0)za();else{c[Fa>>2]=0;Aa=Ea;break}}else{X=c[ga+((fa|8)+ha)>>2]|0;if(X>>>0<ua>>>0)za();$=X+12|0;if((c[$>>2]|0)!=(ia|0))za();Z=aa+8|0;if((c[Z>>2]|0)==(ia|0)){c[$>>2]=aa;c[Z>>2]=X;Aa=aa;break}else za()}while(0);if(!da)break;aa=c[ga+(ha+28+fa)>>2]|0;X=25656+(aa<<2)|0;do if((ia|0)!=(c[X>>2]|0)){if(da>>>0<(c[6342]|0)>>>0)za();Z=da+16|0;if((c[Z>>2]|0)==(ia|0))c[Z>>2]=Aa;else c[da+20>>2]=Aa;if(!Aa)break i}else{c[X>>2]=Aa;if(Aa)break;c[6339]=c[6339]&~(1<<aa);break i}while(0);aa=c[6342]|0;if(Aa>>>0<aa>>>0)za();c[Aa+24>>2]=da;X=fa|16;Z=c[ga+(X+ha)>>2]|0;do if(Z)if(Z>>>0<aa>>>0)za();else{c[Aa+16>>2]=Z;c[Z+24>>2]=Aa;break}while(0);Z=c[ga+(T+X)>>2]|0;if(!Z)break;if(Z>>>0<(c[6342]|0)>>>0)za();else{c[Aa+20>>2]=Z;c[Z+24>>2]=Aa;break}}else{Z=c[ga+((fa|8)+ha)>>2]|0;aa=c[ga+(ha+12+fa)>>2]|0;da=25392+(ea<<1<<2)|0;do if((Z|0)!=(da|0)){if(Z>>>0<ua>>>0)za();if((c[Z+12>>2]|0)==(ia|0))break;za()}while(0);if((aa|0)==(Z|0)){c[6338]=c[6338]&~(1<<ea);break}do if((aa|0)==(da|0))Ga=aa+8|0;else{if(aa>>>0<ua>>>0)za();X=aa+8|0;if((c[X>>2]|0)==(ia|0)){Ga=X;break}za()}while(0);c[Z+12>>2]=aa;c[Ga>>2]=Z}while(0);Ha=ga+((la|fa)+ha)|0;Ia=la+ja|0}else{Ha=ia;Ia=ja}ea=Ha+4|0;c[ea>>2]=c[ea>>2]&-2;c[ga+(S+4)>>2]=Ia|1;c[ga+(Ia+S)>>2]=Ia;ea=Ia>>>3;if(Ia>>>0<256){T=ea<<1;ca=25392+(T<<2)|0;da=c[6338]|0;X=1<<ea;do if(!(da&X)){c[6338]=da|X;Ja=25392+(T+2<<2)|0;Ka=ca}else{ea=25392+(T+2<<2)|0;$=c[ea>>2]|0;if($>>>0>=(c[6342]|0)>>>0){Ja=ea;Ka=$;break}za()}while(0);c[Ja>>2]=ka;c[Ka+12>>2]=ka;c[ga+(S+8)>>2]=Ka;c[ga+(S+12)>>2]=ca;break}T=Ia>>>8;do if(!T)La=0;else{if(Ia>>>0>16777215){La=31;break}X=(T+1048320|0)>>>16&8;da=T<<X;la=(da+520192|0)>>>16&4;$=da<<la;da=($+245760|0)>>>16&2;ea=14-(la|X|da)+($<<da>>>15)|0;La=Ia>>>(ea+7|0)&1|ea<<1}while(0);T=25656+(La<<2)|0;c[ga+(S+28)>>2]=La;c[ga+(S+20)>>2]=0;c[ga+(S+16)>>2]=0;ca=c[6339]|0;ea=1<<La;if(!(ca&ea)){c[6339]=ca|ea;c[T>>2]=ka;c[ga+(S+24)>>2]=T;c[ga+(S+12)>>2]=ka;c[ga+(S+8)>>2]=ka;break}ea=c[T>>2]|0;j:do if((c[ea+4>>2]&-8|0)!=(Ia|0)){T=Ia<<((La|0)==31?0:25-(La>>>1)|0);ca=ea;while(1){da=ca+16+(T>>>31<<2)|0;$=c[da>>2]|0;if(!$){Ma=da;Na=ca;break}if((c[$+4>>2]&-8|0)==(Ia|0)){Oa=$;break j}else{T=T<<1;ca=$}}if(Ma>>>0<(c[6342]|0)>>>0)za();else{c[Ma>>2]=ka;c[ga+(S+24)>>2]=Na;c[ga+(S+12)>>2]=ka;c[ga+(S+8)>>2]=ka;break h}}else Oa=ea;while(0);ea=Oa+8|0;ca=c[ea>>2]|0;T=c[6342]|0;if(ca>>>0>=T>>>0&Oa>>>0>=T>>>0){c[ca+12>>2]=ka;c[ea>>2]=ka;c[ga+(S+8)>>2]=ca;c[ga+(S+12)>>2]=Oa;c[ga+(S+24)>>2]=0;break}else za()}else{ca=(c[6341]|0)+ja|0;c[6341]=ca;c[6344]=ka;c[ga+(S+4)>>2]=ca|1}while(0);n=ga+(ma|8)|0;return n|0}else xa=25800;while(1){S=c[xa>>2]|0;if(S>>>0<=na>>>0?(ka=c[xa+4>>2]|0,ja=S+ka|0,ja>>>0>na>>>0):0){Pa=S;Qa=ka;Ra=ja;break}xa=c[xa+8>>2]|0}ma=Pa+(Qa+-39)|0;ja=Pa+(Qa+-47+((ma&7|0)==0?0:0-ma&7))|0;ma=na+16|0;ka=ja>>>0<ma>>>0?na:ja;ja=ka+8|0;S=ga+8|0;ia=(S&7|0)==0?0:0-S&7;S=ha+-40-ia|0;c[6344]=ga+ia;c[6341]=S;c[ga+(ia+4)>>2]=S|1;c[ga+(ha+-36)>>2]=40;c[6345]=c[6460];S=ka+4|0;c[S>>2]=27;c[ja>>2]=c[6450];c[ja+4>>2]=c[6451];c[ja+8>>2]=c[6452];c[ja+12>>2]=c[6453];c[6450]=ga;c[6451]=ha;c[6453]=0;c[6452]=ja;ja=ka+28|0;c[ja>>2]=7;if((ka+32|0)>>>0<Ra>>>0){ia=ja;do{ja=ia;ia=ia+4|0;c[ia>>2]=7}while((ja+8|0)>>>0<Ra>>>0)}if((ka|0)!=(na|0)){ia=ka-na|0;c[S>>2]=c[S>>2]&-2;c[na+4>>2]=ia|1;c[ka>>2]=ia;ja=ia>>>3;if(ia>>>0<256){fa=ja<<1;ca=25392+(fa<<2)|0;ea=c[6338]|0;T=1<<ja;if(ea&T){ja=25392+(fa+2<<2)|0;Z=c[ja>>2]|0;if(Z>>>0<(c[6342]|0)>>>0)za();else{Sa=ja;Ta=Z}}else{c[6338]=ea|T;Sa=25392+(fa+2<<2)|0;Ta=ca}c[Sa>>2]=na;c[Ta+12>>2]=na;c[na+8>>2]=Ta;c[na+12>>2]=ca;break}ca=ia>>>8;if(ca)if(ia>>>0>16777215)Ua=31;else{fa=(ca+1048320|0)>>>16&8;T=ca<<fa;ca=(T+520192|0)>>>16&4;ea=T<<ca;T=(ea+245760|0)>>>16&2;Z=14-(ca|fa|T)+(ea<<T>>>15)|0;Ua=ia>>>(Z+7|0)&1|Z<<1}else Ua=0;Z=25656+(Ua<<2)|0;c[na+28>>2]=Ua;c[na+20>>2]=0;c[ma>>2]=0;T=c[6339]|0;ea=1<<Ua;if(!(T&ea)){c[6339]=T|ea;c[Z>>2]=na;c[na+24>>2]=Z;c[na+12>>2]=na;c[na+8>>2]=na;break}ea=c[Z>>2]|0;k:do if((c[ea+4>>2]&-8|0)!=(ia|0)){Z=ia<<((Ua|0)==31?0:25-(Ua>>>1)|0);T=ea;while(1){fa=T+16+(Z>>>31<<2)|0;ca=c[fa>>2]|0;if(!ca){Va=fa;Wa=T;break}if((c[ca+4>>2]&-8|0)==(ia|0)){Xa=ca;break k}else{Z=Z<<1;T=ca}}if(Va>>>0<(c[6342]|0)>>>0)za();else{c[Va>>2]=na;c[na+24>>2]=Wa;c[na+12>>2]=na;c[na+8>>2]=na;break g}}else Xa=ea;while(0);ea=Xa+8|0;ia=c[ea>>2]|0;ma=c[6342]|0;if(ia>>>0>=ma>>>0&Xa>>>0>=ma>>>0){c[ia+12>>2]=na;c[ea>>2]=na;c[na+8>>2]=ia;c[na+12>>2]=Xa;c[na+24>>2]=0;break}else za()}}else{ia=c[6342]|0;if((ia|0)==0|ga>>>0<ia>>>0)c[6342]=ga;c[6450]=ga;c[6451]=ha;c[6453]=0;c[6347]=c[6456];c[6346]=-1;ia=0;do{ea=ia<<1;ma=25392+(ea<<2)|0;c[25392+(ea+3<<2)>>2]=ma;c[25392+(ea+2<<2)>>2]=ma;ia=ia+1|0}while((ia|0)!=32);ia=ga+8|0;ma=(ia&7|0)==0?0:0-ia&7;ia=ha+-40-ma|0;c[6344]=ga+ma;c[6341]=ia;c[ga+(ma+4)>>2]=ia|1;c[ga+(ha+-36)>>2]=40;c[6345]=c[6460]}while(0);ha=c[6341]|0;if(ha>>>0>F>>>0){ga=ha-F|0;c[6341]=ga;ha=c[6344]|0;c[6344]=ha+F;c[ha+(F+4)>>2]=ga|1;c[ha+4>>2]=F|3;n=ha+8|0;return n|0}}c[(ya()|0)>>2]=12;n=0;return n|0}function _e(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;if(!a)return;b=a+-8|0;d=c[6342]|0;if(b>>>0<d>>>0)za();e=c[a+-4>>2]|0;f=e&3;if((f|0)==1)za();g=e&-8;h=a+(g+-8)|0;do if(!(e&1)){i=c[b>>2]|0;if(!f)return;j=-8-i|0;k=a+j|0;l=i+g|0;if(k>>>0<d>>>0)za();if((k|0)==(c[6343]|0)){m=a+(g+-4)|0;n=c[m>>2]|0;if((n&3|0)!=3){o=k;p=l;break}c[6340]=l;c[m>>2]=n&-2;c[a+(j+4)>>2]=l|1;c[h>>2]=l;return}n=i>>>3;if(i>>>0<256){i=c[a+(j+8)>>2]|0;m=c[a+(j+12)>>2]|0;q=25392+(n<<1<<2)|0;if((i|0)!=(q|0)){if(i>>>0<d>>>0)za();if((c[i+12>>2]|0)!=(k|0))za()}if((m|0)==(i|0)){c[6338]=c[6338]&~(1<<n);o=k;p=l;break}if((m|0)!=(q|0)){if(m>>>0<d>>>0)za();q=m+8|0;if((c[q>>2]|0)==(k|0))r=q;else za()}else r=m+8|0;c[i+12>>2]=m;c[r>>2]=i;o=k;p=l;break}i=c[a+(j+24)>>2]|0;m=c[a+(j+12)>>2]|0;do if((m|0)==(k|0)){q=a+(j+20)|0;n=c[q>>2]|0;if(!n){s=a+(j+16)|0;t=c[s>>2]|0;if(!t){u=0;break}else{v=t;w=s}}else{v=n;w=q}while(1){q=v+20|0;n=c[q>>2]|0;if(n){v=n;w=q;continue}q=v+16|0;n=c[q>>2]|0;if(!n){x=v;y=w;break}else{v=n;w=q}}if(y>>>0<d>>>0)za();else{c[y>>2]=0;u=x;break}}else{q=c[a+(j+8)>>2]|0;if(q>>>0<d>>>0)za();n=q+12|0;if((c[n>>2]|0)!=(k|0))za();s=m+8|0;if((c[s>>2]|0)==(k|0)){c[n>>2]=m;c[s>>2]=q;u=m;break}else za()}while(0);if(i){m=c[a+(j+28)>>2]|0;q=25656+(m<<2)|0;if((k|0)==(c[q>>2]|0)){c[q>>2]=u;if(!u){c[6339]=c[6339]&~(1<<m);o=k;p=l;break}}else{if(i>>>0<(c[6342]|0)>>>0)za();m=i+16|0;if((c[m>>2]|0)==(k|0))c[m>>2]=u;else c[i+20>>2]=u;if(!u){o=k;p=l;break}}m=c[6342]|0;if(u>>>0<m>>>0)za();c[u+24>>2]=i;q=c[a+(j+16)>>2]|0;do if(q)if(q>>>0<m>>>0)za();else{c[u+16>>2]=q;c[q+24>>2]=u;break}while(0);q=c[a+(j+20)>>2]|0;if(q)if(q>>>0<(c[6342]|0)>>>0)za();else{c[u+20>>2]=q;c[q+24>>2]=u;o=k;p=l;break}else{o=k;p=l}}else{o=k;p=l}}else{o=b;p=g}while(0);if(o>>>0>=h>>>0)za();b=a+(g+-4)|0;u=c[b>>2]|0;if(!(u&1))za();if(!(u&2)){if((h|0)==(c[6344]|0)){d=(c[6341]|0)+p|0;c[6341]=d;c[6344]=o;c[o+4>>2]=d|1;if((o|0)!=(c[6343]|0))return;c[6343]=0;c[6340]=0;return}if((h|0)==(c[6343]|0)){d=(c[6340]|0)+p|0;c[6340]=d;c[6343]=o;c[o+4>>2]=d|1;c[o+d>>2]=d;return}d=(u&-8)+p|0;x=u>>>3;do if(u>>>0>=256){y=c[a+(g+16)>>2]|0;w=c[a+(g|4)>>2]|0;do if((w|0)==(h|0)){v=a+(g+12)|0;r=c[v>>2]|0;if(!r){f=a+(g+8)|0;e=c[f>>2]|0;if(!e){z=0;break}else{A=e;B=f}}else{A=r;B=v}while(1){v=A+20|0;r=c[v>>2]|0;if(r){A=r;B=v;continue}v=A+16|0;r=c[v>>2]|0;if(!r){C=A;D=B;break}else{A=r;B=v}}if(D>>>0<(c[6342]|0)>>>0)za();else{c[D>>2]=0;z=C;break}}else{v=c[a+g>>2]|0;if(v>>>0<(c[6342]|0)>>>0)za();r=v+12|0;if((c[r>>2]|0)!=(h|0))za();f=w+8|0;if((c[f>>2]|0)==(h|0)){c[r>>2]=w;c[f>>2]=v;z=w;break}else za()}while(0);if(y){w=c[a+(g+20)>>2]|0;l=25656+(w<<2)|0;if((h|0)==(c[l>>2]|0)){c[l>>2]=z;if(!z){c[6339]=c[6339]&~(1<<w);break}}else{if(y>>>0<(c[6342]|0)>>>0)za();w=y+16|0;if((c[w>>2]|0)==(h|0))c[w>>2]=z;else c[y+20>>2]=z;if(!z)break}w=c[6342]|0;if(z>>>0<w>>>0)za();c[z+24>>2]=y;l=c[a+(g+8)>>2]|0;do if(l)if(l>>>0<w>>>0)za();else{c[z+16>>2]=l;c[l+24>>2]=z;break}while(0);l=c[a+(g+12)>>2]|0;if(l)if(l>>>0<(c[6342]|0)>>>0)za();else{c[z+20>>2]=l;c[l+24>>2]=z;break}}}else{l=c[a+g>>2]|0;w=c[a+(g|4)>>2]|0;y=25392+(x<<1<<2)|0;if((l|0)!=(y|0)){if(l>>>0<(c[6342]|0)>>>0)za();if((c[l+12>>2]|0)!=(h|0))za()}if((w|0)==(l|0)){c[6338]=c[6338]&~(1<<x);break}if((w|0)!=(y|0)){if(w>>>0<(c[6342]|0)>>>0)za();y=w+8|0;if((c[y>>2]|0)==(h|0))E=y;else za()}else E=w+8|0;c[l+12>>2]=w;c[E>>2]=l}while(0);c[o+4>>2]=d|1;c[o+d>>2]=d;if((o|0)==(c[6343]|0)){c[6340]=d;return}else F=d}else{c[b>>2]=u&-2;c[o+4>>2]=p|1;c[o+p>>2]=p;F=p}p=F>>>3;if(F>>>0<256){u=p<<1;b=25392+(u<<2)|0;d=c[6338]|0;E=1<<p;if(d&E){p=25392+(u+2<<2)|0;h=c[p>>2]|0;if(h>>>0<(c[6342]|0)>>>0)za();else{G=p;H=h}}else{c[6338]=d|E;G=25392+(u+2<<2)|0;H=b}c[G>>2]=o;c[H+12>>2]=o;c[o+8>>2]=H;c[o+12>>2]=b;return}b=F>>>8;if(b)if(F>>>0>16777215)I=31;else{H=(b+1048320|0)>>>16&8;G=b<<H;b=(G+520192|0)>>>16&4;u=G<<b;G=(u+245760|0)>>>16&2;E=14-(b|H|G)+(u<<G>>>15)|0;I=F>>>(E+7|0)&1|E<<1}else I=0;E=25656+(I<<2)|0;c[o+28>>2]=I;c[o+20>>2]=0;c[o+16>>2]=0;G=c[6339]|0;u=1<<I;a:do if(G&u){H=c[E>>2]|0;b:do if((c[H+4>>2]&-8|0)!=(F|0)){b=F<<((I|0)==31?0:25-(I>>>1)|0);d=H;while(1){h=d+16+(b>>>31<<2)|0;p=c[h>>2]|0;if(!p){J=h;K=d;break}if((c[p+4>>2]&-8|0)==(F|0)){L=p;break b}else{b=b<<1;d=p}}if(J>>>0<(c[6342]|0)>>>0)za();else{c[J>>2]=o;c[o+24>>2]=K;c[o+12>>2]=o;c[o+8>>2]=o;break a}}else L=H;while(0);H=L+8|0;d=c[H>>2]|0;b=c[6342]|0;if(d>>>0>=b>>>0&L>>>0>=b>>>0){c[d+12>>2]=o;c[H>>2]=o;c[o+8>>2]=d;c[o+12>>2]=L;c[o+24>>2]=0;break}else za()}else{c[6339]=G|u;c[E>>2]=o;c[o+24>>2]=E;c[o+12>>2]=o;c[o+8>>2]=o}while(0);o=(c[6346]|0)+-1|0;c[6346]=o;if(!o)M=25808;else return;while(1){o=c[M>>2]|0;if(!o)break;else M=o+8|0}c[6346]=-1;return}function $e(){}function af(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>c;return a>>>c|(b&(1<<c)-1)<<32-c}C=(b|0)<0?-1:0;return b>>c-32|0}function bf(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;g=b&3;h=d|d<<8|d<<16|d<<24;i=f&~3;if(g){g=b+4-g|0;while((b|0)<(g|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(i|0)){c[b>>2]=h;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function cf(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function df(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return sa(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function ef(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=a+c>>>0;return (C=b+d+(e>>>0<a>>>0|0)>>>0,e|0)|0}function ff(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;if((c|0)<(b|0)&(b|0)<(c+d|0)){e=b;c=c+d|0;b=b+d|0;while((d|0)>0){b=b-1|0;c=c-1|0;d=d-1|0;a[b>>0]=a[c>>0]|0}b=e}else df(b,c,d)|0;return b|0}function gf(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=b-d>>>0;e=b-d-(c>>>0>a>>>0|0)>>>0;return (C=e,a-c>>>0|0)|0}function hf(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b<<c|(a&(1<<c)-1<<32-c)>>>32-c;return a<<c}C=a<<c-32;return 0}function jf(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>>c;return a>>>c|(b&(1<<c)-1)<<32-c}C=0;return b>>>c-32|0}function kf(b){b=b|0;var c=0;c=a[m+(b&255)>>0]|0;if((c|0)<8)return c|0;c=a[m+(b>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[m+(b>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return (a[m+(b>>>24)>>0]|0)+24|0}function lf(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;c=a&65535;d=b&65535;e=_(d,c)|0;f=a>>>16;a=(e>>>16)+(_(d,f)|0)|0;d=b>>>16;b=_(d,c)|0;return (C=(a>>>16)+(_(d,f)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|e&65535|0)|0}function mf(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;e=b>>31|((b|0)<0?-1:0)<<1;f=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;g=d>>31|((d|0)<0?-1:0)<<1;h=((d|0)<0?-1:0)>>31|((d|0)<0?-1:0)<<1;i=gf(e^a,f^b,e,f)|0;b=C;a=g^e;e=h^f;return gf((rf(i,b,gf(g^c,h^d,g,h)|0,C,0)|0)^a,C^e,a,e)|0}function nf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+8|0;g=f|0;h=b>>31|((b|0)<0?-1:0)<<1;j=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;k=e>>31|((e|0)<0?-1:0)<<1;l=((e|0)<0?-1:0)>>31|((e|0)<0?-1:0)<<1;m=gf(h^a,j^b,h,j)|0;b=C;rf(m,b,gf(k^d,l^e,k,l)|0,C,g)|0;l=gf(c[g>>2]^h,c[g+4>>2]^j,h,j)|0;j=C;i=f;return (C=j,l)|0}function of(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;a=c;c=lf(e,a)|0;f=C;return (C=(_(b,a)|0)+(_(d,e)|0)+f|f&0,c|0|0)|0}function pf(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return rf(a,b,c,d,0)|0}function qf(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=i;i=i+8|0;g=f|0;rf(a,b,d,e,g)|0;i=f;return (C=c[g+4>>2]|0,c[g>>2]|0)|0}function rf(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0;g=a;h=b;i=h;j=d;k=e;l=k;if(!i){m=(f|0)!=0;if(!l){if(m){c[f>>2]=(g>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(g>>>0)/(j>>>0)>>>0;return (C=n,o)|0}else{if(!m){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;o=0;return (C=n,o)|0}}m=(l|0)==0;do if(j){if(!m){p=(aa(l|0)|0)-(aa(i|0)|0)|0;if(p>>>0<=31){q=p+1|0;r=31-p|0;s=p-31>>31;t=q;u=g>>>(q>>>0)&s|i<<r;v=i>>>(q>>>0)&s;w=0;x=g<<r;break}if(!f){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return (C=n,o)|0}r=j-1|0;if(r&j){s=(aa(j|0)|0)+33-(aa(i|0)|0)|0;q=64-s|0;p=32-s|0;y=p>>31;z=s-32|0;A=z>>31;t=s;u=p-1>>31&i>>>(z>>>0)|(i<<p|g>>>(s>>>0))&A;v=A&i>>>(s>>>0);w=g<<q&y;x=(i<<q|g>>>(z>>>0))&y|g<<p&s-33>>31;break}if(f){c[f>>2]=r&g;c[f+4>>2]=0}if((j|0)==1){n=h|b&0;o=a|0|0;return (C=n,o)|0}else{r=kf(j|0)|0;n=i>>>(r>>>0)|0;o=i<<32-r|g>>>(r>>>0)|0;return (C=n,o)|0}}else{if(m){if(f){c[f>>2]=(i>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(i>>>0)/(j>>>0)>>>0;return (C=n,o)|0}if(!g){if(f){c[f>>2]=0;c[f+4>>2]=(i>>>0)%(l>>>0)}n=0;o=(i>>>0)/(l>>>0)>>>0;return (C=n,o)|0}r=l-1|0;if(!(r&l)){if(f){c[f>>2]=a|0;c[f+4>>2]=r&i|b&0}n=0;o=i>>>((kf(l|0)|0)>>>0);return (C=n,o)|0}r=(aa(l|0)|0)-(aa(i|0)|0)|0;if(r>>>0<=30){s=r+1|0;p=31-r|0;t=s;u=i<<p|g>>>(s>>>0);v=i>>>(s>>>0);w=0;x=g<<p;break}if(!f){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return (C=n,o)|0}while(0);if(!t){B=x;D=w;E=v;F=u;G=0;H=0}else{b=d|0|0;d=k|e&0;e=ef(b|0,d|0,-1,-1)|0;k=C;h=x;x=w;w=v;v=u;u=t;t=0;do{a=h;h=x>>>31|h<<1;x=t|x<<1;g=v<<1|a>>>31|0;a=v>>>31|w<<1|0;gf(e,k,g,a)|0;i=C;l=i>>31|((i|0)<0?-1:0)<<1;t=l&1;v=gf(g,a,l&b,(((i|0)<0?-1:0)>>31|((i|0)<0?-1:0)<<1)&d)|0;w=C;u=u-1|0}while((u|0)!=0);B=h;D=x;E=w;F=v;G=0;H=t}t=D;D=0;if(f){c[f>>2]=F;c[f+4>>2]=E}n=(t|0)>>>31|(B|D)<<1|(D<<1|t>>>31)&0|G;o=(t<<1|0>>>31)&-2|H;return (C=n,o)|0}function sf(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;Ha[a&1](b|0,c|0,d|0,e|0,f|0,g|0)}function tf(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;ba(0)} + +// EMSCRIPTEN_END_FUNCS +var Ha=[tf,ee];return{_strlen:cf,_free:_e,_ogv_audio_decoder_destroy:Ue,_ogv_audio_decoder_init:Re,_i64Add:ef,_memmove:ff,_bitshift64Ashr:af,_memset:bf,_ogv_audio_decoder_process_header:Se,_malloc:Ze,_memcpy:df,_ogv_audio_decoder_process_audio:Te,runPostSets:$e,stackAlloc:Ia,stackSave:Ja,stackRestore:Ka,establishStackSpace:La,setThrew:Ma,setTempRet0:Pa,getTempRet0:Qa,dynCall_viiiiii:sf}}) + + +// EMSCRIPTEN_END_ASM +(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var _strlen=Module["_strlen"]=asm["_strlen"];var _free=Module["_free"]=asm["_free"];var runPostSets=Module["runPostSets"]=asm["runPostSets"];var _ogv_audio_decoder_destroy=Module["_ogv_audio_decoder_destroy"]=asm["_ogv_audio_decoder_destroy"];var _ogv_audio_decoder_init=Module["_ogv_audio_decoder_init"]=asm["_ogv_audio_decoder_init"];var _i64Add=Module["_i64Add"]=asm["_i64Add"];var _memmove=Module["_memmove"]=asm["_memmove"];var _bitshift64Ashr=Module["_bitshift64Ashr"]=asm["_bitshift64Ashr"];var _memset=Module["_memset"]=asm["_memset"];var _ogv_audio_decoder_process_header=Module["_ogv_audio_decoder_process_header"]=asm["_ogv_audio_decoder_process_header"];var _malloc=Module["_malloc"]=asm["_malloc"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var _ogv_audio_decoder_process_audio=Module["_ogv_audio_decoder_process_audio"]=asm["_ogv_audio_decoder_process_audio"];var dynCall_viiiiii=Module["dynCall_viiiiii"]=asm["dynCall_viiiiii"];Runtime.stackAlloc=asm["stackAlloc"];Runtime.stackSave=asm["stackSave"];Runtime.stackRestore=asm["stackRestore"];Runtime.establishStackSpace=asm["establishStackSpace"];Runtime.setTempRet0=asm["setTempRet0"];Runtime.getTempRet0=asm["getTempRet0"];var i64Math=(function(){var goog={math:{}};goog.math.Long=(function(low,high){this.low_=low|0;this.high_=high|0});goog.math.Long.IntCache_={};goog.math.Long.fromInt=(function(value){if(-128<=value&&value<128){var cachedObj=goog.math.Long.IntCache_[value];if(cachedObj){return cachedObj}}var obj=new goog.math.Long(value|0,value<0?-1:0);if(-128<=value&&value<128){goog.math.Long.IntCache_[value]=obj}return obj});goog.math.Long.fromNumber=(function(value){if(isNaN(value)||!isFinite(value)){return goog.math.Long.ZERO}else if(value<=-goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MIN_VALUE}else if(value+1>=goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MAX_VALUE}else if(value<0){return goog.math.Long.fromNumber(-value).negate()}else{return new goog.math.Long(value%goog.math.Long.TWO_PWR_32_DBL_|0,value/goog.math.Long.TWO_PWR_32_DBL_|0)}});goog.math.Long.fromBits=(function(lowBits,highBits){return new goog.math.Long(lowBits,highBits)});goog.math.Long.fromString=(function(str,opt_radix){if(str.length==0){throw Error("number format error: empty string")}var radix=opt_radix||10;if(radix<2||36<radix){throw Error("radix out of range: "+radix)}if(str.charAt(0)=="-"){return goog.math.Long.fromString(str.substring(1),radix).negate()}else if(str.indexOf("-")>=0){throw Error('number format error: interior "-" character: '+str)}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,8));var result=goog.math.Long.ZERO;for(var i=0;i<str.length;i+=8){var size=Math.min(8,str.length-i);var value=parseInt(str.substring(i,i+size),radix);if(size<8){var power=goog.math.Long.fromNumber(Math.pow(radix,size));result=result.multiply(power).add(goog.math.Long.fromNumber(value))}else{result=result.multiply(radixToPower);result=result.add(goog.math.Long.fromNumber(value))}}return result});goog.math.Long.TWO_PWR_16_DBL_=1<<16;goog.math.Long.TWO_PWR_24_DBL_=1<<24;goog.math.Long.TWO_PWR_32_DBL_=goog.math.Long.TWO_PWR_16_DBL_*goog.math.Long.TWO_PWR_16_DBL_;goog.math.Long.TWO_PWR_31_DBL_=goog.math.Long.TWO_PWR_32_DBL_/2;goog.math.Long.TWO_PWR_48_DBL_=goog.math.Long.TWO_PWR_32_DBL_*goog.math.Long.TWO_PWR_16_DBL_;goog.math.Long.TWO_PWR_64_DBL_=goog.math.Long.TWO_PWR_32_DBL_*goog.math.Long.TWO_PWR_32_DBL_;goog.math.Long.TWO_PWR_63_DBL_=goog.math.Long.TWO_PWR_64_DBL_/2;goog.math.Long.ZERO=goog.math.Long.fromInt(0);goog.math.Long.ONE=goog.math.Long.fromInt(1);goog.math.Long.NEG_ONE=goog.math.Long.fromInt(-1);goog.math.Long.MAX_VALUE=goog.math.Long.fromBits(4294967295|0,2147483647|0);goog.math.Long.MIN_VALUE=goog.math.Long.fromBits(0,2147483648|0);goog.math.Long.TWO_PWR_24_=goog.math.Long.fromInt(1<<24);goog.math.Long.prototype.toInt=(function(){return this.low_});goog.math.Long.prototype.toNumber=(function(){return this.high_*goog.math.Long.TWO_PWR_32_DBL_+this.getLowBitsUnsigned()});goog.math.Long.prototype.toString=(function(opt_radix){var radix=opt_radix||10;if(radix<2||36<radix){throw Error("radix out of range: "+radix)}if(this.isZero()){return"0"}if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){var radixLong=goog.math.Long.fromNumber(radix);var div=this.div(radixLong);var rem=div.multiply(radixLong).subtract(this);return div.toString(radix)+rem.toInt().toString(radix)}else{return"-"+this.negate().toString(radix)}}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,6));var rem=this;var result="";while(true){var remDiv=rem.div(radixToPower);var intval=rem.subtract(remDiv.multiply(radixToPower)).toInt();var digits=intval.toString(radix);rem=remDiv;if(rem.isZero()){return digits+result}else{while(digits.length<6){digits="0"+digits}result=""+digits+result}}});goog.math.Long.prototype.getHighBits=(function(){return this.high_});goog.math.Long.prototype.getLowBits=(function(){return this.low_});goog.math.Long.prototype.getLowBitsUnsigned=(function(){return this.low_>=0?this.low_:goog.math.Long.TWO_PWR_32_DBL_+this.low_});goog.math.Long.prototype.getNumBitsAbs=(function(){if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){return 64}else{return this.negate().getNumBitsAbs()}}else{var val=this.high_!=0?this.high_:this.low_;for(var bit=31;bit>0;bit--){if((val&1<<bit)!=0){break}}return this.high_!=0?bit+33:bit+1}});goog.math.Long.prototype.isZero=(function(){return this.high_==0&&this.low_==0});goog.math.Long.prototype.isNegative=(function(){return this.high_<0});goog.math.Long.prototype.isOdd=(function(){return(this.low_&1)==1});goog.math.Long.prototype.equals=(function(other){return this.high_==other.high_&&this.low_==other.low_});goog.math.Long.prototype.notEquals=(function(other){return this.high_!=other.high_||this.low_!=other.low_});goog.math.Long.prototype.lessThan=(function(other){return this.compare(other)<0});goog.math.Long.prototype.lessThanOrEqual=(function(other){return this.compare(other)<=0});goog.math.Long.prototype.greaterThan=(function(other){return this.compare(other)>0});goog.math.Long.prototype.greaterThanOrEqual=(function(other){return this.compare(other)>=0});goog.math.Long.prototype.compare=(function(other){if(this.equals(other)){return 0}var thisNeg=this.isNegative();var otherNeg=other.isNegative();if(thisNeg&&!otherNeg){return-1}if(!thisNeg&&otherNeg){return 1}if(this.subtract(other).isNegative()){return-1}else{return 1}});goog.math.Long.prototype.negate=(function(){if(this.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.MIN_VALUE}else{return this.not().add(goog.math.Long.ONE)}});goog.math.Long.prototype.add=(function(other){var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.subtract=(function(other){return this.add(other.negate())});goog.math.Long.prototype.multiply=(function(other){if(this.isZero()){return goog.math.Long.ZERO}else if(other.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){return other.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}else if(other.equals(goog.math.Long.MIN_VALUE)){return this.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().multiply(other.negate())}else{return this.negate().multiply(other).negate()}}else if(other.isNegative()){return this.multiply(other.negate()).negate()}if(this.lessThan(goog.math.Long.TWO_PWR_24_)&&other.lessThan(goog.math.Long.TWO_PWR_24_)){return goog.math.Long.fromNumber(this.toNumber()*other.toNumber())}var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.div=(function(other){if(other.isZero()){throw Error("division by zero")}else if(this.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){if(other.equals(goog.math.Long.ONE)||other.equals(goog.math.Long.NEG_ONE)){return goog.math.Long.MIN_VALUE}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ONE}else{var halfThis=this.shiftRight(1);var approx=halfThis.div(other).shiftLeft(1);if(approx.equals(goog.math.Long.ZERO)){return other.isNegative()?goog.math.Long.ONE:goog.math.Long.NEG_ONE}else{var rem=this.subtract(other.multiply(approx));var result=approx.add(rem.div(other));return result}}}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().div(other.negate())}else{return this.negate().div(other).negate()}}else if(other.isNegative()){return this.div(other.negate()).negate()}var res=goog.math.Long.ZERO;var rem=this;while(rem.greaterThanOrEqual(other)){var approx=Math.max(1,Math.floor(rem.toNumber()/other.toNumber()));var log2=Math.ceil(Math.log(approx)/Math.LN2);var delta=log2<=48?1:Math.pow(2,log2-48);var approxRes=goog.math.Long.fromNumber(approx);var approxRem=approxRes.multiply(other);while(approxRem.isNegative()||approxRem.greaterThan(rem)){approx-=delta;approxRes=goog.math.Long.fromNumber(approx);approxRem=approxRes.multiply(other)}if(approxRes.isZero()){approxRes=goog.math.Long.ONE}res=res.add(approxRes);rem=rem.subtract(approxRem)}return res});goog.math.Long.prototype.modulo=(function(other){return this.subtract(this.div(other).multiply(other))});goog.math.Long.prototype.not=(function(){return goog.math.Long.fromBits(~this.low_,~this.high_)});goog.math.Long.prototype.and=(function(other){return goog.math.Long.fromBits(this.low_&other.low_,this.high_&other.high_)});goog.math.Long.prototype.or=(function(other){return goog.math.Long.fromBits(this.low_|other.low_,this.high_|other.high_)});goog.math.Long.prototype.xor=(function(other){return goog.math.Long.fromBits(this.low_^other.low_,this.high_^other.high_)});goog.math.Long.prototype.shiftLeft=(function(numBits){numBits&=63;if(numBits==0){return this}else{var low=this.low_;if(numBits<32){var high=this.high_;return goog.math.Long.fromBits(low<<numBits,high<<numBits|low>>>32-numBits)}else{return goog.math.Long.fromBits(0,low<<numBits-32)}}});goog.math.Long.prototype.shiftRight=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>numBits)}else{return goog.math.Long.fromBits(high>>numBits-32,high>=0?0:-1)}}});goog.math.Long.prototype.shiftRightUnsigned=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>>numBits)}else if(numBits==32){return goog.math.Long.fromBits(high,0)}else{return goog.math.Long.fromBits(high>>>numBits-32,0)}}});var navigator={appName:"Modern Browser"};var dbits;var canary=0xdeadbeefcafe;var j_lm=(canary&16777215)==15715070;function BigInteger(a,b,c){if(a!=null)if("number"==typeof a)this.fromNumber(a,b,c);else if(b==null&&"string"!=typeof a)this.fromString(a,256);else this.fromString(a,b)}function nbi(){return new BigInteger(null)}function am1(i,x,w,j,c,n){while(--n>=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}if(j_lm&&navigator.appName=="Microsoft Internet Explorer"){BigInteger.prototype.am=am2;dbits=30}else if(j_lm&&navigator.appName!="Netscape"){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz";var BI_RC=new Array;var rr,vv;rr="0".charCodeAt(0);for(vv=0;vv<=9;++vv)BI_RC[rr++]=vv;rr="a".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;rr="A".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;function int2char(n){return BI_RM.charAt(n)}function intAt(s,i){var c=BI_RC[s.charCodeAt(i)];return c==null?-1:c}function bnpCopyTo(r){for(var i=this.t-1;i>=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{this.fromRadix(s,b);return}this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)this[this.t++]=x;else if(sh+k>this.DB){this[this.t-1]|=(x&(1<<this.DB-sh)-1)<<sh;this[this.t++]=x>>this.DB-sh}else this[this.t-1]|=x<<sh;sh+=k;if(sh>=this.DB)sh-=this.DB}if(k==8&&(s[0]&128)!=0){this.s=-1;if(sh>0)this[this.t-1]|=(1<<this.DB-sh)-1<<sh}this.clamp();if(mi)BigInteger.ZERO.subTo(this,this)}function bnpClamp(){var c=this.s&this.DM;while(this.t>0&&this[this.t-1]==c)--this.t}function bnToString(b){if(this.s<0)return"-"+this.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return this.toRadix(b);var km=(1<<k)-1,d,m=false,r="",i=this.t;var p=this.DB-i*this.DB%k;if(i-->0){if(p<this.DB&&(d=this[i]>>p)>0){m=true;r=int2char(d)}while(i>=0){if(p<k){d=(this[i]&(1<<p)-1)<<k-p;d|=this[--i]>>(p+=this.DB-k)}else{d=this[i]>>(p-=k)&km;if(p<=0){p+=this.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i<this.t;++i)r[i-n]=this[i];r.t=Math.max(this.t-n,0);r.s=this.s}function bnpLShiftTo(n,r){var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<cbs)-1;var ds=Math.floor(n/this.DB),c=this.s<<bs&this.DM,i;for(i=this.t-1;i>=0;--i){r[i+ds+1]=this[i]>>cbs|c;c=(this[i]&bm)<<bs}for(i=ds-1;i>=0;--i)r[i]=0;r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp()}function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return}var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<bs)-1;r[0]=this[ds]>>bs;for(var i=ds+1;i<this.t;++i){r[i-ds-1]|=(this[i]&bm)<<cbs;r[i-ds]=this[i]>>bs}if(bs>0)r[this.t-ds-1]|=(this.s&bm)<<cbs;r.t=this.t-ds;r.clamp()}function bnpSubTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]-a[i];r[i++]=c&this.DM;c>>=this.DB}if(a.t<this.t){c-=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB}c+=this.s}else{c+=this.s;while(i<a.t){c-=a[i];r[i++]=c&this.DM;c>>=this.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=this.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i<y.t;++i)r[i+x.t]=x.am(0,y[i],r,i,0,x.t);r.s=0;r.clamp();if(this.s!=a.s)BigInteger.ZERO.subTo(r,r)}function bnpSquareTo(r){var x=this.abs();var i=r.t=2*x.t;while(--i>=0)r[i]=0;for(i=0;i<x.t-1;++i){var c=x.am(i,x[i],r,2*i,0,1);if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1))>=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0)return;var pt=this.abs();if(pt.t<pm.t){if(q!=null)q.fromInt(0);if(r!=null)this.copyTo(r);return}if(r==null)r=nbi();var y=nbi(),ts=this.s,ms=m.s;var nsh=this.DB-nbits(pm[pm.t-1]);if(nsh>0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<<this.F1)+(ys>1?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<<this.F1)/yt,e=1<<this.F2;var i=r.t,j=i-ys,t=q==null?nbi():q;y.dlShiftTo(j,t);if(r.compareTo(t)>=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t<ys)y[y.t++]=0;while(--j>=0){var qd=r[--i]==y0?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))<qd){y.dlShiftTo(j,t);r.subTo(t,r);while(r[i]<--qd)r.subTo(t,r)}}if(q!=null){r.drShiftTo(ys,q);if(ts!=ms)BigInteger.ZERO.subTo(q,q)}r.t=ys;r.clamp();if(nsh>0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<m.DB-15)-1;this.mt2=2*m.t}function montConvert(x){var r=nbi();x.abs().dlShiftTo(this.m.t,r);r.divRemTo(this.m,null,r);if(x.s<0&&r.compareTo(BigInteger.ZERO)>0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i<this.m.t;++i){var j=x[i]&32767;var u0=j*this.mpl+((j*this.mph+(x[i]>>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<<i)>0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnpFromRadix(s,b){this.fromInt(0);if(b==null)b=10;var cs=this.chunkSize(b);var d=Math.pow(b,cs),mi=false,j=0,w=0;for(var i=0;i<s.length;++i){var x=intAt(s,i);if(x<0){if(s.charAt(i)=="-"&&this.signum()==0)mi=true;continue}w=b*w+x;if(++j>=cs){this.dMultiply(d);this.dAddOffset(w,0);j=0;w=0}}if(j>0){this.dMultiply(Math.pow(b,j));this.dAddOffset(w,0)}if(mi)BigInteger.ZERO.subTo(this,this)}function bnpChunkSize(r){return Math.floor(Math.LN2*this.DB/Math.log(r))}function bnSigNum(){if(this.s<0)return-1;else if(this.t<=0||this.t==1&&this[0]<=0)return 0;else return 1}function bnpDMultiply(n){this[this.t]=this.am(0,n-1,this,0,0,this.t);++this.t;this.clamp()}function bnpDAddOffset(n,w){if(n==0)return;while(this.t<=w)this[this.t++]=0;this[w]+=n;while(this[w]>=this.DV){this[w]-=this.DV;if(++w>=this.t)this[this.t++]=0;++this[w]}}function bnpToRadix(b){if(b==null)b=10;if(this.signum()==0||b<2||b>36)return"0";var cs=this.chunkSize(b);var a=Math.pow(b,cs);var d=nbv(a),y=nbi(),z=nbi(),r="";this.divRemTo(d,y,z);while(y.signum()>0){r=(a+z.intValue()).toString(b).substr(1)+r;y.divRemTo(d,y,z)}return z.intValue().toString(b)+r}function bnIntValue(){if(this.s<0){if(this.t==1)return this[0]-this.DV;else if(this.t==0)return-1}else if(this.t==1)return this[0];else if(this.t==0)return 0;return(this[1]&(1<<32-this.DB)-1)<<this.DB|this[0]}function bnpAddTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]+a[i];r[i++]=c&this.DM;c>>=this.DB}if(a.t<this.t){c+=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB}c+=this.s}else{c+=this.s;while(i<a.t){c+=a[i];r[i++]=c&this.DM;c>>=this.DB}c+=a.s}r.s=c<0?-1:0;if(c>0)r[i++]=c;else if(c<-1)r[i++]=this.DV+c;r.t=i;r.clamp()}BigInteger.prototype.fromRadix=bnpFromRadix;BigInteger.prototype.chunkSize=bnpChunkSize;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.dMultiply=bnpDMultiply;BigInteger.prototype.dAddOffset=bnpDAddOffset;BigInteger.prototype.toRadix=bnpToRadix;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.addTo=bnpAddTo;var Wrapper={abs:(function(l,h){var x=new goog.math.Long(l,h);var ret;if(x.isNegative()){ret=x.negate()}else{ret=x}HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_}),ensureTemps:(function(){if(Wrapper.ensuredTemps)return;Wrapper.ensuredTemps=true;Wrapper.two32=new BigInteger;Wrapper.two32.fromString("4294967296",10);Wrapper.two64=new BigInteger;Wrapper.two64.fromString("18446744073709551616",10);Wrapper.temp1=new BigInteger;Wrapper.temp2=new BigInteger}),lh2bignum:(function(l,h){var a=new BigInteger;a.fromString(h.toString(),10);var b=new BigInteger;a.multiplyTo(Wrapper.two32,b);var c=new BigInteger;c.fromString(l.toString(),10);var d=new BigInteger;c.addTo(b,d);return d}),stringify:(function(l,h,unsigned){var ret=(new goog.math.Long(l,h)).toString();if(unsigned&&ret[0]=="-"){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(ret,10);ret=new BigInteger;Wrapper.two64.addTo(bignum,ret);ret=ret.toString(10)}return ret}),fromString:(function(str,base,min,max,unsigned){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(str,base);var bigmin=new BigInteger;bigmin.fromString(min,10);var bigmax=new BigInteger;bigmax.fromString(max,10);if(unsigned&&bignum.compareTo(BigInteger.ZERO)<0){var temp=new BigInteger;bignum.addTo(Wrapper.two64,temp);bignum=temp}var error=false;if(bignum.compareTo(bigmin)<0){bignum=bigmin;error=true}else if(bignum.compareTo(bigmax)>0){bignum=bigmax;error=true}var ret=goog.math.Long.fromString(bignum.toString());HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_;if(error)throw"range error"})};return Wrapper})();function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){assert(runDependencies==0,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");assert(__ATPRERUN__.length==0,"cannot call main when preRun functions remain to be called");args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]),"i8",ALLOC_NORMAL)];pad();for(var i=0;i<argc-1;i=i+1){argv.push(allocate(intArrayFromString(args[i]),"i8",ALLOC_NORMAL));pad()}argv.push(0);argv=allocate(argv,"i32",ALLOC_NORMAL);initialStackTop=STACKTOP;try{var ret=Module["_main"](argc,argv,0);exit(ret,true)}catch(e){if(e instanceof ExitStatus){return}else if(e=="SimulateInfiniteLoop"){Module["noExitRuntime"]=true;return}else{if(e&&typeof e==="object"&&e.stack)Module.printErr("exception thrown: "+[e,e.stack]);throw e}}finally{calledMain=true}};function run(args){args=args||Module["arguments"];if(preloadStartTime===null)preloadStartTime=Date.now();if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(ENVIRONMENT_IS_WEB&&preloadStartTime!==null){Module.printErr("pre-main prep time: "+(Date.now()-preloadStartTime)+" ms")}if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(Module["_main"]&&shouldRunNow)Module["callMain"](args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["stdout"]["once"]("drain",(function(){process["exit"](status)}));console.log(" ");setTimeout((function(){process["exit"](status)}),500)}else if(ENVIRONMENT_IS_SHELL&&typeof quit==="function"){quit(status)}throw new ExitStatus(status)}Module["exit"]=Module.exit=exit;var abortDecorators=[];function abort(what){if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=false;if(Module["noInitialRun"]){shouldRunNow=false}Module["noExitRuntime"]=true;run();var inputBuffer,inputBufferSize;function reallocInputBuffer(size){if(inputBuffer&&inputBufferSize>=size){return inputBuffer}if(inputBuffer){Module._free(inputBuffer)}inputBufferSize=size;inputBuffer=Module._malloc(inputBufferSize);return inputBuffer}Module.loadedMetadata=!!options.audioFormat;Module.audioFormat=options.audioFormat||null;Module.audioBuffer=null;Object.defineProperty(Module,"processing",{get:function getProcessing(){return false}});Module.init=(function(callback){Module._ogv_audio_decoder_init();callback()});Module.processHeader=(function(data,callback){var len=data.byteLength;var buffer=reallocInputBuffer(len);Module.HEAPU8.set(new Uint8Array(data),buffer);var ret=Module._ogv_audio_decoder_process_header(buffer,len);callback(ret)});Module.processAudio=(function(data,callback){var len=data.byteLength;var buffer=reallocInputBuffer(len);Module.HEAPU8.set(new Uint8Array(data),buffer);var ret=Module._ogv_audio_decoder_process_audio(buffer,len);callback(ret)}) + + + + + + return Module; +}; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-audio-vorbis.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-audio-vorbis.js new file mode 100644 index 00000000..7815d228 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-audio-vorbis.js @@ -0,0 +1,23 @@ +var OGVDecoderAudioVorbis = function(Module) { + Module = Module || {}; + +var options=Module;Module={print:(function(str){console.log(str)})};var Module;if(!Module)Module=(typeof OGVDecoderAudioVorbis!=="undefined"?OGVDecoderAudioVorbis:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB;var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath["normalize"](filename);var ret=nodeFS["readFileSync"](filename);if(!ret&&filename!=nodePath["resolve"](filename)){filename=path.join(__dirname,"..","src",filename);ret=nodeFS["readFileSync"](filename)}if(ret&&!binary)ret=ret.toString();return ret};Module["readBinary"]=function readBinary(filename){return Module["read"](filename,true)};Module["load"]=function load(f){globalEval(read(f))};if(!Module["thisProgram"]){if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}else{Module["thisProgram"]="unknown-program"}}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function read(){throw"no read() available (jsc?)"}}Module["readBinary"]=function readBinary(f){if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}var data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function printErr(x){console.log(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WORKER){Module["load"]=importScripts}if(typeof Module["setWindowTitle"]==="undefined"){Module["setWindowTitle"]=(function(title){document.title=title})}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}if(!Module["thisProgram"]){Module["thisProgram"]="./this.program"}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}var Runtime={setTempRet0:(function(value){tempRet0=value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),STACK_ALIGN:16,prepVararg:(function(ptr,type){if(type==="double"||type==="i64"){if(ptr&7){assert((ptr&7)===4);ptr+=4}}else{assert((ptr&3)===0)}return ptr}),getAlignSize:(function(type,size,vararg){if(!vararg&&(type=="i64"||type=="double"))return 8;if(!type)return Math.min(size,8);return Math.min(size||(type?Runtime.getNativeFieldSize(type):0),Runtime.QUANTUM_SIZE)}),dynCall:(function(sig,ptr,args){if(args&&args.length){if(!args.splice)args=Array.prototype.slice.call(args);args.splice(0,0,ptr);return Module["dynCall_"+sig].apply(null,args)}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i<Runtime.functionPointers.length;i++){if(!Runtime.functionPointers[i]){Runtime.functionPointers[i]=func;return 2*(1+i)}}throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."}),removeFunction:(function(index){Runtime.functionPointers[(index-2)/2]=null}),warnOnce:(function(text){if(!Runtime.warnOnce.shown)Runtime.warnOnce.shown={};if(!Runtime.warnOnce.shown[text]){Runtime.warnOnce.shown[text]=1;Module.printErr(text)}}),funcWrappers:{},getFuncWrapper:(function(func,sig){assert(sig);if(!Runtime.funcWrappers[sig]){Runtime.funcWrappers[sig]={}}var sigCache=Runtime.funcWrappers[sig];if(!sigCache[func]){sigCache[func]=function dynCall_wrapper(){return Runtime.dynCall(sig,func,arguments)}}return sigCache[func]}),getCompilerSetting:(function(name){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"}),stackAlloc:(function(size){var ret=STACKTOP;STACKTOP=STACKTOP+size|0;STACKTOP=STACKTOP+15&-16;return ret}),staticAlloc:(function(size){var ret=STATICTOP;STATICTOP=STATICTOP+size|0;STATICTOP=STATICTOP+15&-16;return ret}),dynamicAlloc:(function(size){var ret=DYNAMICTOP;DYNAMICTOP=DYNAMICTOP+size|0;DYNAMICTOP=DYNAMICTOP+15&-16;if(DYNAMICTOP>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){DYNAMICTOP=ret;return 0}}return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:16))*(quantum?quantum:16);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var __THREW__=0;var ABORT=false;var EXITSTATUS=0;var undef=0;var tempValue,tempInt,tempBigInt,tempInt2,tempBigInt2,tempPair,tempBigIntI,tempBigIntR,tempBigIntS,tempBigIntP,tempBigIntD,tempDouble,tempFloat;var tempI64,tempI64b;var tempRet0,tempRet1,tempRet2,tempRet3,tempRet4,tempRet5,tempRet6,tempRet7,tempRet8,tempRet9;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var globalScope=this;function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var JSfuncs={"stackSave":(function(){Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore()}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=Runtime.stackAlloc((str.length<<2)+1);writeStringToMemory(str,ret)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args,opts){var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=Runtime.stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);if(returnType==="string")ret=Pointer_stringify(ret);if(stack!==0){if(opts&&opts.async){EmterpreterAsync.asyncFinalizers.push((function(){Runtime.stackRestore(stack)}));return}Runtime.stackRestore(stack)}return ret};var sourceRegex=/^function\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/;function parseJSFunc(jsfunc){var parsed=jsfunc.toString().match(sourceRegex).slice(1);return{arguments:parsed[0],body:parsed[1],returnValue:parsed[2]}}var JSsource={};for(var fun in JSfuncs){if(JSfuncs.hasOwnProperty(fun)){JSsource[fun]=parseJSFunc(JSfuncs[fun])}}cwrap=function cwrap(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident);var numericArgs=argTypes.every((function(type){return type==="number"}));var numericRet=returnType!=="string";if(numericRet&&numericArgs){return cfunc}var argNames=argTypes.map((function(x,i){return"$"+i}));var funcstr="(function("+argNames.join(",")+") {";var nargs=argTypes.length;if(!numericArgs){funcstr+="var stack = "+JSsource["stackSave"].body+";";for(var i=0;i<nargs;i++){var arg=argNames[i],type=argTypes[i];if(type==="number")continue;var convertCode=JSsource[type+"ToC"];funcstr+="var "+convertCode.arguments+" = "+arg+";";funcstr+=convertCode.body+";";funcstr+=arg+"="+convertCode.returnValue+";"}}var cfuncname=parseJSFunc((function(){return cfunc})).returnValue;funcstr+="var ret = "+cfuncname+"("+argNames.join(",")+");";if(!numericRet){var strgfy=parseJSFunc((function(){return Pointer_stringify})).returnValue;funcstr+="ret = "+strgfy+"(ret);"}if(!numericArgs){funcstr+=JSsource["stackRestore"].body.replace("()","(stack)")+";"}funcstr+="return ret})";return eval(funcstr)}}))();Module["cwrap"]=cwrap;Module["ccall"]=ccall;function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr<stop;ptr+=4){HEAP32[ptr>>2]=0}stop=ret+size;while(ptr<stop){HEAP8[ptr++>>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i<size){var curr=slab[i];if(typeof curr==="function"){curr=Runtime.getFunctionIndex(curr)}type=singleType||types[i];if(type===0){i++;continue}if(type=="i64")type="i32";setValue(ret+i,curr,type);if(previousType!==type){typeSize=Runtime.getNativeTypeSize(type);previousType=type}i+=typeSize}return ret}Module["allocate"]=allocate;function getMemory(size){if(!staticSealed)return Runtime.staticAlloc(size);if(typeof _sbrk!=="undefined"&&!_sbrk.called||!runtimeInitialized)return Runtime.dynamicAlloc(size);return _malloc(size)}Module["getMemory"]=getMemory;function Pointer_stringify(ptr,length){if(length===0||!ptr)return"";var hasUtf=0;var t;var i=0;while(1){t=HEAPU8[ptr+i>>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return Module["UTF8ToString"](ptr)}Module["Pointer_stringify"]=Pointer_stringify;function AsciiToString(ptr){var str="";while(1){var ch=HEAP8[ptr++>>0];if(!ch)return str;str+=String.fromCharCode(ch)}}Module["AsciiToString"]=AsciiToString;function stringToAscii(str,outPtr){return writeAsciiToMemory(str,outPtr,false)}Module["stringToAscii"]=stringToAscii;function UTF8ArrayToString(u8Array,idx){var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}Module["UTF8ArrayToString"]=UTF8ArrayToString;function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}Module["UTF8ToString"]=UTF8ToString;function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}Module["stringToUTF8Array"]=stringToUTF8Array;function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}Module["stringToUTF8"]=stringToUTF8;function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}Module["lengthBytesUTF8"]=lengthBytesUTF8;function UTF16ToString(ptr){var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}Module["UTF16ToString"]=UTF16ToString;function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}Module["stringToUTF16"]=stringToUTF16;function lengthBytesUTF16(str){return str.length*2}Module["lengthBytesUTF16"]=lengthBytesUTF16;function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}Module["UTF32ToString"]=UTF32ToString;function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}Module["stringToUTF32"]=stringToUTF32;function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}Module["lengthBytesUTF32"]=lengthBytesUTF32;function demangle(func){var hasLibcxxabi=!!Module["___cxa_demangle"];if(hasLibcxxabi){try{var buf=_malloc(func.length);writeStringToMemory(func.substr(1),buf);var status=_malloc(4);var ret=Module["___cxa_demangle"](buf,0,0,status);if(getValue(status,"i32")===0&&ret){return Pointer_stringify(ret)}}catch(e){}finally{if(buf)_free(buf);if(status)_free(status);if(ret)_free(ret)}}var i=3;var basicTypes={"v":"void","b":"bool","c":"char","s":"short","i":"int","l":"long","f":"float","d":"double","w":"wchar_t","a":"signed char","h":"unsigned char","t":"unsigned short","j":"unsigned int","m":"unsigned long","x":"long long","y":"unsigned long long","z":"..."};var subs=[];var first=true;function dump(x){if(x)Module.print(x);Module.print(func);var pre="";for(var a=0;a<i;a++)pre+=" ";Module.print(pre+"^")}function parseNested(){i++;if(func[i]==="K")i++;var parts=[];while(func[i]!=="E"){if(func[i]==="S"){i++;var next=func.indexOf("_",i);var num=func.substring(i,next)||0;parts.push(subs[num]||"?");i=next+1;continue}if(func[i]==="C"){parts.push(parts[parts.length-1]);i+=2;continue}var size=parseInt(func.substr(i));var pre=size.toString().length;if(!size||!pre){i--;break}var curr=func.substr(i+pre,size);parts.push(curr);subs.push(curr);i+=pre+size}i++;return parts}function parse(rawList,limit,allowVoid){limit=limit||Infinity;var ret="",list=[];function flushList(){return"("+list.join(", ")+")"}var name;if(func[i]==="N"){name=parseNested().join("::");limit--;if(limit===0)return rawList?[name]:name}else{if(func[i]==="K"||first&&func[i]==="L")i++;var size=parseInt(func.substr(i));if(size){var pre=size.toString().length;name=func.substr(i+pre,size);i+=pre+size}}first=false;if(func[i]==="I"){i++;var iList=parse(true);var iRet=parse(true,1,true);ret+=iRet[0]+" "+name+"<"+iList.join(", ")+">"}else{ret=name}paramLoop:while(i<func.length&&limit-->0){var c=func[i++];if(c in basicTypes){list.push(basicTypes[c])}else{switch(c){case"P":list.push(parse(true,1,true)[0]+"*");break;case"R":list.push(parse(true,1,true)[0]+"&");break;case"L":{i++;var end=func.indexOf("E",i);var size=end-i;list.push(func.substr(i,size));i+=size+2;break};case"A":{var size=parseInt(func.substr(i));i+=size.toString().length;if(func[i]!=="_")throw"?";i++;list.push(parse(true,1,true)[0]+" ["+size+"]");break};case"E":break paramLoop;default:ret+="?"+c;break paramLoop}}}if(!allowVoid&&list.length===1&&list[0]==="void")list=[];if(rawList){if(ret){list.push(ret+"?")}return list}else{return ret+flushList()}}var parsed=func;try{if(func=="Object._main"||func=="_main"){return"main()"}if(typeof func==="number")func=Pointer_stringify(func);if(func[0]!=="_")return func;if(func[1]!=="_")return func;if(func[2]!=="Z")return func;switch(func[3]){case"n":return"operator new()";case"d":return"operator delete()"}parsed=parse()}catch(e){parsed+="?"}if(parsed.indexOf("?")>=0&&!hasLibcxxabi){Runtime.warnOnce("warning: a problem occurred in builtin C++ name demangling; build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling")}return parsed}function demangleAll(text){return text.replace(/__Z[\w\d_]+/g,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){return demangleAll(jsStackTrace())}Module["stackTrace"]=stackTrace;var PAGE_SIZE=4096;function alignMemoryPage(x){if(x%4096>0){x+=4096-x%4096}return x}var HEAP;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var STATIC_BASE=0,STATICTOP=0,staticSealed=false;var STACK_BASE=0,STACKTOP=0,STACK_MAX=0;var DYNAMIC_BASE=0,DYNAMICTOP=0;function enlargeMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.")}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;var totalMemory=64*1024;while(totalMemory<TOTAL_MEMORY||totalMemory<2*TOTAL_STACK){if(totalMemory<16*1024*1024){totalMemory*=2}else{totalMemory+=16*1024*1024}}if(totalMemory!==TOTAL_MEMORY){Module.printErr("increasing TOTAL_MEMORY to "+totalMemory+" to be compliant with the asm.js spec (and given that TOTAL_STACK="+TOTAL_STACK+")");TOTAL_MEMORY=totalMemory}assert(typeof Int32Array!=="undefined"&&typeof Float64Array!=="undefined"&&!!(new Int32Array(1))["subarray"]&&!!(new Int32Array(1))["set"],"JS engine does not provide full typed array support");var buffer;buffer=new ArrayBuffer(TOTAL_MEMORY);HEAP8=new Int8Array(buffer);HEAP16=new Int16Array(buffer);HEAP32=new Int32Array(buffer);HEAPU8=new Uint8Array(buffer);HEAPU16=new Uint16Array(buffer);HEAPU32=new Uint32Array(buffer);HEAPF32=new Float32Array(buffer);HEAPF64=new Float64Array(buffer);HEAP32[0]=255;assert(HEAPU8[0]===255&&HEAPU8[3]===0,"Typed arrays 2 must be run on a little-endian system");Module["HEAP"]=HEAP;Module["buffer"]=buffer;Module["HEAP8"]=HEAP8;Module["HEAP16"]=HEAP16;Module["HEAP32"]=HEAP32;Module["HEAPU8"]=HEAPU8;Module["HEAPU16"]=HEAPU16;Module["HEAPU32"]=HEAPU32;Module["HEAPF32"]=HEAPF32;Module["HEAPF64"]=HEAPF64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Runtime.dynCall("v",func)}else{Runtime.dynCall("vi",func,[callback.arg])}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=Module.addOnPreRun=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=Module.addOnInit=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=Module.addOnPreMain=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=Module.addOnExit=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=Module.addOnPostRun=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i<array.length;i++){var chr=array[i];if(chr>255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){var array=intArrayFromString(string,dontAddNull);var i=0;while(i<array.length){var chr=array[i];HEAP8[buffer+i>>0]=chr;i=i+1}}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){for(var i=0;i<array.length;i++){HEAP8[buffer++>>0]=array[i]}}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;function unSign(value,bits,ignore){if(value>=0){return value}return bits<=32?2*Math.abs(1<<bits-1)+value:Math.pow(2,bits)+value}function reSign(value,bits,ignore){if(value<=0){return value}var half=bits<=32?Math.abs(1<<bits-1):Math.pow(2,bits-1);if(value>=half&&(bits<=32||value>half)){value=-2*half+value}return value}if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];if(!Math["clz32"])Math["clz32"]=(function(x){x=x>>>0;for(var i=0;i<32;i++){if(x&1<<31-i)return i}return 32});Math.clz32=Math["clz32"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_min=Math.min;var Math_clz32=Math.clz32;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;var ASM_CONSTS=[];STATIC_BASE=8;STATICTOP=STATIC_BASE+58272;__ATINIT__.push();allocate([0,0,0,0,1,0,0,0,3,0,0,0,7,0,0,0,15,0,0,0,31,0,0,0,63,0,0,0,127,0,0,0,255,0,0,0,255,1,0,0,255,3,0,0,255,7,0,0,255,15,0,0,255,31,0,0,255,63,0,0,255,127,0,0,255,255,0,0,255,255,1,0,255,255,3,0,255,255,7,0,255,255,15,0,255,255,31,0,255,255,63,0,255,255,127,0,255,255,255,0,255,255,255,1,255,255,255,3,255,255,255,7,255,255,255,15,255,255,255,31,255,255,255,63,255,255,255,127,255,255,255,255,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,8,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,7,0,0,0,8,0,0,0,5,0,0,0,6,0,0,0,2,0,0,0,1,0,0,0,3,0,0,0,2,0,0,0,7,0,0,0,8,0,0,0,5,0,0,0,6,0,0,0,4,0,0,0,2,0,0,0,5,0,0,0,1,0,0,0,9,0,0,0,7,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,176,0,0,0,144,0,0,0,208,0,0,0,240,0,0,0,16,1,0,0,0,0,0,0,48,1,0,0,0,0,0,0,4,0,0,0,2,0,0,0,3,0,0,0,5,0,0,0,144,3,0,0,16,4,0,0,16,5,0,0,16,7,0,0,16,11,0,0,16,19,0,0,16,35,0,0,16,67,0,0,0,0,76,194,0,0,80,194,0,0,84,194,0,0,88,194,0,0,92,194,0,0,96,194,0,0,100,194,0,0,104,194,0,0,108,194,0,0,112,194,0,0,116,194,0,0,120,194,0,0,124,194,0,0,128,194,0,0,130,194,0,0,132,194,0,0,134,194,0,0,136,194,0,0,138,194,0,0,140,194,0,0,142,194,0,0,144,194,0,0,146,194,0,0,148,194,0,0,150,194,0,0,152,194,0,0,154,194,0,0,156,194,0,0,160,194,0,0,162,194,0,0,164,194,0,0,166,194,0,0,168,194,0,0,170,194,0,0,172,194,0,0,174,194,0,0,176,194,0,0,176,194,0,0,178,194,0,0,178,194,0,0,180,194,0,0,182,194,0,0,182,194,0,0,184,194,0,0,186,194,0,0,188,194,0,0,190,194,0,0,192,194,0,0,192,194,0,0,194,194,0,0,196,194,0,0,196,194,0,0,198,194,0,0,198,194,0,0,200,194,0,0,200,194,0,0,202,194,0,0,204,194,0,0,206,194,0,0,208,194,0,0,212,194,0,0,214,194,0,0,214,194,0,0,214,194,0,0,214,194,0,0,210,194,0,0,206,194,0,0,204,194,0,0,202,194,0,0,198,194,0,0,196,194,0,0,192,194,0,0,190,194,0,0,190,194,0,0,192,194,0,0,194,194,0,0,192,194,0,0,190,194,0,0,186,194,0,0,180,194,0,0,160,194,0,0,140,194,0,0,72,194,0,0,32,194,0,0,240,193,0,0,240,193,0,0,240,193,0,0,240,193,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,63,0,0,0,0,0,0,240,63,0,0,0,0,0,0,248,63,0,0,0,0,0,0,4,64,0,0,0,0,0,0,18,64,0,0,0,0,0,0,33,64,0,0,0,0,0,128,48,64,0,0,0,4,107,244,52,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,63,0,0,0,0,0,0,240,63,0,0,0,0,0,0,248,63,0,0,0,0,0,0,0,64,0,0,0,0,0,0,4,64,0,0,0,0,0,0,18,64,0,0,0,0,0,0,33,64,0,0,0,4,107,244,52,66,118,111,114,98,105,115,0,0,24,0,120,58,76,70,11,60,242,204,192,60,116,252,59,61,86,73,154,61,241,93,228,61,248,163,29,62,180,231,78,62,54,157,130,62,78,220,159,62,193,174,190,62,65,132,222,62,173,194,254,62,186,101,15,63,248,0,31,63,29,233,45,63,249,219,59,63,45,162,72,63,160,17,84,63,38,15,94,63,46,143,102,63,112,149,109,63,174,51,115,63,159,135,119,63,66,184,122,63,196,242,124,63,75,103,126,63,196,69,127,63,241,186,127,63,217,237,127,63,162,253,127,63,248,255,127,63,168,9,120,57,17,119,11,59,135,139,193,59,74,113,61,60,148,82,156,60,94,8,233,60,42,83,34,61,74,118,87,61,138,227,137,61,7,140,171,61,34,154,208,61,108,239,248,61,164,52,18,62,100,112,41,62,65,21,66,62,67,11,92,62,47,56,119,62,197,191,137,62,92,97,152,62,135,112,167,62,4,220,182,62,188,145,198,62,231,126,214,62,48,144,230,62,227,177,246,62,13,104,3,63,121,107,11,63,98,89,19,63,42,40,27,63,137,206,34,63,166,67,42,63,49,127,49,63,126,121,56,63,153,43,63,63,92,143,69,63,127,159,75,63,165,87,81,63,104,180,86,63,89,179,91,63,8,83,96,63,252,146,100,63,177,115,104,63,138,246,107,63,198,29,111,63,109,236,113,63,62,102,116,63,154,143,118,63,104,109,120,63,3,5,122,63,26,92,123,63,153,120,124,63,143,96,125,63,17,26,126,63,39,171,126,63,176,25,127,63,74,107,127,63,68,165,127,63,132,204,127,63,123,229,127,63,17,244,127,63,158,251,127,63,219,254,127,63,218,255,127,63,0,0,128,63,5,12,120,56,50,131,11,58,118,186,193,58,226,203,61,59,38,207,156,59,139,32,234,59,245,102,35,60,63,100,89,60,184,127,139,60,59,23,174,60,239,114,212,60,96,140,254,60,45,46,22,61,114,237,46,61,155,127,73,61,220,223,101,61,123,4,130,61,159,250,145,61,71,207,162,61,38,127,180,61,173,6,199,61,16,98,218,61,63,141,238,61,244,193,1,62,185,160,12,62,128,224,23,62,182,126,35,62,166,120,47,62,116,203,59,62,34,116,72,62,141,111,85,62,107,186,98,62,83,81,112,62,180,48,126,62,110,42,134,62,252,92,141,62,9,174,148,62,138,27,156,62,100,163,163,62,112,67,171,62,119,249,178,62,54,195,186,62,93,158,194,62,147,136,202,62,118,127,210,62,154,128,218,62,142,137,226,62,217,151,234,62,2,169,242,62,139,186,250,62,251,100,1,63,99,106,5,63,65,108,9,63,89,105,13,63,116,96,17,63,94,80,21,63,231,55,25,63,231,21,29,63,58,233,32,63,197,176,36,63,116,107,40,63,62,24,44,63,35,182,47,63,43,68,51,63,109,193,54,63,10,45,58,63,48,134,61,63,26,204,64,63,17,254,67,63,107,27,71,63,142,35,74,63,238,21,77,63,15,242,79,63,132,183,82,63,239,101,85,63,3,253,87,63,129,124,90,63,60,228,92,63,21,52,95,63,254,107,97,63,246,139,99,63,14,148,101,63,98,132,103,63,33,93,105,63,133,30,107,63,213,200,108,63,103,92,110,63,155,217,111,63,224,64,113,63,172,146,114,63,131,207,115,63,241,247,116,63,139,12,118,63,239,13,119,63,193,252,119,63,172,217,120,63,99,165,121,63,155,96,122,63,15,12,123,63,124,168,123,63,163,54,124,63,71,183,124,63,41,43,125,63,13,147,125,63,183,239,125,63,229,65,126,63,89,138,126,63,205,201,126,63,251,0,127,63,150,48,127,63,78,89,127,63,205,123,127,63,182,152,127,63,167,176,127,63,53,196,127,63,239,211,127,63,91,224,127,63,245,233,127,63,51,241,127,63,127,246,127,63,59,250,127,63,190,252,127,63,84,254,127,63,64,255,127,63,186,255,127,63,238,255,127,63,254,255,127,63,0,0,128,63,169,12,120,55,54,134,11,57,38,198,193,57,94,226,61,58,234,237,156,58,85,101,234,58,56,170,35,59,207,219,89,59,169,226,139,59,42,178,174,59,13,91,213,59,204,219,255,59,91,25,23,60,250,46,48,60,194,45,75,60,156,20,104,60,46,113,131,60,225,202,147,60,185,22,165,60,1,84,183,60,245,129,202,60,198,159,222,60,155,172,243,60,199,211,4,61,213,71,16,61,250,49,28,61,174,145,40,61,101,102,53,61,141,175,66,61,140,108,80,61,193,156,94,61,133,63,109,61,41,84,124,61,252,236,133,61,26,232,141,61,13,27,150,61,110,133,158,61,212,38,167,61,210,254,175,61,245,12,185,61,200,80,194,61,209,201,203,61,146,119,213,61,139,89,223,61,51,111,233,61,2,184,243,61,105,51,254,61,106,112,4,62,214,223,9,62,171,103,15,62,153,7,21,62,77,191,26,62,116,142,32,62,181,116,38,62,184,113,44,62,34,133,50,62,149,174,56,62,178,237,62,62,21,66,69,62,92,171,75,62,30,41,82,62,243,186,88,62,112,96,95,62,40,25,102,62,170,228,108,62,132,194,115,62,68,178,122,62,185,217,128,62,203,98,132,62,26,244,135,62,105,141,139,62,120,46,143,62,6,215,146,62,211,134,150,62,156,61,154,62,29,251,157,62,19,191,161,62,57,137,165,62,71,89,169,62,249,46,173,62,5,10,177,62,36,234,180,62,13,207,184,62,117,184,188,62,18,166,192,62,153,151,196,62,190,140,200,62,52,133,204,62,175,128,208,62,225,126,212,62,125,127,216,62,52,130,220,62,184,134,224,62,185,140,228,62,233,147,232,62,248,155,236,62,150,164,240,62,117,173,244,62,67,182,248,62,178,190,252,62,57,99,0,63,153,102,2,63,82,105,4,63,60,107,6,63,48,108,8,63,6,108,10,63,151,106,12,63,188,103,14,63,78,99,16,63,39,93,18,63,33,85,20,63,21,75,22,63,222,62,24,63,87,48,26,63,92,31,28,63,199,11,30,63,117,245,31,63,66,220,33,63,12,192,35,63,176,160,37,63,12,126,39,63,254,87,41,63,104,46,43,63,39,1,45,63,29,208,46,63,43,155,48,63,51,98,50,63,23,37,52,63,188,227,53,63,4,158,55,63,214,83,57,63,23,5,59,63,173,177,60,63,128,89,62,63,120,252,63,63,126,154,65,63,124,51,67,63,93,199,68,63,12,86,70,63,119,223,71,63,138,99,73,63,54,226,74,63,104,91,76,63,17,207,77,63,35,61,79,63,145,165,80,63,76,8,82,63,75,101,83,63,130,188,84,63,231,13,86,63,114,89,87,63,26,159,88,63,218,222,89,63,172,24,91,63,138,76,92,63,113,122,93,63,93,162,94,63,78,196,95,63,67,224,96,63,58,246,97,63,54,6,99,63,56,16,100,63,67,20,101,63,92,18,102,63,133,10,103,63,198,252,103,63,37,233,104,63,168,207,105,63,89,176,106,63,64,139,107,63,102,96,108,63,216,47,109,63,159,249,109,63,201,189,110,63,97,124,111,63,118,53,112,63,23,233,112,63,81,151,113,63,53,64,114,63,212,227,114,63,61,130,115,63,131,27,116,63,184,175,116,63,238,62,117,63,56,201,117,63,171,78,118,63,90,207,118,63,90,75,119,63,192,194,119,63,162,53,120,63,21,164,120,63,48,14,121,63,8,116,121,63,182,213,121,63,79,51,122,63,235,140,122,63,162,226,122,63,139,52,123,63,191,130,123,63,85,205,123,63,102,20,124,63,9,88,124,63,88,152,124,63,106,213,124,63,88,15,125,63,58,70,125,63,41,122,125,63,62,171,125,63,143,217,125,63,54,5,126,63,75,46,126,63,228,84,126,63,27,121,126,63,7,155,126,63,190,186,126,63,88,216,126,63,236,243,126,63,144,13,127,63,91,37,127,63,99,59,127,63,188,79,127,63,125,98,127,63,185,115,127,63,135,131,127,63,249,145,127,63,36,159,127,63,26,171,127,63,238,181,127,63,179,191,127,63,122,200,127,63,85,208,127,63,84,215,127,63,136,221,127,63,0,227,127,63,204,231,127,63,249,235,127,63,150,239,127,63,177,242,127,63,85,245,127,63,144,247,127,63,109,249,127,63,246,250,127,63,54,252,127,63,55,253,127,63,1,254,127,63,156,254,127,63,18,255,127,63,103,255,127,63,163,255,127,63,204,255,127,63,229,255,127,63,244,255,127,63,252,255,127,63,255,255,127,63,0,0,128,63,0,0,128,63,60,12,120,54,253,134,11,56,19,201,193,56,248,231,61,57,148,245,156,57,115,118,234,57,238,186,35,58,113,249,89,58,32,251,139,58,96,216,174,58,34,148,213,58,3,23,0,59,209,82,23,59,65,125,48,59,21,150,75,59,8,157,104,59,233,200,131,59,20,58,148,59,218,161,165,59,16,0,184,59,136,84,203,59,16,159,223,59,118,223,244,59,194,138,5,60,128,32,17,60,217,48,29,60,172,187,41,60,219,192,54,60,67,64,68,60,194,57,82,60,52,173,96,60,115,154,111,60,88,1,127,60,222,112,135,60,186,157,143,60,42,7,152,60,25,173,160,60,112,143,169,60,23,174,178,60,246,8,188,60,243,159,197,60,245,114,207,60,225,129,217,60,156,204,227,60,10,83,238,60,14,21,249,60,70,9,2,61,177,165,7,61,187,95,13,61,81,55,19,61,102,44,25,61,230,62,31,61,195,110,37,61,233,187,43,61,71,38,50,61,202,173,56,61,97,82,63,61,247,19,70,61,121,242,76,61,210,237,83,61,240,5,91,61,187,58,98,61,32,140,105,61,8,250,112,61,93,132,120,61,132,21,128,61,249,246,131,61,130,230,135,61,19,228,139,61,159,239,143,61,26,9,148,61,119,48,152,61,169,101,156,61,163,168,160,61,88,249,164,61,186,87,169,61,186,195,173,61,76,61,178,61,95,196,182,61,230,88,187,61,209,250,191,61,18,170,196,61,152,102,201,61,85,48,206,61,56,7,211,61,48,235,215,61,47,220,220,61,34,218,225,61,248,228,230,61,161,252,235,61,11,33,241,61,35,82,246,61,217,143,251,61,13,109,0,62,105,24,3,62,247,201,5,62,174,129,8,62,133,63,11,62,113,3,14,62,104,205,16,62,96,157,19,62,79,115,22,62,42,79,25,62,232,48,28,62,124,24,31,62,221,5,34,62,255,248,36,62,215,241,39,62,90,240,42,62,125,244,45,62,51,254,48,62,114,13,52,62,45,34,55,62,88,60,58,62,232,91,61,62,208,128,64,62,3,171,67,62,118,218,70,62,26,15,74,62,229,72,77,62,199,135,80,62,181,203,83,62,162,20,87,62,127,98,90,62,63,181,93,62,213,12,97,62,50,105,100,62,73,202,103,62,12,48,107,62,108,154,110,62,92,9,114,62,203,124,117,62,173,244,120,62,241,112,124,62,138,241,127,62,52,187,129,62,190,127,131,62,91,70,133,62,4,15,135,62,176,217,136,62,89,166,138,62,245,116,140,62,126,69,142,62,234,23,144,62,50,236,145,62,78,194,147,62,54,154,149,62,224,115,151,62,70,79,153,62,93,44,155,62,31,11,157,62,130,235,158,62,127,205,160,62,11,177,162,62,31,150,164,62,177,124,166,62,186,100,168,62,47,78,170,62,9,57,172,62,62,37,174,62,198,18,176,62,150,1,178,62,167,241,179,62,238,226,181,62,100,213,183,62,254,200,185,62,179,189,187,62,122,179,189,62,74,170,191,62,25,162,193,62,221,154,195,62,142,148,197,62,34,143,199,62,142,138,201,62,203,134,203,62,205,131,205,62,140,129,207,62,253,127,209,62,24,127,211,62,210,126,213,62,33,127,215,62,252,127,217,62,88,129,219,62,45,131,221,62,112,133,223,62,23,136,225,62,25,139,227,62,108,142,229,62,5,146,231,62,219,149,233,62,228,153,235,62,21,158,237,62,102,162,239,62,203,166,241,62,59,171,243,62,173,175,245,62,21,180,247,62,107,184,249,62,164,188,251,62,181,192,253,62,150,196,255,62,30,228,0,63,207,229,1,63,88,231,2,63,182,232,3,63,226,233,4,63,215,234,5,63,146,235,6,63,12,236,7,63,66,236,8,63,45,236,9,63,202,235,10,63,19,235,11,63,4,234,12,63,151,232,13,63,200,230,14,63,145,228,15,63,239,225,16,63,220,222,17,63,84,219,18,63,81,215,19,63,208,210,20,63,202,205,21,63,61,200,22,63,34,194,23,63,117,187,24,63,50,180,25,63,85,172,26,63,215,163,27,63,182,154,28,63,236,144,29,63,117,134,30,63,77,123,31,63,110,111,32,63,214,98,33,63,126,85,34,63,100,71,35,63,130,56,36,63,212,40,37,63,87,24,38,63,5,7,39,63,219,244,39,63,213,225,40,63,239,205,41,63,36,185,42,63,113,163,43,63,209,140,44,63,64,117,45,63,188,92,46,63,63,67,47,63,199,40,48,63,78,13,49,63,211,240,49,63,80,211,50,63,195,180,51,63,39,149,52,63,122,116,53,63,184,82,54,63,220,47,55,63,229,11,56,63,206,230,56,63,149,192,57,63,54,153,58,63,174,112,59,63,249,70,60,63,21,28,61,63,255,239,61,63,179,194,62,63,48,148,63,63,113,100,64,63,116,51,65,63,55,1,66,63,182,205,66,63,239,152,67,63,224,98,68,63,134,43,69,63,222,242,69,63,230,184,70,63,156,125,71,63,253,64,72,63,7,3,73,63,184,195,73,63,14,131,74,63,6,65,75,63,159,253,75,63,215,184,76,63,172,114,77,63,28,43,78,63,38,226,78,63,199,151,79,63,253,75,80,63,201,254,80,63,39,176,81,63,22,96,82,63,150,14,83,63,164,187,83,63,63,103,84,63,103,17,85,63,26,186,85,63,86,97,86,63,28,7,87,63,105,171,87,63,62,78,88,63,152,239,88,63,120,143,89,63,221,45,90,63,198,202,90,63,50,102,91,63,33,0,92,63,147,152,92,63,134,47,93,63,251,196,93,63,242,88,94,63,105,235,94,63,98,124,95,63,219,11,96,63,213,153,96,63,80,38,97,63,76,177,97,63,201,58,98,63,199,194,98,63,70,73,99,63,71,206,99,63,202,81,100,63,208,211,100,63,88,84,101,63,100,211,101,63,244,80,102,63,9,205,102,63,163,71,103,63,195,192,103,63,107,56,104,63,154,174,104,63,82,35,105,63,147,150,105,63,96,8,106,63,184,120,106,63,157,231,106,63,16,85,107,63,19,193,107,63,166,43,108,63,203,148,108,63,132,252,108,63,209,98,109,63,180,199,109,63,48,43,110,63,68,141,110,63,244,237,110,63,64,77,111,63,42,171,111,63,181,7,112,63,225,98,112,63,177,188,112,63,38,21,113,63,67,108,113,63,10,194,113,63,123,22,114,63,155,105,114,63,106,187,114,63,234,11,115,63,31,91,115,63,9,169,115,63,172,245,115,63,9,65,116,63,35,139,116,63,252,211,116,63,151,27,117,63,245,97,117,63,26,167,117,63,8,235,117,63,193,45,118,63,72,111,118,63,159,175,118,63,202,238,118,63,201,44,119,63,161,105,119,63,84,165,119,63,228,223,119,63,85,25,120,63,168,81,120,63,226,136,120,63,3,191,120,63,16,244,120,63,11,40,121,63,247,90,121,63,215,140,121,63,173,189,121,63,125,237,121,63,73,28,122,63,20,74,122,63,226,118,122,63,181,162,122,63,144,205,122,63,118,247,122,63,107,32,123,63,112,72,123,63,138,111,123,63,186,149,123,63,5,187,123,63,109,223,123,63,245,2,124,63,160,37,124,63,113,71,124,63,108,104,124,63,147,136,124,63,233,167,124,63,114,198,124,63,48,228,124,63,38,1,125,63,89,29,125,63,201,56,125,63,124,83,125,63,115,109,125,63,178,134,125,63,60,159,125,63,19,183,125,63,60,206,125,63,184,228,125,63,139,250,125,63,184,15,126,63,66,36,126,63,44,56,126,63,120,75,126,63,43,94,126,63,70,112,126,63,204,129,126,63,194,146,126,63,41,163,126,63,4,179,126,63,86,194,126,63,35,209,126,63,109,223,126,63,55,237,126,63,131,250,126,63,85,7,127,63,175,19,127,63,148,31,127,63,7,43,127,63,10,54,127,63,160,64,127,63,205,74,127,63,146,84,127,63,242,93,127,63,239,102,127,63,141,111,127,63,206,119,127,63,181,127,127,63,67,135,127,63,124,142,127,63,98,149,127,63,247,155,127,63,61,162,127,63,56,168,127,63,233,173,127,63,83,179,127,63,120,184,127,63,90,189,127,63,252,193,127,63,95,198,127,63,134,202,127,63,116,206,127,63,41,210,127,63,168,213,127,63,244,216,127,63,13,220,127,63,247,222,127,63,179,225,127,63,67,228,127,63,168,230,127,63,229,232,127,63,252,234,127,63,237,236,127,63,188,238,127,63,105,240,127,63,246,241,127,63,101,243,127,63,183,244,127,63,238,245,127,63,11,247,127,63,16,248,127,63,254,248,127,63,214,249,127,63,155,250,127,63,76,251,127,63,236,251,127,63,124,252,127,63,252,252,127,63,110,253,127,63,211,253,127,63,44,254,127,63,121,254,127,63,189,254,127,63,247,254,127,63,42,255,127,63,84,255,127,63,120,255,127,63,150,255,127,63,175,255,127,63,195,255,127,63,211,255,127,63,224,255,127,63,234,255,127,63,241,255,127,63,246,255,127,63,250,255,127,63,253,255,127,63,254,255,127,63,255,255,127,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,171,15,120,53,24,135,11,55,225,201,193,55,107,233,61,56,128,247,156,56,187,122,234,56,24,191,35,57,213,0,90,57,56,1,140,57,229,225,174,57,88,162,213,57,60,33,0,58,24,97,23,58,175,144,48,58,243,175,75,58,212,190,104,58,159,222,131,58,143,85,148,58,48,196,165,58,119,42,184,58,90,136,203,58,204,221,223,58,191,42,245,58,148,183,5,59,124,85,17,59,16,111,29,59,73,4,42,59,31,21,55,59,138,161,68,59,129,169,82,59,252,44,97,59,241,43,112,59,88,166,127,59,19,206,135,59,169,6,144,59,233,124,152,59,204,48,161,59,79,34,170,59,106,81,179,59,26,190,188,59,86,104,198,59,26,80,208,59,95,117,218,59,31,216,228,59,83,120,239,59,244,85,250,59,126,184,2,60,177,100,8,60,145,47,14,60,25,25,20,60,70,33,26,60,19,72,32,60,126,141,38,60,129,241,44,60,25,116,51,60,65,21,58,60,246,212,64,60,50,179,71,60,243,175,78,60,50,203,85,60,235,4,93,60,26,93,100,60,186,211,107,60,198,104,115,60,58,28,123,60,7,119,129,60,33,111,133,60,102,118,137,60,212,140,141,60,105,178,145,60,33,231,149,60,251,42,154,60,243,125,158,60,6,224,162,60,50,81,167,60,115,209,171,60,199,96,176,60,43,255,180,60,154,172,185,60,19,105,190,60,146,52,195,60,20,15,200,60,149,248,204,60,19,241,209,60,137,248,214,60,245,14,220,60,83,52,225,60,160,104,230,60,215,171,235,60,246,253,240,60,249,94,246,60,220,206,251,60,205,166,0,61,153,109,3,61,207,59,6,61,109,17,9,61,114,238,11,61,220,210,14,61,167,190,17,61,211,177,20,61,94,172,23,61,68,174,26,61,133,183,29,61,30,200,32,61,12,224,35,61,78,255,38,61,225,37,42,61,196,83,45,61,243,136,48,61,109,197,51,61,47,9,55,61,55,84,58,61,130,166,61,61,15,0,65,61,218,96,68,61,226,200,71,61,35,56,75,61,156,174,78,61,73,44,82,61,40,177,85,61,55,61,89,61,115,208,92,61,217,106,96,61,103,12,100,61,25,181,103,61,238,100,107,61,227,27,111,61,244,217,114,61,30,159,118,61,96,107,122,61,182,62,126,61,143,12,129,61,73,253,130,61,138,241,132,61,79,233,134,61,150,228,136,61,94,227,138,61,167,229,140,61,109,235,142,61,175,244,144,61,109,1,147,61,164,17,149,61,83,37,151,61,120,60,153,61,17,87,155,61,30,117,157,61,155,150,159,61,136,187,161,61,226,227,163,61,169,15,166,61,218,62,168,61,116,113,170,61,116,167,172,61,218,224,174,61,162,29,177,61,205,93,179,61,87,161,181,61,62,232,183,61,130,50,186,61,32,128,188,61,22,209,190,61,98,37,193,61,2,125,195,61,245,215,197,61,57,54,200,61,203,151,202,61,169,252,204,61,211,100,207,61,68,208,209,61,252,62,212,61,249,176,214,61,56,38,217,61,184,158,219,61,117,26,222,61,111,153,224,61,163,27,227,61,14,161,229,61,175,41,232,61,132,181,234,61,138,68,237,61,191,214,239,61,33,108,242,61,174,4,245,61,99,160,247,61,62,63,250,61,61,225,252,61,93,134,255,61,78,23,1,62,252,108,2,62,56,196,3,62,255,28,5,62,81,119,6,62,45,211,7,62,145,48,9,62,125,143,10,62,238,239,11,62,228,81,13,62,94,181,14,62,89,26,16,62,214,128,17,62,210,232,18,62,77,82,20,62,69,189,21,62,184,41,23,62,166,151,24,62,13,7,26,62,236,119,27,62,65,234,28,62,11,94,30,62,73,211,31,62,250,73,33,62,28,194,34,62,173,59,36,62,172,182,37,62,24,51,39,62,240,176,40,62,50,48,42,62,220,176,43,62,238,50,45,62,101,182,46,62,64,59,48,62,126,193,49,62,30,73,51,62,29,210,52,62,123,92,54,62,54,232,55,62,76,117,57,62,187,3,59,62,131,147,60,62,162,36,62,62,22,183,63,62,222,74,65,62,248,223,66,62,98,118,68,62,28,14,70,62,35,167,71,62,117,65,73,62,18,221,74,62,247,121,76,62,35,24,78,62,149,183,79,62,74,88,81,62,66,250,82,62,121,157,84,62,240,65,86,62,163,231,87,62,146,142,89,62,186,54,91,62,26,224,92,62,177,138,94,62,124,54,96,62,122,227,97,62,169,145,99,62,7,65,101,62,147,241,102,62,75,163,104,62,44,86,106,62,54,10,108,62,102,191,109,62,187,117,111,62,51,45,113,62,204,229,114,62,132,159,116,62,90,90,118,62,75,22,120,62,85,211,121,62,120,145,123,62,176,80,125,62,253,16,127,62,46,105,128,62,101,74,129,62,36,44,130,62,105,14,131,62,52,241,131,62,130,212,132,62,84,184,133,62,169,156,134,62,127,129,135,62,213,102,136,62,171,76,137,62,255,50,138,62,209,25,139,62,32,1,140,62,233,232,140,62,46,209,141,62,236,185,142,62,34,163,143,62,208,140,144,62,244,118,145,62,142,97,146,62,156,76,147,62,29,56,148,62,17,36,149,62,118,16,150,62,76,253,150,62,144,234,151,62,67,216,152,62,99,198,153,62,239,180,154,62,230,163,155,62,71,147,156,62,17,131,157,62,67,115,158,62,219,99,159,62,218,84,160,62,60,70,161,62,3,56,162,62,43,42,163,62,181,28,164,62,160,15,165,62,233,2,166,62,145,246,166,62,149,234,167,62,245,222,168,62,176,211,169,62,197,200,170,62,50,190,171,62,246,179,172,62,17,170,173,62,129,160,174,62,69,151,175,62,91,142,176,62,196,133,177,62,125,125,178,62,133,117,179,62,220,109,180,62,128,102,181,62,112,95,182,62,171,88,183,62,47,82,184,62,252,75,185,62,17,70,186,62,108,64,187,62,11,59,188,62,239,53,189,62,22,49,190,62,126,44,191,62,38,40,192,62,13,36,193,62,51,32,194,62,150,28,195,62,52,25,196,62,12,22,197,62,30,19,198,62,104,16,199,62,233,13,200,62,159,11,201,62,138,9,202,62,169,7,203,62,249,5,204,62,123,4,205,62,44,3,206,62,11,2,207,62,24,1,208,62,81,0,209,62,181,255,209,62,66,255,210,62,248,254,211,62,213,254,212,62,216,254,213,62,255,254,214,62,75,255,215,62,184,255,216,62,71,0,218,62,245,0,219,62,195,1,220,62,173,2,221,62,180,3,222,62,214,4,223,62,17,6,224,62,101,7,225,62,208,8,226,62,81,10,227,62,231,11,228,62,144,13,229,62,76,15,230,62,25,17,231,62,245,18,232,62,224,20,233,62,217,22,234,62,221,24,235,62,236,26,236,62,5,29,237,62,39,31,238,62,79,33,239,62,125,35,240,62,176,37,241,62,230,39,242,62,31,42,243,62,88,44,244,62,145,46,245,62,200,48,246,62,253,50,247,62,45,53,248,62,88,55,249,62,124,57,250,62,153,59,251,62,172,61,252,62,181,63,253,62,179,65,254,62,163,67,255,62,195,34,0,63,173,163,0,63,142,36,1,63,102,165,1,63,53,38,2,63,250,166,2,63,180,39,3,63,99,168,3,63,5,41,4,63,155,169,4,63,36,42,5,63,159,170,5,63,12,43,6,63,105,171,6,63,183,43,7,63,244,171,7,63,32,44,8,63,59,172,8,63,68,44,9,63,58,172,9,63,28,44,10,63,235,171,10,63,164,43,11,63,73,171,11,63,216,42,12,63,80,170,12,63,177,41,13,63,251,168,13,63,44,40,14,63,69,167,14,63,68,38,15,63,41,165,15,63,243,35,16,63,162,162,16,63,53,33,17,63,172,159,17,63,5,30,18,63,65,156,18,63,95,26,19,63,94,152,19,63,61,22,20,63,252,147,20,63,155,17,21,63,24,143,21,63,116,12,22,63,173,137,22,63,195,6,23,63,182,131,23,63,133,0,24,63,46,125,24,63,179,249,24,63,18,118,25,63,74,242,25,63,91,110,26,63,69,234,26,63,6,102,27,63,159,225,27,63,14,93,28,63,84,216,28,63,111,83,29,63,95,206,29,63,36,73,30,63,188,195,30,63,40,62,31,63,102,184,31,63,119,50,32,63,90,172,32,63,14,38,33,63,146,159,33,63,230,24,34,63,10,146,34,63,253,10,35,63,190,131,35,63,77,252,35,63,169,116,36,63,211,236,36,63,200,100,37,63,138,220,37,63,22,84,38,63,110,203,38,63,143,66,39,63,122,185,39,63,47,48,40,63,172,166,40,63,241,28,41,63,254,146,41,63,210,8,42,63,108,126,42,63,205,243,42,63,243,104,43,63,223,221,43,63,143,82,44,63,3,199,44,63,59,59,45,63,54,175,45,63,244,34,46,63,116,150,46,63,182,9,47,63,185,124,47,63,125,239,47,63,1,98,48,63,69,212,48,63,72,70,49,63,10,184,49,63,139,41,50,63,202,154,50,63,198,11,51,63,127,124,51,63,246,236,51,63,40,93,52,63,22,205,52,63,191,60,53,63,36,172,53,63,66,27,54,63,27,138,54,63,174,248,54,63,249,102,55,63,254,212,55,63,187,66,56,63,47,176,56,63,91,29,57,63,63,138,57,63,217,246,57,63,41,99,58,63,48,207,58,63,236,58,59,63,93,166,59,63,130,17,60,63,93,124,60,63,235,230,60,63,44,81,61,63,33,187,61,63,201,36,62,63,35,142,62,63,48,247,62,63,238,95,63,63,94,200,63,63,126,48,64,63,80,152,64,63,209,255,64,63,3,103,65,63,228,205,65,63,117,52,66,63,181,154,66,63,163,0,67,63,64,102,67,63,139,203,67,63,131,48,68,63,41,149,68,63,124,249,68,63,123,93,69,63,39,193,69,63,127,36,70,63,132,135,70,63,51,234,70,63,142,76,71,63,148,174,71,63,68,16,72,63,159,113,72,63,164,210,72,63,83,51,73,63,172,147,73,63,174,243,73,63,89,83,74,63,173,178,74,63,169,17,75,63,77,112,75,63,154,206,75,63,143,44,76,63,43,138,76,63,110,231,76,63,89,68,77,63,234,160,77,63,34,253,77,63,0,89,78,63,133,180,78,63,176,15,79,63,128,106,79,63,246,196,79,63,18,31,80,63,210,120,80,63,56,210,80,63,66,43,81,63,242,131,81,63,69,220,81,63,61,52,82,63,217,139,82,63,24,227,82,63,252,57,83,63,131,144,83,63,174,230,83,63,123,60,84,63,236,145,84,63,0,231,84,63,183,59,85,63,16,144,85,63,12,228,85,63,170,55,86,63,235,138,86,63,206,221,86,63,83,48,87,63,121,130,87,63,66,212,87,63,172,37,88,63,184,118,88,63,101,199,88,63,180,23,89,63,164,103,89,63,53,183,89,63,104,6,90,63,59,85,90,63,175,163,90,63,197,241,90,63,123,63,91,63,210,140,91,63,201,217,91,63,97,38,92,63,154,114,92,63,115,190,92,63,237,9,93,63,7,85,93,63,194,159,93,63,29,234,93,63,24,52,94,63,179,125,94,63,239,198,94,63,203,15,95,63,72,88,95,63,100,160,95,63,33,232,95,63,126,47,96,63,123,118,96,63,24,189,96,63,85,3,97,63,51,73,97,63,177,142,97,63,207,211,97,63,141,24,98,63,236,92,98,63,235,160,98,63,138,228,98,63,202,39,99,63,170,106,99,63,42,173,99,63,75,239,99,63,13,49,100,63,111,114,100,63,114,179,100,63,21,244,100,63,90,52,101,63,63,116,101,63,197,179,101,63,236,242,101,63,180,49,102,63,29,112,102,63,39,174,102,63,211,235,102,63,32,41,103,63,15,102,103,63,159,162,103,63,209,222,103,63,164,26,104,63,26,86,104,63,49,145,104,63,235,203,104,63,71,6,105,63,69,64,105,63,230,121,105,63,42,179,105,63,16,236,105,63,153,36,106,63,197,92,106,63,148,148,106,63,7,204,106,63,29,3,107,63,214,57,107,63,52,112,107,63,53,166,107,63,218,219,107,63,36,17,108,63,18,70,108,63,164,122,108,63,220,174,108,63,184,226,108,63,57,22,109,63,96,73,109,63,44,124,109,63,157,174,109,63,181,224,109,63,115,18,110,63,214,67,110,63,225,116,110,63,146,165,110,63,233,213,110,63,232,5,111,63,142,53,111,63,219,100,111,63,209,147,111,63,110,194,111,63,179,240,111,63,160,30,112,63,54,76,112,63,117,121,112,63,93,166,112,63,239,210,112,63,41,255,112,63,14,43,113,63,156,86,113,63,213,129,113,63,184,172,113,63,70,215,113,63,127,1,114,63,99,43,114,63,243,84,114,63,46,126,114,63,21,167,114,63,169,207,114,63,233,247,114,63,214,31,115,63,113,71,115,63,184,110,115,63,173,149,115,63,80,188,115,63,162,226,115,63,161,8,116,63,80,46,116,63,174,83,116,63,187,120,116,63,119,157,116,63,228,193,116,63,1,230,116,63,206,9,117,63,76,45,117,63,123,80,117,63,92,115,117,63,238,149,117,63,51,184,117,63,42,218,117,63,211,251,117,63,48,29,118,63,64,62,118,63,3,95,118,63,122,127,118,63,166,159,118,63,134,191,118,63,27,223,118,63,101,254,118,63,101,29,119,63,27,60,119,63,135,90,119,63,169,120,119,63,131,150,119,63,19,180,119,63,91,209,119,63,91,238,119,63,20,11,120,63,132,39,120,63,174,67,120,63,145,95,120,63,46,123,120,63,132,150,120,63,149,177,120,63,96,204,120,63,231,230,120,63,41,1,121,63,38,27,121,63,223,52,121,63,85,78,121,63,136,103,121,63,120,128,121,63,37,153,121,63,144,177,121,63,185,201,121,63,161,225,121,63,72,249,121,63,174,16,122,63,212,39,122,63,185,62,122,63,96,85,122,63,198,107,122,63,238,129,122,63,216,151,122,63,131,173,122,63,241,194,122,63,33,216,122,63,20,237,122,63,202,1,123,63,68,22,123,63,130,42,123,63,133,62,123,63,77,82,123,63,217,101,123,63,43,121,123,63,68,140,123,63,34,159,123,63,200,177,123,63,52,196,123,63,104,214,123,63,99,232,123,63,39,250,123,63,180,11,124,63,9,29,124,63,40,46,124,63,17,63,124,63,196,79,124,63,65,96,124,63,137,112,124,63,156,128,124,63,124,144,124,63,39,160,124,63,158,175,124,63,226,190,124,63,244,205,124,63,211,220,124,63,128,235,124,63,251,249,124,63,69,8,125,63,94,22,125,63,71,36,125,63,255,49,125,63,136,63,125,63,225,76,125,63,11,90,125,63,7,103,125,63,212,115,125,63,115,128,125,63,229,140,125,63,42,153,125,63,66,165,125,63,46,177,125,63,238,188,125,63,130,200,125,63,235,211,125,63,41,223,125,63,61,234,125,63,38,245,125,63,230,255,125,63,124,10,126,63,234,20,126,63,47,31,126,63,75,41,126,63,64,51,126,63,13,61,126,63,180,70,126,63,51,80,126,63,140,89,126,63,191,98,126,63,205,107,126,63,181,116,126,63,120,125,126,63,23,134,126,63,146,142,126,63,233,150,126,63,28,159,126,63,44,167,126,63,26,175,126,63,229,182,126,63,142,190,126,63,22,198,126,63,124,205,126,63,194,212,126,63,231,219,126,63,235,226,126,63,208,233,126,63,149,240,126,63,59,247,126,63,195,253,126,63,44,4,127,63,118,10,127,63,163,16,127,63,179,22,127,63,165,28,127,63,123,34,127,63,52,40,127,63,210,45,127,63,83,51,127,63,186,56,127,63,5,62,127,63,53,67,127,63,75,72,127,63,72,77,127,63,42,82,127,63,243,86,127,63,163,91,127,63,58,96,127,63,185,100,127,63,32,105,127,63,111,109,127,63,166,113,127,63,199,117,127,63,208,121,127,63,196,125,127,63,161,129,127,63,104,133,127,63,25,137,127,63,182,140,127,63,61,144,127,63,176,147,127,63,14,151,127,63,89,154,127,63,143,157,127,63,179,160,127,63,195,163,127,63,192,166,127,63,171,169,127,63,132,172,127,63,74,175,127,63,255,177,127,63,163,180,127,63,53,183,127,63,183,185,127,63,40,188,127,63,137,190,127,63,217,192,127,63,26,195,127,63,76,197,127,63,111,199,127,63,130,201,127,63,135,203,127,63,126,205,127,63,102,207,127,63,65,209,127,63,14,211,127,63,205,212,127,63,128,214,127,63,38,216,127,63,191,217,127,63,76,219,127,63,204,220,127,63,65,222,127,63,170,223,127,63,8,225,127,63,91,226,127,63,163,227,127,63,224,228,127,63,19,230,127,63,59,231,127,63,90,232,127,63,110,233,127,63,122,234,127,63,124,235,127,63,116,236,127,63,100,237,127,63,75,238,127,63,42,239,127,63,1,240,127,63,207,240,127,63,149,241,127,63,84,242,127,63,12,243,127,63,188,243,127,63,101,244,127,63,7,245,127,63,162,245,127,63,55,246,127,63,198,246,127,63,78,247,127,63,209,247,127,63,77,248,127,63,196,248,127,63,54,249,127,63,162,249,127,63,9,250,127,63,108,250,127,63,201,250,127,63,34,251,127,63,118,251,127,63,198,251,127,63,18,252,127,63,89,252,127,63,157,252,127,63,221,252,127,63,26,253,127,63,83,253,127,63,136,253,127,63,187,253,127,63,234,253,127,63,22,254,127,63,64,254,127,63,103,254,127,63,139,254,127,63,173,254,127,63,204,254,127,63,234,254,127,63,5,255,127,63,30,255,127,63,53,255,127,63,74,255,127,63,94,255,127,63,112,255,127,63,128,255,127,63,143,255,127,63,157,255,127,63,169,255,127,63,180,255,127,63,191,255,127,63,200,255,127,63,208,255,127,63,215,255,127,63,221,255,127,63,227,255,127,63,232,255,127,63,236,255,127,63,239,255,127,63,243,255,127,63,245,255,127,63,248,255,127,63,249,255,127,63,251,255,127,63,252,255,127,63,253,255,127,63,254,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,204,8,120,52,171,134,11,54,79,202,193,54,190,233,61,55,238,247,156,55,192,123,234,55,43,192,35,56,161,2,90,56,189,2,140,56,76,228,174,56,227,165,213,56,199,35,0,57,168,100,23,57,134,149,48,57,104,182,75,57,64,199,104,57,7,228,131,57,105,92,148,57,191,204,165,57,6,53,184,57,65,149,203,57,105,237,223,57,120,61,245,57,184,194,5,58,166,98,17,58,134,126,29,58,81,22,42,58,9,42,55,58,172,185,68,58,54,197,82,58,165,76,97,58,250,79,112,58,47,207,127,58,34,229,135,58,154,32,144,58,255,153,152,58,80,81,161,58,139,70,170,58,174,121,179,58,186,234,188,58,171,153,198,58,129,134,208,58,58,177,218,58,212,25,229,58,79,192,239,58,167,164,250,58,109,227,2,59,117,147,8,59,105,98,14,59,73,80,20,59,19,93,26,59,199,136,32,59,100,211,38,59,232,60,45,59,83,197,51,59,164,108,58,59,218,50,65,59,243,23,72,59,239,27,79,59,204,62,86,59,138,128,93,59,38,225,100,59,161,96,108,59,249,254,115,59,45,188,123,59,29,204,129,59,145,201,133,59,113,214,137,59,188,242,141,59,113,30,146,59,145,89,150,59,26,164,154,59,12,254,158,59,102,103,163,59,40,224,167,59,80,104,172,59,222,255,176,59,209,166,181,59,40,93,186,59,228,34,191,59,2,248,195,59,131,220,200,59,101,208,205,59,168,211,210,59,74,230,215,59,76,8,221,59,172,57,226,59,105,122,231,59,131,202,236,59,249,41,242,59,202,152,247,59,245,22,253,59,60,82,1,60,170,32,4,60,196,246,6,60,137,212,9,60,249,185,12,60,19,167,15,60,216,155,18,60,69,152,21,60,92,156,24,60,26,168,27,60,129,187,30,60,143,214,33,60,69,249,36,60,160,35,40,60,162,85,43,60,73,143,46,60,149,208,49,60,133,25,53,60,26,106,56,60,81,194,59,60,44,34,63,60,168,137,66,60,199,248,69,60,134,111,73,60,230,237,76,60,231,115,80,60,134,1,84,60,197,150,87,60,162,51,91,60,28,216,94,60,52,132,98,60,232,55,102,60,56,243,105,60,35,182,109,60,170,128,113,60,202,82,117,60,131,44,121,60,214,13,125,60,96,123,128,60,161,115,130,60,174,111,132,60,134,111,134,60,40,115,136,60,149,122,138,60,205,133,140,60,206,148,142,60,152,167,144,60,44,190,146,60,136,216,148,60,173,246,150,60,154,24,153,60,78,62,155,60,202,103,157,60,13,149,159,60,23,198,161,60,231,250,163,60,125,51,166,60,217,111,168,60,249,175,170,60,223,243,172,60,137,59,175,60,247,134,177,60,40,214,179,60,29,41,182,60,213,127,184,60,80,218,186,60,140,56,189,60,138,154,191,60,74,0,194,60,202,105,196,60,11,215,198,60,12,72,201,60,205,188,203,60,77,53,206,60,140,177,208,60,137,49,211,60,69,181,213,60,189,60,216,60,243,199,218,60,230,86,221,60,149,233,223,60,0,128,226,60,39,26,229,60,8,184,231,60,164,89,234,60,250,254,236,60,9,168,239,60,210,84,242,60,83,5,245,60,141,185,247,60,126,113,250,60,39,45,253,60,134,236,255,60,206,87,1,61,52,187,2,61,117,32,4,61,144,135,5,61,133,240,6,61,84,91,8,61,253,199,9,61,128,54,11,61,219,166,12,61,16,25,14,61,29,141,15,61,3,3,17,61,193,122,18,61,87,244,19,61,197,111,21,61,10,237,22,61,39,108,24,61,26,237,25,61,228,111,27,61,132,244,28,61,251,122,30,61,71,3,32,61,105,141,33,61,96,25,35,61,45,167,36,61,206,54,38,61,67,200,39,61,141,91,41,61,171,240,42,61,156,135,44,61,96,32,46,61,248,186,47,61,99,87,49,61,160,245,50,61,175,149,52,61,144,55,54,61,67,219,55,61,199,128,57,61,28,40,59,61,65,209,60,61,56,124,62,61,254,40,64,61,148,215,65,61,250,135,67,61,47,58,69,61,51,238,70,61,5,164,72,61,166,91,74,61,20,21,76,61,80,208,77,61,90,141,79,61,49,76,81,61,212,12,83,61,68,207,84,61,128,147,86,61,135,89,88,61,90,33,90,61,248,234,91,61,97,182,93,61,148,131,95,61,145,82,97,61,88,35,99,61,232,245,100,61,65,202,102,61,100,160,104,61,78,120,106,61,1,82,108,61,123,45,110,61,188,10,112,61,197,233,113,61,148,202,115,61,41,173,117,61,133,145,119,61,166,119,121,61,140,95,123,61,55,73,125,61,166,52,127,61,237,144,128,61,105,136,129,61,198,128,130,61,5,122,131,61,37,116,132,61,39,111,133,61,9,107,134,61,204,103,135,61,112,101,136,61,244,99,137,61,88,99,138,61,157,99,139,61,193,100,140,61,196,102,141,61,167,105,142,61,106,109,143,61,11,114,144,61,139,119,145,61,234,125,146,61,40,133,147,61,67,141,148,61,61,150,149,61,20,160,150,61,201,170,151,61,92,182,152,61,203,194,153,61,24,208,154,61,66,222,155,61,72,237,156,61,42,253,157,61,233,13,159,61,132,31,160,61,250,49,161,61,76,69,162,61,122,89,163,61,130,110,164,61,101,132,165,61,35,155,166,61,188,178,167,61,47,203,168,61,124,228,169,61,162,254,170,61,163,25,172,61,124,53,173,61,47,82,174,61,187,111,175,61,31,142,176,61,92,173,177,61,113,205,178,61,94,238,179,61,35,16,181,61,192,50,182,61,52,86,183,61,127,122,184,61,160,159,185,61,153,197,186,61],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);allocate([104,236,187,61,13,20,189,61,136,60,190,61,217,101,191,61,255,143,192,61,250,186,193,61,202,230,194,61,111,19,196,61,233,64,197,61,55,111,198,61,89,158,199,61,78,206,200,61,23,255,201,61,179,48,203,61,35,99,204,61,101,150,205,61,121,202,206,61,96,255,207,61,25,53,209,61,164,107,210,61,0,163,211,61,45,219,212,61,44,20,214,61,251,77,215,61,154,136,216,61,10,196,217,61,74,0,219,61,89,61,220,61,56,123,221,61,230,185,222,61,99,249,223,61,174,57,225,61,200,122,226,61,176,188,227,61,102,255,228,61,233,66,230,61,58,135,231,61,88,204,232,61,66,18,234,61,249,88,235,61,124,160,236,61,203,232,237,61,230,49,239,61,204,123,240,61,125,198,241,61,249,17,243,61,63,94,244,61,79,171,245,61,42,249,246,61,206,71,248,61,60,151,249,61,114,231,250,61,114,56,252,61,58,138,253,61,202,220,254,61,17,24,0,62,33,194,0,62,149,108,1,62,108,23,2,62,166,194,2,62,68,110,3,62,69,26,4,62,168,198,4,62,111,115,5,62,152,32,6,62,35,206,6,62,17,124,7,62,98,42,8,62,20,217,8,62,40,136,9,62,157,55,10,62,117,231,10,62,173,151,11,62,71,72,12,62,66,249,12,62,158,170,13,62,91,92,14,62,120,14,15,62,246,192,15,62,213,115,16,62,19,39,17,62,177,218,17,62,175,142,18,62,13,67,19,62,202,247,19,62,231,172,20,62,99,98,21,62,62,24,22,62,120,206,22,62,16,133,23,62,7,60,24,62,92,243,24,62,16,171,25,62,33,99,26,62,145,27,27,62,94,212,27,62,137,141,28,62,17,71,29,62,246,0,30,62,56,187,30,62,215,117,31,62,211,48,32,62,43,236,32,62,224,167,33,62,241,99,34,62,93,32,35,62,38,221,35,62,74,154,36,62,202,87,37,62,165,21,38,62,219,211,38,62,108,146,39,62,88,81,40,62,159,16,41,62,64,208,41,62,59,144,42,62,144,80,43,62,63,17,44,62,72,210,44,62,170,147,45,62,102,85,46,62,122,23,47,62,232,217,47,62,175,156,48,62,206,95,49,62,69,35,50,62,21,231,50,62,61,171,51,62,189,111,52,62,148,52,53,62,195,249,53,62,73,191,54,62,38,133,55,62,91,75,56,62,230,17,57,62,199,216,57,62,255,159,58,62,141,103,59,62,113,47,60,62,171,247,60,62,59,192,61,62,31,137,62,62,89,82,63,62,232,27,64,62,204,229,64,62,5,176,65,62,146,122,66,62,115,69,67,62,168,16,68,62,49,220,68,62,14,168,69,62,62,116,70,62,194,64,71,62,152,13,72,62,193,218,72,62,61,168,73,62,12,118,74,62,44,68,75,62,159,18,76,62,100,225,76,62,122,176,77,62,225,127,78,62,154,79,79,62,164,31,80,62,255,239,80,62,170,192,81,62,166,145,82,62,242,98,83,62,141,52,84,62,121,6,85,62,180,216,85,62,63,171,86,62,25,126,87,62,65,81,88,62,185,36,89,62,126,248,89,62,147,204,90,62,245,160,91,62,165,117,92,62,163,74,93,62,238,31,94,62,135,245,94,62,109,203,95,62,159,161,96,62,30,120,97,62,233,78,98,62,1,38,99,62,100,253,99,62,19,213,100,62,14,173,101,62,84,133,102,62,229,93,103,62,193,54,104,62,231,15,105,62,88,233,105,62,19,195,106,62,24,157,107,62,103,119,108,62,255,81,109,62,224,44,110,62,11,8,111,62,126,227,111,62,58,191,112,62,62,155,113,62,139,119,114,62,31,84,115,62,251,48,116,62,31,14,117,62,138,235,117,62,59,201,118,62,52,167,119,62,115,133,120,62,248,99,121,62,196,66,122,62,213,33,123,62,44,1,124,62,200,224,124,62,170,192,125,62,208,160,126,62,59,129,127,62,245,48,128,62,111,161,128,62,11,18,129,62,201,130,129,62,168,243,129,62,169,100,130,62,204,213,130,62,15,71,131,62,117,184,131,62,251,41,132,62,162,155,132,62,107,13,133,62,84,127,133,62,93,241,133,62,136,99,134,62,210,213,134,62,61,72,135,62,200,186,135,62,116,45,136,62,63,160,136,62,42,19,137,62,52,134,137,62,94,249,137,62,168,108,138,62,17,224,138,62,153,83,139,62,64,199,139,62,6,59,140,62,235,174,140,62,239,34,141,62,17,151,141,62,82,11,142,62,177,127,142,62,46,244,142,62,201,104,143,62,130,221,143,62,89,82,144,62,78,199,144,62,96,60,145,62,143,177,145,62,220,38,146,62,70,156,146,62,205,17,147,62,113,135,147,62,50,253,147,62,16,115,148,62,9,233,148,62,32,95,149,62,82,213,149,62,161,75,150,62,12,194,150,62,146,56,151,62,53,175,151,62,243,37,152,62,204,156,152,62,193,19,153,62,209,138,153,62,252,1,154,62,66,121,154,62,163,240,154,62,31,104,155,62,181,223,155,62,101,87,156,62,48,207,156,62,21,71,157,62,20,191,157,62,45,55,158,62,96,175,158,62,172,39,159,62,18,160,159,62,145,24,160,62,41,145,160,62,218,9,161,62,165,130,161,62,136,251,161,62,132,116,162,62,152,237,162,62,197,102,163,62,10,224,163,62,103,89,164,62,220,210,164,62,105,76,165,62,14,198,165,62,202,63,166,62,158,185,166,62,137,51,167,62,139,173,167,62,164,39,168,62,213,161,168,62,27,28,169,62,121,150,169,62,237,16,170,62,119,139,170,62,24,6,171,62,206,128,171,62,155,251,171,62,125,118,172,62,117,241,172,62,130,108,173,62,165,231,173,62,221,98,174,62,42,222,174,62,140,89,175,62,2,213,175,62,142,80,176,62,46,204,176,62,226,71,177,62,170,195,177,62,135,63,178,62,119,187,178,62,124,55,179,62,148,179,179,62,191,47,180,62,254,171,180,62,80,40,181,62,181,164,181,62,45,33,182,62,184,157,182,62,85,26,183,62,5,151,183,62,199,19,184,62,156,144,184,62,130,13,185,62,123,138,185,62,133,7,186,62,161,132,186,62,206,1,187,62,13,127,187,62,93,252,187,62,190,121,188,62,48,247,188,62,178,116,189,62,70,242,189,62,233,111,190,62,157,237,190,62,98,107,191,62,54,233,191,62,26,103,192,62,14,229,192,62,17,99,193,62,36,225,193,62,70,95,194,62,119,221,194,62,184,91,195,62,7,218,195,62,100,88,196,62,209,214,196,62,75,85,197,62,212,211,197,62,107,82,198,62,16,209,198,62,195,79,199,62,132,206,199,62,82,77,200,62,45,204,200,62,21,75,201,62,11,202,201,62,13,73,202,62,29,200,202,62,56,71,203,62,97,198,203,62,149,69,204,62,214,196,204,62,34,68,205,62,123,195,205,62,223,66,206,62,79,194,206,62,202,65,207,62,81,193,207,62,226,64,208,62,127,192,208,62,38,64,209,62,216,191,209,62,148,63,210,62,91,191,210,62,44,63,211,62,7,191,211,62,235,62,212,62,218,190,212,62,210,62,213,62,211,190,213,62,222,62,214,62,242,190,214,62,15,63,215,62,53,191,215,62,99,63,216,62,154,191,216,62,217,63,217,62,32,192,217,62,112,64,218,62,199,192,218,62,38,65,219,62,140,193,219,62,250,65,220,62,112,194,220,62,236,66,221,62,112,195,221,62,250,67,222,62,139,196,222,62,34,69,223,62,192,197,223,62,100,70,224,62,14,199,224,62,189,71,225,62,115,200,225,62,46,73,226,62,239,201,226,62,181,74,227,62,127,203,227,62,79,76,228,62,36,205,228,62,253,77,229,62,219,206,229,62,190,79,230,62,164,208,230,62,142,81,231,62,125,210,231,62,111,83,232,62,100,212,232,62,93,85,233,62,89,214,233,62,89,87,234,62,91,216,234,62,96,89,235,62,104,218,235,62,114,91,236,62,126,220,236,62,141,93,237,62,158,222,237,62,176,95,238,62,196,224,238,62,218,97,239,62,241,226,239,62,10,100,240,62,35,229,240,62,62,102,241,62,89,231,241,62,116,104,242,62,145,233,242,62,173,106,243,62,202,235,243,62,230,108,244,62,3,238,244,62,31,111,245,62,59,240,245,62,86,113,246,62,112,242,246,62,137,115,247,62,161,244,247,62,184,117,248,62,206,246,248,62,226,119,249,62,244,248,249,62,4,122,250,62,18,251,250,62,30,124,251,62,40,253,251,62,47,126,252,62,52,255,252,62,54,128,253,62,52,1,254,62,48,130,254,62,40,3,255,62,29,132,255,62,135,2,0,63,254,66,0,63,115,131,0,63,230,195,0,63,86,4,1,63,197,68,1,63,49,133,1,63,155,197,1,63,3,6,2,63,103,70,2,63,202,134,2,63,42,199,2,63,135,7,3,63,225,71,3,63,56,136,3,63,141,200,3,63,222,8,4,63,44,73,4,63,119,137,4,63,191,201,4,63,3,10,5,63,68,74,5,63,130,138,5,63,188,202,5,63,242,10,6,63,36,75,6,63,83,139,6,63,126,203,6,63,165,11,7,63,199,75,7,63,230,139,7,63,1,204,7,63,23,12,8,63,41,76,8,63,54,140,8,63,63,204,8,63,67,12,9,63,67,76,9,63,62,140,9,63,52,204,9,63,37,12,10,63,18,76,10,63,249,139,10,63,219,203,10,63,184,11,11,63,144,75,11,63,98,139,11,63,47,203,11,63,246,10,12,63,184,74,12,63,116,138,12,63,43,202,12,63,219,9,13,63,134,73,13,63,43,137,13,63,202,200,13,63,98,8,14,63,245,71,14,63,129,135,14,63,7,199,14,63,135,6,15,63,0,70,15,63,114,133,15,63,222,196,15,63,67,4,16,63,161,67,16,63,249,130,16,63,73,194,16,63,147,1,17,63,213,64,17,63,17,128,17,63,69,191,17,63,114,254,17,63,151,61,18,63,181,124,18,63,203,187,18,63,218,250,18,63,225,57,19,63,225,120,19,63,216,183,19,63,200,246,19,63,176,53,20,63,143,116,20,63,103,179,20,63,54,242,20,63,253,48,21,63,188,111,21,63,114,174,21,63,32,237,21,63,197,43,22,63,98,106,22,63,246,168,22,63,129,231,22,63,3,38,23,63,125,100,23,63,237,162,23,63,84,225,23,63,178,31,24,63,7,94,24,63,83,156,24,63,149,218,24,63,206,24,25,63,253,86,25,63,35,149,25,63,63,211,25,63,82,17,26,63,90,79,26,63,89,141,26,63,78,203,26,63,57,9,27,63,25,71,27,63,240,132,27,63,188,194,27,63,126,0,28,63,54,62,28,63,227,123,28,63,134,185,28,63,30,247,28,63,172,52,29,63,47,114,29,63,167,175,29,63,20,237,29,63,118,42,30,63,206,103,30,63,26,165,30,63,91,226,30,63,145,31,31,63,188,92,31,63,219,153,31,63,239,214,31,63,247,19,32,63,244,80,32,63,230,141,32,63,203,202,32,63,165,7,33,63,115,68,33,63,53,129,33,63,235,189,33,63,150,250,33,63,52,55,34,63,198,115,34,63,75,176,34,63,197,236,34,63,50,41,35,63,146,101,35,63,230,161,35,63,46,222,35,63,105,26,36,63,151,86,36,63,185,146,36,63,205,206,36,63,213,10,37,63,208,70,37,63,190,130,37,63,158,190,37,63,114,250,37,63,56,54,38,63,241,113,38,63,157,173,38,63,59,233,38,63,204,36,39,63,79,96,39,63,197,155,39,63,45,215,39,63,135,18,40,63,211,77,40,63,18,137,40,63,66,196,40,63,101,255,40,63,121,58,41,63,128,117,41,63,120,176,41,63,98,235,41,63,62,38,42,63,11,97,42,63,202,155,42,63,122,214,42,63,28,17,43,63,175,75,43,63,52,134,43,63,170,192,43,63,16,251,43,63,105,53,44,63,178,111,44,63,236,169,44,63,23,228,44,63,51,30,45,63,64,88,45,63,61,146,45,63,43,204,45,63,10,6,46,63,218,63,46,63,154,121,46,63,74,179,46,63,235,236,46,63,124,38,47,63,254,95,47,63,112,153,47,63,210,210,47,63,36,12,48,63,102,69,48,63,152,126,48,63,186,183,48,63,204,240,48,63,205,41,49,63,191,98,49,63,160,155,49,63,113,212,49,63,49,13,50,63,225,69,50,63,128,126,50,63,15,183,50,63,141,239,50,63,251,39,51,63,87,96,51,63,163,152,51,63,222,208,51,63,8,9,52,63,34,65,52,63,42,121,52,63,33,177,52,63,7,233,52,63,219,32,53,63,159,88,53,63,81,144,53,63,242,199,53,63,129,255,53,63,255,54,54,63,108,110,54,63,198,165,54,63,16,221,54,63,71,20,55,63,109,75,55,63,129,130,55,63,131,185,55,63,116,240,55,63,82,39,56,63,30,94,56,63,217,148,56,63,129,203,56,63,23,2,57,63,155,56,57,63,13,111,57,63,108,165,57,63,185,219,57,63,244,17,58,63,28,72,58,63,50,126,58,63,53,180,58,63,38,234,58,63,4,32,59,63,207,85,59,63,135,139,59,63,45,193,59,63,192,246,59,63,64,44,60,63,173,97,60,63,7,151,60,63,78,204,60,63,130,1,61,63,163,54,61,63,177,107,61,63,171,160,61,63,146,213,61,63,102,10,62,63,39,63,62,63,212,115,62,63,110,168,62,63,244,220,62,63,103,17,63,63,198,69,63,63,17,122,63,63,73,174,63,63,109,226,63,63,126,22,64,63,122,74,64,63,99,126,64,63,56,178,64,63,248,229,64,63,165,25,65,63,62,77,65,63,195,128,65,63,52,180,65,63,144,231,65,63,216,26,66,63,13,78,66,63,44,129,66,63,56,180,66,63,47,231,66,63,18,26,67,63,224,76,67,63,154,127,67,63,64,178,67,63,208,228,67,63,77,23,68,63,180,73,68,63,7,124,68,63,69,174,68,63,111,224,68,63,131,18,69,63,131,68,69,63,110,118,69,63,68,168,69,63,5,218,69,63,177,11,70,63,72,61,70,63,202,110,70,63,55,160,70,63,143,209,70,63,210,2,71,63,255,51,71,63,23,101,71,63,26,150,71,63,8,199,71,63,224,247,71,63,163,40,72,63,81,89,72,63,233,137,72,63,107,186,72,63,216,234,72,63,48,27,73,63,114,75,73,63,158,123,73,63,181,171,73,63,181,219,73,63,161,11,74,63,118,59,74,63,54,107,74,63,224,154,74,63,116,202,74,63,242,249,74,63,90,41,75,63,173,88,75,63,233,135,75,63,15,183,75,63,32,230,75,63,26,21,76,63,254,67,76,63,204,114,76,63,132,161,76,63,38,208,76,63,177,254,76,63,38,45,77,63,133,91,77,63,206,137,77,63,0,184,77,63,28,230,77,63,34,20,78,63,17,66,78,63,234,111,78,63,172,157,78,63,88,203,78,63,238,248,78,63,108,38,79,63,213,83,79,63,38,129,79,63,97,174,79,63,134,219,79,63,147,8,80,63,138,53,80,63,107,98,80,63,52,143,80,63,231,187,80,63,131,232,80,63,8,21,81,63,119,65,81,63,206,109,81,63,15,154,81,63,57,198,81,63,76,242,81,63,71,30,82,63,44,74,82,63,250,117,82,63,177,161,82,63,81,205,82,63,218,248,82,63,76,36,83,63,166,79,83,63,234,122,83,63,22,166,83,63,44,209,83,63,42,252,83,63,17,39,84,63,224,81,84,63,153,124,84,63,58,167,84,63,196,209,84,63,54,252,84,63,146,38,85,63,214,80,85,63,2,123,85,63,24,165,85,63,22,207,85,63,252,248,85,63,204,34,86,63,131,76,86,63,36,118,86,63,172,159,86,63,30,201,86,63,120,242,86,63,186,27,87,63,229,68,87,63,248,109,87,63,244,150,87,63,216,191,87,63,165,232,87,63,90,17,88,63,248,57,88,63,126,98,88,63,236,138,88,63,67,179,88,63,130,219,88,63,169,3,89,63,185,43,89,63,177,83,89,63,145,123,89,63,90,163,89,63,11,203,89,63,164,242,89,63,37,26,90,63,143,65,90,63,225,104,90,63,27,144,90,63,62,183,90,63,72,222,90,63,59,5,91,63,22,44,91,63,217,82,91,63,133,121,91,63,24,160,91,63,148,198,91,63,248,236,91,63,68,19,92,63,120,57,92,63,149,95,92,63,153,133,92,63,134,171,92,63,91,209,92,63,24,247,92,63,189,28,93,63,74,66,93,63,191,103,93,63,28,141,93,63,98,178,93,63,143,215,93,63,165,252,93,63,162,33,94,63,136,70,94,63,86,107,94,63,11,144,94,63,169,180,94,63,47,217,94,63,157,253,94,63,243,33,95,63,49,70,95,63,88,106,95,63,102,142,95,63,92,178,95,63,59,214,95,63,1,250,95,63,175,29,96,63,70,65,96,63,196,100,96,63,43,136,96,63,122,171,96,63,176,206,96,63,207,241,96,63,214,20,97,63,197,55,97,63,155,90,97,63,90,125,97,63,1,160,97,63,144,194,97,63,8,229,97,63,103,7,98,63,174,41,98,63,221,75,98,63,245,109,98,63,244,143,98,63,220,177,98,63,171,211,98,63,99,245,98,63,3,23,99,63,139,56,99,63,251,89,99,63,83,123,99,63,147,156,99,63,188,189,99,63,204,222,99,63,197,255,99,63,166,32,100,63,110,65,100,63,32,98,100,63,185,130,100,63,58,163,100,63,164,195,100,63,245,227,100,63,47,4,101,63,82,36,101,63,92,68,101,63,78,100,101,63,41,132,101,63,236,163,101,63,151,195,101,63,43,227,101,63,167,2,102,63,11,34,102,63,87,65,102,63,139,96,102,63,168,127,102,63,174,158,102,63,155,189,102,63,113,220,102,63,47,251,102,63,214,25,103,63,101,56,103,63,220,86,103,63,59,117,103,63,132,147,103,63,180,177,103,63,205,207,103,63,206,237,103,63,184,11,104,63,138,41,104,63,69,71,104,63,233,100,104,63,116,130,104,63,233,159,104,63,69,189,104,63,139,218,104,63,185,247,104,63,207,20,105,63,207,49,105,63,182,78,105,63,135,107,105,63,64,136,105,63,225,164,105,63,108,193,105,63,223,221,105,63,59,250,105,63,127,22,106,63,172,50,106,63,195,78,106,63,193,106,106,63,169,134,106,63,121,162,106,63,51,190,106,63,213,217,106,63,96,245,106,63,212,16,107,63,48,44,107,63,118,71,107,63,165,98,107,63,188,125,107,63,189,152,107,63,167,179,107,63,121,206,107,63,53,233,107,63,218,3,108,63,104,30,108,63,223,56,108,63,63,83,108,63,136,109,108,63,187,135,108,63,214,161,108,63,219,187,108,63,201,213,108,63,161,239,108,63,97,9,109,63,11,35,109,63,159,60,109,63,27,86,109,63,129,111,109,63,209,136,109,63,9,162,109,63,44,187,109,63,56,212,109,63,45,237,109,63,12,6,110,63,212,30,110,63,134,55,110,63,33,80,110,63,166,104,110,63,21,129,110,63,110,153,110,63,176,177,110,63,220,201,110,63,241,225,110,63,241,249,110,63,218,17,111,63,173,41,111,63,106,65,111,63,16,89,111,63,161,112,111,63,28,136,111,63,128,159,111,63,207,182,111,63,7,206,111,63,42,229,111,63,54,252,111,63,45,19,112,63,14,42,112,63,217,64,112,63,142,87,112,63,46,110,112,63,184,132,112,63,43,155,112,63,138,177,112,63,210,199,112,63,5,222,112,63,35,244,112,63,42,10,113,63,29,32,113,63,249,53,113,63,193,75,113,63,114,97,113,63,15,119,113,63,150,140,113,63,7,162,113,63,99,183,113,63,170,204,113,63,220,225,113,63,249,246,113,63,0,12,114,63,242,32,114,63,207,53,114,63,151,74,114,63,73,95,114,63,231,115,114,63,112,136,114,63,227,156,114,63,66,177,114,63,140,197,114,63,193,217,114,63,225,237,114,63,236,1,115,63,227,21,115,63,197,41,115,63,146,61,115,63,74,81,115,63,238,100,115,63,125,120,115,63,248,139,115,63,94,159,115,63,175,178,115,63,236,197,115,63,21,217,115,63,41,236,115,63,41,255,115,63,21,18,116,63,236,36,116,63,175,55,116,63,94,74,116,63,248,92,116,63,127,111,116,63,241,129,116,63,80,148,116,63,154,166,116,63,208,184,116,63,242,202,116,63,1,221,116,63,251,238,116,63,226,0,117,63,181,18,117,63,116,36,117,63,31,54,117,63,183,71,117,63,59,89,117,63,171,106,117,63,8,124,117,63,81,141,117,63,135,158,117,63,169,175,117,63,184,192,117,63,179,209,117,63,155,226,117,63,112,243,117,63,50,4,118,63,224,20,118,63,123,37,118,63,3,54,118,63,120,70,118,63,217,86,118,63,40,103,118,63,100,119,118,63,140,135,118,63,162,151,118,63,165,167,118,63,149,183,118,63,114,199,118,63,61,215,118,63,245,230,118,63,154,246,118,63,44,6,119,63,172,21,119,63,26,37,119,63,117,52,119,63,189,67,119,63,243,82,119,63,22,98,119,63,40,113,119,63,39,128,119,63,19,143,119,63,238,157,119,63,182,172,119,63,108,187,119,63,16,202,119,63,162,216,119,63,34,231,119,63,144,245,119,63,236,3,120,63,55,18,120,63,111,32,120,63,150,46,120,63,170,60,120,63,174,74,120,63,159,88,120,63,127,102,120,63,77,116,120,63,10,130,120,63,181,143,120,63,79,157,120,63,215,170,120,63,78,184,120,63,180,197,120,63,8,211,120,63,76,224,120,63,126,237,120,63,158,250,120,63,174,7,121,63,173,20,121,63,155,33,121,63,119,46,121,63,67,59,121,63,254,71,121,63,168,84,121,63,66,97,121,63,202,109,121,63,66,122,121,63,169,134,121,63,0,147,121,63,70,159,121,63,124,171,121,63,161,183,121,63,181,195,121,63,186,207,121,63,173,219,121,63,145,231,121,63,100,243,121,63,40,255,121,63,219,10,122,63,126,22,122,63,16,34,122,63,147,45,122,63,6,57,122,63,105,68,122,63,188,79,122,63,255,90,122,63,51,102,122,63,86,113,122,63,106,124,122,63,111,135,122,63,99,146,122,63,72,157,122,63,30,168,122,63,228,178,122,63,155,189,122,63,66,200,122,63,218,210,122,63,99,221,122,63,221,231,122,63,71,242,122,63,162,252,122,63,238,6,123,63,43,17,123,63,89,27,123,63,120,37,123,63,137,47,123,63,138,57,123,63,124,67,123,63,96,77,123,63,53,87,123,63,252,96,123,63,179,106,123,63,92,116,123,63,247,125,123,63,131,135,123,63,1,145,123,63,112,154,123,63,209,163,123,63,36,173,123,63,104,182,123,63,158,191,123,63,198,200,123,63,224,209,123,63,236,218,123,63,234,227,123,63,218,236,123,63,188,245,123,63,144,254,123,63,86,7,124,63,14,16,124,63,185,24,124,63,86,33,124,63,230,41,124,63,104,50,124,63,220,58,124,63,67,67,124,63,156,75,124,63,232,83,124,63,39,92,124,63,88,100,124,63,124,108,124,63,147,116,124,63,157,124,124,63,153,132,124,63,137,140,124,63,107,148,124,63,65,156,124,63,9,164,124,63,197,171,124,63,116,179,124,63,22,187,124,63,172,194,124,63,52,202,124,63,176,209,124,63,32,217,124,63,131,224,124,63,217,231,124,63,35,239,124,63,97,246,124,63,146,253,124,63,183,4,125,63,208,11,125,63,221,18,125,63,221,25,125,63,209,32,125,63,185,39,125,63,150,46,125,63,102,53,125,63,42,60,125,63,227,66,125,63,143,73,125,63,48,80,125,63,197,86,125,63,78,93,125,63,204,99,125,63,62,106,125,63,165,112,125,63,0,119,125,63,80,125,125,63,148,131,125,63,205,137,125,63,251,143,125,63,29,150,125,63,52,156,125,63,64,162,125,63,65,168,125,63,55,174,125,63,34,180,125,63,2,186,125,63,215,191,125,63,161,197,125,63,96,203,125,63,21,209,125,63,190,214,125,63,93,220,125,63,242,225,125,63,124,231,125,63,251,236,125,63,112,242,125,63,218,247,125,63,58,253,125,63,143,2,126,63,219,7,126,63,28,13,126,63,82,18,126,63,127,23,126,63,161,28,126,63,186,33,126,63,200,38,126,63,204,43,126,63,199,48,126,63,183,53,126,63,158,58,126,63,123,63,126,63,78,68,126,63,23,73,126,63,215,77,126,63,141,82,126,63,58,87,126,63,221,91,126,63,118,96,126,63,6,101,126,63,141,105,126,63,10,110,126,63,126,114,126,63,233,118,126,63,75,123,126,63,164,127,126,63,243,131,126,63,57,136,126,63,119,140,126,63,171,144,126,63,214,148,126,63,249,152,126,63,18,157,126,63,35,161,126,63,44,165,126,63,43,169,126,63,34,173,126,63,16,177,126,63,246,180,126,63,211,184,126,63,167,188,126,63,115,192,126,63,55,196,126,63,243,199,126,63,166,203,126,63,81,207,126,63,243,210,126,63,142,214,126,63,32,218,126,63,171,221,126,63,45,225,126,63,167,228,126,63,26,232,126,63,132,235,126,63,231,238,126,63,66,242,126,63,149,245,126,63,224,248,126,63,36,252,126,63,96,255,126,63,148,2,127,63,193,5,127,63,230,8,127,63,4,12,127,63,27,15,127,63,42,18,127,63,50,21,127,63,50,24,127,63,43,27,127,63,29,30,127,63,8,33,127,63,236,35,127,63,201,38,127,63,158,41,127,63,109,44,127,63,53,47,127,63,246,49,127,63,175,52,127,63,99,55,127,63,15,58,127,63,181,60,127,63,83,63,127,63,236,65,127,63,125,68,127,63,8,71,127,63,141,73,127,63,11,76,127,63,131,78,127,63,244,80,127,63,95,83,127,63,195,85,127,63,33,88,127,63,121,90,127,63,203,92,127,63,23,95,127,63,92,97,127,63,155,99,127,63,213,101,127,63,8,104,127,63,54,106,127,63,93,108,127,63,127,110,127,63,155,112,127,63,177,114,127,63,193,116,127,63,203,118,127,63,208,120,127,63,207,122,127,63,201,124,127,63,189,126,127,63,171,128,127,63,148,130,127,63,120,132,127,63,86,134,127,63,47,136,127,63,2,138,127,63,209,139,127,63,153,141,127,63,93,143,127,63,28,145,127,63,213,146,127,63,137,148,127,63,57,150,127,63,227,151,127,63,136,153,127,63,40,155,127,63,196,156,127,63,90,158,127,63,236,159,127,63,121,161,127,63,1,163,127,63,132,164,127,63,3,166,127,63,125,167,127,63,242,168,127,63,99,170,127,63,207,171,127,63,55,173,127,63,154,174,127,63,249,175,127,63,84,177,127,63,170,178,127,63,251,179,127,63,73,181,127,63,146,182,127,63,215,183,127,63,24,185,127,63,85,186,127,63,141,187,127,63,193,188,127,63,242,189,127,63,30,191,127,63,71,192,127,63,107,193,127,63,140,194,127,63,168,195,127,63,193,196,127,63,214,197,127,63,231,198,127,63,245,199,127,63,255,200,127,63,5,202,127,63,7,203,127,63,6,204,127,63,1,205,127,63,249,205,127,63,237,206,127,63,222,207,127,63,203,208,127,63,181,209,127,63,156,210,127,63,127,211,127,63,95,212,127,63,59,213,127,63,20,214,127,63,234,214,127,63,189,215,127,63,141,216,127,63,90,217,127,63,35,218,127,63,233,218,127,63,173,219,127,63,109,220,127,63,43,221,127,63,229,221,127,63,156,222,127,63,81,223,127,63,3,224,127,63,178,224,127,63,94,225,127,63,7,226,127,63,174,226,127,63,82,227,127,63,243,227,127,63,146,228,127,63,46,229,127,63,199,229,127,63,94,230,127,63,242,230,127,63,132,231,127,63,19,232,127,63,160,232,127,63,42,233,127,63,178,233,127,63,56,234,127,63,187,234,127,63,60,235,127,63,187,235,127,63,55,236,127,63,177,236,127,63,41,237,127,63,159,237,127,63,18,238,127,63,132,238,127,63,243,238,127,63,96,239,127,63,204,239,127,63,53,240,127,63,156,240,127,63,1,241,127,63,101,241,127,63,198,241,127,63,37,242,127,63,131,242,127,63,222,242,127,63,56,243,127,63,144,243,127,63,231,243,127,63,59,244,127,63,142,244,127,63,223,244,127,63,46,245,127,63,124,245,127,63,200,245,127,63,19,246,127,63,91,246,127,63,163,246,127,63,233,246,127,63,45,247,127,63,111,247,127,63,177,247,127,63,240,247,127,63,47,248,127,63,108,248,127,63,167,248,127,63,225,248,127,63,26,249,127,63,82,249,127,63,136,249,127,63,188,249,127,63,240,249,127,63,34,250,127,63,83,250,127,63,131,250,127,63,178,250,127,63,224,250,127,63,12,251,127,63,55,251,127,63,97,251,127,63,138,251,127,63,178,251,127,63,217,251,127,63,255,251,127,63,36,252,127,63,72,252,127,63,107,252,127,63,141,252,127,63,173,252,127,63,205,252,127,63,237,252,127,63,11,253,127,63,40,253,127,63,69,253,127,63,96,253,127,63,123,253,127,63,149,253,127,63,174,253,127,63,199,253,127,63,222,253,127,63,245,253,127,63,12,254,127,63,33,254,127,63,54,254,127,63,74,254,127,63,93,254,127,63,112,254,127,63,130,254,127,63,148,254,127,63,165,254,127,63,181,254,127,63,197,254,127,63,212,254,127,63,227,254,127,63,241,254,127,63,254,254,127,63,11,255,127,63,24,255,127,63,36,255,127,63,47,255,127,63,59,255,127,63,69,255,127,63,79,255,127,63,89,255,127,63,99,255,127,63,108,255,127,63,116,255,127,63,124,255,127,63,132,255,127,63,140,255,127,63,147,255,127,63,154,255,127,63,160,255,127,63,166,255,127,63,172,255,127,63,178,255,127,63,183,255,127,63,188,255,127,63,193,255,127,63,197,255,127,63,202,255,127,63,206,255,127,63,209,255,127,63,213,255,127,63,216,255,127,63,220,255,127,63,223,255,127,63,225,255,127,63,228,255,127,63,230,255,127,63,233,255,127,63,235,255,127,63,237,255,127,63,239,255,127,63,240,255,127,63,242,255,127,63,243,255,127,63,245,255,127,63,246,255,127,63,247,255,127,63,248,255,127,63,249,255,127,63,250,255,127,63,251,255,127,63,251,255,127,63,252,255,127,63,252,255,127,63,253,255,127,63,253,255,127,63,254,255,127,63,254,255,127,63,254,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,198,63,120,51,98,136,11,53,151,200,193,53,80,233,61,54,183,247,156,54,46,124,234,54,153,192,35,55,244,2,90,55,56,3,140,55,227,228,174,55,177,166,213,55,108,36,0,56,146,101,23,56,201,150,48,56,18,184,75,56,81,201,104,56,94,229,131,56,29,94,148,56,229,206,165,56,167,55,184,56,128,152,203,56,85,241,223,56,36,66,245,56,126,197,5,57,238,101,17,57,99,130,29,57,207,26,42,57,63,47,55,57,179,191,68,57,30,204,82,57,141,84,97,57,243,88,112,57,94,217,127,57,227,234,135,57,18,39,144,57,64,161,152,57,105,89,161,57,146,79,170,57,181,131,179,57,215,245,188,57,245,165,198,57,14,148,208,57,34,192,218,57,46,42,229,57,57,210,239,57,60,184,250,57,27,238,2,58,22,159,8,58,13,111,14,58,0,94,20,58,239,107,26,58,218,152,32,58,192,228,38,58,161,79,45,58,124,217,51,58,83,130,58,58,37,74,65,58,240,48,72,58,182,54,79,58,116,91,86,58,45,159,93,58,222,1,101,58,136,131,108,58,42,36,116,58,196,227,123,58,44,225,129,58,241,223,133,58,49,238,137,58,238,11,142,58,37,57,146,58,215,117,150,58,5,194,154,58,174,29,159,58,209,136,163,58,110,3,168,58,134,141,172,58,24,39,177,58,36,208,181,58,169,136,186,58,169,80,191,58,33,40,196,58,19,15,201,58,126,5,206,58,98,11,211,58,191,32,216,58,148,69,221,58,225,121,226,58,166,189,231,58,227,16,237,58,152,115,242,58,196,229,247,58,103,103,253,58,65,124,1,59,137,76,4,59,141,36,7,59,76,4,10,59,198,235,12,59,251,218,15,59,235,209,18,59,149,208,21,59,251,214,24,59,26,229,27,59,244,250,30,59,136,24,34,59,215,61,37,59,223,106,40,59,161,159,43,59,29,220,46,59,83,32,50,59,66,108,53,59,234,191,56,59,76,27,60,59,103,126,63,59,59,233,66,59,199,91,70,59,12,214,73,59,10,88,77,59,193,225,80,59,48,115,84,59,86,12,88,59,53,173,91,59,204,85,95,59,26,6,99,59,32,190,102,59,222,125,106,59,82,69,110,59,127,20,114,59,97,235,117,59,251,201,121,59,76,176,125,59,41,207,128,59,8,202,130,59,194,200,132,59,87,203,134,59,198,209,136,59,17,220,138,59,55,234,140,59,55,252,142,59,18,18,145,59,199,43,147,59,87,73,149,59,194,106,151,59,6,144,153,59,37,185,155,59,30,230,157,59,241,22,160,59,158,75,162,59,37,132,164,59,134,192,166,59,192,0,169,59,212,68,171,59,193,140,173,59,137,216,175,59,41,40,178,59,163,123,180,59,245,210,182,59,33,46,185,59,38,141,187,59,4,240,189,59,186,86,192,59,73,193,194,59,177,47,197,59,242,161,199,59,10,24,202,59,251,145,204,59,196,15,207,59,102,145,209,59,223,22,212,59,49,160,214,59,90,45,217,59,91,190,219,59,51,83,222,59,227,235,224,59,107,136,227,59,201,40,230,59,255,204,232,59,12,117,235,59,240,32,238,59,171,208,240,59,61,132,243,59,165,59,246,59,228,246,248,59,250,181,251,59,229,120,254,59,212,159,0,60,32,5,2,60,87,108,3,60,121,213,4,60,134,64,6,60,126,173,7,60,96,28,9,60,45,141,10,60,229,255,11,60,136,116,13,60,21,235,14,60,141,99,16,60,239,221,17,60,59,90,19,60,114,216,20,60,147,88,22,60,158,218,23,60,147,94,25,60,115,228,26,60,60,108,28,60,240,245,29,60,141,129,31,60,20,15,33,60,133,158,34,60,224,47,36,60,36,195,37,60,82,88,39,60,105,239,40,60,106,136,42,60,84,35,44,60,40,192,45,60,229,94,47,60,139,255,48,60,26,162,50,60,146,70,52,60,243,236,53,60,61,149,55,60,112,63,57,60,140,235,58,60,145,153,60,60,126,73,62,60,84,251,63,60,18,175,65,60,185,100,67,60,72,28,69,60,192,213,70,60,31,145,72,60,103,78,74,60,151,13,76,60,175,206,77,60,176,145,79,60,152,86,81,60,103,29,83,60,31,230,84,60,190,176,86,60,69,125,88,60,179,75,90,60,9,28,92,60,71,238,93,60,107,194,95,60,119,152,97,60,106,112,99,60,68,74,101,60,5,38,103,60,173,3,105,60,60,227,106,60,178,196,108,60,14,168,110,60,81,141,112,60,123,116,114,60,139,93,116,60,130,72,118,60,95,53,120,60,34,36,122,60,203,20,124,60,90,7,126,60,208,251,127,60,22,249,128,60,54,245,129,60,74,242,130,60,80,240,131,60,73,239,132,60,53,239,133,60,19,240,134,60,229,241,135,60,169,244,136,60,95,248,137,60,8,253,138,60,164,2,140,60,50,9,141,60,178,16,142,60,37,25,143,60,139,34,144,60,226,44,145,60,44,56,146,60,104,68,147,60,150,81,148,60,182,95,149,60,201,110,150,60,205,126,151,60,196,143,152,60,172,161,153,60,135,180,154,60,83,200,155,60,17,221,156,60,193,242,157,60,98,9,159,60,245,32,160,60,122,57,161,60,241,82,162,60,89,109,163,60,178,136,164,60,253,164,165,60,57,194,166,60,103,224,167,60,134,255,168,60,151,31,170,60,152,64,171,60,139,98,172,60,111,133,173,60,68,169,174,60,10,206,175,60,193,243,176,60,105,26,178,60,2,66,179,60,139,106,180,60,6,148,181,60,113,190,182,60,205,233,183,60,26,22,185,60,87,67,186,60,133,113,187,60,163,160,188,60,177,208,189,60,177,1,191,60,160,51,192,60,128,102,193,60,80,154,194,60,16,207,195,60,193,4,197,60,97,59,198,60,242,114,199,60,114,171,200,60,227,228,201,60,67,31,203,60,147,90,204,60,211,150,205,60,3,212,206,60,34,18,208,60,49,81,209,60,48,145,210,60,30,210,211,60,252,19,213,60,201,86,214,60,133,154,215,60,49,223,216,60,204,36,218,60,86,107,219,60,208,178,220,60,56,251,221,60,144,68,223,60,214,142,224,60,12,218,225,60,48,38,227,60,67,115,228,60,69,193,229,60,54,16,231,60,21,96,232,60,227,176,233,60,160,2,235,60,75,85,236,60,228,168,237,60,108,253,238,60,226,82,240,60,70,169,241,60,153,0,243,60,218,88,244,60,8,178,245,60,37,12,247,60,48,103,248,60,41,195,249,60,15,32,251,60,228,125,252,60,166,220,253,60,85,60,255,60,121,78,0,61,63,255,0,61,123,176,1,61,46,98,2,61,88,20,3,61,248,198,3,61,15,122,4,61,156,45,5,61,161,225,5,61,27,150,6,61,12,75,7,61,116,0,8,61,82,182,8,61,167,108,9,61,113,35,10,61,179,218,10,61,106,146,11,61,152,74,12,61,60,3,13,61,87,188,13,61,231,117,14,61,238,47,15,61,107,234,15,61,94,165,16,61,199,96,17,61,166,28,18,61,251,216,18,61,198,149,19,61,7,83,20,61,190,16,21,61,234,206,21,61,141,141,22,61,165,76,23,61,52,12,24,61,56,204,24,61,177,140,25,61,161,77,26,61,6,15,27,61,224,208,27,61,48,147,28,61,246,85,29,61,49,25,30,61,226,220,30,61,8,161,31,61,164,101,32,61,181,42,33,61,59,240,33,61,55,182,34,61,168,124,35,61,142,67,36,61,233,10,37,61,186,210,37,61,255,154,38,61,186,99,39,61,234,44,40,61,143,246,40,61,168,192,41,61,55,139,42,61,59,86,43,61,180,33,44,61,161,237,44,61,4,186,45,61,219,134,46,61,38,84,47,61,231,33,48,61,28,240,48,61,198,190,49,61,229,141,50,61,120,93,51,61,127,45,52,61,251,253,52,61,236,206,53,61,81,160,54,61,42,114,55,61,120,68,56,61,58,23,57,61,112,234,57,61,27,190,58,61,58,146,59,61,204,102,60,61,211,59,61,61,79,17,62,61,62,231,62,61,161,189,63,61,120,148,64,61,195,107,65,61,130,67,66,61,181,27,67,61,92,244,67,61,118,205,68,61,4,167,69,61,6,129,70,61,124,91,71,61,101,54,72,61,194,17,73,61,146,237,73,61,214,201,74,61,141,166,75,61,184,131,76,61,86,97,77,61,104,63,78,61,236,29,79,61,229,252,79,61,80,220,80,61,46,188,81,61,128,156,82,61,69,125,83,61,125,94,84,61,40,64,85,61,69,34,86,61,214,4,87,61,218,231,87,61,81,203,88,61,58,175,89,61,150,147,90,61,101,120,91,61,167,93,92,61,91,67,93,61,130,41,94,61,28,16,95,61,40,247,95,61,167,222,96,61,152,198,97,61,251,174,98,61,209,151,99,61,25,129,100,61,212,106,101,61,0,85,102,61,159,63,103,61,176,42,104,61,51,22,105,61,41,2,106,61,144,238,106,61,105,219,107,61,180,200,108,61,113,182,109,61,160,164,110,61,65,147,111,61,84,130,112,61,216,113,113,61,206,97,114,61,54,82,115,61,15,67,116,61,89,52,117,61,22,38,118,61,67,24,119,61,226,10,120,61,243,253,120,61,117,241,121,61,104,229,122,61,204,217,123,61,162,206,124,61,232,195,125,61,160,185,126,61,201,175,127,61,49,83,128,61,183,206,128,61,117,74,129,61,107,198,129,61,154,66,130,61,1,191,130,61,160,59,131,61,120,184,131,61,136,53,132,61,209,178,132,61,81,48,133,61,10,174,133,61,251,43,134,61,37,170,134,61,134,40,135,61,32,167,135,61,242,37,136,61,252,164,136,61,62,36,137,61,184,163,137,61,106,35,138,61,84,163,138,61,118,35,139,61,209,163,139,61,99,36,140,61,45,165,140,61,46,38,141,61,104,167,141,61,218,40,142,61,131,170,142,61,100,44,143,61,125,174,143,61,206,48,144,61,86,179,144,61,23,54,145,61,14,185,145,61,62,60,146,61,165,191,146,61,67,67,147,61,26,199,147,61,39,75,148,61,109,207,148,61,234,83,149,61,158,216,149,61,138,93,150,61,173,226,150,61,7,104,151,61,153,237,151,61,98,115,152,61,99,249,152,61,155,127,153,61,10,6,154,61,176,140,154,61,142,19,155,61,163,154,155,61,239,33,156,61,114,169,156,61,44,49,157,61,29,185,157,61,69,65,158,61,165,201,158,61,59,82,159,61,8,219,159,61,13,100,160,61,72,237,160,61,186,118,161,61,99,0,162,61,67,138,162,61,90,20,163,61,167,158,163,61,43,41,164,61,230,179,164,61,216,62,165,61,0,202,165,61,95,85,166,61,245,224,166,61,193,108,167,61,196,248,167,61,254,132,168,61,110,17,169,61,20,158,169,61,241,42,170,61,4,184,170,61,78,69,171,61,206,210,171,61,133,96,172,61,113,238,172,61,149,124,173,61,238,10,174,61,126,153,174,61,67,40,175,61,63,183,175,61,114,70,176,61,218,213,176,61,120,101,177,61,77,245,177,61,88,133,178,61,152,21,179,61,15,166,179,61,187,54,180,61,158,199,180,61,182,88,181,61,4,234,181,61,137,123,182,61,67,13,183,61,50,159,183,61,88,49,184,61,179,195,184,61,68,86,185,61,11,233,185,61,7,124,186,61,57,15,187,61,160,162,187,61,61,54,188,61,16,202,188,61,24,94,189,61,85,242,189,61,200,134,190,61,112,27,191,61,78,176,191,61,97,69,192,61,170,218,192,61,39,112,193,61,218,5,194,61,194,155,194,61,224,49,195,61,50,200,195,61,186,94,196,61,119,245,196,61,104,140,197,61,143,35,198,61,235,186,198,61,124,82,199,61,66,234,199,61,61,130,200,61,108,26,201,61,209,178,201,61,106,75,202,61,57,228,202,61,59,125,203,61,115,22,204,61,224,175,204,61,129,73,205,61,86,227,205,61,97,125,206,61,159,23,207,61,19,178,207,61,187,76,208,61,151,231,208,61,168,130,209,61,237,29,210,61,103,185,210,61,21,85,211,61,248,240,211,61,14,141,212,61,89,41,213,61,216,197,213,61,140,98,214,61,115,255,214,61,143,156,215,61,223,57,216,61,99,215,216,61,27,117,217,61,7,19,218,61,38,177,218,61,122,79,219,61,2,238,219,61,189,140,220,61,173,43,221,61,208,202,221,61,39,106,222,61,178,9,223,61,112,169,223,61,98,73,224,61,136,233,224,61,226,137,225,61,111,42,226,61,47,203,226,61,35,108,227,61,74,13,228,61,165,174,228,61,52,80,229,61,245,241,229,61,234,147,230,61,19,54,231,61,110,216,231,61,253,122,232,61,191,29,233,61,180,192,233,61,221,99,234,61,56,7,235,61,199,170,235,61,136,78,236,61,125,242,236,61,164,150,237,61,255,58,238,61,140,223,238,61,76,132,239,61,63,41,240,61,101,206,240,61,189,115,241,61,73,25,242,61,7,191,242,61,247,100,243,61,26,11,244,61,112,177,244,61,248,87,245,61,179,254,245,61,160,165,246,61,192,76,247,61,18,244,247,61,151,155,248,61,77,67,249,61,55,235,249,61,82,147,250,61,159,59,251,61,31,228,251,61,209,140,252,61,181,53,253,61,203,222,253,61,19,136,254,61,141,49,255,61,57,219,255,61,140,66,0,62,148,151,0,62,181,236,0,62,238,65,1,62,65,151,1,62,173,236,1,62,49,66,2,62,206,151,2,62,132,237,2,62,83,67,3,62,59,153,3,62,59,239,3,62,84,69,4,62,134,155,4,62,209,241,4,62,52,72,5,62,176,158,5,62,68,245,5,62,242,75,6,62,183,162,6,62,150,249,6,62,141,80,7,62,156,167,7,62,196,254,7,62,5,86,8,62,94,173,8,62,207,4,9,62,89,92,9,62,252,179,9,62,183,11,10,62,138,99,10,62,118,187,10,62,122,19,11,62,150,107,11,62,203,195,11,62,24,28,12,62,125,116,12,62,250,204,12,62,144,37,13,62,62,126,13,62,4,215,13,62,227,47,14,62,217,136,14,62,232,225,14,62,15,59,15,62,78,148,15,62,165,237,15,62,20,71,16,62,155,160,16,62,58,250,16,62,241,83,17,62,193,173,17,62,168,7,18,62,167,97,18,62,190,187,18,62,237,21,19,62,51,112,19,62,146,202,19,62,9,37,20,62,151,127,20,62,61,218,20,62,251,52,21,62,209,143,21,62,190,234,21,62,195,69,22,62,224,160,22,62,21,252,22,62,97,87,23,62,197,178,23,62,64,14,24,62,211,105,24,62,126,197,24,62,64,33,25,62,26,125,25,62,11,217,25,62,20,53,26,62,52,145,26,62,108,237,26,62,187,73,27,62,34,166,27,62,160,2,28,62,53,95,28,62,226,187,28,62],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE+10240);allocate([166,24,29,62,129,117,29,62,116,210,29,62,126,47,30,62,159,140,30,62,215,233,30,62,39,71,31,62,141,164,31,62,11,2,32,62,160,95,32,62,76,189,32,62,16,27,33,62,234,120,33,62,219,214,33,62,228,52,34,62,3,147,34,62,58,241,34,62,135,79,35,62,235,173,35,62,103,12,36,62,249,106,36,62,162,201,36,62,98,40,37,62,56,135,37,62,38,230,37,62,42,69,38,62,69,164,38,62,119,3,39,62,192,98,39,62,31,194,39,62,149,33,40,62,33,129,40,62,197,224,40,62,126,64,41,62,79,160,41,62,54,0,42,62,51,96,42,62,72,192,42,62,114,32,43,62,179,128,43,62,11,225,43,62,121,65,44,62,253,161,44,62,152,2,45,62,73,99,45,62,16,196,45,62,238,36,46,62,226,133,46,62,237,230,46,62,13,72,47,62,68,169,47,62,145,10,48,62,245,107,48,62,110,205,48,62,254,46,49,62,163,144,49,62,95,242,49,62,49,84,50,62,25,182,50,62,23,24,51,62,43,122,51,62,85,220,51,62,148,62,52,62,234,160,52,62,86,3,53,62,216,101,53,62,111,200,53,62,28,43,54,62,223,141,54,62,184,240,54,62,167,83,55,62,171,182,55,62,197,25,56,62,245,124,56,62,59,224,56,62,150,67,57,62,7,167,57,62,141,10,58,62,41,110,58,62,219,209,58,62,162,53,59,62,126,153,59,62,112,253,59,62,120,97,60,62,149,197,60,62,199,41,61,62,15,142,61,62,108,242,61,62,222,86,62,62,102,187,62,62,3,32,63,62,181,132,63,62,125,233,63,62,90,78,64,62,75,179,64,62,83,24,65,62,111,125,65,62,160,226,65,62,231,71,66,62,66,173,66,62,179,18,67,62,57,120,67,62,211,221,67,62,131,67,68,62,71,169,68,62,33,15,69,62,15,117,69,62,18,219,69,62,42,65,70,62,87,167,70,62,153,13,71,62,240,115,71,62,91,218,71,62,219,64,72,62,111,167,72,62,25,14,73,62,215,116,73,62,169,219,73,62,144,66,74,62,140,169,74,62,157,16,75,62,193,119,75,62,251,222,75,62,73,70,76,62,171,173,76,62,34,21,77,62,173,124,77,62,76,228,77,62,0,76,78,62,200,179,78,62,164,27,79,62,149,131,79,62,154,235,79,62,179,83,80,62,225,187,80,62,34,36,81,62,120,140,81,62,225,244,81,62,95,93,82,62,241,197,82,62,151,46,83,62,81,151,83,62,31,0,84,62,1,105,84,62,247,209,84,62,0,59,85,62,30,164,85,62,79,13,86,62,149,118,86,62,238,223,86,62,91,73,87,62,219,178,87,62,112,28,88,62,24,134,88,62,211,239,88,62,163,89,89,62,134,195,89,62,124,45,90,62,134,151,90,62,164,1,91,62,213,107,91,62,26,214,91,62,114,64,92,62,221,170,92,62,92,21,93,62,239,127,93,62,148,234,93,62,77,85,94,62,26,192,94,62,249,42,95,62,236,149,95,62,242,0,96,62,11,108,96,62,55,215,96,62,119,66,97,62,202,173,97,62,47,25,98,62,168,132,98,62,52,240,98,62,210,91,99,62,132,199,99,62,73,51,100,62,32,159,100,62,11,11,101,62,8,119,101,62,24,227,101,62,59,79,102,62,113,187,102,62,186,39,103,62,21,148,103,62,131,0,104,62,3,109,104,62,151,217,104,62,60,70,105,62,245,178,105,62,192,31,106,62,157,140,106,62,141,249,106,62,144,102,107,62,165,211,107,62,204,64,108,62,6,174,108,62,82,27,109,62,176,136,109,62,33,246,109,62,164,99,110,62,57,209,110,62,225,62,111,62,154,172,111,62,102,26,112,62,68,136,112,62,52,246,112,62,55,100,113,62,75,210,113,62,113,64,114,62,169,174,114,62,243,28,115,62,80,139,115,62,190,249,115,62,61,104,116,62,207,214,116,62,115,69,117,62,40,180,117,62,239,34,118,62,200,145,118,62,179,0,119,62,175,111,119,62,189,222,119,62,221,77,120,62,14,189,120,62,80,44,121,62,165,155,121,62,10,11,122,62,130,122,122,62,10,234,122,62,164,89,123,62,80,201,123,62,13,57,124,62,219,168,124,62,186,24,125,62,171,136,125,62,173,248,125,62,192,104,126,62,228,216,126,62,26,73,127,62,96,185,127,62,220,20,128,62,16,77,128,62,77,133,128,62,147,189,128,62,225,245,128,62,55,46,129,62,150,102,129,62,253,158,129,62,109,215,129,62,229,15,130,62,102,72,130,62,238,128,130,62,128,185,130,62,25,242,130,62,187,42,131,62,102,99,131,62,24,156,131,62,211,212,131,62,150,13,132,62,98,70,132,62,53,127,132,62,17,184,132,62,245,240,132,62,226,41,133,62,214,98,133,62,211,155,133,62,216,212,133,62,229,13,134,62,250,70,134,62,23,128,134,62,61,185,134,62,106,242,134,62,160,43,135,62,221,100,135,62,35,158,135,62,112,215,135,62,198,16,136,62,35,74,136,62,137,131,136,62,247,188,136,62,108,246,136,62,233,47,137,62,111,105,137,62,252,162,137,62,145,220,137,62,46,22,138,62,211,79,138,62,127,137,138,62,52,195,138,62,240,252,138,62,180,54,139,62,128,112,139,62,84,170,139,62,47,228,139,62,18,30,140,62,253,87,140,62,239,145,140,62,233,203,140,62,235,5,141,62,245,63,141,62,6,122,141,62,31,180,141,62,63,238,141,62,103,40,142,62,150,98,142,62,205,156,142,62,12,215,142,62,82,17,143,62,159,75,143,62,245,133,143,62,81,192,143,62,181,250,143,62,33,53,144,62,147,111,144,62,14,170,144,62,143,228,144,62,25,31,145,62,169,89,145,62,65,148,145,62,224,206,145,62,134,9,146,62,52,68,146,62,233,126,146,62,165,185,146,62,105,244,146,62,52,47,147,62,6,106,147,62,223,164,147,62,191,223,147,62,167,26,148,62,150,85,148,62,139,144,148,62,136,203,148,62,140,6,149,62,152,65,149,62,170,124,149,62,195,183,149,62,227,242,149,62,11,46,150,62,57,105,150,62,111,164,150,62,171,223,150,62,238,26,151,62,56,86,151,62,138,145,151,62,226,204,151,62,65,8,152,62,167,67,152,62,19,127,152,62,135,186,152,62,1,246,152,62,130,49,153,62,10,109,153,62,153,168,153,62,47,228,153,62,203,31,154,62,110,91,154,62,24,151,154,62,200,210,154,62,127,14,155,62,61,74,155,62,2,134,155,62,205,193,155,62,158,253,155,62,119,57,156,62,85,117,156,62,59,177,156,62,39,237,156,62,25,41,157,62,18,101,157,62,18,161,157,62,24,221,157,62,36,25,158,62,55,85,158,62,80,145,158,62,112,205,158,62,150,9,159,62,195,69,159,62,246,129,159,62,47,190,159,62,111,250,159,62,180,54,160,62,1,115,160,62,83,175,160,62,172,235,160,62,11,40,161,62,112,100,161,62,219,160,161,62,77,221,161,62,196,25,162,62,66,86,162,62,198,146,162,62,81,207,162,62,225,11,163,62,119,72,163,62,20,133,163,62,182,193,163,62,95,254,163,62,13,59,164,62,194,119,164,62,125,180,164,62,61,241,164,62,4,46,165,62,208,106,165,62,162,167,165,62,123,228,165,62,89,33,166,62,61,94,166,62,39,155,166,62,23,216,166,62,12,21,167,62,7,82,167,62,8,143,167,62,15,204,167,62,28,9,168,62,46,70,168,62,70,131,168,62,100,192,168,62,136,253,168,62,177,58,169,62,223,119,169,62,20,181,169,62,78,242,169,62,141,47,170,62,211,108,170,62,29,170,170,62,109,231,170,62,195,36,171,62,31,98,171,62,127,159,171,62,230,220,171,62,81,26,172,62,194,87,172,62,57,149,172,62,181,210,172,62,54,16,173,62,189,77,173,62,73,139,173,62,218,200,173,62,113,6,174,62,13,68,174,62,174,129,174,62,85,191,174,62,0,253,174,62,177,58,175,62,103,120,175,62,35,182,175,62,227,243,175,62,169,49,176,62,116,111,176,62,68,173,176,62,25,235,176,62,243,40,177,62,210,102,177,62,182,164,177,62,160,226,177,62,142,32,178,62,129,94,178,62,121,156,178,62,119,218,178,62,121,24,179,62,128,86,179,62,140,148,179,62,157,210,179,62,178,16,180,62,205,78,180,62,236,140,180,62,16,203,180,62,57,9,181,62,103,71,181,62,154,133,181,62,209,195,181,62,13,2,182,62,78,64,182,62,147,126,182,62,221,188,182,62,44,251,182,62,127,57,183,62,215,119,183,62,52,182,183,62,149,244,183,62,251,50,184,62,101,113,184,62,212,175,184,62,71,238,184,62,191,44,185,62,59,107,185,62,188,169,185,62,65,232,185,62,202,38,186,62,88,101,186,62,235,163,186,62,129,226,186,62,28,33,187,62,188,95,187,62,95,158,187,62,7,221,187,62,180,27,188,62,100,90,188,62,25,153,188,62,210,215,188,62,143,22,189,62,80,85,189,62,22,148,189,62,223,210,189,62,173,17,190,62,127,80,190,62,85,143,190,62,47,206,190,62,13,13,191,62,239,75,191,62,213,138,191,62,191,201,191,62,173,8,192,62,159,71,192,62,149,134,192,62,143,197,192,62,141,4,193,62,143,67,193,62,148,130,193,62,158,193,193,62,171,0,194,62,188,63,194,62,209,126,194,62,234,189,194,62,6,253,194,62,38,60,195,62,74,123,195,62,113,186,195,62,157,249,195,62,204,56,196,62,254,119,196,62,52,183,196,62,110,246,196,62,171,53,197,62,236,116,197,62,49,180,197,62,121,243,197,62,196,50,198,62,19,114,198,62,102,177,198,62,188,240,198,62,21,48,199,62,114,111,199,62,210,174,199,62,54,238,199,62,157,45,200,62,7,109,200,62,117,172,200,62,230,235,200,62,90,43,201,62,209,106,201,62,76,170,201,62,202,233,201,62,75,41,202,62,208,104,202,62,88,168,202,62,226,231,202,62,112,39,203,62,1,103,203,62,149,166,203,62,45,230,203,62,199,37,204,62,100,101,204,62,4,165,204,62,168,228,204,62,78,36,205,62,248,99,205,62,164,163,205,62,83,227,205,62,5,35,206,62,186,98,206,62,114,162,206,62,45,226,206,62,234,33,207,62,171,97,207,62,110,161,207,62,52,225,207,62,253,32,208,62,200,96,208,62,150,160,208,62,103,224,208,62,59,32,209,62,17,96,209,62,234,159,209,62,198,223,209,62,164,31,210,62,133,95,210,62,104,159,210,62,78,223,210,62,55,31,211,62,33,95,211,62,15,159,211,62,255,222,211,62,241,30,212,62,230,94,212,62,221,158,212,62,215,222,212,62,211,30,213,62,209,94,213,62,210,158,213,62,213,222,213,62,219,30,214,62,226,94,214,62,236,158,214,62,248,222,214,62,7,31,215,62,24,95,215,62,42,159,215,62,63,223,215,62,87,31,216,62,112,95,216,62,139,159,216,62,169,223,216,62,200,31,217,62,234,95,217,62,14,160,217,62,51,224,217,62,91,32,218,62,133,96,218,62,176,160,218,62,222,224,218,62,13,33,219,62,63,97,219,62,114,161,219,62,167,225,219,62,222,33,220,62,23,98,220,62,82,162,220,62,142,226,220,62,204,34,221,62,12,99,221,62,78,163,221,62,146,227,221,62,215,35,222,62,29,100,222,62,102,164,222,62,176,228,222,62,252,36,223,62,73,101,223,62,152,165,223,62,232,229,223,62,58,38,224,62,142,102,224,62,227,166,224,62,57,231,224,62,145,39,225,62,234,103,225,62,69,168,225,62,161,232,225,62,255,40,226,62,94,105,226,62,190,169,226,62,32,234,226,62,131,42,227,62,231,106,227,62,76,171,227,62,179,235,227,62,27,44,228,62,132,108,228,62,238,172,228,62,90,237,228,62,199,45,229,62,52,110,229,62,163,174,229,62,19,239,229,62,133,47,230,62,247,111,230,62,106,176,230,62,222,240,230,62,83,49,231,62,202,113,231,62,65,178,231,62,185,242,231,62,50,51,232,62,172,115,232,62,38,180,232,62,162,244,232,62,31,53,233,62,156,117,233,62,26,182,233,62,153,246,233,62,25,55,234,62,153,119,234,62,26,184,234,62,156,248,234,62,31,57,235,62,162,121,235,62,38,186,235,62,170,250,235,62,47,59,236,62,181,123,236,62,59,188,236,62,194,252,236,62,73,61,237,62,209,125,237,62,89,190,237,62,226,254,237,62,107,63,238,62,245,127,238,62,127,192,238,62,10,1,239,62,149,65,239,62,32,130,239,62,171,194,239,62,55,3,240,62,196,67,240,62,80,132,240,62,221,196,240,62,106,5,241,62,247,69,241,62,132,134,241,62,18,199,241,62,160,7,242,62,45,72,242,62,187,136,242,62,74,201,242,62,216,9,243,62,102,74,243,62,244,138,243,62,131,203,243,62,17,12,244,62,159,76,244,62,46,141,244,62,188,205,244,62,74,14,245,62,216,78,245,62,102,143,245,62,244,207,245,62,129,16,246,62,15,81,246,62,156,145,246,62,41,210,246,62,182,18,247,62,67,83,247,62,207,147,247,62,91,212,247,62,231,20,248,62,115,85,248,62,254,149,248,62,136,214,248,62,19,23,249,62,157,87,249,62,38,152,249,62,175,216,249,62,56,25,250,62,192,89,250,62,72,154,250,62,207,218,250,62,86,27,251,62,220,91,251,62,97,156,251,62,230,220,251,62,106,29,252,62,238,93,252,62,113,158,252,62,243,222,252,62,117,31,253,62,245,95,253,62,118,160,253,62,245,224,253,62,116,33,254,62,241,97,254,62,110,162,254,62,235,226,254,62,102,35,255,62,224,99,255,62,90,164,255,62,211,228,255,62,165,18,0,63,225,50,0,63,27,83,0,63,86,115,0,63,144,147,0,63,201,179,0,63,2,212,0,63,58,244,0,63,114,20,1,63,169,52,1,63,224,84,1,63,22,117,1,63,76,149,1,63,129,181,1,63,181,213,1,63,233,245,1,63,28,22,2,63,78,54,2,63,128,86,2,63,178,118,2,63,226,150,2,63,18,183,2,63,65,215,2,63,112,247,2,63,157,23,3,63,203,55,3,63,247,87,3,63,35,120,3,63,78,152,3,63,120,184,3,63,161,216,3,63,202,248,3,63,242,24,4,63,25,57,4,63,63,89,4,63,101,121,4,63,137,153,4,63,173,185,4,63,208,217,4,63,243,249,4,63,20,26,5,63,52,58,5,63,84,90,5,63,115,122,5,63,145,154,5,63,173,186,5,63,202,218,5,63,229,250,5,63,255,26,6,63,24,59,6,63,48,91,6,63,72,123,6,63,94,155,6,63,116,187,6,63,136,219,6,63,155,251,6,63,174,27,7,63,191,59,7,63,208,91,7,63,223,123,7,63,237,155,7,63,250,187,7,63,7,220,7,63,18,252,7,63,28,28,8,63,37,60,8,63,44,92,8,63,51,124,8,63,57,156,8,63,61,188,8,63,64,220,8,63,67,252,8,63,68,28,9,63,68,60,9,63,66,92,9,63,64,124,9,63,60,156,9,63,55,188,9,63,49,220,9,63,41,252,9,63,33,28,10,63,23,60,10,63,12,92,10,63,255,123,10,63,242,155,10,63,227,187,10,63,211,219,10,63,193,251,10,63,174,27,11,63,154,59,11,63,133,91,11,63,110,123,11,63,86,155,11,63,60,187,11,63,33,219,11,63,5,251,11,63,231,26,12,63,200,58,12,63,168,90,12,63,134,122,12,63,98,154,12,63,62,186,12,63,23,218,12,63,240,249,12,63,199,25,13,63,156,57,13,63,112,89,13,63,66,121,13,63,19,153,13,63,227,184,13,63,176,216,13,63,125,248,13,63,72,24,14,63,17,56,14,63,216,87,14,63,159,119,14,63,99,151,14,63,38,183,14,63,232,214,14,63,167,246,14,63,101,22,15,63,34,54,15,63,221,85,15,63,150,117,15,63,78,149,15,63,4,181,15,63,184,212,15,63,106,244,15,63,27,20,16,63,202,51,16,63,120,83,16,63,36,115,16,63,206,146,16,63,118,178,16,63,28,210,16,63,193,241,16,63,100,17,17,63,6,49,17,63,165,80,17,63,67,112,17,63,223,143,17,63,121,175,17,63,17,207,17,63,167,238,17,63,60,14,18,63,206,45,18,63,95,77,18,63,238,108,18,63,123,140,18,63,7,172,18,63,144,203,18,63,23,235,18,63,157,10,19,63,32,42,19,63,162,73,19,63,34,105,19,63,159,136,19,63,27,168,19,63,149,199,19,63,13,231,19,63,131,6,20,63,247,37,20,63,104,69,20,63,216,100,20,63,70,132,20,63,178,163,20,63,27,195,20,63,131,226,20,63,233,1,21,63,76,33,21,63,174,64,21,63,13,96,21,63,106,127,21,63,197,158,21,63,31,190,21,63,117,221,21,63,202,252,21,63,29,28,22,63,109,59,22,63,188,90,22,63,8,122,22,63,82,153,22,63,153,184,22,63,223,215,22,63,34,247,22,63,100,22,23,63,162,53,23,63,223,84,23,63,26,116,23,63,82,147,23,63,136,178,23,63,187,209,23,63,237,240,23,63,28,16,24,63,73,47,24,63,115,78,24,63,155,109,24,63,193,140,24,63,228,171,24,63,6,203,24,63,36,234,24,63,65,9,25,63,91,40,25,63,115,71,25,63,136,102,25,63,155,133,25,63,171,164,25,63,185,195,25,63,197,226,25,63,206,1,26,63,213,32,26,63,217,63,26,63,219,94,26,63,218,125,26,63,215,156,26,63,210,187,26,63,202,218,26,63,191,249,26,63,178,24,27,63,162,55,27,63,144,86,27,63,123,117,27,63,100,148,27,63,74,179,27,63,46,210,27,63,15,241,27,63,237,15,28,63,201,46,28,63,162,77,28,63,121,108,28,63,77,139,28,63,31,170,28,63,237,200,28,63,185,231,28,63,131,6,29,63,74,37,29,63,14,68,29,63,207,98,29,63,142,129,29,63,74,160,29,63,3,191,29,63,186,221,29,63,110,252,29,63,31,27,30,63,205,57,30,63,121,88,30,63,34,119,30,63,200,149,30,63,107,180,30,63,12,211,30,63,170,241,30,63,69,16,31,63,221,46,31,63,114,77,31,63,5,108,31,63,148,138,31,63,33,169,31,63,171,199,31,63,50,230,31,63,182,4,32,63,56,35,32,63,182,65,32,63,50,96,32,63,170,126,32,63,32,157,32,63,147,187,32,63,3,218,32,63,112,248,32,63,218,22,33,63,65,53,33,63,165,83,33,63,6,114,33,63,100,144,33,63,191,174,33,63,23,205,33,63,108,235,33,63,190,9,34,63,13,40,34,63,89,70,34,63,162,100,34,63,232,130,34,63,43,161,34,63,107,191,34,63,167,221,34,63,225,251,34,63,24,26,35,63,75,56,35,63,123,86,35,63,168,116,35,63,211,146,35,63,249,176,35,63,29,207,35,63,62,237,35,63,91,11,36,63,118,41,36,63,141,71,36,63,161,101,36,63,177,131,36,63,191,161,36,63,201,191,36,63,208,221,36,63,212,251,36,63,213,25,37,63,210,55,37,63,204,85,37,63,195,115,37,63,183,145,37,63,167,175,37,63,148,205,37,63,126,235,37,63,101,9,38,63,72,39,38,63,40,69,38,63,4,99,38,63,221,128,38,63,179,158,38,63,134,188,38,63,85,218,38,63,33,248,38,63,233,21,39,63,174,51,39,63,112,81,39,63,46,111,39,63,233,140,39,63,160,170,39,63,84,200,39,63,4,230,39,63,178,3,40,63,91,33,40,63,1,63,40,63,164,92,40,63,67,122,40,63,223,151,40,63,120,181,40,63,12,211,40,63,158,240,40,63,43,14,41,63,182,43,41,63,60,73,41,63,192,102,41,63,63,132,41,63,187,161,41,63,52,191,41,63,169,220,41,63,26,250,41,63,136,23,42,63,242,52,42,63,89,82,42,63,188,111,42,63,28,141,42,63,119,170,42,63,208,199,42,63,36,229,42,63,117,2,43,63,194,31,43,63,12,61,43,63,82,90,43,63,148,119,43,63,211,148,43,63,14,178,43,63,69,207,43,63,120,236,43,63,168,9,44,63,212,38,44,63,252,67,44,63,33,97,44,63,66,126,44,63,95,155,44,63,120,184,44,63,142,213,44,63,159,242,44,63,173,15,45,63,184,44,45,63,190,73,45,63,193,102,45,63,191,131,45,63,186,160,45,63,177,189,45,63,165,218,45,63,148,247,45,63,128,20,46,63,103,49,46,63,75,78,46,63,43,107,46,63,7,136,46,63,224,164,46,63,180,193,46,63,132,222,46,63,81,251,46,63,26,24,47,63,222,52,47,63,159,81,47,63,92,110,47,63,21,139,47,63,202,167,47,63,123,196,47,63,40,225,47,63,209,253,47,63,118,26,48,63,23,55,48,63,180,83,48,63,77,112,48,63,226,140,48,63,115,169,48,63,0,198,48,63,137,226,48,63,14,255,48,63,142,27,49,63,11,56,49,63,132,84,49,63,248,112,49,63,105,141,49,63,214,169,49,63,62,198,49,63,162,226,49,63,2,255,49,63,95,27,50,63,182,55,50,63,10,84,50,63,90,112,50,63,166,140,50,63,237,168,50,63,48,197,50,63,111,225,50,63,170,253,50,63,225,25,51,63,19,54,51,63,66,82,51,63,108,110,51,63,146,138,51,63,180,166,51,63,209,194,51,63,234,222,51,63,0,251,51,63,16,23,52,63,29,51,52,63,37,79,52,63,41,107,52,63,41,135,52,63,37,163,52,63,28,191,52,63,15,219,52,63,253,246,52,63,232,18,53,63,206,46,53,63,176,74,53,63,141,102,53,63,102,130,53,63,59,158,53,63,11,186,53,63,215,213,53,63,159,241,53,63,98,13,54,63,33,41,54,63,220,68,54,63,146,96,54,63,68,124,54,63,241,151,54,63,154,179,54,63,63,207,54,63,223,234,54,63,123,6,55,63,18,34,55,63,165,61,55,63,52,89,55,63,190,116,55,63,67,144,55,63,196,171,55,63,65,199,55,63,185,226,55,63,45,254,55,63,156,25,56,63,7,53,56,63,109,80,56,63,207,107,56,63,44,135,56,63,133,162,56,63,217,189,56,63,40,217,56,63,115,244,56,63,186,15,57,63,252,42,57,63,57,70,57,63,114,97,57,63,166,124,57,63,214,151,57,63,1,179,57,63,40,206,57,63,74,233,57,63,103,4,58,63,128,31,58,63,148,58,58,63,163,85,58,63,174,112,58,63,180,139,58,63,182,166,58,63,179,193,58,63,171,220,58,63,159,247,58,63,142,18,59,63,120,45,59,63,94,72,59,63,63,99,59,63,27,126,59,63,243,152,59,63,197,179,59,63,148,206,59,63,93,233,59,63,34,4,60,63,226,30,60,63,157,57,60,63,84,84,60,63,5,111,60,63,178,137,60,63,91,164,60,63,254,190,60,63,157,217,60,63,55,244,60,63,204,14,61,63,93,41,61,63,232,67,61,63,111,94,61,63,241,120,61,63,110,147,61,63,231,173,61,63,91,200,61,63,201,226,61,63,51,253,61,63,152,23,62,63,249,49,62,63,84,76,62,63,171,102,62,63,252,128,62,63,73,155,62,63,145,181,62,63,212,207,62,63,19,234,62,63,76,4,63,63,128,30,63,63,176,56,63,63,219,82,63,63,0,109,63,63,33,135,63,63,61,161,63,63,84,187,63,63,102,213,63,63,115,239,63,63,123,9,64,63,127,35,64,63,125,61,64,63,118,87,64,63,106,113,64,63,90,139,64,63,68,165,64,63,42,191,64,63,10,217,64,63,229,242,64,63,188,12,65,63,141,38,65,63,90,64,65,63,33,90,65,63,228,115,65,63,161,141,65,63,89,167,65,63,13,193,65,63,187,218,65,63,100,244,65,63,8,14,66,63,167,39,66,63,65,65,66,63,214,90,66,63,102,116,66,63,241,141,66,63,119,167,66,63,248,192,66,63,115,218,66,63,234,243,66,63,91,13,67,63,199,38,67,63,47,64,67,63,145,89,67,63,238,114,67,63,69,140,67,63,152,165,67,63,230,190,67,63,46,216,67,63,113,241,67,63,175,10,68,63,232,35,68,63,28,61,68,63,75,86,68,63,116,111,68,63,153,136,68,63,184,161,68,63,210,186,68,63,230,211,68,63,246,236,68,63,0,6,69,63,5,31,69,63,5,56,69,63,0,81,69,63,245,105,69,63,230,130,69,63,209,155,69,63,182,180,69,63,151,205,69,63,114,230,69,63,72,255,69,63,25,24,70,63,229,48,70,63,171,73,70,63,108,98,70,63,40,123,70,63,222,147,70,63,143,172,70,63,59,197,70,63,226,221,70,63,131,246,70,63,31,15,71,63,182,39,71,63,71,64,71,63,211,88,71,63,90,113,71,63,220,137,71,63,88,162,71,63,207,186,71,63,64,211,71,63,172,235,71,63,19,4,72,63,116,28,72,63,209,52,72,63,39,77,72,63,121,101,72,63,197,125,72,63,11,150,72,63,77,174,72,63,137,198,72,63,191,222,72,63,240,246,72,63,28,15,73,63,66,39,73,63,99,63,73,63,127,87,73,63,149,111,73,63,166,135,73,63,177,159,73,63,183,183,73,63,183,207,73,63,178,231,73,63,168,255,73,63,152,23,74,63,131,47,74,63,104,71,74,63,72,95,74,63,34,119,74,63,247,142,74,63,199,166,74,63,145,190,74,63,85,214,74,63,20,238,74,63,206,5,75,63,130,29,75,63,49,53,75,63,218,76,75,63,126,100,75,63,28,124,75,63,181,147,75,63,72,171,75,63,213,194,75,63,93,218,75,63,224,241,75,63,93,9,76,63,213,32,76,63,71,56,76,63,179,79,76,63,26,103,76,63,124,126,76,63,216,149,76,63,46,173,76,63,127,196,76,63,202,219,76,63,16,243,76,63,80,10,77,63,139,33,77,63,192,56,77,63,240,79,77,63,26,103,77,63,62,126,77,63,93,149,77,63,118,172,77,63,137,195,77,63,151,218,77,63,160,241,77,63,163,8,78,63,160,31,78,63,151,54,78,63,137,77,78,63,118,100,78,63,93,123,78,63,62,146,78,63,25,169,78,63,239,191,78,63,192,214,78,63,138,237,78,63,79,4,79,63,15,27,79,63,201,49,79,63,125,72,79,63,43,95,79,63,212,117,79,63,119,140,79,63,21,163,79,63,172,185,79,63,63,208,79,63,203,230,79,63,82,253,79,63,211,19,80,63,79,42,80,63,197,64,80,63,53,87,80,63,159,109,80,63,4,132,80,63,99,154,80,63,189,176,80,63,16,199,80,63,94,221,80,63,167,243,80,63,233,9,81,63,38,32,81,63,93,54,81,63,143,76,81,63,187,98,81,63,225,120,81,63,1,143,81,63,28,165,81,63,48,187,81,63,64,209,81,63,73,231,81,63,77,253,81,63,75,19,82,63,67,41,82,63,53,63,82,63,34,85,82,63,9,107,82,63,234,128,82,63,198,150,82,63,155,172,82,63,107,194,82,63,53,216,82,63,250,237,82,63,185,3,83,63,113,25,83,63,37,47,83,63,210,68,83,63,121,90,83,63,27,112,83,63,183,133,83,63,77,155,83,63,222,176,83,63,104,198,83,63,237,219,83,63,108,241,83,63,230,6,84,63,89,28,84,63,199,49,84,63,46,71,84,63,145,92,84,63,237,113,84,63,67,135,84,63,148,156,84,63,223,177,84,63,35,199,84,63,99,220,84,63,156,241,84,63,207,6,85,63,253,27,85,63,37,49,85,63,71,70,85,63,99,91,85,63,121,112,85,63,138,133,85,63,149,154,85,63,153,175,85,63,152,196,85,63,146,217,85,63,133,238,85,63,114,3,86,63,90,24,86,63,60,45,86,63,24,66,86,63,238,86,86,63,190,107,86,63,136,128,86,63,76,149,86,63,11,170,86,63,196,190,86,63,118,211,86,63,35,232,86,63,203,252,86,63,108,17,87,63,7,38,87,63,156,58,87,63,44,79,87,63,182,99,87,63,58,120,87,63,183,140,87,63,47,161,87,63,162,181,87,63,14,202,87,63,116,222,87,63,213,242,87,63,47,7,88,63,132,27,88,63,211,47,88,63,28,68,88,63,95,88,88,63,156,108,88,63,211,128,88,63,4,149,88,63,47,169,88,63,85,189,88,63,116,209,88,63,142,229,88,63,162,249,88,63,175,13,89,63,183,33,89,63,185,53,89,63,181,73,89,63,171,93,89,63,155,113,89,63,134,133,89,63,106,153,89,63,72,173,89,63,33,193,89,63,243,212,89,63,192,232,89,63,135,252,89,63,71,16,90,63,2,36,90,63,183,55,90,63,102,75,90,63,15,95,90,63,178,114,90,63,79,134,90,63,230,153,90,63,119,173,90,63,3,193,90,63,136,212,90,63,7,232,90,63,129,251,90,63,244,14,91,63,98,34,91,63,201,53,91,63,43,73,91,63,135,92,91,63,220,111,91,63,44,131,91,63,118,150,91,63,186,169,91,63,248,188,91,63,47,208,91,63,97,227,91,63,141,246,91,63,179,9,92,63,212,28,92,63,238,47,92,63,2,67,92,63,16,86,92,63,24,105,92,63,26,124,92,63,23,143,92,63,13,162,92,63,253,180,92,63,232,199,92,63,204,218,92,63,171,237,92,63,131,0,93,63,86,19,93,63,34,38,93,63,233,56,93,63,169,75,93,63,100,94,93,63,24,113,93,63,199,131,93,63,112,150,93,63,18,169,93,63,175,187,93,63,70,206,93,63,215,224,93,63,97,243,93,63,230,5,94,63,101,24,94,63,222,42,94,63,81,61,94,63,190,79,94,63,36,98,94,63,133,116,94,63,224,134,94,63,53,153,94,63,132,171,94,63,205,189,94,63,16,208,94,63,77,226,94,63,132,244,94,63,181,6,95,63,224,24,95,63,5,43,95,63,36,61,95,63,61,79,95,63,80,97,95,63,93,115,95,63,101,133,95,63,102,151,95,63,97,169,95,63,86,187,95,63,69,205,95,63,46,223,95,63,18,241,95,63,239,2,96,63,198,20,96,63,151,38,96,63,98,56,96,63,40,74,96,63,231,91,96,63,160,109,96,63,84,127,96,63,1,145,96,63,168,162,96,63,73,180,96,63,229,197,96,63,122,215,96,63,10,233,96,63,147,250,96,63,22,12,97,63,148,29,97,63,11,47,97,63,125,64,97,63,232,81,97,63,77,99,97,63,173,116,97,63,6,134,97,63,90,151,97,63,167,168,97,63,239,185,97,63,48,203,97,63,108,220,97,63,162,237,97,63,209,254,97,63,251,15,98,63,30,33,98,63,60,50,98,63,84,67,98,63,101,84,98,63,113,101,98,63,119,118,98,63,119,135,98,63,112,152,98,63,100,169,98,63,82,186,98,63,58,203,98,63,28,220,98,63,247,236,98,63,205,253,98,63,157,14,99,63,103,31,99,63,43,48,99,63,233,64,99,63,161,81,99,63,83,98,99,63,255,114,99,63,165,131,99,63,69,148,99,63,224,164,99,63,116,181,99,63,2,198,99,63,138,214,99,63,13,231,99,63,137,247,99,63,255,7,100,63,112,24,100,63,218,40,100,63,62,57,100,63,157,73,100,63,246,89,100,63,72,106,100,63,149,122,100,63,219,138,100,63,28,155,100,63,87,171,100,63,140,187,100,63,186,203,100,63,227,219,100,63,6,236,100,63,35,252,100,63,58,12,101,63,75,28,101,63,86,44,101,63,91,60,101,63,91,76,101,63,84,92,101,63,71,108,101,63,53,124,101,63,28,140,101,63,254,155,101,63,217,171,101,63,175,187,101,63,126,203,101,63,72,219,101,63,12,235,101,63,202,250,101,63,130,10,102,63,52,26,102,63,224,41,102,63,134,57,102,63,38,73,102,63,193,88,102,63,85,104,102,63,227,119,102,63,108,135,102,63,238,150,102,63,107,166,102,63,226,181,102,63,83,197,102,63,190,212,102,63,35,228,102,63,130,243,102,63,219,2,103,63,46,18,103,63,124,33,103,63,195,48,103,63,5,64,103,63,64,79,103,63,118,94,103,63,166,109,103,63,208,124,103,63,244,139,103,63,18,155,103,63,42,170,103,63,61,185,103,63,73,200,103,63,80,215,103,63,80,230,103,63,75,245,103,63,64,4,104,63,47,19,104,63,24,34,104,63,251,48,104,63,217,63,104,63,176,78,104,63,130,93,104,63,78,108,104,63,20,123,104,63,212,137,104,63,142,152,104,63,66,167,104,63,240,181,104,63,153,196,104,63,60,211,104,63,217,225,104,63,112,240,104,63,1,255,104,63,140,13,105,63,17,28,105,63,145,42,105,63,11,57,105,63,127,71,105,63,237,85,105,63,85,100,105,63,183,114,105,63,20,129,105,63,106,143,105,63,187,157,105,63,6,172,105,63,75,186,105,63,139,200,105,63,196,214,105,63,248,228,105,63,38,243,105,63,78,1,106,63,112,15,106,63,141,29,106,63,163,43,106,63,180,57,106,63,191,71,106,63,196,85,106,63,196,99,106,63,189,113,106,63,177,127,106,63,159,141,106,63,135,155,106,63,106,169,106,63,70,183,106,63,29,197,106,63,238,210,106,63,186,224,106,63,127,238,106,63,63,252,106,63,249,9,107,63,173,23,107,63,91,37,107,63,4,51,107,63,167,64,107,63,68,78,107,63,219,91,107,63,109,105,107,63,249,118,107,63,127,132,107,63,255,145,107,63,122,159,107,63,238,172,107,63,94,186,107,63,199,199,107,63,42,213,107,63,136,226,107,63,224,239,107,63,51,253,107,63,128,10,108,63,198,23,108,63,8,37,108,63,67,50,108,63,121,63,108,63,169,76,108,63,211,89,108,63,248,102,108,63,23,116,108,63,48,129,108,63,68,142,108,63,82,155,108,63,90,168,108,63,92,181,108,63,89,194,108,63,80,207,108,63,65,220,108,63,45,233,108,63,19,246,108,63,243,2,109,63,206,15,109,63,163,28,109,63,114,41,109,63,60,54,109,63,0,67,109,63,190,79,109,63,119,92,109,63,42,105,109,63,215,117,109,63,127,130,109,63,33,143,109,63,189,155,109,63,84,168,109,63,229,180,109,63,113,193,109,63,247,205,109,63,119,218,109,63,242,230,109,63,103,243,109,63,214,255,109,63,64,12,110,63,164,24,110,63,3,37,110,63,91,49,110,63,175,61,110,63,253,73,110,63,69,86,110,63,135,98,110,63,196,110,110,63,252,122,110,63,45,135,110,63,90,147,110,63,128,159,110,63,161,171,110,63,189,183,110,63,211,195,110,63,227,207,110,63,238,219,110,63,243,231,110,63,243,243,110,63,237,255,110,63,226,11,111,63,209,23,111,63,186,35,111,63,158,47,111,63,125,59,111,63,85,71,111,63,41,83,111,63,247,94,111,63,191,106,111,63,130,118,111,63,63,130,111,63,247,141,111,63,169,153,111,63,86,165,111,63,253,176,111,63,159,188,111,63,59,200,111,63,210,211,111,63,99,223,111,63,239,234,111,63,117,246,111,63,246,1,112,63,114,13,112,63,231,24,112,63,88,36,112,63,195,47,112,63,40,59,112,63,137,70,112,63,227,81,112,63,56,93,112,63,136,104,112,63,210,115,112,63,23,127,112,63,87,138,112,63,145,149,112,63,197,160,112,63,244,171,112,63,30,183,112,63,66,194,112,63,97,205,112,63,123,216,112,63,143,227,112,63,157,238,112,63,167,249,112,63,171,4,113,63,169,15,113,63,162,26,113,63,150,37,113,63,132,48,113,63,109,59,113,63,81,70,113,63,47,81,113,63,8,92,113,63,219,102,113,63,170,113,113,63,114,124,113,63,54,135,113,63,244,145,113,63,173,156,113,63,96,167,113,63,14,178,113,63,183,188,113,63,91,199,113,63,249,209,113,63,146,220,113,63,37,231,113,63,179,241,113,63,60,252,113,63,192,6,114,63,62,17,114,63,183,27,114,63,43,38,114,63,154,48,114,63,3,59,114,63,103,69,114,63,197,79,114,63,31,90,114,63,115,100,114,63,194,110,114,63,11,121,114,63,79,131,114,63,143,141,114,63,200,151,114,63,253,161,114,63,44,172,114,63,87,182,114,63,123,192,114,63,155,202,114,63,182,212,114,63,203,222,114,63,219,232,114,63,230,242,114,63,235,252,114,63,236,6,115,63,231,16,115,63,221,26,115,63,206,36,115,63,186,46,115,63,160,56,115,63,130,66,115,63,94,76,115,63,53,86,115,63,7,96,115,63,212,105,115,63,155,115,115,63,94,125,115,63,27,135,115,63,211,144,115,63,134,154,115,63,52,164,115,63,221,173,115,63,128,183,115,63,31,193,115,63,184,202,115,63,77,212,115,63,220,221,115,63,102,231,115,63,235,240,115,63,107,250,115,63,230,3,116,63,92,13,116,63,204,22,116,63,56,32,116,63,159,41,116,63,0,51,116,63,93,60,116,63,180,69,116,63,6,79,116,63,84,88,116,63,156,97,116,63,223,106,116,63,29,116,116,63,87,125,116,63,139,134,116,63,186,143,116,63,228,152,116,63,9,162,116,63,41,171,116,63,68,180,116,63,91,189,116,63,108,198,116,63,120,207,116,63,127,216,116,63,129,225,116,63,127,234,116,63,119,243,116,63,106,252,116,63,89,5,117,63,66,14,117,63,38,23,117,63,6,32,117,63,225,40,117,63,182,49,117,63,135,58,117,63,83,67,117,63,26,76,117,63,220,84,117,63,153,93,117,63,81,102,117,63,4,111,117,63,179,119,117,63,92,128,117,63,1,137,117,63,160,145,117,63,59,154,117,63,209,162,117,63,98,171,117,63,239,179,117,63,118,188,117,63,249,196,117,63,118,205,117,63,239,213,117,63,99,222,117,63,210,230,117,63,61,239,117,63,162,247,117,63,3,0,118,63,95,8,118,63,182,16,118,63,8,25,118,63,86,33,118,63,159,41,118,63,227,49,118,63,34,58,118,63,92,66,118,63,146,74,118,63,195,82,118,63,239,90,118,63,22,99,118,63,57,107,118,63,86,115,118,63,112,123,118,63,132,131,118,63,148,139,118,63,158,147,118,63,165,155,118,63,166,163,118,63,163,171,118,63,155,179,118,63,142,187,118,63,125,195,118,63,103,203,118,63,76,211,118,63,45,219,118,63,9,227,118,63,224,234,118,63,178,242,118,63,128,250,118,63,74,2,119,63,14,10,119,63,206,17,119,63,137,25,119,63,64,33,119,63,242,40,119,63,160,48,119,63,72,56,119,63,237,63,119,63,140,71,119,63,39,79,119,63,190,86,119,63,79,94,119,63,220,101,119,63,101,109,119,63,233,116,119,63,105,124,119,63,228,131,119,63,90,139,119,63,204,146,119,63,57,154,119,63,162,161,119,63,6,169,119,63,101,176,119,63,192,183,119,63,23,191,119,63,105,198,119,63,182,205,119,63,255,212,119,63,68,220,119,63,132,227,119,63,191,234,119,63,246,241,119,63,41,249,119,63,87,0,120,63,129,7,120,63,166,14,120,63,198,21,120,63,227,28,120,63,250,35,120,63,14,43,120,63,28,50,120,63,39,57,120,63,45,64,120,63,46,71,120,63,44,78,120,63,36,85,120,63,25,92,120,63,9,99,120,63,244,105,120,63,219,112,120,63,190,119,120,63,156,126,120,63,118,133,120,63,76,140,120,63,29,147,120,63,234,153,120,63,179,160,120,63,119,167,120,63,55,174,120,63,242,180,120,63,169,187,120,63,92,194,120,63,11,201,120,63,181,207,120,63,91,214,120,63,252,220,120,63,154,227,120,63,51,234,120,63,199,240,120,63,88,247,120,63,228,253,120,63,108,4,121,63,240,10,121,63,111,17,121,63,234,23,121,63,97,30,121,63,211,36,121,63,66,43,121,63,172,49,121,63,18,56,121,63,116,62,121,63,209,68,121,63,42,75,121,63,127,81,121,63,208,87,121,63,29,94,121,63,101,100,121,63,170,106,121,63,234,112,121,63,38,119,121,63,93,125,121,63,145,131,121,63,193,137,121,63,236,143,121,63,19,150,121,63,54,156,121,63,85,162,121,63,112,168,121,63,134,174,121,63,153,180,121,63,167,186,121,63,178,192,121,63,184,198,121,63,186,204,121,63,184,210,121,63,178,216,121,63,168,222,121,63,154,228,121,63,135,234,121,63,113,240,121,63,87,246,121,63,56,252,121,63,22,2,122,63,239,7,122,63,197,13,122,63,150,19,122,63,100,25,122,63,45,31,122,63,243,36,122,63,180,42,122,63,113,48,122,63,43,54,122,63,224,59,122,63,146,65,122,63,63,71,122,63,233,76,122,63,142,82,122,63,48,88,122,63,206,93,122,63,103,99,122,63,253,104,122,63,143,110,122,63,29,116,122,63,167,121,122,63,45,127,122,63,175,132,122,63,45,138,122,63,168,143,122,63,30,149,122,63,145,154,122,63,255,159,122,63,106,165,122,63,209,170,122,63,52,176,122,63,147,181,122,63,239,186,122,63,70,192,122,63,154,197,122,63,234,202,122,63,54,208,122,63,126,213,122,63,194,218,122,63,3,224,122,63,64,229,122,63,121,234,122,63,174,239,122,63,223,244,122,63,13,250,122,63,55,255,122,63,93,4,123,63,127,9,123,63,157,14,123,63,184,19,123,63,207,24,123,63,227,29,123,63,242,34,123,63,254,39,123,63,6,45,123,63,10,50,123,63,11,55,123,63,8,60,123,63,1,65,123,63,247,69,123,63,233,74,123,63,215,79,123,63,193,84,123,63,168,89,123,63,139,94,123,63,107,99,123,63,71,104,123,63,31,109,123,63,243,113,123,63,196,118,123,63,146,123,123,63,91,128,123,63,33,133,123,63,228,137,123,63,163,142,123,63,94,147,123,63,22,152,123,63,202,156,123,63,122,161,123,63,39,166,123,63,208,170,123,63,118,175,123,63,24,180,123,63,183,184,123,63,82,189,123,63,233,193,123,63,125,198,123,63,14,203,123,63,155,207,123,63,36,212,123,63,170,216,123,63,45,221,123,63,172,225,123,63,39,230,123,63,159,234,123,63,19,239,123,63,132,243,123,63,242,247,123,63,92,252,123,63,195,0,124,63,38,5,124,63,133,9,124,63,226,13,124,63,58,18,124,63,144,22,124,63,226,26,124,63,48,31,124,63,123,35,124,63,195,39,124,63,7,44,124,63,72,48,124,63,134,52,124,63,192,56,124,63,247,60,124,63,42,65,124,63,90,69,124,63,135,73,124,63,176,77,124,63,214,81,124,63,249,85,124,63,24,90,124,63,52,94,124,63,77,98,124,63,98,102,124,63,116,106,124,63,131,110,124,63,142,114,124,63,150,118,124,63,155,122,124,63,157,126,124,63,155,130,124,63,150,134,124,63,142,138,124,63,130,142,124,63,116,146,124,63,98,150,124,63,77,154,124,63,52,158,124,63,24,162,124,63,249,165,124,63,215,169,124,63,178,173,124,63,137,177,124,63,94,181,124,63,47,185,124,63,253,188,124,63,199,192,124,63,143,196,124,63,83,200,124,63,20,204,124,63,211,207,124,63,141,211,124,63,69,215,124,63,250,218,124,63,171,222,124,63,90,226,124,63,5,230,124,63,173,233,124,63,82,237,124,63,244,240,124,63,147,244,124,63,46,248,124,63,199,251,124,63,93,255,124,63,239,2,125,63,127,6,125,63,11,10,125,63,148,13,125,63,27,17,125,63,158,20,125,63,30,24,125,63,155,27,125,63,21,31,125,63,140,34,125,63,0,38,125,63,114,41,125,63,224,44,125,63,75,48,125,63,179,51,125,63,24,55,125,63,122,58,125,63,217,61,125,63,54,65,125,63,143,68,125,63,229,71,125,63,56,75,125,63,137,78,125,63,214,81,125,63,33,85,125,63,104,88,125,63,173,91,125,63,239,94,125,63,46,98,125,63,106,101,125,63,163,104,125,63,217,107,125,63,12,111,125,63,61,114,125,63,106,117,125,63,149,120,125,63,189,123,125,63,226,126,125,63,4,130,125,63,36,133,125,63,64,136,125,63,90,139,125,63,112,142,125,63,133,145,125,63,150,148,125,63,164,151,125,63,176,154,125,63,185,157,125,63,191,160,125,63,194,163,125,63,194,166,125,63,192,169,125,63,187,172,125,63,179,175,125,63,168,178,125,63,155,181,125,63,139,184,125,63,120,187,125,63,99,190,125,63,74,193,125,63,48,196,125,63,18,199,125,63,241,201,125,63,206,204,125,63,169,207,125,63,128,210,125,63,85,213,125,63,39,216,125,63,247,218,125,63,196,221,125,63,142,224,125,63,85,227,125,63,26,230,125,63,220,232,125,63,156,235,125,63,89,238,125,63,19,241,125,63,203,243,125,63,128,246,125,63,51,249,125,63,227,251,125,63,144,254,125,63,59,1,126,63,227,3,126,63,137,6,126,63,44,9,126,63,204,11,126,63,106,14,126,63,6,17,126,63,158,19,126,63,53,22,126,63,200,24,126,63,90,27,126,63,232,29,126,63,116,32,126,63,254,34,126,63,133,37,126,63,10,40,126,63,140,42,126,63,12,45,126,63,137,47,126,63,4,50,126,63,124,52,126,63,242,54,126,63,101,57,126,63,214,59,126,63,68,62,126,63,176,64,126,63,26,67,126,63,129,69,126,63,230,71,126,63,72,74,126,63,168,76,126,63,5,79,126,63,96,81,126,63,185,83,126,63,15,86,126,63,99,88,126,63,181,90,126,63,4,93,126,63,81,95,126,63,155,97,126,63],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE+20480);allocate([227,99,126,63,41,102,126,63,108,104,126,63,173,106,126,63,236,108,126,63,40,111,126,63,98,113,126,63,154,115,126,63,208,117,126,63,3,120,126,63,51,122,126,63,98,124,126,63,142,126,126,63,184,128,126,63,224,130,126,63,5,133,126,63,40,135,126,63,73,137,126,63,104,139,126,63,132,141,126,63,159,143,126,63,183,145,126,63,204,147,126,63,224,149,126,63,241,151,126,63,0,154,126,63,13,156,126,63,24,158,126,63,32,160,126,63,38,162,126,63,42,164,126,63,44,166,126,63,44,168,126,63,41,170,126,63,37,172,126,63,30,174,126,63,21,176,126,63,10,178,126,63,253,179,126,63,238,181,126,63,220,183,126,63,201,185,126,63,179,187,126,63,155,189,126,63,129,191,126,63,101,193,126,63,71,195,126,63,39,197,126,63,5,199,126,63,224,200,126,63,186,202,126,63,145,204,126,63,103,206,126,63,58,208,126,63,12,210,126,63,219,211,126,63,168,213,126,63,115,215,126,63,61,217,126,63,4,219,126,63,201,220,126,63,140,222,126,63,77,224,126,63,12,226,126,63,202,227,126,63,133,229,126,63,62,231,126,63,245,232,126,63,170,234,126,63,94,236,126,63,15,238,126,63,190,239,126,63,108,241,126,63,23,243,126,63,193,244,126,63,104,246,126,63,14,248,126,63,178,249,126,63,84,251,126,63,243,252,126,63,145,254,126,63,46,0,127,63,200,1,127,63,96,3,127,63,247,4,127,63,139,6,127,63,30,8,127,63,175,9,127,63,62,11,127,63,203,12,127,63,86,14,127,63,223,15,127,63,103,17,127,63,237,18,127,63,112,20,127,63,242,21,127,63,115,23,127,63,241,24,127,63,110,26,127,63,233,27,127,63,98,29,127,63,217,30,127,63,78,32,127,63,194,33,127,63,52,35,127,63,164,36,127,63,18,38,127,63,127,39,127,63,234,40,127,63,83,42,127,63,186,43,127,63,32,45,127,63,131,46,127,63,230,47,127,63,70,49,127,63,165,50,127,63,2,52,127,63,93,53,127,63,182,54,127,63,14,56,127,63,100,57,127,63,185,58,127,63,12,60,127,63,93,61,127,63,172,62,127,63,250,63,127,63,70,65,127,63,145,66,127,63,217,67,127,63,33,69,127,63,102,70,127,63,170,71,127,63,236,72,127,63,45,74,127,63,108,75,127,63,169,76,127,63,229,77,127,63,31,79,127,63,88,80,127,63,143,81,127,63,196,82,127,63,248,83,127,63,42,85,127,63,91,86,127,63,138,87,127,63,184,88,127,63,228,89,127,63,14,91,127,63,55,92,127,63,94,93,127,63,132,94,127,63,169,95,127,63,203,96,127,63,237,97,127,63,12,99,127,63,42,100,127,63,71,101,127,63,98,102,127,63,124,103,127,63,148,104,127,63,171,105,127,63,192,106,127,63,212,107,127,63,230,108,127,63,247,109,127,63,6,111,127,63,20,112,127,63,33,113,127,63,44,114,127,63,53,115,127,63,61,116,127,63,68,117,127,63,73,118,127,63,77,119,127,63,79,120,127,63,80,121,127,63,80,122,127,63,78,123,127,63,75,124,127,63,70,125,127,63,64,126,127,63,57,127,127,63,48,128,127,63,38,129,127,63,27,130,127,63,14,131,127,63,0,132,127,63,240,132,127,63,223,133,127,63,205,134,127,63,185,135,127,63,164,136,127,63,142,137,127,63,118,138,127,63,93,139,127,63,67,140,127,63,40,141,127,63,11,142,127,63,237,142,127,63,205,143,127,63,173,144,127,63,139,145,127,63,103,146,127,63,67,147,127,63,29,148,127,63,246,148,127,63,205,149,127,63,164,150,127,63,121,151,127,63,77,152,127,63,31,153,127,63,241,153,127,63,193,154,127,63,144,155,127,63,93,156,127,63,42,157,127,63,245,157,127,63,191,158,127,63,136,159,127,63,79,160,127,63,22,161,127,63,219,161,127,63,159,162,127,63,98,163,127,63,36,164,127,63,228,164,127,63,163,165,127,63,98,166,127,63,31,167,127,63,219,167,127,63,149,168,127,63,79,169,127,63,7,170,127,63,190,170,127,63,117,171,127,63,42,172,127,63,221,172,127,63,144,173,127,63,66,174,127,63,242,174,127,63,162,175,127,63,80,176,127,63,253,176,127,63,169,177,127,63,85,178,127,63,254,178,127,63,167,179,127,63,79,180,127,63,246,180,127,63,156,181,127,63,64,182,127,63,228,182,127,63,134,183,127,63,40,184,127,63,200,184,127,63,103,185,127,63,6,186,127,63,163,186,127,63,63,187,127,63,219,187,127,63,117,188,127,63,14,189,127,63,166,189,127,63,61,190,127,63,212,190,127,63,105,191,127,63,253,191,127,63,144,192,127,63,34,193,127,63,180,193,127,63,68,194,127,63,211,194,127,63,98,195,127,63,239,195,127,63,123,196,127,63,7,197,127,63,145,197,127,63,27,198,127,63,163,198,127,63,43,199,127,63,178,199,127,63,56,200,127,63,189,200,127,63,65,201,127,63,196,201,127,63,70,202,127,63,199,202,127,63,71,203,127,63,199,203,127,63,69,204,127,63,195,204,127,63,64,205,127,63,187,205,127,63,54,206,127,63,177,206,127,63,42,207,127,63,162,207,127,63,26,208,127,63,144,208,127,63,6,209,127,63,123,209,127,63,239,209,127,63,98,210,127,63,213,210,127,63,70,211,127,63,183,211,127,63,39,212,127,63,150,212,127,63,4,213,127,63,114,213,127,63,222,213,127,63,74,214,127,63,181,214,127,63,32,215,127,63,137,215,127,63,242,215,127,63,89,216,127,63,192,216,127,63,39,217,127,63,140,217,127,63,241,217,127,63,85,218,127,63,184,218,127,63,27,219,127,63,124,219,127,63,221,219,127,63,61,220,127,63,157,220,127,63,251,220,127,63,89,221,127,63,183,221,127,63,19,222,127,63,111,222,127,63,202,222,127,63,36,223,127,63,126,223,127,63,215,223,127,63,47,224,127,63,134,224,127,63,221,224,127,63,51,225,127,63,137,225,127,63,221,225,127,63,49,226,127,63,133,226,127,63,215,226,127,63,41,227,127,63,122,227,127,63,203,227,127,63,27,228,127,63,106,228,127,63,185,228,127,63,7,229,127,63,84,229,127,63,161,229,127,63,237,229,127,63,56,230,127,63,131,230,127,63,205,230,127,63,23,231,127,63,96,231,127,63,168,231,127,63,239,231,127,63,54,232,127,63,125,232,127,63,195,232,127,63,8,233,127,63,76,233,127,63,144,233,127,63,212,233,127,63,23,234,127,63,89,234,127,63,154,234,127,63,219,234,127,63,28,235,127,63,92,235,127,63,155,235,127,63,218,235,127,63,24,236,127,63,86,236,127,63,147,236,127,63,207,236,127,63,11,237,127,63,71,237,127,63,130,237,127,63,188,237,127,63,246,237,127,63,47,238,127,63,104,238,127,63,160,238,127,63,216,238,127,63,15,239,127,63,69,239,127,63,123,239,127,63,177,239,127,63,230,239,127,63,27,240,127,63,79,240,127,63,130,240,127,63,182,240,127,63,232,240,127,63,26,241,127,63,76,241,127,63,125,241,127,63,174,241,127,63,222,241,127,63,14,242,127,63,61,242,127,63,108,242,127,63,154,242,127,63,200,242,127,63,245,242,127,63,34,243,127,63,79,243,127,63,123,243,127,63,166,243,127,63,209,243,127,63,252,243,127,63,38,244,127,63,80,244,127,63,121,244,127,63,162,244,127,63,203,244,127,63,243,244,127,63,27,245,127,63,66,245,127,63,105,245,127,63,143,245,127,63,181,245,127,63,219,245,127,63,0,246,127,63,37,246,127,63,73,246,127,63,109,246,127,63,145,246,127,63,180,246,127,63,215,246,127,63,250,246,127,63,28,247,127,63,62,247,127,63,95,247,127,63,128,247,127,63,160,247,127,63,193,247,127,63,225,247,127,63,0,248,127,63,31,248,127,63,62,248,127,63,93,248,127,63,123,248,127,63,152,248,127,63,182,248,127,63,211,248,127,63,240,248,127,63,12,249,127,63,40,249,127,63,68,249,127,63,95,249,127,63,122,249,127,63,149,249,127,63,175,249,127,63,202,249,127,63,227,249,127,63,253,249,127,63,22,250,127,63,47,250,127,63,71,250,127,63,96,250,127,63,120,250,127,63,143,250,127,63,166,250,127,63,190,250,127,63,212,250,127,63,235,250,127,63,1,251,127,63,23,251,127,63,44,251,127,63,66,251,127,63,87,251,127,63,108,251,127,63,128,251,127,63,148,251,127,63,168,251,127,63,188,251,127,63,208,251,127,63,227,251,127,63,246,251,127,63,8,252,127,63,27,252,127,63,45,252,127,63,63,252,127,63,81,252,127,63,98,252,127,63,115,252,127,63,132,252,127,63,149,252,127,63,165,252,127,63,182,252,127,63,198,252,127,63,213,252,127,63,229,252,127,63,244,252,127,63,3,253,127,63,18,253,127,63,33,253,127,63,47,253,127,63,62,253,127,63,76,253,127,63,89,253,127,63,103,253,127,63,116,253,127,63,130,253,127,63,143,253,127,63,155,253,127,63,168,253,127,63,181,253,127,63,193,253,127,63,205,253,127,63,217,253,127,63,228,253,127,63,240,253,127,63,251,253,127,63,6,254,127,63,17,254,127,63,28,254,127,63,38,254,127,63,49,254,127,63,59,254,127,63,69,254,127,63,79,254,127,63,89,254,127,63,98,254,127,63,108,254,127,63,117,254,127,63,126,254,127,63,135,254,127,63,144,254,127,63,152,254,127,63,161,254,127,63,169,254,127,63,177,254,127,63,185,254,127,63,193,254,127,63,201,254,127,63,208,254,127,63,216,254,127,63,223,254,127,63,230,254,127,63,237,254,127,63,244,254,127,63,251,254,127,63,2,255,127,63,8,255,127,63,14,255,127,63,21,255,127,63,27,255,127,63,33,255,127,63,39,255,127,63,45,255,127,63,50,255,127,63,56,255,127,63,61,255,127,63,67,255,127,63,72,255,127,63,77,255,127,63,82,255,127,63,87,255,127,63,92,255,127,63,96,255,127,63,101,255,127,63,105,255,127,63,110,255,127,63,114,255,127,63,118,255,127,63,122,255,127,63,126,255,127,63,130,255,127,63,134,255,127,63,138,255,127,63,142,255,127,63,145,255,127,63,149,255,127,63,152,255,127,63,155,255,127,63,159,255,127,63,162,255,127,63,165,255,127,63,168,255,127,63,171,255,127,63,174,255,127,63,176,255,127,63,179,255,127,63,182,255,127,63,184,255,127,63,187,255,127,63,189,255,127,63,192,255,127,63,194,255,127,63,196,255,127,63,198,255,127,63,201,255,127,63,203,255,127,63,205,255,127,63,207,255,127,63,209,255,127,63,210,255,127,63,212,255,127,63,214,255,127,63,216,255,127,63,217,255,127,63,219,255,127,63,220,255,127,63,222,255,127,63,223,255,127,63,225,255,127,63,226,255,127,63,227,255,127,63,229,255,127,63,230,255,127,63,231,255,127,63,232,255,127,63,233,255,127,63,234,255,127,63,235,255,127,63,236,255,127,63,237,255,127,63,238,255,127,63,239,255,127,63,240,255,127,63,241,255,127,63,241,255,127,63,242,255,127,63,243,255,127,63,244,255,127,63,244,255,127,63,245,255,127,63,246,255,127,63,246,255,127,63,247,255,127,63,247,255,127,63,248,255,127,63,248,255,127,63,249,255,127,63,249,255,127,63,250,255,127,63,250,255,127,63,250,255,127,63,251,255,127,63,251,255,127,63,251,255,127,63,252,255,127,63,252,255,127,63,252,255,127,63,253,255,127,63,253,255,127,63,253,255,127,63,253,255,127,63,254,255,127,63,254,255,127,63,254,255,127,63,254,255,127,63,254,255,127,63,254,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,255,255,127,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,128,63,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,112,194,0,0,120,194,0,0,120,194,0,0,130,194,0,0,146,194,0,0,138,194,0,0,136,194,0,0,136,194,0,0,134,194,0,0,140,194,0,0,140,194,0,0,144,194,0,0,148,194,0,0,150,194,0,0,158,194,0,0,158,194,0,0,160,194,0,0,166,194,0,0,176,194,0,0,186,194,0,0,200,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,84,194,0,0,116,194,0,0,132,194,0,0,132,194,0,0,136,194,0,0,134,194,0,0,140,194,0,0,152,194,0,0,152,194,0,0,144,194,0,0,146,194,0,0,150,194,0,0,152,194,0,0,156,194,0,0,158,194,0,0,166,194,0,0,176,194,0,0,186,194,0,0,200,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,20,194,0,0,20,194,0,0,20,194,0,0,20,194,0,0,20,194,0,0,20,194,0,0,20,194,0,0,20,194,0,0,24,194,0,0,32,194,0,0,40,194,0,0,56,194,0,0,64,194,0,0,84,194,0,0,92,194,0,0,120,194,0,0,130,194,0,0,104,194,0,0,96,194,0,0,96,194,0,0,116,194,0,0,112,194,0,0,130,194,0,0,134,194,0,0,138,194,0,0,142,194,0,0,154,194,0,0,154,194,0,0,156,194,0,0,160,194,0,0,164,194,0,0,168,194,0,0,176,194,0,0,186,194,0,0,196,194,0,0,212,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,200,193,0,0,200,193,0,0,200,193,0,0,200,193,0,0,200,193,0,0,200,193,0,0,200,193,0,0,200,193,0,0,200,193,0,0,208,193,0,0,216,193,0,0,232,193,0,0,0,194,0,0,24,194,0,0,64,194,0,0,80,194,0,0,80,194,0,0,72,194,0,0,64,194,0,0,64,194,0,0,76,194,0,0,80,194,0,0,88,194,0,0,112,194,0,0,134,194,0,0,134,194,0,0,132,194,0,0,136,194,0,0,138,194,0,0,146,194,0,0,146,194,0,0,152,194,0,0,160,194,0,0,162,194,0,0,162,194,0,0,170,194,0,0,170,194,0,0,172,194,0,0,176,194,0,0,186,194,0,0,200,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,128,193,0,0,128,193,0,0,128,193,0,0,128,193,0,0,128,193,0,0,128,193,0,0,128,193,0,0,128,193,0,0,136,193,0,0,152,193,0,0,160,193,0,0,176,193,0,0,208,193,0,0,224,193,0,0,248,193,0,0,32,194,0,0,60,194,0,0,28,194,0,0,28,194,0,0,32,194,0,0,40,194,0,0,44,194,0,0,60,194,0,0,76,194,0,0,100,194,0,0,80,194,0,0,92,194,0,0,92,194,0,0,112,194,0,0,104,194,0,0,120,194,0,0,124,194,0,0,140,194,0,0,134,194,0,0,138,194,0,0,144,194,0,0,146,194,0,0,154,194,0,0,160,194,0,0,164,194,0,0,166,194,0,0,174,194,0,0,180,194,0,0,188,194,0,0,196,194,0,0,208,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,0,193,0,0,0,193,0,0,0,193,0,0,0,193,0,0,0,193,0,0,0,193,0,0,0,193,0,0,0,193,0,0,0,193,0,0,0,193,0,0,32,193,0,0,48,193,0,0,112,193,0,0,152,193,0,0,200,193,0,0,240,193,0,0,8,194,0,0,248,193,0,0,240,193,0,0,248,193,0,0,232,193,0,0,0,194,0,0,12,194,0,0,40,194,0,0,64,194,0,0,40,194,0,0,48,194,0,0,56,194,0,0,72,194,0,0,72,194,0,0,76,194,0,0,80,194,0,0,108,194,0,0,88,194,0,0,92,194,0,0,92,194,0,0,104,194,0,0,120,194,0,0,124,194,0,0,132,194,0,0,144,194,0,0,146,194,0,0,152,194,0,0,150,194,0,0,156,194,0,0,160,194,0,0,160,194,0,0,162,194,0,0,168,194,0,0,176,194,0,0,180,194,0,0,188,194,0,0,196,194,0,0,202,194,0,0,212,194,0,0,220,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,134,194,0,0,134,194,0,0,134,194,0,0,152,194,0,0,144,194,0,0,142,194,0,0,148,194,0,0,152,194,0,0,152,194,0,0,150,194,0,0,156,194,0,0,158,194,0,0,158,194,0,0,162,194,0,0,166,194,0,0,172,194,0,0,178,194,0,0,186,194,0,0,194,194,0,0,200,194,0,0,210,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,64,194,0,0,76,194,0,0,92,194,0,0,108,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,134,194,0,0,132,194,0,0,136,194,0,0,138,194,0,0,140,194,0,0,148,194,0,0,158,194,0,0,154,194,0,0,154,194,0,0,156,194,0,0,160,194,0,0,162,194,0,0,164,194,0,0,168,194,0,0,172,194,0,0,176,194,0,0,182,194,0,0,190,194,0,0,200,194,0,0,216,194,0,0,232,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,20,194,0,0,20,194,0,0,36,194,0,0,48,194,0,0,64,194,0,0,76,194,0,0,104,194,0,0,120,194,0,0,112,194,0,0,100,194,0,0,108,194,0,0,108,194,0,0,112,194,0,0,124,194,0,0,130,194,0,0,144,194,0,0,142,194,0,0,140,194,0,0,144,194,0,0,148,194,0,0,154,194,0,0,152,194,0,0,156,194,0,0,162,194,0,0,162,194,0,0,160,194,0,0,166,194,0,0,172,194,0,0,182,194,0,0,192,194,0,0,200,194,0,0,210,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,224,193,0,0,224,193,0,0,224,193,0,0,224,193,0,0,224,193,0,0,224,193,0,0,224,193,0,0,224,193,0,0,224,193,0,0,240,193,0,0,0,194,0,0,0,194,0,0,4,194,0,0,12,194,0,0,36,194,0,0,68,194,0,0,72,194,0,0,68,194,0,0,60,194,0,0,64,194,0,0,64,194,0,0,80,194,0,0,76,194,0,0,100,194,0,0,130,194,0,0,116,194,0,0,108,194,0,0,116,194,0,0,128,194,0,0,138,194,0,0,140,194,0,0,148,194,0,0,154,194,0,0,154,194,0,0,156,194,0,0,162,194,0,0,168,194,0,0,170,194,0,0,174,194,0,0,180,194,0,0,184,194,0,0,192,194,0,0,200,194,0,0,214,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,152,193,0,0,152,193,0,0,152,193,0,0,152,193,0,0,152,193,0,0,152,193,0,0,152,193,0,0,152,193,0,0,160,193,0,0,168,193,0,0,184,193,0,0,216,193,0,0,240,193,0,0,12,194,0,0,16,194,0,0,36,194,0,0,56,194,0,0,48,194,0,0,40,194,0,0,32,194,0,0,36,194,0,0,36,194,0,0,44,194,0,0,64,194,0,0,92,194,0,0,84,194,0,0,80,194,0,0,84,194,0,0,96,194,0,0,108,194,0,0,104,194,0,0,112,194,0,0,134,194,0,0,132,194,0,0,138,194,0,0,142,194,0,0,144,194,0,0,150,194,0,0,158,194,0,0,162,194,0,0,168,194,0,0,174,194,0,0,180,194,0,0,186,194,0,0,194,194,0,0,202,194,0,0,214,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,16,193,0,0,16,193,0,0,16,193,0,0,16,193,0,0,16,193,0,0,16,193,0,0,16,193,0,0,16,193,0,0,48,193,0,0,64,193,0,0,64,193,0,0,112,193,0,0,128,193,0,0,160,193,0,0,184,193,0,0,240,193,0,0,20,194,0,0,8,194,0,0,4,194,0,0,8,194,0,0,248,193,0,0,0,194,0,0,0,194,0,0,24,194,0,0,60,194,0,0,48,194,0,0,36,194,0,0,32,194,0,0,60,194,0,0,68,194,0,0,56,194,0,0,56,194,0,0,104,194,0,0,72,194,0,0,72,194,0,0,88,194,0,0,104,194,0,0,120,194,0,0,128,194,0,0,134,194,0,0,134,194,0,0,140,194,0,0,144,194,0,0,152,194,0,0,158,194,0,0,166,194,0,0,174,194,0,0,182,194,0,0,192,194,0,0,200,194,0,0,208,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,120,194,0,0,120,194,0,0,120,194,0,0,120,194,0,0,120,194,0,0,120,194,0,0,120,194,0,0,120,194,0,0,120,194,0,0,120,194,0,0,124,194,0,0,128,194,0,0,132,194,0,0,134,194,0,0,132,194,0,0,136,194,0,0,150,194,0,0,144,194,0,0,152,194,0,0,150,194,0,0,152,194,0,0,156,194,0,0,158,194,0,0,164,194,0,0,168,194,0,0,170,194,0,0,180,194,0,0,188,194,0,0,202,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,108,194,0,0,108,194,0,0,108,194,0,0,108,194,0,0,108,194,0,0,108,194,0,0,108,194,0,0,108,194,0,0,108,194,0,0,108,194,0,0,108,194,0,0,112,194,0,0,112,194,0,0,116,194,0,0,124,194,0,0,132,194,0,0,142,194,0,0,136,194,0,0,140,194,0,0,140,194,0,0,142,194,0,0,144,194,0,0,144,194,0,0,150,194,0,0,162,194,0,0,156,194,0,0,158,194,0,0,164,194,0,0,166,194,0,0,172,194,0,0,180,194,0,0,194,194,0,0,206,194,0,0,226,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,84,194,0,0,84,194,0,0,84,194,0,0,84,194,0,0,84,194,0,0,84,194,0,0,84,194,0,0,84,194,0,0,84,194,0,0,88,194,0,0,92,194,0,0,100,194,0,0,96,194,0,0,100,194,0,0,92,194,0,0,116,194,0,0,130,194,0,0,112,194,0,0,112,194,0,0,120,194,0,0,124,194,0,0,124,194,0,0,132,194,0,0,136,194,0,0,148,194,0,0,146,194,0,0,150,194,0,0,150,194,0,0,156,194,0,0,160,194,0,0,160,194,0,0,164,194,0,0,170,194,0,0,180,194,0,0,192,194,0,0,202,194,0,0,216,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,56,194,0,0,56,194,0,0,56,194,0,0,56,194,0,0,56,194,0,0,56,194,0,0,56,194,0,0,56,194,0,0,56,194,0,0,56,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,60,194,0,0,64,194,0,0,76,194,0,0,100,194,0,0,76,194,0,0,68,194,0,0,72,194,0,0,76,194,0,0,84,194,0,0,88,194,0,0,108,194,0,0,132,194,0,0,112,194,0,0,120,194,0,0,134,194,0,0,134,194,0,0,140,194,0,0,144,194,0,0,150,194,0,0,152,194,0,0,156,194,0,0,162,194,0,0,170,194,0,0,176,194,0,0,188,194,0,0,194,194,0,0,208,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,16,194,0,0,28,194,0,0,36,194,0,0,40,194,0,0,40,194,0,0,28,194,0,0,24,194,0,0,36,194,0,0,44,194,0,0,80,194,0,0,48,194,0,0,32,194,0,0,28,194,0,0,20,194,0,0,20,194,0,0,32,194,0,0,60,194,0,0,88,194,0,0,72,194,0,0,64,194,0,0,72,194,0,0,92,194,0,0,116,194,0,0,108,194,0,0,120,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,138,194,0,0,138,194,0,0,146,194,0,0,148,194,0,0,148,194,0,0,150,194,0,0,154,194,0,0,158,194,0,0,164,194,0,0,174,194,0,0,182,194,0,0,190,194,0,0,200,194,0,0,216,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,224,193,0,0,208,193,0,0,192,193,0,0,176,193,0,0,160,193,0,0,160,193,0,0,184,193,0,0,232,193,0,0,240,193,0,0,248,193,0,0,224,193,0,0,216,193,0,0,224,193,0,0,224,193,0,0,224,193,0,0,12,194,0,0,32,194,0,0,4,194,0,0,0,194,0,0,232,193,0,0,240,193,0,0,240,193,0,0,240,193,0,0,20,194,0,0,52,194,0,0,36,194,0,0,20,194,0,0,24,194,0,0,52,194,0,0,60,194,0,0,60,194,0,0,64,194,0,0,84,194,0,0,68,194,0,0,64,194,0,0,72,194,0,0,68,194,0,0,68,194,0,0,76,194,0,0,80,194,0,0,104,194,0,0,96,194,0,0,100,194,0,0,96,194,0,0,112,194,0,0,116,194,0,0,120,194,0,0,140,194,0,0,144,194,0,0,148,194,0,0,156,194,0,0,166,194,0,0,176,194,0,0,186,194,0,0,200,194,0,0,212,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,210,194,0,0,200,194,0,0,190,194,0,0,182,194,0,0,174,194,0,0,166,194,0,0,160,194,0,0,156,194,0,0,152,194,0,0,156,194,0,0,156,194,0,0,162,194,0,0,166,194,0,0,170,194,0,0,172,194,0,0,170,194,0,0,172,194,0,0,174,194,0,0,180,194,0,0,194,194,0,0,214,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,210,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,170,194,0,0,162,194,0,0,154,194,0,0,146,194,0,0,140,194,0,0,134,194,0,0,134,194,0,0,136,194,0,0,150,194,0,0,146,194,0,0,140,194,0,0,138,194,0,0,140,194,0,0,144,194,0,0,150,194,0,0,158,194,0,0,168,194,0,0,166,194,0,0,168,194,0,0,172,194,0,0,176,194,0,0,178,194,0,0,178,194,0,0,186,194,0,0,196,194,0,0,210,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,170,194,0,0,160,194,0,0,152,194,0,0,142,194,0,0,136,194,0,0,136,194,0,0,130,194,0,0,124,194,0,0,124,194,0,0,120,194,0,0,120,194,0,0,128,194,0,0,130,194,0,0,128,194,0,0,116,194,0,0,120,194,0,0,124,194,0,0,128,194,0,0,132,194,0,0,136,194,0,0,146,194,0,0,146,194,0,0,148,194,0,0,150,194,0,0,152,194,0,0,162,194,0,0,166,194,0,0,170,194,0,0,176,194,0,0,178,194,0,0,184,194,0,0,190,194,0,0,200,194,0,0,216,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,160,194,0,0,150,194,0,0,142,194,0,0,136,194,0,0,130,194,0,0,124,194,0,0,120,194,0,0,116,194,0,0,116,194,0,0,116,194,0,0,116,194,0,0,108,194,0,0,96,194,0,0,100,194,0,0,84,194,0,0,72,194,0,0,104,194,0,0,80,194,0,0,72,194,0,0,72,194,0,0,80,194,0,0,84,194,0,0,88,194,0,0,104,194,0,0,134,194,0,0,124,194,0,0,134,194,0,0,136,194,0,0,144,194,0,0,150,194,0,0,156,194,0,0,160,194,0,0,162,194,0,0,162,194,0,0,164,194,0,0,170,194,0,0,178,194,0,0,180,194,0,0,186,194,0,0,194,194,0,0,202,194,0,0,214,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,130,194,0,0,116,194,0,0,108,194,0,0,100,194,0,0,96,194,0,0,92,194,0,0,92,194,0,0,96,194,0,0,96,194,0,0,100,194,0,0,92,194,0,0,84,194,0,0,80,194,0,0,60,194,0,0,48,194,0,0,48,194,0,0,72,194,0,0,48,194,0,0,36,194,0,0,28,194,0,0,28,194,0,0,40,194,0,0,32,194,0,0,56,194,0,0,76,194,0,0,68,194,0,0,72,194,0,0,84,194,0,0,88,194,0,0,124,194,0,0,112,194,0,0,116,194,0,0,120,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,140,194,0,0,146,194,0,0,148,194,0,0,150,194,0,0,152,194,0,0,150,194,0,0,158,194,0,0,170,194,0,0,178,194,0,0,182,194,0,0,192,194,0,0,204,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,80,194,0,0,72,194,0,0,68,194,0,0,68,194,0,0,64,194,0,0,64,194,0,0,64,194,0,0,68,194,0,0,72,194,0,0,72,194,0,0,68,194,0,0,56,194,0,0,44,194,0,0,28,194,0,0,12,194,0,0,4,194,0,0,24,194,0,0,16,194,0,0,0,194,0,0,232,193,0,0,0,194,0,0,0,194,0,0,0,194,0,0,12,194,0,0,48,194,0,0,28,194,0,0,24,194,0,0,24,194,0,0,56,194,0,0,72,194,0,0,52,194,0,0,56,194,0,0,84,194,0,0,72,194,0,0,72,194,0,0,72,194,0,0,88,194,0,0,88,194,0,0,84,194,0,0,84,194,0,0,96,194,0,0,100,194,0,0,108,194,0,0,132,194,0,0,140,194,0,0,144,194,0,0,148,194,0,0,158,194,0,0,166,194,0,0,170,194,0,0,180,194,0,0,194,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,210,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,172,194,0,0,160,194,0,0,150,194,0,0,150,194,0,0,158,194,0,0,160,194,0,0,158,194,0,0,160,194,0,0,162,194,0,0,164,194,0,0,176,194,0,0,190,194,0,0,206,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,206,194,0,0,196,194,0,0,186,194,0,0,176,194,0,0,166,194,0,0,158,194,0,0,156,194,0,0,150,194,0,0,142,194,0,0,134,194,0,0,136,194,0,0,146,194,0,0,146,194,0,0,144,194,0,0,146,194,0,0,150,194,0,0,154,194,0,0,160,194,0,0,164,194,0,0,176,194,0,0,186,194,0,0,200,194,0,0,214,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,210,194,0,0,202,194,0,0,192,194,0,0,180,194,0,0,172,194,0,0,162,194,0,0,154,194,0,0,146,194,0,0,138,194,0,0,132,194,0,0,116,194,0,0,120,194,0,0,132,194,0,0,128,194,0,0,120,194,0,0,130,194,0,0,132,194,0,0,140,194,0,0,144,194,0,0,152,194,0,0,162,194,0,0,160,194,0,0,168,194,0,0,180,194,0,0,190,194,0,0,204,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,206,194,0,0,194,194,0,0,184,194,0,0,176,194,0,0,166,194,0,0,158,194,0,0,148,194,0,0,140,194,0,0,132,194,0,0,108,194,0,0,84,194,0,0,104,194,0,0,120,194,0,0,92,194,0,0,88,194,0,0,88,194,0,0,88,194,0,0,104,194,0,0,116,194,0,0,120,194,0,0,144,194,0,0,140,194,0,0,144,194,0,0,150,194,0,0,156,194,0,0,160,194,0,0,162,194,0,0,160,194,0,0,166,194,0,0,166,194,0,0,176,194,0,0,186,194,0,0,200,194,0,0,214,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,170,194,0,0,160,194,0,0,150,194,0,0,140,194,0,0,132,194,0,0,120,194,0,0,96,194,0,0,64,194,0,0,48,194,0,0,64,194,0,0,56,194,0,0,56,194,0,0,44,194,0,0,56,194,0,0,64,194,0,0,64,194,0,0,76,194,0,0,104,194,0,0,104,194,0,0,108,194,0,0,112,194,0,0,120,194,0,0,120,194,0,0,116,194,0,0,116,194,0,0,130,194,0,0,128,194,0,0,130,194,0,0,136,194,0,0,140,194,0,0,148,194,0,0,150,194,0,0,156,194,0,0,162,194,0,0,172,194,0,0,190,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,170,194,0,0,160,194,0,0,150,194,0,0,140,194,0,0,130,194,0,0,116,194,0,0,92,194,0,0,68,194,0,0,28,194,0,0,4,194,0,0,32,194,0,0,12,194,0,0,0,194,0,0,24,194,0,0,32,194,0,0,4,194,0,0,12,194,0,0,20,194,0,0,56,194,0,0,36,194,0,0,52,194,0,0,48,194,0,0,56,194,0,0,40,194,0,0,52,194,0,0,56,194,0,0,80,194,0,0,72,194,0,0,72,194,0,0,72,194,0,0,88,194,0,0,88,194,0,0,92,194,0,0,100,194,0,0,120,194,0,0,128,194,0,0,132,194,0,0,136,194,0,0,140,194,0,0,152,194,0,0,162,194,0,0,180,194,0,0,200,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,196,194,0,0,180,194,0,0,170,194,0,0,164,194,0,0,166,194,0,0,160,194,0,0,156,194,0,0,168,194,0,0,158,194,0,0,160,194,0,0,166,194,0,0,174,194,0,0,178,194,0,0,182,194,0,0,186,194,0,0,198,194,0,0,212,194,0,0,234,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,196,194,0,0,180,194,0,0,170,194,0,0,160,194,0,0,150,194,0,0,140,194,0,0,136,194,0,0,148,194,0,0,144,194,0,0,148,194,0,0,154,194,0,0,160,194,0,0,164,194,0,0,170,194,0,0,174,194,0,0,184,194,0,0,178,194,0,0,182,194,0,0,190,194,0,0,200,194,0,0,212,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,196,194,0,0,180,194,0,0,166,194,0,0,150,194,0,0,142,194,0,0,124,194,0,0,128,194,0,0,134,194,0,0,120,194,0,0,128,194,0,0,134,194,0,0,140,194,0,0,146,194,0,0,154,194,0,0,162,194,0,0,168,194,0,0,166,194,0,0,170,194,0,0,178,194,0,0,180,194,0,0,186,194,0,0,196,194,0,0,208,194,0,0,218,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE+30720);allocate([0,192,121,196,0,192,121,196,0,0,206,194,0,0,192,194,0,0,176,194,0,0,162,194,0,0,150,194,0,0,136,194,0,0,104,194,0,0,88,194,0,0,96,194,0,0,88,194,0,0,96,194,0,0,96,194,0,0,104,194,0,0,112,194,0,0,124,194,0,0,132,194,0,0,148,194,0,0,138,194,0,0,144,194,0,0,144,194,0,0,150,194,0,0,148,194,0,0,154,194,0,0,162,194,0,0,162,194,0,0,164,194,0,0,168,194,0,0,174,194,0,0,186,194,0,0,192,194,0,0,198,194,0,0,208,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,204,194,0,0,192,194,0,0,182,194,0,0,170,194,0,0,160,194,0,0,148,194,0,0,136,194,0,0,112,194,0,0,76,194,0,0,56,194,0,0,64,194,0,0,56,194,0,0,44,194,0,0,52,194,0,0,60,194,0,0,60,194,0,0,68,194,0,0,64,194,0,0,96,194,0,0,84,194,0,0,92,194,0,0,104,194,0,0,100,194,0,0,124,194,0,0,104,194,0,0,112,194,0,0,132,194,0,0,128,194,0,0,134,194,0,0,140,194,0,0,140,194,0,0,148,194,0,0,154,194,0,0,168,194,0,0,172,194,0,0,178,194,0,0,182,194,0,0,186,194,0,0,188,194,0,0,202,194,0,0,218,194,0,0,236,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,206,194,0,0,196,194,0,0,186,194,0,0,176,194,0,0,166,194,0,0,156,194,0,0,146,194,0,0,136,194,0,0,112,194,0,0,84,194,0,0,48,194,0,0,12,194,0,0,24,194,0,0,24,194,0,0,8,194,0,0,8,194,0,0,16,194,0,0,32,194,0,0,36,194,0,0,48,194,0,0,76,194,0,0,52,194,0,0,56,194,0,0,60,194,0,0,56,194,0,0,88,194,0,0,72,194,0,0,68,194,0,0,72,194,0,0,72,194,0,0,72,194,0,0,76,194,0,0,88,194,0,0,100,194,0,0,104,194,0,0,112,194,0,0,132,194,0,0,132,194,0,0,132,194,0,0,128,194,0,0,130,194,0,0,136,194,0,0,154,194,0,0,164,194,0,0,174,194,0,0,190,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,204,194,0,0,194,194,0,0,184,194,0,0,174,194,0,0,166,194,0,0,156,194,0,0,150,194,0,0,164,194,0,0,158,194,0,0,166,194,0,0,170,194,0,0,178,194,0,0,184,194,0,0,190,194,0,0,196,194,0,0,202,194,0,0,210,194,0,0,218,194,0,0,226,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,212,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,172,194,0,0,162,194,0,0,156,194,0,0,148,194,0,0,138,194,0,0,148,194,0,0,148,194,0,0,152,194,0,0,158,194,0,0,166,194,0,0,168,194,0,0,172,194,0,0,178,194,0,0,184,194,0,0,194,194,0,0,186,194,0,0,200,194,0,0,206,194,0,0,214,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,212,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,174,194,0,0,166,194,0,0,160,194,0,0,150,194,0,0,138,194,0,0,112,194,0,0,132,194,0,0,132,194,0,0,136,194,0,0,140,194,0,0,148,194,0,0,156,194,0,0,158,194,0,0,162,194,0,0,162,194,0,0,166,194,0,0,168,194,0,0,174,194,0,0,186,194,0,0,192,194,0,0,198,194,0,0,206,194,0,0,214,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,206,194,0,0,196,194,0,0,186,194,0,0,178,194,0,0,170,194,0,0,164,194,0,0,156,194,0,0,142,194,0,0,120,194,0,0,92,194,0,0,104,194,0,0,104,194,0,0,88,194,0,0,88,194,0,0,92,194,0,0,108,194,0,0,116,194,0,0,120,194,0,0,140,194,0,0,132,194,0,0,132,194,0,0,134,194,0,0,140,194,0,0,144,194,0,0,150,194,0,0,156,194,0,0,168,194,0,0,168,194,0,0,168,194,0,0,176,194,0,0,182,194,0,0,180,194,0,0,190,194,0,0,196,194,0,0,204,194,0,0,206,194,0,0,212,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,206,194,0,0,196,194,0,0,188,194,0,0,180,194,0,0,174,194,0,0,164,194,0,0,158,194,0,0,146,194,0,0,134,194,0,0,104,194,0,0,60,194,0,0,72,194,0,0,52,194,0,0,36,194,0,0,52,194,0,0,64,194,0,0,48,194,0,0,48,194,0,0,68,194,0,0,88,194,0,0,76,194,0,0,64,194,0,0,60,194,0,0,68,194,0,0,72,194,0,0,76,194,0,0,100,194,0,0,104,194,0,0,112,194,0,0,124,194,0,0,138,194,0,0,140,194,0,0,138,194,0,0,142,194,0,0,148,194,0,0,156,194,0,0,164,194,0,0,180,194,0,0,190,194,0,0,202,194,0,0,210,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,202,194,0,0,194,194,0,0,186,194,0,0,180,194,0,0,170,194,0,0,160,194,0,0,154,194,0,0,144,194,0,0,130,194,0,0,96,194,0,0,64,194,0,0,20,194,0,0,32,194,0,0,16,194,0,0,8,194,0,0,32,194,0,0,72,194,0,0,60,194,0,0,24,194,0,0,36,194,0,0,60,194,0,0,24,194,0,0,12,194,0,0,28,194,0,0,24,194,0,0,44,194,0,0,32,194,0,0,52,194,0,0,72,194,0,0,52,194,0,0,48,194,0,0,60,194,0,0,72,194,0,0,92,194,0,0,64,194,0,0,64,194,0,0,80,194,0,0,132,194,0,0,140,194,0,0,152,194,0,0,164,194,0,0,180,194,0,0,194,194,0,0,210,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,206,194,0,0,196,194,0,0,186,194,0,0,172,194,0,0,158,194,0,0,152,194,0,0,166,194,0,0,162,194,0,0,170,194,0,0,174,194,0,0,178,194,0,0,186,194,0,0,196,194,0,0,204,194,0,0,214,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,206,194,0,0,196,194,0,0,186,194,0,0,172,194,0,0,158,194,0,0,142,194,0,0,154,194,0,0,148,194,0,0,154,194,0,0,158,194,0,0,162,194,0,0,168,194,0,0,170,194,0,0,180,194,0,0,184,194,0,0,186,194,0,0,184,194,0,0,196,194,0,0,202,194,0,0,216,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,206,194,0,0,196,194,0,0,186,194,0,0,174,194,0,0,156,194,0,0,136,194,0,0,130,194,0,0,132,194,0,0,120,194,0,0,130,194,0,0,134,194,0,0,140,194,0,0,146,194,0,0,150,194,0,0,156,194,0,0,164,194,0,0,164,194,0,0,166,194,0,0,168,194,0,0,182,194,0,0,186,194,0,0,196,194,0,0,204,194,0,0,212,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,164,194,0,0,148,194,0,0,120,194,0,0,100,194,0,0,104,194,0,0,96,194,0,0,76,194,0,0,80,194,0,0,80,194,0,0,88,194,0,0,88,194,0,0,104,194,0,0,132,194,0,0,108,194,0,0,112,194,0,0,124,194,0,0,132,194,0,0,138,194,0,0,146,194,0,0,158,194,0,0,166,194,0,0,168,194,0,0,160,194,0,0,162,194,0,0,162,194,0,0,164,194,0,0,176,194,0,0,184,194,0,0,196,194,0,0,210,194,0,0,226,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,204,194,0,0,194,194,0,0,184,194,0,0,168,194,0,0,158,194,0,0,138,194,0,0,100,194,0,0,60,194,0,0,80,194,0,0,60,194,0,0,48,194,0,0,52,194,0,0,72,194,0,0,80,194,0,0,40,194,0,0,40,194,0,0,84,194,0,0,44,194,0,0,44,194,0,0,64,194,0,0,76,194,0,0,96,194,0,0,92,194,0,0,80,194,0,0,100,194,0,0,108,194,0,0,116,194,0,0,120,194,0,0,134,194,0,0,142,194,0,0,156,194,0,0,166,194,0,0,172,194,0,0,188,194,0,0,196,194,0,0,206,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,200,194,0,0,190,194,0,0,180,194,0,0,168,194,0,0,156,194,0,0,140,194,0,0,116,194,0,0,76,194,0,0,36,194,0,0,32,194,0,0,24,194,0,0,32,194,0,0,56,194,0,0,80,194,0,0,76,194,0,0,36,194,0,0,32,194,0,0,56,194,0,0,32,194,0,0,24,194,0,0,24,194,0,0,36,194,0,0,56,194,0,0,36,194,0,0,56,194,0,0,60,194,0,0,44,194,0,0,44,194,0,0,52,194,0,0,36,194,0,0,52,194,0,0,96,194,0,0,134,194,0,0,136,194,0,0,166,194,0,0,174,194,0,0,180,194,0,0,190,194,0,0,204,194,0,0,214,194,0,0,226,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,218,194,0,0,210,194,0,0,202,194,0,0,192,194,0,0,182,194,0,0,168,194,0,0,154,194,0,0,164,194,0,0,164,194,0,0,170,194,0,0,178,194,0,0,188,194,0,0,200,194,0,0,212,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,212,194,0,0,206,194,0,0,196,194,0,0,184,194,0,0,170,194,0,0,160,194,0,0,142,194,0,0,150,194,0,0,144,194,0,0,152,194,0,0,160,194,0,0,168,194,0,0,172,194,0,0,178,194,0,0,186,194,0,0,200,194,0,0,214,194,0,0,226,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,208,194,0,0,202,194,0,0,194,194,0,0,184,194,0,0,176,194,0,0,168,194,0,0,160,194,0,0,128,194,0,0,132,194,0,0,124,194,0,0,128,194,0,0,132,194,0,0,138,194,0,0,146,194,0,0,154,194,0,0,166,194,0,0,166,194,0,0,172,194,0,0,182,194,0,0,196,194,0,0,208,194,0,0,222,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,208,194,0,0,202,194,0,0,194,194,0,0,184,194,0,0,180,194,0,0,168,194,0,0,148,194,0,0,100,194,0,0,104,194,0,0,80,194,0,0,92,194,0,0,88,194,0,0,72,194,0,0,80,194,0,0,72,194,0,0,80,194,0,0,124,194,0,0,120,194,0,0,138,194,0,0,152,194,0,0,154,194,0,0,156,194,0,0,156,194,0,0,158,194,0,0,164,194,0,0,176,194,0,0,188,194,0,0,200,194,0,0,212,194,0,0,222,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,212,194,0,0,204,194,0,0,196,194,0,0,190,194,0,0,180,194,0,0,170,194,0,0,166,194,0,0,156,194,0,0,140,194,0,0,72,194,0,0,72,194,0,0,36,194,0,0,48,194,0,0,68,194,0,0,60,194,0,0,72,194,0,0,72,194,0,0,48,194,0,0,92,194,0,0,56,194,0,0,60,194,0,0,64,194,0,0,64,194,0,0,88,194,0,0,68,194,0,0,68,194,0,0,104,194,0,0,120,194,0,0,142,194,0,0,162,194,0,0,174,194,0,0,184,194,0,0,194,194,0,0,204,194,0,0,216,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,212,194,0,0,204,194,0,0,196,194,0,0,190,194,0,0,180,194,0,0,170,194,0,0,166,194,0,0,156,194,0,0,140,194,0,0,52,194,0,0,44,194,0,0,36,194,0,0,60,194,0,0,72,194,0,0,76,194,0,0,72,194,0,0,68,194,0,0,52,194,0,0,60,194,0,0,36,194,0,0,48,194,0,0,36,194,0,0,28,194,0,0,44,194,0,0,24,194,0,0,20,194,0,0,32,194,0,0,36,194,0,0,48,194,0,0,72,194,0,0,104,194,0,0,130,194,0,0,146,194,0,0,158,194,0,0,170,194,0,0,184,194,0,0,194,194,0,0,202,194,0,0,210,194,0,0,218,194,0,0,226,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,200,194,0,0,190,194,0,0,174,194,0,0,162,194,0,0,170,194,0,0,166,194,0,0,176,194,0,0,186,194,0,0,200,194,0,0,214,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,202,194,0,0,190,194,0,0,176,194,0,0,166,194,0,0,152,194,0,0,146,194,0,0,144,194,0,0,158,194,0,0,168,194,0,0,180,194,0,0,190,194,0,0,200,194,0,0,210,194,0,0,220,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,208,194,0,0,196,194,0,0,184,194,0,0,174,194,0,0,162,194,0,0,140,194,0,0,130,194,0,0,120,194,0,0,134,194,0,0,142,194,0,0,148,194,0,0,160,194,0,0,170,194,0,0,182,194,0,0,190,194,0,0,198,194,0,0,206,194,0,0,216,194,0,0,222,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,206,194,0,0,194,194,0,0,180,194,0,0,170,194,0,0,152,194,0,0,112,194,0,0,96,194,0,0,88,194,0,0,112,194,0,0,120,194,0,0,116,194,0,0,96,194,0,0,124,194,0,0,130,194,0,0,146,194,0,0,148,194,0,0,154,194,0,0,150,194,0,0,156,194,0,0,162,194,0,0,172,194,0,0,174,194,0,0,176,194,0,0,182,194,0,0,188,194,0,0,196,194,0,0,206,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,200,194,0,0,194,194,0,0,184,194,0,0,172,194,0,0,162,194,0,0,158,194,0,0,140,194,0,0,100,194,0,0,76,194,0,0,60,194,0,0,76,194,0,0,104,194,0,0,112,194,0,0,96,194,0,0,84,194,0,0,72,194,0,0,104,194,0,0,80,194,0,0,72,194,0,0,72,194,0,0,84,194,0,0,92,194,0,0,128,194,0,0,138,194,0,0,142,194,0,0,170,194,0,0,164,194,0,0,156,194,0,0,162,194,0,0,170,194,0,0,190,194,0,0,204,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,200,194,0,0,194,194,0,0,184,194,0,0,170,194,0,0,166,194,0,0,158,194,0,0,144,194,0,0,68,194,0,0,32,194,0,0,44,194,0,0,44,194,0,0,88,194,0,0,96,194,0,0,76,194,0,0,72,194,0,0,32,194,0,0,44,194,0,0,24,194,0,0,16,194,0,0,12,194,0,0,20,194,0,0,24,194,0,0,20,194,0,0,48,194,0,0,88,194,0,0,112,194,0,0,100,194,0,0,112,194,0,0,140,194,0,0,150,194,0,0,168,194,0,0,184,194,0,0,206,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,204,194,0,0,190,194,0,0,178,194,0,0,164,194,0,0,166,194,0,0,168,194,0,0,180,194,0,0,184,194,0,0,198,194,0,0,214,194,0,0,226,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,202,194,0,0,190,194,0,0,178,194,0,0,166,194,0,0,144,194,0,0,148,194,0,0,156,194,0,0,170,194,0,0,176,194,0,0,176,194,0,0,180,194,0,0,184,194,0,0,196,194,0,0,210,194,0,0,222,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,218,194,0,0,206,194,0,0,194,194,0,0,186,194,0,0,174,194,0,0,162,194,0,0,140,194,0,0,140,194,0,0,134,194,0,0,150,194,0,0,146,194,0,0,152,194,0,0,158,194,0,0,162,194,0,0,166,194,0,0,176,194,0,0,178,194,0,0,194,194,0,0,206,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,214,194,0,0,200,194,0,0,188,194,0,0,176,194,0,0,166,194,0,0,150,194,0,0,124,194,0,0,108,194,0,0,108,194,0,0,124,194,0,0,132,194,0,0,112,194,0,0,120,194,0,0,134,194,0,0,134,194,0,0,154,194,0,0,152,194,0,0,162,194,0,0,176,194,0,0,172,194,0,0,184,194,0,0,192,194,0,0,204,194,0,0,218,194,0,0,232,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,196,194,0,0,184,194,0,0,172,194,0,0,162,194,0,0,146,194,0,0,96,194,0,0,80,194,0,0,60,194,0,0,92,194,0,0,112,194,0,0,104,194,0,0,80,194,0,0,76,194,0,0,52,194,0,0,68,194,0,0,72,194,0,0,84,194,0,0,88,194,0,0,116,194,0,0,142,194,0,0,140,194,0,0,138,194,0,0,156,194,0,0,158,194,0,0,174,194,0,0,180,194,0,0,192,194,0,0,208,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,206,194,0,0,192,194,0,0,180,194,0,0,172,194,0,0,156,194,0,0,140,194,0,0,76,194,0,0,40,194,0,0,60,194,0,0,64,194,0,0,92,194,0,0,88,194,0,0,88,194,0,0,84,194,0,0,40,194,0,0,12,194,0,0,224,193,0,0,4,194,0,0,24,194,0,0,20,194,0,0,48,194,0,0,60,194,0,0,68,194,0,0,88,194,0,0,124,194,0,0,136,194,0,0,156,194,0,0,164,194,0,0,178,194,0,0,188,194,0,0,198,194,0,0,208,194,0,0,218,194,0,0,228,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,200,194,0,0,180,194,0,0,158,194,0,0,170,194,0,0,162,194,0,0,164,194,0,0,164,194,0,0,178,194,0,0,188,194,0,0,198,194,0,0,206,194,0,0,218,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,194,194,0,0,170,194,0,0,144,194,0,0,148,194,0,0,140,194,0,0,140,194,0,0,140,194,0,0,152,194,0,0,170,194,0,0,182,194,0,0,186,194,0,0,194,194,0,0,206,194,0,0,218,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,224,194,0,0,186,194,0,0,162,194,0,0,136,194,0,0,120,194,0,0,112,194,0,0,112,194,0,0,100,194,0,0,124,194,0,0,140,194,0,0,154,194,0,0,164,194,0,0,180,194,0,0,186,194,0,0,196,194,0,0,208,194,0,0,218,194,0,0,226,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,226,194,0,0,200,194,0,0,186,194,0,0,168,194,0,0,124,194,0,0,104,194,0,0,64,194,0,0,84,194,0,0,88,194,0,0,80,194,0,0,80,194,0,0,100,194,0,0,128,194,0,0,132,194,0,0,152,194,0,0,166,194,0,0,162,194,0,0,170,194,0,0,170,194,0,0,180,194,0,0,190,194,0,0,196,194,0,0,202,194,0,0,206,194,0,0,212,194,0,0,216,194,0,0,222,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,210,194,0,0,190,194,0,0,172,194,0,0,148,194,0,0,84,194,0,0,72,194,0,0,24,194,0,0,44,194,0,0,68,194,0,0,44,194,0,0,40,194,0,0,28,194,0,0,28,194,0,0,56,194,0,0,80,194,0,0,100,194,0,0,96,194,0,0,144,194,0,0,138,194,0,0,148,194,0,0,162,194,0,0,174,194,0,0,184,194,0,0,188,194,0,0,194,194,0,0,198,194,0,0,204,194,0,0,210,194,0,0,216,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,216,194,0,0,198,194,0,0,180,194,0,0,152,194,0,0,132,194,0,0,52,194,0,0,44,194,0,0,36,194,0,0,48,194,0,0,60,194,0,0,44,194,0,0,60,194,0,0,32,194,0,0,240,193,0,0,248,193,0,0,248,193,0,0,28,194,0,0,4,194,0,0,32,194,0,0,36,194,0,0,44,194,0,0,84,194,0,0,108,194,0,0,140,194,0,0,146,194,0,0,154,194,0,0,158,194,0,0,164,194,0,0,168,194,0,0,174,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,182,194,0,0,152,194,0,0,150,194,0,0,170,194,0,0,186,194,0,0,196,194,0,0,208,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,182,194,0,0,140,194,0,0,140,194,0,0,150,194,0,0,172,194,0,0,178,194,0,0,188,194,0,0,196,194,0,0,202,194,0,0,212,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,190,194,0,0,160,194,0,0,112,194,0,0,130,194,0,0,128,194,0,0,148,194,0,0,166,194,0,0,176,194,0,0,182,194,0,0,190,194,0,0,198,194,0,0,206,194,0,0,214,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,190,194,0,0,160,194,0,0,104,194,0,0,92,194,0,0,68,194,0,0,132,194,0,0,136,194,0,0,142,194,0,0,156,194,0,0,156,194,0,0,160,194,0,0,176,194,0,0,170,194,0,0,178,194,0,0,194,194,0,0,200,194,0,0,210,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,190,194,0,0,160,194,0,0,84,194,0,0,80,194,0,0,36,194,0,0,108,194,0,0,108,194,0,0,68,194,0,0,104,194,0,0,96,194,0,0,124,194,0,0,172,194,0,0,158,194,0,0,180,194,0,0,186,194,0,0,196,194,0,0,206,194,0,0,214,194,0,0,224,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,194,194,0,0,182,194,0,0,146,194,0,0,52,194,0,0,32,194,0,0,4,194,0,0,84,194,0,0,116,194,0,0,68,194,0,0,88,194,0,0,72,194,0,0,72,194,0,0,112,194,0,0,80,194,0,0,134,194,0,0,148,194,0,0,162,194,0,0,184,194,0,0,192,194,0,0,200,194,0,0,210,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,226,194,0,0,212,194,0,0,198,194,0,0,184,194,0,0,154,194,0,0,160,194,0,0,176,194,0,0,194,194,0,0,212,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE+40960);allocate([0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,232,194,0,0,218,194,0,0,204,194,0,0,190,194,0,0,178,194,0,0,148,194,0,0,144,194,0,0,176,194,0,0,174,194,0,0,190,194,0,0,204,194,0,0,218,194,0,0,232,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,232,194,0,0,218,194,0,0,204,194,0,0,190,194,0,0,178,194,0,0,150,194,0,0,132,194,0,0,148,194,0,0,154,194,0,0,156,194,0,0,172,194,0,0,174,194,0,0,180,194,0,0,192,194,0,0,210,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,230,194,0,0,216,194,0,0,202,194,0,0,188,194,0,0,176,194,0,0,132,194,0,0,96,194,0,0,116,194,0,0,140,194,0,0,130,194,0,0,156,194,0,0,144,194,0,0,166,194,0,0,168,194,0,0,186,194,0,0,196,194,0,0,210,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,210,194,0,0,190,194,0,0,178,194,0,0,164,194,0,0,100,194,0,0,80,194,0,0,80,194,0,0,108,194,0,0,96,194,0,0,108,194,0,0,104,194,0,0,138,194,0,0,134,194,0,0,176,194,0,0,164,194,0,0,164,194,0,0,178,194,0,0,188,194,0,0,200,194,0,0,216,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,202,194,0,0,192,194,0,0,180,194,0,0,166,194,0,0,154,194,0,0,88,194,0,0,44,194,0,0,24,194,0,0,72,194,0,0,64,194,0,0,80,194,0,0,64,194,0,0,40,194,0,0,40,194,0,0,76,194,0,0,80,194,0,0,84,194,0,0,108,194,0,0,130,194,0,0,142,194,0,0,156,194,0,0,170,194,0,0,190,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,240,194,0,0,210,194,0,0,172,194,0,0,136,194,0,0,156,194,0,0,158,194,0,0,180,194,0,0,200,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,240,194,0,0,210,194,0,0,172,194,0,0,132,194,0,0,146,194,0,0,154,194,0,0,176,194,0,0,192,194,0,0,210,194,0,0,230,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,240,194,0,0,210,194,0,0,184,194,0,0,160,194,0,0,116,194,0,0,128,194,0,0,136,194,0,0,160,194,0,0,174,194,0,0,184,194,0,0,200,194,0,0,220,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,240,194,0,0,208,194,0,0,182,194,0,0,158,194,0,0,80,194,0,0,112,194,0,0,88,194,0,0,128,194,0,0,138,194,0,0,154,194,0,0,160,194,0,0,164,194,0,0,168,194,0,0,170,194,0,0,174,194,0,0,176,194,0,0,180,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,236,194,0,0,200,194,0,0,174,194,0,0,154,194,0,0,68,194,0,0,72,194,0,0,48,194,0,0,104,194,0,0,116,194,0,0,116,194,0,0,134,194,0,0,130,194,0,0,120,194,0,0,120,194,0,0,120,194,0,0,130,194,0,0,136,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,230,194,0,0,196,194,0,0,168,194,0,0,120,194,0,0,68,194,0,0,48,194,0,0,24,194,0,0,56,194,0,0,68,194,0,0,68,194,0,0,56,194,0,0,28,194,0,0,20,194,0,0,28,194,0,0,32,194,0,0,40,194,0,0,44,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,176,194,0,0,148,194,0,0,154,194,0,0,164,194,0,0,164,194,0,0,170,194,0,0,180,194,0,0,188,194,0,0,198,194,0,0,208,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,176,194,0,0,132,194,0,0,140,194,0,0,162,194,0,0,160,194,0,0,162,194,0,0,168,194,0,0,176,194,0,0,182,194,0,0,186,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,176,194,0,0,116,194,0,0,124,194,0,0,140,194,0,0,142,194,0,0,148,194,0,0,154,194,0,0,160,194,0,0,166,194,0,0,170,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,172,194,0,0,120,194,0,0,124,194,0,0,120,194,0,0,120,194,0,0,104,194,0,0,80,194,0,0,72,194,0,0,72,194,0,0,80,194,0,0,88,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,236,194,0,0,216,194,0,0,168,194,0,0,84,194,0,0,72,194,0,0,72,194,0,0,72,194,0,0,92,194,0,0,60,194,0,0,52,194,0,0,32,194,0,0,32,194,0,0,32,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,236,194,0,0,200,194,0,0,146,194,0,0,44,194,0,0,20,194,0,0,40,194,0,0,44,194,0,0,84,194,0,0,24,194,0,0,20,194,0,0,12,194,0,0,12,194,0,0,24,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,200,194,0,0,182,194,0,0,168,194,0,0,148,194,0,0,160,194,0,0,160,194,0,0,160,194,0,0,160,194,0,0,160,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,200,194,0,0,182,194,0,0,168,194,0,0,148,194,0,0,136,194,0,0,136,194,0,0,136,194,0,0,136,194,0,0,136,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,200,194,0,0,172,194,0,0,156,194,0,0,140,194,0,0,112,194,0,0,52,194,0,0,240,193,0,0,168,193,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,200,194,0,0,174,194,0,0,156,194,0,0,134,194,0,0,64,194,0,0,24,194,0,0,232,193,0,0,168,193,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,200,194,0,0,172,194,0,0,138,194,0,0,96,194,0,0,52,194,0,0,12,194,0,0,4,194,0,0,232,193,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,0,220,194,0,0,200,194,0,0,166,194,0,0,142,194,0,0,64,194,0,0,216,193,0,0,24,194,0,0,20,194,0,0,8,194,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,0,192,121,196,62,180,228,51,9,145,243,51,139,178,1,52,60,32,10,52,35,26,19,52,96,169,28,52,167,215,38,52,75,175,49,52,80,59,61,52,112,135,73,52,35,160,86,52,184,146,100,52,85,109,115,52,136,159,129,52,252,11,138,52,147,4,147,52,105,146,156,52,50,191,166,52,63,149,177,52,147,31,189,52,228,105,201,52,173,128,214,52,54,113,228,52,166,73,243,52,136,140,1,53,192,247,9,53,6,239,18,53,118,123,28,53,192,166,38,53,55,123,49,53,218,3,61,53,94,76,73,53,59,97,86,53,185,79,100,53,252,37,115,53,138,121,129,53,134,227,137,53,124,217,146,53,133,100,156,53,82,142,166,53,51,97,177,53,37,232,188,53,220,46,201,53,206,65,214,53,65,46,228,53,87,2,243,53,143,102,1,54,79,207,9,54,245,195,18,54,152,77,28,54,232,117,38,54,50,71,49,54,116,204,60,54,94,17,73,54,101,34,86,54,206,12,100,54,184,222,114,54,151,83,129,54,28,187,137,54,114,174,146,54,175,54,156,54,129,93,166,54,53,45,177,54,199,176,188,54,228,243,200,54,1,3,214,54,96,235,227,54,30,187,242,54,162,64,1,55,235,166,9,55,241,152,18,55,201,31,28,55,30,69,38,55,61,19,49,55,30,149,60,55,111,214,72,55,162,227,85,55,247,201,99,55,137,151,114,55,175,45,129,55,190,146,137,55,116,131,146,55,230,8,156,55,190,44,166,55,71,249,176,55,121,121,188,55,254,184,200,55,71,196,213,55,146,168,227,55,248,115,242,55,192,26,1,56,147,126,9,56,249,109,18,56,6,242,27,56,98,20,38,56,86,223,48,56,216,93,60,56,146,155,72,56,242,164,85,56,51,135,99,56,110,80,114,56,211,7,129,56,107,106,137,56,130,88,146,56,42,219,155,56,9,252,165,56,104,197,176,56,59,66,188,56,41,126,200,56,160,133,213,56,217,101,227,56,232,44,242,56,233,244,0,57,70,86,9,57,14,67,18,57,81,196,27,57,181,227,37,57,127,171,48,57,162,38,60,57,197,96,72,57,83,102,85,57,131,68,99,57,104,9,114,57,1,226,128,57,36,66,137,57,157,45,146,57,123,173,155,57,99,203,165,57,153,145,176,57,13,11,188,57,102,67,200,57,11,71,213,57,50,35,227,57,237,229,241,57,29,207,0,58,5,46,9,58,48,24,18,58,169,150,27,58,21,179,37,58,183,119,48,58,124,239,59,58,10,38,72,58,199,39,85,58,230,1,99,58,120,194,113,58,59,188,128,58,233,25,137,58,198,2,146,58,219,127,155,58,203,154,165,58,216,93,176,58,239,211,187,58,179,8,200,58,136,8,213,58,159,224,226,58,7,159,241,58,92,169,0,59,208,5,9,59,94,237,17,59,15,105,27,59,132,130,37,59,253,67,48,59,103,184,59,59,97,235,71,59,77,233,84,59,93,191,98,59,156,123,113,59,127,150,128,59,186,241,136,59,249,215,145,59,71,82,155,59,65,106,165,59,39,42,176,59,226,156,187,59,18,206,199,59,23,202,212,59,32,158,226,59,53,88,241,59,166,131,0,60,167,221,8,60,152,194,17,60,130,59,27,60,1,82,37,60,84,16,48,60,97,129,59,60,200,176,71,60,229,170,84,60,232,124,98,60,212,52,113,60,207,112,128,60,150,201,136,60,58,173,145,60,192,36,155,60,197,57,165,60,133,246,175,60,229,101,187,60,130,147,199,60,185,139,212,60,180,91,226,60,121,17,241,60,251,93,0,61,137,181,8,61,223,151,17,61,2,14,27,61,141,33,37,61,185,220,47,61,109,74,59,61,64,118,71,61,145,108,84,61,133,58,98,61,34,238,112,61,42,75,128,61,127,161,136,61,136,130,145,61,72,247,154,61,88,9,165,61,242,194,175,61,248,46,187,61,3,89,199,61,109,77,212,61,92,25,226,61,209,202,240,61,91,56,0,62,119,141,8,62,51,109,17,62,144,224,26,62,39,241,36,62,46,169,47,62,135,19,59,62,202,59,71,62,77,46,84,62,55,248,97,62,132,167,112,62,143,37,128,62,115,121,136,62,226,87,145,62,220,201,154,62,249,216,164,62,109,143,175,62,27,248,186,62,149,30,199,62,51,15,212,62,23,215,225,62,61,132,240,62,198,18,0,63,114,101,8,63,147,66,17,63,43,179,26,63,206,192,36,63,177,117,47,63,178,220,58,63,101,1,71,63,29,240,83,63,251,181,97,63,251,96,112,63,0,0,128,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,73,110,118,97,108,105,100,32,118,111,114,98,105,115,32,104,101,97,100,101,114,63,0,0,86,111,114,98,105,115,32,100,101,99,111,100,101,114,32,102,97,105,108,101,100,32,109,121,115,116,101,114,105,111,117,115,108,121,63,32,37,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE+51200);var tempDoublePtr=Runtime.alignMemory(allocate(12,"i8",ALLOC_STATIC),8);assert(tempDoublePtr%8==0);function copyTempFloat(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3]}function copyTempDouble(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3];HEAP8[tempDoublePtr+4]=HEAP8[ptr+4];HEAP8[tempDoublePtr+5]=HEAP8[ptr+5];HEAP8[tempDoublePtr+6]=HEAP8[ptr+6];HEAP8[tempDoublePtr+7]=HEAP8[ptr+7]}var _cosf=Math_cos;Module["_i64Subtract"]=_i64Subtract;var _fabsf=Math_abs;var ___errno_state=0;function ___setErrNo(value){HEAP32[___errno_state>>2]=value;return value}var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 85:return totalMemory/PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 79:return 0;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(ERRNO_CODES.EINVAL);return-1}Module["_memset"]=_memset;var _BDtoILow=true;Module["_bitshift64Shl"]=_bitshift64Shl;function _abort(){Module["abort"]()}var FS=undefined;var SOCKFS=undefined;function _send(fd,buf,len,flags){var sock=SOCKFS.getSocket(fd);if(!sock){___setErrNo(ERRNO_CODES.EBADF);return-1}return _write(fd,buf,len)}function _pwrite(fildes,buf,nbyte,offset){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte,offset)}catch(e){FS.handleFSError(e);return-1}}function _write(fildes,buf,nbyte){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte)}catch(e){FS.handleFSError(e);return-1}}function _fileno(stream){stream=FS.getStreamFromPtr(stream);if(!stream)return-1;return stream.fd}function _fwrite(ptr,size,nitems,stream){var bytesToWrite=nitems*size;if(bytesToWrite==0)return 0;var fd=_fileno(stream);var bytesWritten=_write(fd,ptr,bytesToWrite);if(bytesWritten==-1){var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=true;return 0}else{return bytesWritten/size|0}}Module["_strlen"]=_strlen;function __reallyNegative(x){return x<0||x===0&&1/x===-Infinity}function __formatString(format,varargs){assert((varargs&3)===0);var textIndex=format;var argIndex=0;function getNextArg(type){var ret;argIndex=Runtime.prepVararg(argIndex,type);if(type==="double"){ret=(HEAP32[tempDoublePtr>>2]=HEAP32[varargs+argIndex>>2],HEAP32[tempDoublePtr+4>>2]=HEAP32[varargs+(argIndex+4)>>2],+HEAPF64[tempDoublePtr>>3]);argIndex+=8}else if(type=="i64"){ret=[HEAP32[varargs+argIndex>>2],HEAP32[varargs+(argIndex+4)>>2]];argIndex+=8}else{assert((argIndex&3)===0);type="i32";ret=HEAP32[varargs+argIndex>>2];argIndex+=4}return ret}var ret=[];var curr,next,currArg;while(1){var startTextIndex=textIndex;curr=HEAP8[textIndex>>0];if(curr===0)break;next=HEAP8[textIndex+1>>0];if(curr==37){var flagAlwaysSigned=false;var flagLeftAlign=false;var flagAlternative=false;var flagZeroPad=false;var flagPadSign=false;flagsLoop:while(1){switch(next){case 43:flagAlwaysSigned=true;break;case 45:flagLeftAlign=true;break;case 35:flagAlternative=true;break;case 48:if(flagZeroPad){break flagsLoop}else{flagZeroPad=true;break};case 32:flagPadSign=true;break;default:break flagsLoop}textIndex++;next=HEAP8[textIndex+1>>0]}var width=0;if(next==42){width=getNextArg("i32");textIndex++;next=HEAP8[textIndex+1>>0]}else{while(next>=48&&next<=57){width=width*10+(next-48);textIndex++;next=HEAP8[textIndex+1>>0]}}var precisionSet=false,precision=-1;if(next==46){precision=0;precisionSet=true;textIndex++;next=HEAP8[textIndex+1>>0];if(next==42){precision=getNextArg("i32");textIndex++}else{while(1){var precisionChr=HEAP8[textIndex+1>>0];if(precisionChr<48||precisionChr>57)break;precision=precision*10+(precisionChr-48);textIndex++}}next=HEAP8[textIndex+1>>0]}if(precision<0){precision=6;precisionSet=false}var argSize;switch(String.fromCharCode(next)){case"h":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==104){textIndex++;argSize=1}else{argSize=2}break;case"l":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==108){textIndex++;argSize=8}else{argSize=4}break;case"L":case"q":case"j":argSize=8;break;case"z":case"t":case"I":argSize=4;break;default:argSize=null}if(argSize)textIndex++;next=HEAP8[textIndex+1>>0];switch(String.fromCharCode(next)){case"d":case"i":case"u":case"o":case"x":case"X":case"p":{var signed=next==100||next==105;argSize=argSize||4;var currArg=getNextArg("i"+argSize*8);var origArg=currArg;var argText;if(argSize==8){currArg=Runtime.makeBigInt(currArg[0],currArg[1],next==117)}if(argSize<=4){var limit=Math.pow(256,argSize)-1;currArg=(signed?reSign:unSign)(currArg&limit,argSize*8)}var currAbsArg=Math.abs(currArg);var prefix="";if(next==100||next==105){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],null);else argText=reSign(currArg,8*argSize,1).toString(10)}else if(next==117){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],true);else argText=unSign(currArg,8*argSize,1).toString(10);currArg=Math.abs(currArg)}else if(next==111){argText=(flagAlternative?"0":"")+currAbsArg.toString(8)}else if(next==120||next==88){prefix=flagAlternative&&currArg!=0?"0x":"";if(argSize==8&&i64Math){if(origArg[1]){argText=(origArg[1]>>>0).toString(16);var lower=(origArg[0]>>>0).toString(16);while(lower.length<8)lower="0"+lower;argText+=lower}else{argText=(origArg[0]>>>0).toString(16)}}else if(currArg<0){currArg=-currArg;argText=(currAbsArg-1).toString(16);var buffer=[];for(var i=0;i<argText.length;i++){buffer.push((15-parseInt(argText[i],16)).toString(16))}argText=buffer.join("");while(argText.length<argSize*2)argText="f"+argText}else{argText=currAbsArg.toString(16)}if(next==88){prefix=prefix.toUpperCase();argText=argText.toUpperCase()}}else if(next==112){if(currAbsArg===0){argText="(nil)"}else{prefix="0x";argText=currAbsArg.toString(16)}}if(precisionSet){while(argText.length<precision){argText="0"+argText}}if(currArg>=0){if(flagAlwaysSigned){prefix="+"+prefix}else if(flagPadSign){prefix=" "+prefix}}if(argText.charAt(0)=="-"){prefix="-"+prefix;argText=argText.substr(1)}while(prefix.length+argText.length<width){if(flagLeftAlign){argText+=" "}else{if(flagZeroPad){argText="0"+argText}else{prefix=" "+prefix}}}argText=prefix+argText;argText.split("").forEach((function(chr){ret.push(chr.charCodeAt(0))}));break};case"f":case"F":case"e":case"E":case"g":case"G":{var currArg=getNextArg("double");var argText;if(isNaN(currArg)){argText="nan";flagZeroPad=false}else if(!isFinite(currArg)){argText=(currArg<0?"-":"")+"inf";flagZeroPad=false}else{var isGeneral=false;var effectivePrecision=Math.min(precision,20);if(next==103||next==71){isGeneral=true;precision=precision||1;var exponent=parseInt(currArg.toExponential(effectivePrecision).split("e")[1],10);if(precision>exponent&&exponent>=-4){next=(next==103?"f":"F").charCodeAt(0);precision-=exponent+1}else{next=(next==103?"e":"E").charCodeAt(0);precision--}effectivePrecision=Math.min(precision,20)}if(next==101||next==69){argText=currArg.toExponential(effectivePrecision);if(/[eE][-+]\d$/.test(argText)){argText=argText.slice(0,-1)+"0"+argText.slice(-1)}}else if(next==102||next==70){argText=currArg.toFixed(effectivePrecision);if(currArg===0&&__reallyNegative(currArg)){argText="-"+argText}}var parts=argText.split("e");if(isGeneral&&!flagAlternative){while(parts[0].length>1&&parts[0].indexOf(".")!=-1&&(parts[0].slice(-1)=="0"||parts[0].slice(-1)==".")){parts[0]=parts[0].slice(0,-1)}}else{if(flagAlternative&&argText.indexOf(".")==-1)parts[0]+=".";while(precision>effectivePrecision++)parts[0]+="0"}argText=parts[0]+(parts.length>1?"e"+parts[1]:"");if(next==69)argText=argText.toUpperCase();if(currArg>=0){if(flagAlwaysSigned){argText="+"+argText}else if(flagPadSign){argText=" "+argText}}}while(argText.length<width){if(flagLeftAlign){argText+=" "}else{if(flagZeroPad&&(argText[0]=="-"||argText[0]=="+")){argText=argText[0]+"0"+argText.slice(1)}else{argText=(flagZeroPad?"0":" ")+argText}}}if(next<97)argText=argText.toUpperCase();argText.split("").forEach((function(chr){ret.push(chr.charCodeAt(0))}));break};case"s":{var arg=getNextArg("i8*");var argLength=arg?_strlen(arg):"(null)".length;if(precisionSet)argLength=Math.min(argLength,precision);if(!flagLeftAlign){while(argLength<width--){ret.push(32)}}if(arg){for(var i=0;i<argLength;i++){ret.push(HEAPU8[arg++>>0])}}else{ret=ret.concat(intArrayFromString("(null)".substr(0,argLength),true))}if(flagLeftAlign){while(argLength<width--){ret.push(32)}}break};case"c":{if(flagLeftAlign)ret.push(getNextArg("i8"));while(--width>0){ret.push(32)}if(!flagLeftAlign)ret.push(getNextArg("i8"));break};case"n":{var ptr=getNextArg("i32*");HEAP32[ptr>>2]=ret.length;break};case"%":{ret.push(curr);break};default:{for(var i=startTextIndex;i<textIndex+2;i++){ret.push(HEAP8[i>>0])}}}textIndex+=2}else{ret.push(curr);textIndex+=1}}return ret}function _fprintf(stream,format,varargs){var result=__formatString(format,varargs);var stack=Runtime.stackSave();var ret=_fwrite(allocate(result,"i8",ALLOC_STACK),1,result.length,stream);Runtime.stackRestore(stack);return ret}function _printf(format,varargs){var result=__formatString(format,varargs);var string=intArrayToString(result);if(string[string.length-1]==="\n")string=string.substr(0,string.length-1);Module.print(string);return result.length}Module["_i64Add"]=_i64Add;function _fputs(s,stream){var fd=_fileno(stream);return _write(fd,s,_strlen(s))}function _fputc(c,stream){var chr=unSign(c&255);HEAP8[_fputc.ret>>0]=chr;var fd=_fileno(stream);var ret=_write(fd,_fputc.ret,1);if(ret==-1){var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=true;return-1}else{return chr}}var _stdout=allocate(1,"i32*",ALLOC_STATIC);function _puts(s){var result=Pointer_stringify(s);var string=result.substr(0);if(string[string.length-1]==="\n")string=string.substr(0,string.length-1);Module.print(string);return result.length}var _floor=Math_floor;function _ogvjs_callback_init_audio(channels,rate){Module.audioFormat={channels:channels,rate:rate};Module.loadedMetadata=true}var _llvm_sqrt_f64=Math_sqrt;function __exit(status){Module["exit"](status)}function _exit(status){__exit(status)}var _sin=Math_sin;var _atan=Math_atan;var _BDtoIHigh=true;var _ceil=Math_ceil;var _sinf=Math_sin;function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}Module["_memcpy"]=_memcpy;var _log=Math_log;var _cos=Math_cos;var _llvm_pow_f64=Math_pow;function _ogvjs_callback_audio(buffers,channels,sampleCount){var HEAPU32=Module.HEAPU32;var HEAPF32=Module.HEAPF32;var outputBuffers=[];if(buffers!==0){var inPtr,inArray,outArray,i;for(var channel=0;channel<channels;channel++){inPtr=HEAPU32[buffers/4+channel];inArray=HEAPF32.subarray(inPtr/4,inPtr/4+sampleCount);outArray=new Float32Array(inArray);outputBuffers.push(outArray)}}Module.audioBuffer=outputBuffers}function ___errno_location(){return ___errno_state}var _BItoD=true;function _sbrk(bytes){var self=_sbrk;if(!self.called){DYNAMICTOP=alignMemoryPage(DYNAMICTOP);self.called=true;assert(Runtime.dynamicAlloc);self.alloc=Runtime.dynamicAlloc;Runtime.dynamicAlloc=(function(){abort("cannot dynamically allocate, sbrk now has control")})}var ret=DYNAMICTOP;if(bytes!=0){var success=self.alloc(bytes);if(!success)return-1>>>0}return ret}var _exp=Math_exp;function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}___errno_state=Runtime.staticAlloc(4);HEAP32[___errno_state>>2]=0;_fputc.ret=allocate([0],"i8",ALLOC_STATIC);STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP);staticSealed=true;STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=DYNAMICTOP=Runtime.alignMemory(STACK_MAX);assert(DYNAMIC_BASE<TOTAL_MEMORY,"TOTAL_MEMORY not big enough for stack");var cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_DYNAMIC);function invoke_iiiii(index,a1,a2,a3,a4){try{return Module["dynCall_iiiii"](index,a1,a2,a3,a4)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_vi(index,a1){try{Module["dynCall_vi"](index,a1)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_vii(index,a1,a2){try{Module["dynCall_vii"](index,a1,a2)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_ii(index,a1){try{return Module["dynCall_ii"](index,a1)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_viii(index,a1,a2,a3){try{Module["dynCall_viii"](index,a1,a2,a3)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_iiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8){try{return Module["dynCall_iiiiiiiii"](index,a1,a2,a3,a4,a5,a6,a7,a8)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_iii(index,a1,a2){try{return Module["dynCall_iii"](index,a1,a2)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_iiiiii(index,a1,a2,a3,a4,a5){try{return Module["dynCall_iiiiii"](index,a1,a2,a3,a4,a5)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}Module.asmGlobalArg={"Math":Math,"Int8Array":Int8Array,"Int16Array":Int16Array,"Int32Array":Int32Array,"Uint8Array":Uint8Array,"Uint16Array":Uint16Array,"Uint32Array":Uint32Array,"Float32Array":Float32Array,"Float64Array":Float64Array,"NaN":NaN,"Infinity":Infinity};Module.asmLibraryArg={"abort":abort,"assert":assert,"invoke_iiiii":invoke_iiiii,"invoke_vi":invoke_vi,"invoke_vii":invoke_vii,"invoke_ii":invoke_ii,"invoke_viii":invoke_viii,"invoke_iiiiiiiii":invoke_iiiiiiiii,"invoke_iii":invoke_iii,"invoke_iiiiii":invoke_iiiiii,"_sin":_sin,"_exp":_exp,"_cosf":_cosf,"_send":_send,"___setErrNo":___setErrNo,"_floor":_floor,"_pwrite":_pwrite,"_llvm_sqrt_f64":_llvm_sqrt_f64,"_llvm_pow_f64":_llvm_pow_f64,"__reallyNegative":__reallyNegative,"_fabsf":_fabsf,"_sbrk":_sbrk,"_atan":_atan,"_sinf":_sinf,"_fileno":_fileno,"_sysconf":_sysconf,"_ogvjs_callback_init_audio":_ogvjs_callback_init_audio,"_cos":_cos,"_puts":_puts,"_printf":_printf,"_ogvjs_callback_audio":_ogvjs_callback_audio,"_log":_log,"_write":_write,"_emscripten_memcpy_big":_emscripten_memcpy_big,"___errno_location":___errno_location,"_fputc":_fputc,"__exit":__exit,"_abort":_abort,"_fwrite":_fwrite,"_time":_time,"_fprintf":_fprintf,"_ceil":_ceil,"__formatString":__formatString,"_fputs":_fputs,"_exit":_exit,"STACKTOP":STACKTOP,"STACK_MAX":STACK_MAX,"tempDoublePtr":tempDoublePtr,"ABORT":ABORT,"cttz_i8":cttz_i8};// EMSCRIPTEN_START_ASM +var asm=(function(global,env,buffer) { +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=env.cttz_i8|0;var n=0;var o=0;var p=0;var q=0;var r=global.NaN,s=global.Infinity;var t=0,u=0,v=0,w=0,x=0.0,y=0,z=0,A=0,B=0.0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=0;var M=global.Math.floor;var N=global.Math.abs;var O=global.Math.sqrt;var P=global.Math.pow;var Q=global.Math.cos;var R=global.Math.sin;var S=global.Math.tan;var T=global.Math.acos;var U=global.Math.asin;var V=global.Math.atan;var W=global.Math.atan2;var X=global.Math.exp;var Y=global.Math.log;var Z=global.Math.ceil;var _=global.Math.imul;var $=global.Math.min;var aa=global.Math.clz32;var ba=env.abort;var ca=env.assert;var da=env.invoke_iiiii;var ea=env.invoke_vi;var fa=env.invoke_vii;var ga=env.invoke_ii;var ha=env.invoke_viii;var ia=env.invoke_iiiiiiiii;var ja=env.invoke_iii;var ka=env.invoke_iiiiii;var la=env._sin;var ma=env._exp;var na=env._cosf;var oa=env._send;var pa=env.___setErrNo;var qa=env._floor;var ra=env._pwrite;var sa=env._llvm_sqrt_f64;var ta=env._llvm_pow_f64;var ua=env.__reallyNegative;var va=env._fabsf;var wa=env._sbrk;var xa=env._atan;var ya=env._sinf;var za=env._fileno;var Aa=env._sysconf;var Ba=env._ogvjs_callback_init_audio;var Ca=env._cos;var Da=env._puts;var Ea=env._printf;var Fa=env._ogvjs_callback_audio;var Ga=env._log;var Ha=env._write;var Ia=env._emscripten_memcpy_big;var Ja=env.___errno_location;var Ka=env._fputc;var La=env.__exit;var Ma=env._abort;var Na=env._fwrite;var Oa=env._time;var Pa=env._fprintf;var Qa=env._ceil;var Ra=env.__formatString;var Sa=env._fputs;var Ta=env._exit;var Ua=0.0; +// EMSCRIPTEN_START_FUNCS +function bb(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function cb(){return i|0}function db(a){a=a|0;i=a}function eb(a,b){a=a|0;b=b|0;i=a;j=b}function fb(a,b){a=a|0;b=b|0;if(!n){n=a;o=b}}function gb(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function hb(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function ib(a){a=a|0;C=a}function jb(){return C|0}function kb(b){b=b|0;var d=0;c[b>>2]=0;c[b+4>>2]=0;c[b+8>>2]=0;c[b+12>>2]=0;d=xd(256)|0;c[b+8>>2]=d;c[b+12>>2]=d;a[d>>0]=0;c[b+16>>2]=256;return}function lb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0;do if(f>>>0<=32){g=b+16|0;h=c[g>>2]|0;i=b+12|0;j=c[i>>2]|0;if((c[b>>2]|0)<(h+-4|0))k=j;else{if(!j)return;if((h|0)>2147483391)break;j=b+8|0;l=Ad(c[j>>2]|0,h+256|0)|0;if(!l)break;c[j>>2]=l;c[g>>2]=(c[g>>2]|0)+256;g=l+(c[b>>2]|0)|0;c[i>>2]=g;k=g}g=c[8+(f<<2)>>2]&e;l=b+4|0;j=c[l>>2]|0;h=j+f|0;a[k>>0]=d[k>>0]|0|g<<j;do if((((h|0)>7?(a[(c[i>>2]|0)+1>>0]=g>>>(8-(c[l>>2]|0)|0),(h|0)>15):0)?(a[(c[i>>2]|0)+2>>0]=g>>>(16-(c[l>>2]|0)|0),(h|0)>23):0)?(a[(c[i>>2]|0)+3>>0]=g>>>(24-(c[l>>2]|0)|0),(h|0)>31):0){j=c[l>>2]|0;if(!j){a[(c[i>>2]|0)+4>>0]=0;break}else{a[(c[i>>2]|0)+4>>0]=g>>>(32-j|0);break}}while(0);g=(h|0)/8|0;c[b>>2]=(c[b>>2]|0)+g;c[i>>2]=(c[i>>2]|0)+g;c[l>>2]=h&7;return}while(0);k=c[b+8>>2]|0;if(k)yd(k);c[b>>2]=0;c[b+4>>2]=0;c[b+8>>2]=0;c[b+12>>2]=0;c[b+16>>2]=0;return}function mb(a){a=a|0;var b=0;b=c[a+8>>2]|0;if(b)yd(b);c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;return}function nb(a,b,d){a=a|0;b=b|0;d=d|0;c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+12>>2]=b;c[a+8>>2]=b;c[a+16>>2]=d;return}function ob(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;if(b>>>0>32){e=-1;return e|0}f=c[8+(b<<2)>>2]|0;g=c[a+4>>2]|0;h=g+b|0;b=c[a>>2]|0;i=c[a+16>>2]|0;if((b|0)>=(i+-4|0)){if((b|0)>(i-(h+7>>3)|0)){e=-1;return e|0}if(!h){e=0;return e|0}}i=c[a+12>>2]|0;a=(d[i>>0]|0)>>>g;if((h|0)>8){b=(d[i+1>>0]|0)<<8-g|a;if((h|0)>16){j=(d[i+2>>0]|0)<<16-g|b;if((h|0)>24){k=(d[i+3>>0]|0)<<24-g|j;if((h|0)<33|(g|0)==0)l=k;else l=(d[i+4>>0]|0)<<32-g|k}else l=j}else l=b}else l=a;e=l&f;return e|0}function pb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=a+4|0;e=(c[d>>2]|0)+b|0;b=c[a>>2]|0;f=c[a+16>>2]|0;if((b|0)>(f-(e+7>>3)|0)){c[a+12>>2]=0;c[a>>2]=f;g=1;c[d>>2]=g;return}else{f=(e|0)/8|0;h=a+12|0;c[h>>2]=(c[h>>2]|0)+f;c[a>>2]=b+f;g=e&7;c[d>>2]=g;return}}function qb(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;do if(b>>>0>32){e=a;f=a+4|0;g=c[a+16>>2]|0}else{h=c[8+(b<<2)>>2]|0;i=a+4|0;j=c[i>>2]|0;k=j+b|0;l=c[a>>2]|0;m=c[a+16>>2]|0;if((l|0)>=(m+-4|0)){if((l|0)>(m-(k+7>>3)|0)){e=a;f=i;g=m;break}if(!k){n=0;return n|0}}m=a+12|0;o=c[m>>2]|0;p=(d[o>>0]|0)>>>j;if((k|0)>8){q=(d[o+1>>0]|0)<<8-j|p;if((k|0)>16){r=(d[o+2>>0]|0)<<16-j|q;if((k|0)>24){s=(d[o+3>>0]|0)<<24-j|r;if((k|0)<33|(j|0)==0)t=s;else t=(d[o+4>>0]|0)<<32-j|s}else t=r}else t=q}else t=p;p=(k|0)/8|0;c[m>>2]=o+p;c[a>>2]=l+p;c[i>>2]=k&7;n=t&h;return n|0}while(0);c[a+12>>2]=0;c[e>>2]=g;c[f>>2]=1;n=-1;return n|0}function rb(a){a=a|0;return (((c[a+4>>2]|0)+7|0)/8|0)+(c[a>>2]|0)|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,i=0.0,j=0,k=0.0,l=0,m=0.0,n=0.0,o=0,p=0.0,q=0,r=0,s=0,t=0;d=(b|0)/4|0;e=xd(d<<2)|0;f=xd(d+b<<2)|0;h=b>>1;i=+(b|0);j=~~+td(+Y(+i)*1.4426950408889634);c[a+4>>2]=j;c[a>>2]=b;c[a+8>>2]=f;c[a+12>>2]=e;if((b|0)<=3){k=4.0/i;l=a+16|0;g[l>>2]=k;return}m=3.141592653589793/+(b|0);n=3.141592653589793/+(b<<1|0);o=0;do{p=m*+(o<<2|0);q=o<<1;g[f+(q<<2)>>2]=+Q(+p);r=q|1;g[f+(r<<2)>>2]=-+R(+p);p=n*+(r|0);r=q+h|0;g[f+(r<<2)>>2]=+Q(+p);g[f+(r+1<<2)>>2]=+R(+p);o=o+1|0}while((o|0)<(d|0));d=(b|0)/8|0;o=(b|0)>7;if(!o){k=4.0/i;l=a+16|0;g[l>>2]=k;return}n=3.141592653589793/+(b|0);h=0;do{m=n*+(h<<2|2|0);r=(h<<1)+b|0;g[f+(r<<2)>>2]=+Q(+m)*.5;g[f+(r+1<<2)>>2]=+R(+m)*-.5;h=h+1|0}while((h|0)<(d|0));h=(1<<j+-1)+-1|0;f=1<<j+-2;if(o)s=0;else{k=4.0/i;l=a+16|0;g[l>>2]=k;return}do{o=f;j=0;b=0;while(1){r=((o&s|0)==0?0:1<<b)|j;b=b+1|0;o=f>>b;if(!o){t=r;break}else j=r}j=s<<1;c[e+(j<<2)>>2]=(h&~t)+-1;c[e+((j|1)<<2)>>2]=t;s=s+1|0}while((s|0)<(d|0));k=4.0/i;l=a+16|0;g[l>>2]=k;return}function tb(a){a=a|0;var b=0;if(!a)return;b=c[a+8>>2]|0;if(b)yd(b);b=c[a+12>>2]|0;if(b)yd(b);c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;return}function ub(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0.0,t=0,u=0;e=c[a>>2]|0;f=e>>1;h=e>>2;e=d+(f+h<<2)|0;i=a+8|0;j=c[i>>2]|0;k=j+(h<<2)|0;l=k;m=b+(f+-7<<2)|0;n=e;while(1){o=n;n=n+-16|0;p=m+8|0;q=l+12|0;r=l+8|0;g[n>>2]=-(+g[p>>2]*+g[q>>2])-+g[r>>2]*+g[m>>2];g[o+-12>>2]=+g[q>>2]*+g[m>>2]-+g[r>>2]*+g[p>>2];p=m+24|0;r=l+4|0;q=m+16|0;g[o+-8>>2]=-(+g[p>>2]*+g[r>>2])-+g[l>>2]*+g[q>>2];g[o+-4>>2]=+g[r>>2]*+g[q>>2]-+g[l>>2]*+g[p>>2];m=m+-32|0;if(m>>>0<b>>>0)break;else l=l+16|0}l=d+(f<<2)|0;m=k;k=b+(f+-8<<2)|0;n=e;while(1){p=k+16|0;q=m+-4|0;r=k+24|0;o=m+-8|0;g[n>>2]=+g[o>>2]*+g[r>>2]+ +g[q>>2]*+g[p>>2];g[n+4>>2]=+g[o>>2]*+g[p>>2]-+g[q>>2]*+g[r>>2];r=m+-12|0;m=m+-16|0;q=k+8|0;g[n+8>>2]=+g[m>>2]*+g[q>>2]+ +g[r>>2]*+g[k>>2];g[n+12>>2]=+g[m>>2]*+g[k>>2]-+g[r>>2]*+g[q>>2];k=k+-32|0;if(k>>>0<b>>>0)break;else n=n+16|0}Ec(c[a+4>>2]|0,j,l,f);Fc(c[a>>2]|0,c[i>>2]|0,c[a+12>>2]|0,d);a=(c[i>>2]|0)+(f<<2)|0;f=d;i=e;j=e;while(1){n=a+4|0;b=f+4|0;g[i+-4>>2]=+g[n>>2]*+g[f>>2]-+g[a>>2]*+g[b>>2];g[j>>2]=-(+g[a>>2]*+g[f>>2]+ +g[n>>2]*+g[b>>2]);b=f+8|0;n=a+12|0;k=f+12|0;m=a+8|0;g[i+-8>>2]=+g[n>>2]*+g[b>>2]-+g[m>>2]*+g[k>>2];g[j+4>>2]=-(+g[m>>2]*+g[b>>2]+ +g[n>>2]*+g[k>>2]);k=f+16|0;n=a+20|0;b=f+20|0;m=a+16|0;g[i+-12>>2]=+g[n>>2]*+g[k>>2]-+g[m>>2]*+g[b>>2];i=i+-16|0;g[j+8>>2]=-(+g[m>>2]*+g[k>>2]+ +g[n>>2]*+g[b>>2]);b=f+24|0;n=a+28|0;k=f+28|0;m=a+24|0;g[i>>2]=+g[n>>2]*+g[b>>2]-+g[m>>2]*+g[k>>2];g[j+12>>2]=-(+g[m>>2]*+g[b>>2]+ +g[n>>2]*+g[k>>2]);f=f+32|0;if(f>>>0>=i>>>0)break;else{a=a+32|0;j=j+16|0}}j=d+(h<<2)|0;h=e;d=j;a=j;do{j=d;d=d+-16|0;s=+g[h+-4>>2];g[j+-4>>2]=s;g[a>>2]=-s;s=+g[h+-8>>2];g[j+-8>>2]=s;g[a+4>>2]=-s;s=+g[h+-12>>2];h=h+-16|0;g[j+-12>>2]=s;g[a+8>>2]=-s;s=+g[h>>2];g[d>>2]=s;g[a+12>>2]=-s;a=a+16|0}while(a>>>0<h>>>0);t=e;u=e;while(1){e=u;u=u+-16|0;c[u>>2]=c[t+12>>2];c[e+-12>>2]=c[t+8>>2];c[e+-8>>2]=c[t+4>>2];c[e+-4>>2]=c[t>>2];if(u>>>0<=l>>>0)break;else t=t+16|0}return}function vb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0.0,B=0.0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;e=i;f=c[a>>2]|0;h=f>>1;j=f>>2;k=f>>3;l=i;i=i+((1*(f<<2)|0)+15&-16)|0;m=l+(h<<2)|0;n=h+j|0;o=b+(n<<2)|0;p=a+8|0;q=c[p>>2]|0;r=q+(h<<2)|0;if((k|0)>0){s=(k+-1|0)>>>1;t=s<<1;u=h+-2-t|0;v=n+-4-(s<<2)|0;s=r;w=0;x=o;y=b+(n+1<<2)|0;while(1){n=x;x=x+-16|0;z=s;s=s+-8|0;A=+g[y>>2]+ +g[n+-8>>2];B=+g[y+8>>2]+ +g[x>>2];n=z+-4|0;g[l+(w+h<<2)>>2]=+g[s>>2]*A+B*+g[n>>2];g[l+((w|1)+h<<2)>>2]=+g[s>>2]*B-+g[n>>2]*A;w=w+2|0;if((w|0)>=(k|0))break;else y=y+16|0}C=u;D=q+(u<<2)|0;E=t+2|0;F=b+(v<<2)|0}else{C=h;D=r;E=0;F=o}o=b+4|0;r=h-k|0;if((E|0)<(r|0)){v=(h+-1-E-k|0)>>>1;k=v<<1;t=E+k|0;u=(v<<2)+5|0;v=-2-k|0;k=D;y=E;w=F;F=o;while(1){s=k;k=k+-8|0;A=+g[w+-8>>2]-+g[F>>2];w=w+-16|0;B=+g[w>>2]-+g[F+8>>2];x=s+-4|0;g[l+(y+h<<2)>>2]=+g[k>>2]*A+B*+g[x>>2];g[l+((y|1)+h<<2)>>2]=+g[k>>2]*B-+g[x>>2]*A;y=y+2|0;if((y|0)>=(r|0))break;else F=F+16|0}G=q+(C+v<<2)|0;H=t+2|0;I=b+(u<<2)|0}else{G=D;H=E;I=o}if((H|0)<(h|0)){o=G;G=H;H=b+(f<<2)|0;f=I;while(1){I=o;o=o+-8|0;A=-+g[H+-8>>2]-+g[f>>2];H=H+-16|0;B=-+g[H>>2]-+g[f+8>>2];b=I+-4|0;g[l+(G+h<<2)>>2]=+g[o>>2]*A+B*+g[b>>2];g[l+((G|1)+h<<2)>>2]=+g[o>>2]*B-+g[b>>2]*A;G=G+2|0;if((G|0)>=(h|0))break;else f=f+16|0}}Ec(c[a+4>>2]|0,q,m,h);Fc(c[a>>2]|0,c[p>>2]|0,c[a+12>>2]|0,l);if((j|0)<=0){i=e;return}m=a+16|0;a=(c[p>>2]|0)+(h<<2)|0;p=0;q=l;l=d+(h<<2)|0;while(1){l=l+-4|0;h=q+4|0;f=a+4|0;g[d+(p<<2)>>2]=(+g[f>>2]*+g[h>>2]+ +g[a>>2]*+g[q>>2])*+g[m>>2];g[l>>2]=(+g[f>>2]*+g[q>>2]-+g[a>>2]*+g[h>>2])*+g[m>>2];p=p+1|0;if((p|0)==(j|0))break;else{a=a+8|0;q=q+8|0}}i=e;return}function wb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;d=c[a>>2]|0;if((d|0)==1)return;e=c[a+4>>2]|0;f=c[a+8>>2]|0;a=c[f+4>>2]|0;if((a|0)<=0)return;g=a+1|0;h=d+-1|0;i=d;j=0;k=d;l=1;while(1){m=c[f+(g-j<<2)>>2]|0;n=(d|0)/(k|0)|0;k=(k|0)/(m|0)|0;o=_(n,k)|0;i=i-(_(n,m+-1|0)|0)|0;p=1-l|0;do if((m|0)==4){q=i+n|0;r=e+(h+i<<2)|0;s=e+(h+q<<2)|0;t=e+(h+n+q<<2)|0;if(!p){Gc(n,k,b,e,r,s,t);u=0;break}else{Gc(n,k,e,b,r,s,t);u=p;break}}else if((m|0)==2){t=e+(h+i<<2)|0;if(!p){Hc(n,k,b,e,t);u=0;break}else{Hc(n,k,e,b,t);u=p;break}}else{t=e+(h+i<<2)|0;if(!(((n|0)==1?l:p)|0)){Ic(n,m,k,o,b,b,b,e,e,t);u=1;break}else{Ic(n,m,k,o,e,e,e,b,b,t);u=0;break}}while(0);j=j+1|0;if((j|0)==(a|0)){v=u;break}else l=u}if((d|0)>0&(v|0)!=1)w=0;else return;do{c[b+(w<<2)>>2]=c[e+(w<<2)>>2];w=w+1|0}while((w|0)!=(d|0));return}function xb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0.0,x=0.0,y=0.0,z=0.0,A=0;c[a>>2]=b;d=zd(b*3|0,4)|0;c[a+4>>2]=d;e=zd(32,4)|0;c[a+8>>2]=e;if((b|0)==1)return;a=e+8|0;f=-1;h=0;i=b;j=0;a:while(1){k=f+1|0;if((k|0)<4)l=c[360+(k<<2)>>2]|0;else l=j+2|0;m=(l|0)!=2;n=h;o=i;while(1){p=n+1|0;q=o;o=(o|0)/(l|0)|0;if((q|0)!=(_(o,l)|0)){f=k;h=n;i=q;j=l;continue a}c[e+(n+2<<2)>>2]=l;q=(n|0)==0;if(!(m|q)){if((n|0)>=1){r=1;do{s=p-r|0;c[e+(s+2<<2)>>2]=c[e+(s+1<<2)>>2];r=r+1|0}while((r|0)!=(p|0))}c[a>>2]=2}if((o|0)==1){t=q;u=p;v=n;break a}else n=p}}c[e>>2]=b;c[e+4>>2]=u;w=6.2831854820251465/+(b|0);if(!((v|0)>0&(t^1)))return;t=b+1|0;u=0;a=0;l=1;while(1){j=c[e+(a+2<<2)>>2]|0;i=l;l=_(j,l)|0;h=(b|0)/(l|0)|0;if((j|0)>1){f=(h|0)>2;n=j+-1|0;j=u;o=0;m=0;while(1){m=m+i|0;x=+(m|0)*w;if(f){y=0.0;k=j;r=2;while(1){y=y+1.0;z=x*y;g[d+(k+b<<2)>>2]=+Q(+z);g[d+(t+k<<2)>>2]=+R(+z);r=r+2|0;if((r|0)>=(h|0))break;else k=k+2|0}}o=o+1|0;if((o|0)==(n|0))break;else j=j+h|0}A=(_(h,n)|0)+u|0}else A=u;a=a+1|0;if((a|0)==(v|0))break;else u=A}return}function yb(a){a=a|0;var b=0;if(!a)return;b=c[a+4>>2]|0;if(b)yd(b);b=c[a+8>>2]|0;if(b)yd(b);c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;return}function zb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=b;e=d+112|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(e|0));c[b+64>>2]=a;c[b+76>>2]=0;c[b+68>>2]=0;if(!(c[a>>2]|0))return 0;a=zd(1,72)|0;c[b+104>>2]=a;g[a+4>>2]=-9999.0;d=b+4|0;b=a+12|0;e=a+40|0;a=0;while(1)if((a|0)!=7){f=zd(1,20)|0;c[b+(a<<2)>>2]=f;kb(f);f=a+1|0;if((f|0)==15)break;else{a=f;continue}}else{c[e>>2]=d;kb(d);a=8;continue}return 0}function Ab(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;d=b+7&-8;b=a+72|0;e=c[b>>2]|0;f=a+76|0;g=a+68|0;h=c[g>>2]|0;if((e+d|0)<=(c[f>>2]|0)){i=h;j=e;k=i+j|0;l=j+d|0;c[b>>2]=l;return k|0}if(h){m=xd(8)|0;n=a+80|0;c[n>>2]=(c[n>>2]|0)+e;e=a+84|0;c[m+4>>2]=c[e>>2];c[m>>2]=h;c[e>>2]=m}c[f>>2]=d;f=xd(d)|0;c[g>>2]=f;c[b>>2]=0;i=f;j=0;k=i+j|0;l=j+d|0;c[b>>2]=l;return k|0}function Bb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;b=a+84|0;d=c[b>>2]|0;if(d){e=d;do{d=e;e=c[e+4>>2]|0;yd(c[d>>2]|0);yd(d)}while((e|0)!=0)}e=a+80|0;d=c[e>>2]|0;if(!d){f=a+72|0;c[f>>2]=0;c[b>>2]=0;return}g=a+68|0;h=a+76|0;c[g>>2]=Ad(c[g>>2]|0,(c[h>>2]|0)+d|0)|0;c[h>>2]=(c[h>>2]|0)+(c[e>>2]|0);c[e>>2]=0;f=a+72|0;c[f>>2]=0;c[b>>2]=0;return}function Cb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;b=c[a+104>>2]|0;d=a+84|0;e=c[d>>2]|0;if(e){f=e;do{e=f;f=c[f+4>>2]|0;yd(c[e>>2]|0);yd(e)}while((f|0)!=0)}f=a+80|0;e=c[f>>2]|0;g=a+68|0;h=c[g>>2]|0;if(!e)i=h;else{j=a+76|0;k=Ad(h,(c[j>>2]|0)+e|0)|0;c[g>>2]=k;c[j>>2]=(c[j>>2]|0)+(c[f>>2]|0);c[f>>2]=0;i=k}c[a+72>>2]=0;c[d>>2]=0;if(i)yd(i);if(!b){l=a;m=l+112|0;do{c[l>>2]=0;l=l+4|0}while((l|0)<(m|0));return 0}else n=0;while(1){i=b+12+(n<<2)|0;mb(c[i>>2]|0);if((n|0)==7){n=8;continue}yd(c[i>>2]|0);n=n+1|0;if((n|0)==15)break}yd(b);l=a;m=l+112|0;do{c[l>>2]=0;l=l+4|0}while((l|0)<(m|0));return 0}function Db(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;if(!a)return;b=c[a+4>>2]|0;d=(b|0)!=0;if(d)e=c[b+28>>2]|0;else e=0;f=c[a+104>>2]|0;g=(f|0)!=0;if(g){h=c[f>>2]|0;if(h){Ib(h);yd(c[f>>2]|0)}h=f+12|0;i=c[h>>2]|0;if(i){tb(c[i>>2]|0);yd(c[c[h>>2]>>2]|0);yd(c[h>>2]|0)}h=f+16|0;i=c[h>>2]|0;if(i){tb(c[i>>2]|0);yd(c[c[h>>2]>>2]|0);yd(c[h>>2]|0)}h=f+48|0;i=c[h>>2]|0;if(i){if((e|0)!=0?(j=e+16|0,(c[j>>2]|0)>0):0){k=e+800|0;Wa[c[(c[328+(c[k>>2]<<2)>>2]|0)+16>>2]&7](c[i>>2]|0);if((c[j>>2]|0)>1){l=1;do{Wa[c[(c[328+(c[k+(l<<2)>>2]<<2)>>2]|0)+16>>2]&7](c[(c[h>>2]|0)+(l<<2)>>2]|0);l=l+1|0}while((l|0)<(c[j>>2]|0))}m=c[h>>2]|0}else m=i;yd(m)}m=f+52|0;i=c[m>>2]|0;if(i){if((e|0)!=0?(h=e+20|0,(c[h>>2]|0)>0):0){j=e+1312|0;Wa[c[(c[336+(c[j>>2]<<2)>>2]|0)+16>>2]&7](c[i>>2]|0);if((c[h>>2]|0)>1){l=1;do{Wa[c[(c[336+(c[j+(l<<2)>>2]<<2)>>2]|0)+16>>2]&7](c[(c[m>>2]|0)+(l<<2)>>2]|0);l=l+1|0}while((l|0)<(c[h>>2]|0))}n=c[m>>2]|0}else n=i;yd(n)}n=f+56|0;i=c[n>>2]|0;if(i){if((e|0)!=0?(m=e+28|0,(c[m>>2]|0)>0):0){Qb(i);if((c[m>>2]|0)>1){e=1;do{Qb((c[n>>2]|0)+(e*52|0)|0);e=e+1|0}while((e|0)<(c[m>>2]|0))}o=c[n>>2]|0}else o=i;yd(o)}o=c[f+60>>2]|0;if(o)Nb(o);Cc(f+80|0);yb(f+20|0);yb(f+32|0)}o=a+8|0;i=c[o>>2]|0;if(i){if(d?(d=b+4|0,b=c[d>>2]|0,(b|0)>0):0){n=i;m=b;b=0;while(1){e=c[n+(b<<2)>>2]|0;if(!e)p=m;else{yd(e);p=c[d>>2]|0}e=b+1|0;if((e|0)>=(p|0))break;n=c[o>>2]|0;m=p;b=e}q=c[o>>2]|0}else q=i;yd(q);q=c[a+12>>2]|0;if(q)yd(q)}if(g){g=c[f+64>>2]|0;if(g)yd(g);g=c[f+68>>2]|0;if(g)yd(g);g=c[f+72>>2]|0;if(g)yd(g);yd(f)}f=a;a=f+112|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(a|0));return}function Eb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;if(Jc(a,b,0)|0){Db(a);d=1;return d|0}b=c[a+4>>2]|0;e=c[a+104>>2]|0;if((b|0)==0|(e|0)==0){d=0;return d|0}f=c[b+28>>2]|0;if(!f){d=0;return d|0}b=c[f+3656>>2]|0;g=c[f+4>>2]>>b+1;c[a+48>>2]=g;c[a+20>>2]=g>>b;c[a+24>>2]=-1;b=a+56|0;c[b>>2]=-1;c[b+4>>2]=-1;c[b+8>>2]=-1;c[b+12>>2]=-1;c[a+32>>2]=0;a=e+128|0;c[a>>2]=-1;c[a+4>>2]=-1;d=0;return d|0}function Fb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0;d=c[a+4>>2]|0;e=c[d+28>>2]|0;f=c[a+104>>2]|0;h=c[e+3656>>2]|0;if(!b){i=-131;return i|0}j=a+20|0;k=c[j>>2]|0;l=a+24|0;m=c[l>>2]|0;if(!((k|0)<=(m|0)|(m|0)==-1)){i=-131;return i|0}n=a+40|0;o=c[n>>2]|0;p=a+36|0;c[p>>2]=o;q=c[b+28>>2]|0;c[n>>2]=q;c[a+44>>2]=-1;r=a+64|0;s=r;t=c[s>>2]|0;u=c[s+4>>2]|0;if(!((t|0)==-1&(u|0)==-1)){s=Id(t|0,u|0,1,0)|0;u=C;t=b+56|0;v=c[t>>2]|0;w=c[t+4>>2]|0;if((s|0)==(v|0)&(u|0)==(w|0)){x=s;y=u}else{z=v;A=w;B=6}}else{w=b+56|0;z=c[w>>2]|0;A=c[w+4>>2]|0;B=6}if((B|0)==6){B=a+56|0;c[B>>2]=-1;c[B+4>>2]=-1;B=f+128|0;c[B>>2]=-1;c[B+4>>2]=-1;x=z;y=A}A=r;c[A>>2]=x;c[A+4>>2]=y;do if(c[b>>2]|0){y=h+1|0;A=c[e+(q<<2)>>2]>>y;x=c[e>>2]>>y;r=c[e+4>>2]>>y;y=c[b+88>>2]|0;z=a+72|0;B=z;w=Id(c[B>>2]|0,c[B+4>>2]|0,y|0,((y|0)<0)<<31>>31|0)|0;y=z;c[y>>2]=w;c[y+4>>2]=C;y=c[b+92>>2]|0;w=a+80|0;z=w;B=Id(c[z>>2]|0,c[z+4>>2]|0,y|0,((y|0)<0)<<31>>31|0)|0;y=w;c[y>>2]=B;c[y+4>>2]=C;y=c[b+96>>2]|0;B=a+88|0;w=B;z=Id(c[w>>2]|0,c[w+4>>2]|0,y|0,((y|0)<0)<<31>>31|0)|0;y=B;c[y>>2]=z;c[y+4>>2]=C;y=c[b+100>>2]|0;z=a+96|0;B=z;w=Id(c[B>>2]|0,c[B+4>>2]|0,y|0,((y|0)<0)<<31>>31|0)|0;y=z;c[y>>2]=w;c[y+4>>2]=C;y=a+48|0;w=c[y>>2]|0;z=(w|0)==0;B=z?r:0;v=z?0:r;z=d+4|0;if((c[z>>2]|0)>0){u=f+4|0;s=a+8|0;t=(r|0)/2|0;D=(x|0)/2|0;E=t-D|0;F=(x|0)>0;G=D+t|0;D=x+-1|0;H=(A|0)>0;I=f+8|0;J=(r|0)>0;K=r+-1|0;L=t+B+((x|0)/-2|0)|0;t=o;M=q;N=0;while(1){O=(M|0)!=0;a:do if(!t){P=Jb((c[u>>2]|0)-h|0)|0;Q=c[(c[s>>2]|0)+(N<<2)>>2]|0;R=c[(c[b>>2]|0)+(N<<2)>>2]|0;if(!O){if(F)S=0;else{T=R;U=Q;break}while(1){V=Q+(S+B<<2)|0;g[V>>2]=+g[P+(S<<2)>>2]*+g[R+(S<<2)>>2]+ +g[P+(D-S<<2)>>2]*+g[V>>2];S=S+1|0;if((S|0)==(x|0)){T=R;U=Q;break a}}}if(F){V=0;do{W=Q+(V+B<<2)|0;g[W>>2]=+g[P+(V<<2)>>2]*+g[R+(V+E<<2)>>2]+ +g[P+(D-V<<2)>>2]*+g[W>>2];V=V+1|0}while((V|0)!=(x|0));X=x}else X=0;if((X|0)<(G|0)){V=X;do{c[Q+(V+B<<2)>>2]=c[R+(V+E<<2)>>2];V=V+1|0}while((V|0)!=(G|0));T=R;U=Q}else{T=R;U=Q}}else if(O){V=Jb((c[I>>2]|0)-h|0)|0;P=c[(c[s>>2]|0)+(N<<2)>>2]|0;W=c[(c[b>>2]|0)+(N<<2)>>2]|0;if(J)Y=0;else{T=W;U=P;break}do{Z=P+(Y+B<<2)|0;g[Z>>2]=+g[V+(Y<<2)>>2]*+g[W+(Y<<2)>>2]+ +g[V+(K-Y<<2)>>2]*+g[Z>>2];Y=Y+1|0}while((Y|0)!=(r|0));T=W;U=P}else{P=Jb((c[u>>2]|0)-h|0)|0;W=c[(c[s>>2]|0)+(N<<2)>>2]|0;V=c[(c[b>>2]|0)+(N<<2)>>2]|0;if(F)_=0;else{T=V;U=W;break}do{Q=W+(L+_<<2)|0;g[Q>>2]=+g[P+(_<<2)>>2]*+g[V+(_<<2)>>2]+ +g[P+(D-_<<2)>>2]*+g[Q>>2];_=_+1|0}while((_|0)!=(x|0));T=V;U=W}while(0);if(H){O=0;do{c[U+(O+v<<2)>>2]=c[T+(O+A<<2)>>2];O=O+1|0}while((O|0)!=(A|0))}O=N+1|0;if((O|0)>=(c[z>>2]|0))break;t=c[p>>2]|0;M=c[n>>2]|0;N=O}$=c[y>>2]|0;aa=c[l>>2]|0}else{$=w;aa=m}c[y>>2]=($|0)==0?r:0;if((aa|0)==-1){c[l>>2]=v;c[j>>2]=v;ba=v;ca=v;break}else{c[l>>2]=B;N=(((c[e+(c[n>>2]<<2)>>2]|0)/4|0)+((c[e+(c[p>>2]<<2)>>2]|0)/4|0)>>h)+B|0;c[j>>2]=N;ba=N;ca=B;break}}else{ba=k;ca=m}while(0);m=f+128|0;f=m;k=c[f>>2]|0;aa=c[f+4>>2]|0;if((k|0)==-1&(aa|0)==-1){da=0;ea=0}else{f=((c[e+(c[n>>2]<<2)>>2]|0)/4|0)+((c[e+(c[p>>2]<<2)>>2]|0)/4|0)|0;$=Id(f|0,((f|0)<0)<<31>>31|0,k|0,aa|0)|0;da=$;ea=C}$=m;c[$>>2]=da;c[$+4>>2]=ea;$=a+56|0;m=$;aa=c[m>>2]|0;k=c[m+4>>2]|0;do if((aa|0)==-1&(k|0)==-1){m=b+48|0;f=c[m>>2]|0;T=c[m+4>>2]|0;if(!((f|0)==-1&(T|0)==-1)?(m=$,c[m>>2]=f,c[m+4>>2]=T,(ea|0)>(T|0)|(ea|0)==(T|0)&da>>>0>f>>>0):0){m=Ed(da|0,ea|0,f|0,T|0)|0;T=(m|0)<0?0:m;if(!(c[b+44>>2]|0)){m=ca+(T>>h)|0;c[l>>2]=(m|0)>(ba|0)?ba:m;break}else{m=ba-ca<<h;c[j>>2]=ba-(((T|0)>(m|0)?m:T)>>h);break}}}else{T=((c[e+(c[n>>2]<<2)>>2]|0)/4|0)+((c[e+(c[p>>2]<<2)>>2]|0)/4|0)|0;m=Id(T|0,((T|0)<0)<<31>>31|0,aa|0,k|0)|0;T=C;f=$;c[f>>2]=m;c[f+4>>2]=T;f=b+48|0;U=c[f>>2]|0;_=c[f+4>>2]|0;if(!((U|0)==-1&(_|0)==-1|(m|0)==(U|0)&(T|0)==(_|0))){if(((T|0)>(_|0)|(T|0)==(_|0)&m>>>0>U>>>0?(f=Ed(m|0,T|0,U|0,_|0)|0,(f|0)!=0):0)?(c[b+44>>2]|0)!=0:0){T=ba-ca<<h;m=(f|0)>(T|0)?T:f;c[j>>2]=ba-(((m|0)<0?0:m)>>h)}m=$;c[m>>2]=U;c[m+4>>2]=_}}while(0);if(!(c[b+44>>2]|0)){i=0;return i|0}c[a+32>>2]=1;i=0;return i|0}function Gb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;d=c[a+24>>2]|0;if((d|0)<=-1){e=0;return e|0}f=c[a+20>>2]|0;if((f|0)<=(d|0)){e=0;return e|0}if(b){g=c[(c[a+4>>2]|0)+4>>2]|0;if((g|0)>0){h=a+8|0;i=a+12|0;j=0;do{c[(c[i>>2]|0)+(j<<2)>>2]=(c[(c[h>>2]|0)+(j<<2)>>2]|0)+(d<<2);j=j+1|0}while((j|0)<(g|0));k=i}else k=a+12|0;c[b>>2]=c[k>>2]}e=f-d|0;return e|0}function Hb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=a+24|0;e=c[d>>2]|0;if((b|0)!=0?(e+b|0)>(c[a+20>>2]|0):0){f=-131;return f|0}c[d>>2]=e+b;f=0;return f|0}function Ib(a){a=a|0;tb(a+16|0);yd(c[a+48>>2]|0);yd(c[a+64>>2]|0);yd(c[a+80>>2]|0);yd(c[a+96>>2]|0);yd(c[a+112>>2]|0);yd(c[a+128>>2]|0);yd(c[a+144>>2]|0);yd(c[a+36>>2]|0);yd(c[a+152>>2]|0);yd(c[a+160>>2]|0);Fd(a|0,0,180)|0;return}function Jb(a){a=a|0;return c[376+(a<<2)>>2]|0}function Kb(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;i=(f|0)!=0;j=i?e:0;e=i?h:0;h=c[376+(c[b+(j<<2)>>2]<<2)>>2]|0;i=c[376+(c[b+(e<<2)>>2]<<2)>>2]|0;b=c[d+(f<<2)>>2]|0;f=c[d+(j<<2)>>2]|0;j=c[d+(e<<2)>>2]|0;e=(b|0)/4|0;d=(f|0)/4|0;k=e-d|0;l=(f|0)/2|0;f=((b|0)/2|0)+e+((j|0)/-4|0)|0;m=(j|0)/2|0;n=f+m|0;if((k|0)>0){Fd(a|0,0,e-d<<2|0)|0;o=k}else o=0;if((o|0)<(k+l|0)){k=e+l-o-d|0;d=o;o=0;while(1){l=a+(d<<2)|0;g[l>>2]=+g[l>>2]*+g[h+(o<<2)>>2];o=o+1|0;if((o|0)==(k|0))break;else d=d+1|0}}if((j|0)>1){j=f+1|0;d=(n|0)>(j|0);k=f;o=m;do{o=o+-1|0;m=a+(k<<2)|0;g[m>>2]=+g[m>>2]*+g[i+(o<<2)>>2];k=k+1|0}while((k|0)<(n|0));p=d?n:j}else p=f;if((b|0)<=(p|0))return;Fd(a+(p<<2)|0,0,b-p<<2|0)|0;return}function Lb(a,b,d,e,f,h,i,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;i=+i;j=+j;var k=0.0,l=0,m=0.0,n=0,o=0.0,p=0.0,q=0.0,r=0,s=0,t=0,u=0,v=0.0,w=0.0,x=0.0,y=0.0,z=0.0,A=0;k=3.141592653589793/+(e|0);if((h|0)>0){e=0;do{l=f+(e<<2)|0;g[l>>2]=+Q(+(+g[l>>2]))*2.0;e=e+1|0}while((e|0)!=(h|0))}if((d|0)<=0)return;m=i;i=j;if((h|0)<=1){e=(h|0)==1;l=0;while(1){n=c[b+(l<<2)>>2]|0;j=+Q(+(+(n|0)*k))*2.0;if(e){o=(j-+g[f>>2])*.5;p=4.0-j*j;q=o*o}else{p=2.0-j;q=(j+2.0)*.25}j=+X(+((m/+O(+(q+p*.25))-i)*.1151292473077774));r=a+(l<<2)|0;g[r>>2]=+g[r>>2]*j;r=l+1|0;if((c[b+(r<<2)>>2]|0)==(n|0)){s=r;while(1){t=a+(s<<2)|0;g[t>>2]=+g[t>>2]*j;t=s+1|0;if((c[b+(t<<2)>>2]|0)==(n|0))s=t;else{u=t;break}}}else u=r;if((u|0)<(d|0))l=u;else break}return}u=((h+-2&-2)+3|0)==(h|0);l=f+(h+-1<<2)|0;e=0;while(1){s=c[b+(e<<2)>>2]|0;p=+Q(+(+(s|0)*k))*2.0;n=1;q=.5;j=.5;while(1){o=(p-+g[f+(n+-1<<2)>>2])*j;v=(p-+g[f+(n<<2)>>2])*q;n=n+2|0;if((n|0)>=(h|0)){w=o;x=v;break}else{q=v;j=o}}if(u){j=(p-+g[l>>2])*w;y=x*x*(4.0-p*p);z=j*j}else{y=x*x*(2.0-p);z=w*w*(p+2.0)}j=+X(+((m/+O(+(z+y))-i)*.1151292473077774));n=a+(e<<2)|0;g[n>>2]=+g[n>>2]*j;n=e+1|0;if((c[b+(n<<2)>>2]|0)==(s|0)){r=n;while(1){t=a+(r<<2)|0;g[t>>2]=+g[t>>2]*j;t=r+1|0;if((c[b+(t<<2)>>2]|0)==(s|0))r=t;else{A=t;break}}}else A=n;if((A|0)<(d|0))e=A;else break}return}function Mb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;d=(a|0)!=0;if(d?(e=c[a+64>>2]|0,(e|0)!=0):0){f=c[e+104>>2]|0;g=c[e+4>>2]|0;if(!g){h=f;i=1;j=0;k=0;l=0}else{h=f;i=1;j=1;k=c[g+28>>2]|0;l=g}}else{h=0;i=0;j=0;k=0;l=0}g=d?a+4|0:0;if(!(d&((k|0)!=0&(j&(i&(h|0)!=0))))){m=-136;return m|0}Bb(a);nb(g,c[b>>2]|0,c[b+4>>2]|0);if(qb(g,1)|0){m=-135;return m|0}i=qb(g,c[h+44>>2]|0)|0;if((i|0)==-1){m=-136;return m|0}c[a+40>>2]=i;h=k+32+(i<<2)|0;i=c[h>>2]|0;if(!i){m=-136;return m|0}j=c[i>>2]|0;i=a+28|0;c[i>>2]=j;do if(j){c[a+24>>2]=qb(g,1)|0;d=qb(g,1)|0;c[a+32>>2]=d;if((d|0)==-1){m=-136;return m|0}else{n=c[i>>2]|0;break}}else{c[a+24>>2]=0;c[a+32>>2]=0;n=0}while(0);i=b+16|0;g=c[i+4>>2]|0;j=a+48|0;c[j>>2]=c[i>>2];c[j+4>>2]=g;g=b+24|0;j=c[g+4>>2]|0;i=a+56|0;c[i>>2]=c[g>>2];c[i+4>>2]=j;c[a+44>>2]=c[b+12>>2];b=a+36|0;c[b>>2]=c[k+(n<<2)>>2];n=l+4|0;c[a>>2]=Ab(a,c[n>>2]<<2)|0;if((c[n>>2]|0)>0){l=0;do{j=Ab(a,c[b>>2]<<2)|0;c[(c[a>>2]|0)+(l<<2)>>2]=j;l=l+1|0}while((l|0)<(c[n>>2]|0))}n=c[(c[h>>2]|0)+12>>2]|0;m=$a[c[(c[352+(c[k+288+(n<<2)>>2]<<2)>>2]|0)+16>>2]&15](a,c[k+544+(n<<2)>>2]|0)|0;return m|0}function Nb(a){a=a|0;if(!a)return;yd(a);return}function Ob(a){a=a|0;if(a)yd(a);return}function Pb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var h=0,i=0,j=0.0,k=0.0,l=0.0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0.0,B=0.0,C=0.0,D=0,E=0,F=0.0,G=0;h=a;i=h+48|0;do{c[h>>2]=0;h=h+4|0}while((h|0)<(i|0));h=c[d>>2]|0;c[a+36>>2]=h;d=~~(+td(+Y(+(+(h|0)*8.0))*1.4426950408889634)+-1.0);i=a+32|0;c[i>>2]=d;j=+(f|0);k=+(e|0);l=+(1<<d+1|0);d=~~(l*(+Y(+(j*.25*.5/k))*1.4426950216293335+-5.965784072875977)-+(h|0));c[a+28>>2]=d;c[a+40>>2]=1-d+~~(l*(+Y(+((+(e|0)+.25)*j*.5/k))*1.4426950216293335+-5.965784072875977)+.5);d=e<<2;h=xd(d)|0;c[a+16>>2]=h;m=xd(d)|0;c[a+20>>2]=m;n=xd(d)|0;c[a+24>>2]=n;o=a+4|0;c[o>>2]=b;c[a>>2]=e;c[a+44>>2]=f;p=a+48|0;g[p>>2]=1.0;do if((f|0)>=26e3){if((f|0)<38e3){g[p>>2]=.9399999976158142;break}if((f|0)>46e3)g[p>>2]=1.274999976158142}else g[p>>2]=0.0;while(0);j=k*2.0;l=+(f|0);p=(e|0)>0;q=0;r=0;a:while(1){s=p^1;t=q;while(1){u=t;t=t+1|0;v=~~+td(j*+X(+(+(t|0)*.08664337545633316+2.7488713472395148))/l);if(!((v|0)<=(r|0)|s)){w=t;x=v;y=u;break}if((t|0)>=87){z=r;break a}}A=+g[408+(y<<2)>>2];B=(+g[408+(w<<2)>>2]-A)/+(x-r|0);t=r-x|0;s=r-e|0;u=r-(t>>>0>s>>>0?t:s)|0;C=A;s=r;while(1){g[h+(s<<2)>>2]=C+100.0;s=s+1|0;if((s|0)==(u|0))break;else C=C+B}if((w|0)<87){p=(u|0)<(e|0);q=w;r=u}else{z=u;break}}if((z|0)<(e|0)){r=z;do{c[h+(r<<2)>>2]=c[h+(r+-1<<2)>>2];r=r+1|0}while((r|0)!=(e|0))}r=(e|0)>0;if(r){h=(f|0)/(e<<1|0)|0;f=c[b+120>>2]|0;z=b+124|0;w=b+116|0;q=b+112|0;p=1;x=0;y=-99;while(1){s=_(h,x)|0;B=+(s|0);C=+V(+(+(_(s,s)|0)*1.8499999754340024e-08))*2.240000009536743+ +V(+(B*7.399999885819852e-04))*13.100000381469727+B*9.999999747378752e-05;b:do if((f+y|0)<(x|0)){B=C-+g[q>>2];s=y;while(1){t=_(s,h)|0;A=+(t|0);if(!(+V(+(A*7.399999885819852e-04))*13.100000381469727+A*9.999999747378752e-05+ +V(+(+(_(t,t)|0)*1.8499999754340024e-08))*2.240000009536743<B)){D=s;break b}t=s+1|0;if((f+t|0)<(x|0))s=t;else{D=t;break}}}else D=y;while(0);c:do if((p|0)>(e|0))E=p;else{u=(c[z>>2]|0)+x|0;s=p;while(1){if((s|0)>=(u|0)?(t=_(s,h)|0,B=+(t|0),A=+V(+(B*7.399999885819852e-04))*13.100000381469727+B*9.999999747378752e-05+ +V(+(+(_(t,t)|0)*1.8499999754340024e-08))*2.240000009536743,!(A<+g[w>>2]+C)):0){E=s;break c}t=s+1|0;if((s|0)<(e|0))s=t;else{E=t;break}}}while(0);c[n+(x<<2)>>2]=(D<<16)+-65537+E;x=x+1|0;if((x|0)==(e|0))break;else{p=E;y=D}}if(r){C=l*.5;A=+(1<<(c[i>>2]|0)+1|0);i=0;do{c[m+(i<<2)>>2]=~~(A*(+Y(+(C*(+(i|0)+.25)/k))*1.4426950216293335+-5.965784072875977)+.5);i=i+1|0}while((i|0)!=(e|0));F=C}else G=19}else G=19;if((G|0)==19)F=l*.5;c[a+8>>2]=Kc(b+36|0,F/k,e,+g[b+24>>2],+g[b+28>>2])|0;b=xd(12)|0;c[a+12>>2]=b;c[b>>2]=xd(d)|0;c[b+4>>2]=xd(d)|0;c[b+8>>2]=xd(d)|0;if(!r)return;r=c[o>>2]|0;o=c[b>>2]|0;d=c[b+4>>2]|0;a=c[b+8>>2]|0;b=0;do{k=+Y(+((+(b|0)+.5)*l/j))*2.885390043258667+-11.931568145751953;F=k<0.0?0.0:k;k=F>=16.0?16.0:F;G=~~k;F=k-+(G|0);k=1.0-F;i=G+1|0;g[o+(b<<2)>>2]=+g[r+132+(i<<2)>>2]*F+ +g[r+132+(G<<2)>>2]*k;g[d+(b<<2)>>2]=+g[r+200+(i<<2)>>2]*F+ +g[r+200+(G<<2)>>2]*k;g[a+(b<<2)>>2]=+g[r+268+(i<<2)>>2]*F+ +g[r+268+(G<<2)>>2]*k;b=b+1|0}while((b|0)!=(e|0));return}function Qb(a){a=a|0;var b=0,d=0,e=0,f=0;if(!a)return;b=c[a+16>>2]|0;if(b)yd(b);b=c[a+20>>2]|0;if(b)yd(b);b=c[a+24>>2]|0;if(b)yd(b);b=a+8|0;d=c[b>>2]|0;if(d){e=d;d=0;while(1){yd(c[c[e+(d<<2)>>2]>>2]|0);yd(c[(c[(c[b>>2]|0)+(d<<2)>>2]|0)+4>>2]|0);yd(c[(c[(c[b>>2]|0)+(d<<2)>>2]|0)+8>>2]|0);yd(c[(c[(c[b>>2]|0)+(d<<2)>>2]|0)+12>>2]|0);yd(c[(c[(c[b>>2]|0)+(d<<2)>>2]|0)+16>>2]|0);yd(c[(c[(c[b>>2]|0)+(d<<2)>>2]|0)+20>>2]|0);yd(c[(c[(c[b>>2]|0)+(d<<2)>>2]|0)+24>>2]|0);yd(c[(c[(c[b>>2]|0)+(d<<2)>>2]|0)+28>>2]|0);yd(c[(c[b>>2]|0)+(d<<2)>>2]|0);f=d+1|0;if((f|0)==17)break;e=c[b>>2]|0;d=f}yd(c[b>>2]|0)}b=a+12|0;d=c[b>>2]|0;if(d){yd(c[d>>2]|0);yd(c[(c[b>>2]|0)+4>>2]|0);yd(c[(c[b>>2]|0)+8>>2]|0);yd(c[b>>2]|0)}b=a;a=b+52|0;do{c[b>>2]=0;b=b+4|0}while((b|0)<(a|0));return}function Rb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0;e=i;f=c[a>>2]|0;h=i;i=i+((1*(f<<2)|0)+15&-16)|0;j=a+24|0;Lc(f,c[j>>2]|0,b,d,140.0,-1);k=(f|0)>0;if(k){l=0;do{g[h+(l<<2)>>2]=+g[b+(l<<2)>>2]-+g[d+(l<<2)>>2];l=l+1|0}while((l|0)!=(f|0))}l=a+4|0;Lc(f,c[j>>2]|0,h,d,0.0,c[(c[l>>2]|0)+128>>2]|0);if(k)m=0;else{i=e;return}do{j=h+(m<<2)|0;g[j>>2]=+g[b+(m<<2)>>2]-+g[j>>2];m=m+1|0}while((m|0)!=(f|0));if(!k){i=e;return}k=c[l>>2]|0;l=0;do{m=d+(l<<2)|0;b=~~(+g[m>>2]+.5);j=(b|0)>39?39:b;g[m>>2]=+g[k+336+(((j|0)<0?0:j)<<2)>>2]+ +g[h+(l<<2)>>2];l=l+1|0}while((l|0)!=(f|0));i=e;return}function Sb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=+e;f=+f;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0.0,q=0,r=0.0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0.0,E=0,F=0,G=0,H=0,I=0,J=0,K=0.0,L=0.0,M=0,N=0,O=0,P=0;h=i;j=c[a>>2]|0;k=a+40|0;l=c[k>>2]|0;m=i;i=i+((1*(l<<2)|0)+15&-16)|0;n=a+4|0;o=c[n>>2]|0;p=+g[o+4>>2]+f;if((l|0)>0){q=0;do{g[m+(q<<2)>>2]=-9999.0;q=q+1|0}while((q|0)<(l|0))}f=+g[o+8>>2];r=p<f?f:p;q=(j|0)>0;if(q){s=c[a+16>>2]|0;t=0;do{g[d+(t<<2)>>2]=+g[s+(t<<2)>>2]+r;t=t+1|0}while((t|0)!=(j|0));t=c[a+8>>2]|0;r=+g[o+496>>2]-e;if(q){q=c[a+20>>2]|0;o=a+32|0;s=a+36|0;u=a+28|0;v=0;while(1){w=c[q+(v<<2)>>2]|0;x=v;e=+g[b+(v<<2)>>2];a:while(1){y=x;while(1){z=y+1|0;if((z|0)>=(j|0)){A=0;B=z;C=y;D=e;break a}if((c[q+(z<<2)>>2]|0)!=(w|0)){A=1;B=z;C=y;D=e;break a}p=+g[b+(z<<2)>>2];if(p>e){x=z;e=p;continue a}else y=z}}if(D+6.0>+g[d+(C<<2)>>2]?(x=w>>c[o>>2],y=(x|0)>16?16:x,x=c[s>>2]|0,z=~~((r+D+-30.0)*.10000000149011612),E=(z|0)<0?0:z,z=c[(c[t+(((y|0)<0?0:y)<<2)>>2]|0)+(((E|0)>7?7:E)<<2)>>2]|0,E=~~+g[z+4>>2],e=+g[z>>2],y=~~e,(y|0)<(E|0)):0){F=y;y=~~((e+-16.0)*+(x|0)-+(x>>1|0)+ +((c[q+(C<<2)>>2]|0)-(c[u>>2]|0)|0));do{if((y|0)>0?(e=+g[z+(F+2<<2)>>2]+D,G=m+(y<<2)|0,+g[G>>2]<e):0)g[G>>2]=e;y=y+x|0;F=F+1|0}while((F|0)<(E|0)&(y|0)<(l|0))}if(A)v=B;else{H=s;break}}}else I=7}else I=7;if((I|0)==7)H=a+36|0;I=c[H>>2]|0;Mc(m,I,l);l=c[a>>2]|0;b:do if((l|0)>1){H=c[a+20>>2]|0;s=c[H>>2]|0;B=c[a+28>>2]|0;v=(c[n>>2]|0)+32|0;A=1;u=s;C=0;q=s-(I>>1)-B|0;while(1){D=+g[m+(q<<2)>>2];s=((c[H+(A<<2)>>2]|0)+u>>1)-B|0;r=+g[v>>2];e=D>r?r:D;c:do if((q|0)<(s|0)){t=q;D=e;while(1){o=D==-9999.0;b=t;while(1){j=b+1|0;r=+g[m+(j<<2)>>2];if(r>-9999.0){if(o|r<D){J=j;K=r;break}}else if(o){J=j;K=r;break}if((j|0)<(s|0))b=j;else{L=D;M=j;break c}}if((J|0)<(s|0)){t=J;D=K}else{L=K;M=J;break}}}else{L=e;M=q}while(0);s=M+B|0;d:do if((C|0)>=(l|0)|(u|0)>(s|0))N=C;else{t=C;while(1){b=d+(t<<2)|0;if(+g[b>>2]<L)g[b>>2]=L;b=t+1|0;if((b|0)>=(l|0)){N=b;break d}if((c[H+(b<<2)>>2]|0)>(s|0)){N=b;break}else t=b}}while(0);s=N+1|0;if((s|0)>=(l|0)){O=N;break b}A=s;u=c[H+(N<<2)>>2]|0;C=N;q=M}}else O=0;while(0);L=+g[m+((c[k>>2]|0)+-1<<2)>>2];if((O|0)<(l|0))P=O;else{i=h;return}do{O=d+(P<<2)|0;if(+g[O>>2]<L)g[O>>2]=L;P=P+1|0}while((P|0)!=(l|0));i=h;return}function Tb(a,b,d,e,f,h,i){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;i=i|0;var j=0,k=0,l=0.0,m=0,n=0,o=0.0,p=0.0,q=0.0,r=0.0,s=0.0,t=0.0;j=c[a>>2]|0;k=c[a+4>>2]|0;l=+g[k+12+(e<<2)>>2];if((j|0)<=0)return;m=c[(c[a+12>>2]|0)+(e<<2)>>2]|0;n=k+108|0;k=(e|0)==1;o=+g[a+48>>2];p=o*.005;q=o*.0003;a=0;do{o=+g[m+(a<<2)>>2]+ +g[b+(a<<2)>>2];r=+g[n>>2];s=o>r?r:o;o=+g[d+(a<<2)>>2]+l;g[f+(a<<2)>>2]=s<o?o:s;if(k){o=s-+g[i+(a<<2)>>2];s=o+17.200000762939453;if(o>-17.200000762939453){o=1.0-p*s;if(o<0.0)t=9.999999747378752e-05;else t=o}else t=1.0-q*s;e=h+(a<<2)|0;g[e>>2]=+g[e>>2]*t}a=a+1|0}while((a|0)!=(j|0));return}function Ub(a,b,d,e,f,j,k,l,m){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;j=j|0;k=k|0;l=l|0;m=m|0;var n=0,o=0,p=0,q=0,r=0,s=0.0,t=0,u=0,v=0,w=0,x=0,y=0,z=0.0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,O=0,P=0,Q=0,R=0,S=0.0,T=0,U=0.0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0.0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0;n=i;o=c[d>>2]|0;p=d+4|0;d=c[p>>2]|0;if(!(c[d+500>>2]|0))q=16;else q=c[d+508>>2]|0;r=c[b+132+((c[d>>2]|0)*60|0)+(a<<2)>>2]|0;s=+h[760+(c[b+252+(a<<2)>>2]<<3)>>3];d=m<<2;t=i;i=i+((1*d|0)+15&-16)|0;u=i;i=i+((1*d|0)+15&-16)|0;v=i;i=i+((1*d|0)+15&-16)|0;w=i;i=i+((1*d|0)+15&-16)|0;x=i;i=i+((1*d|0)+15&-16)|0;y=e+1156|0;z=+h[((o|0)>1e3?832:760)+(c[b+312+(a<<2)>>2]<<3)>>3];a=_(d,q)|0;b=i;i=i+((1*a|0)+15&-16)|0;c[t>>2]=b;A=i;i=i+((1*a|0)+15&-16)|0;c[u>>2]=A;B=i;i=i+((1*a|0)+15&-16)|0;c[v>>2]=B;C=i;i=i+((1*a|0)+15&-16)|0;c[w>>2]=C;if((m|0)>1?(c[t+4>>2]=b+(q<<2),c[u+4>>2]=A+(q<<2),c[v+4>>2]=B+(q<<2),c[w+4>>2]=C+(q<<2),(m|0)!=2):0){C=2;do{B=c[u>>2]|0;A=c[v>>2]|0;b=c[w>>2]|0;D=_(C,q)|0;c[t+(C<<2)>>2]=(c[t>>2]|0)+(D<<2);c[u+(C<<2)>>2]=B+(D<<2);c[v+(C<<2)>>2]=A+(D<<2);c[w+(C<<2)>>2]=b+(D<<2);C=C+1|0}while((C|0)!=(m|0))}C=c[y>>2]|0;if((o|0)>0){D=c[w>>2]|0;b=(m|0)>0;A=~q;B=0;E=~o;while(1){F=~((E|0)>(A|0)?E:A);G=o-B|0;H=(q|0)>(G|0)?G:q;Jd(x|0,k|0,d|0)|0;Fd(D|0,0,a|0)|0;if(b){G=(H|0)>0;I=r-B|0;J=0;do{K=c[j+(J<<2)>>2]|0;L=K+(B<<2)|0;if(!(c[x+(J<<2)>>2]|0)){if(G){M=c[v+(J<<2)>>2]|0;O=c[t+(J<<2)>>2]|0;P=c[u+(J<<2)>>2]|0;Q=c[w+(J<<2)>>2]|0;R=0;do{g[M+(R<<2)>>2]=1.000000013351432e-10;g[O+(R<<2)>>2]=0.0;g[P+(R<<2)>>2]=0.0;c[Q+(R<<2)>>2]=0;c[K+(R+B<<2)>>2]=0;R=R+1|0}while((R|0)!=(F|0))}}else{R=c[v+(J<<2)>>2]|0;if(G){Q=0;do{c[R+(Q<<2)>>2]=c[56400+(c[K+(Q+B<<2)>>2]<<2)>>2];Q=Q+1|0}while((Q|0)!=(F|0));Q=c[f+(J<<2)>>2]|0;K=c[w+(J<<2)>>2]|0;if(G){P=0;do{S=+N(+(+g[Q+(P+B<<2)>>2]));c[K+(P<<2)>>2]=!(S/+g[R+(P<<2)>>2]<((P|0)>=(I|0)?z:s))&1;P=P+1|0}while((P|0)!=(H|0));if(G){P=c[t+(J<<2)>>2]|0;K=u+(J<<2)|0;O=c[K>>2]|0;M=0;do{T=Q+(M+B<<2)|0;S=+g[T>>2];U=S*S;V=P+(M<<2)|0;g[V>>2]=U;g[O+(M<<2)>>2]=U;if(+g[T>>2]<0.0)g[V>>2]=-+g[V>>2];V=R+(M<<2)|0;U=+g[V>>2];g[V>>2]=U*U;M=M+1|0}while((M|0)!=(F|0));W=K;X=P}else Y=21}else Y=21}else Y=21;if((Y|0)==21){Y=0;W=u+(J<<2)|0;X=c[t+(J<<2)>>2]|0}+Nc(c[p>>2]|0,r,X,c[W>>2]|0,R,0,B,H,L)}J=J+1|0}while((J|0)!=(m|0))}J=c[y>>2]|0;if((J|0)>0){G=(H|0)>0;I=l-B|0;P=r-B|0;K=J;M=0;while(1){O=c[e+1160+(M<<2)>>2]|0;Q=c[e+2184+(M<<2)>>2]|0;V=c[j+(O<<2)>>2]|0;T=V+(B<<2)|0;Z=c[j+(Q<<2)>>2]|0;$=c[t+(O<<2)>>2]|0;aa=c[t+(Q<<2)>>2]|0;ba=c[u+(O<<2)>>2]|0;ca=c[u+(Q<<2)>>2]|0;da=c[v+(O<<2)>>2]|0;ea=c[v+(Q<<2)>>2]|0;fa=c[w+(O<<2)>>2]|0;ga=c[w+(Q<<2)>>2]|0;ha=x+(O<<2)|0;O=x+(Q<<2)|0;if((c[ha>>2]|0)==0?(c[O>>2]|0)==0:0)ia=K;else{c[O>>2]=1;c[ha>>2]=1;if(G){ha=0;do{do if((ha|0)<(I|0)){O=fa+(ha<<2)|0;Q=ga+(ha<<2)|0;if((c[O>>2]|0)==0?(c[Q>>2]|0)==0:0){do if((ha|0)>=(P|0)){ja=$+(ha<<2)|0;U=+g[ja>>2];ka=aa+(ha<<2)|0;S=+g[ka>>2];la=+N(+S)+ +N(+U);g[ba+(ha<<2)>>2]=la;if(S+U<0.0){g[ja>>2]=-la;ma=ka;break}else{g[ja>>2]=la;ma=ka;break}}else{ka=aa+(ha<<2)|0;ja=$+(ha<<2)|0;la=+g[ja>>2]+ +g[ka>>2];g[ja>>2]=la;g[ba+(ha<<2)>>2]=+N(+la);ma=ka}while(0);g[ca+(ha<<2)>>2]=0.0;g[ma>>2]=0.0;c[Q>>2]=1;c[Z+(ha+B<<2)>>2]=0;break}ka=$+(ha<<2)|0;la=+N(+(+g[ka>>2]));g[ka>>2]=+N(+(+g[aa+(ha<<2)>>2]))+la;ka=ba+(ha<<2)|0;g[ka>>2]=+g[ca+(ha<<2)>>2]+ +g[ka>>2];c[Q>>2]=1;c[O>>2]=1;ka=ha+B|0;ja=V+(ka<<2)|0;na=c[ja>>2]|0;oa=Z+(ka<<2)|0;ka=c[oa>>2]|0;if((((na|0)>-1?na:0-na|0)|0)>(((ka|0)>-1?ka:0-ka|0)|0)){pa=(na|0)>0?na-ka|0:ka-na|0;c[oa>>2]=pa;qa=c[ja>>2]|0;ra=pa}else{c[oa>>2]=(ka|0)>0?na-ka|0:ka-na|0;c[ja>>2]=ka;qa=ka;ra=c[oa>>2]|0}if((ra|0)>=(((qa|0)>-1?qa:0-qa|0)<<1|0)){c[oa>>2]=0-ra;c[ja>>2]=0-(c[ja>>2]|0)}}while(0);ja=da+(ha<<2)|0;oa=ea+(ha<<2)|0;la=+g[oa>>2]+ +g[ja>>2];g[oa>>2]=la;g[ja>>2]=la;ha=ha+1|0}while((ha|0)!=(F|0))}+Nc(c[p>>2]|0,r,$,ba,da,fa,B,H,T);ia=c[y>>2]|0}M=M+1|0;if((M|0)>=(ia|0)){sa=ia;break}else K=ia}}else sa=J;B=B+q|0;if((o|0)<=(B|0)){ta=sa;break}else E=E+q|0}}else ta=C;if((ta|0)>0){ua=ta;va=0}else{i=n;return}while(1){ta=k+(c[e+1160+(va<<2)>>2]<<2)|0;C=e+2184+(va<<2)|0;if((c[ta>>2]|0)==0?(c[k+(c[C>>2]<<2)>>2]|0)==0:0)wa=ua;else{c[ta>>2]=1;c[k+(c[C>>2]<<2)>>2]=1;wa=c[y>>2]|0}va=va+1|0;if((va|0)>=(wa|0))break;else ua=wa}i=n;return}function Vb(a){a=a|0;c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;return}function Wb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;if(!a)return;b=c[a>>2]|0;if(b){d=a+8|0;e=c[d>>2]|0;if((e|0)>0){f=e;e=b;g=0;while(1){h=c[e+(g<<2)>>2]|0;if(!h)i=f;else{yd(h);i=c[d>>2]|0}h=g+1|0;if((h|0)>=(i|0))break;f=i;e=c[a>>2]|0;g=h}j=c[a>>2]|0}else j=b;yd(j)}j=c[a+4>>2]|0;if(j)yd(j);j=c[a+12>>2]|0;if(j)yd(j);c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;return}function Xb(a){a=a|0;c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;c[a+20>>2]=0;c[a+24>>2]=0;c[a+28>>2]=zd(1,3664)|0;return}function Yb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;b=c[a+28>>2]|0;if(!b){c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;c[a+20>>2]=0;c[a+24>>2]=0;c[a+28>>2]=0;return}d=b+8|0;e=c[d>>2]|0;if((e|0)>0){f=e;e=0;while(1){g=c[b+32+(e<<2)>>2]|0;if(!g)h=f;else{yd(g);h=c[d>>2]|0}e=e+1|0;if((e|0)>=(h|0))break;else f=h}}h=b+12|0;f=c[h>>2]|0;if((f|0)>0){e=f;f=0;while(1){d=c[b+544+(f<<2)>>2]|0;if(!d)i=e;else{Wa[c[(c[352+(c[b+288+(f<<2)>>2]<<2)>>2]|0)+8>>2]&7](d);i=c[h>>2]|0}f=f+1|0;if((f|0)>=(i|0))break;else e=i}}i=b+16|0;e=c[i>>2]|0;if((e|0)>0){f=e;e=0;while(1){h=c[b+1056+(e<<2)>>2]|0;if(!h)j=f;else{Wa[c[(c[328+(c[b+800+(e<<2)>>2]<<2)>>2]|0)+12>>2]&7](h);j=c[i>>2]|0}e=e+1|0;if((e|0)>=(j|0))break;else f=j}}j=b+20|0;f=c[j>>2]|0;if((f|0)>0){e=f;f=0;while(1){i=c[b+1568+(f<<2)>>2]|0;if(!i)k=e;else{Wa[c[(c[336+(c[b+1312+(f<<2)>>2]<<2)>>2]|0)+12>>2]&7](i);k=c[j>>2]|0}f=f+1|0;if((f|0)>=(k|0))break;else e=k}}k=b+24|0;e=b+2848|0;if((c[k>>2]|0)>0){f=0;do{j=c[b+1824+(f<<2)>>2]|0;if(j)yc(j);j=c[e>>2]|0;if(j)zc(j+(f*56|0)|0);f=f+1|0}while((f|0)<(c[k>>2]|0))}k=c[e>>2]|0;if(k)yd(k);k=b+28|0;if((c[k>>2]|0)>0){e=0;do{Ob(c[b+2852+(e<<2)>>2]|0);e=e+1|0}while((e|0)<(c[k>>2]|0))}yd(b);c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;c[a+20>>2]=0;c[a+24>>2]=0;c[a+28>>2]=0;return}function Zb(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;f=i;i=i+32|0;g=f;h=f+20|0;if(!e){j=-133;i=f;return j|0}nb(g,c[e>>2]|0,c[e+4>>2]|0);k=qb(g,8)|0;a[h>>0]=0;a[h+1>>0]=0;a[h+2>>0]=0;a[h+3>>0]=0;a[h+4>>0]=0;a[h>>0]=qb(g,8)|0;a[h+1>>0]=qb(g,8)|0;a[h+2>>0]=qb(g,8)|0;a[h+3>>0]=qb(g,8)|0;a[h+4>>0]=qb(g,8)|0;a[h+5>>0]=qb(g,8)|0;if(wd(h,904,6)|0){j=-132;i=f;return j|0}if((k|0)==5){if(!(c[b+8>>2]|0)){j=-133;i=f;return j|0}if(!(c[d+12>>2]|0)){j=-133;i=f;return j|0}h=c[b+28>>2]|0;if(!h){j=-129;i=f;return j|0}l=qb(g,8)|0;m=h+24|0;c[m>>2]=l+1;a:do if((l|0)>=0){n=0;do{o=nc(g)|0;c[h+1824+(n<<2)>>2]=o;n=n+1|0;if(!o)break a}while((n|0)<(c[m>>2]|0));n=qb(g,6)|0;if((n|0)>=0){o=0;while(1){if(qb(g,16)|0)break a;if((o|0)<(n|0))o=o+1|0;else break}o=qb(g,6)|0;n=h+16|0;c[n>>2]=o+1;if((o|0)>=0){o=0;do{p=qb(g,16)|0;c[h+800+(o<<2)>>2]=p;if(p>>>0>1)break a;q=$a[c[(c[328+(p<<2)>>2]|0)+4>>2]&15](b,g)|0;c[h+1056+(o<<2)>>2]=q;o=o+1|0;if(!q)break a}while((o|0)<(c[n>>2]|0));n=qb(g,6)|0;o=h+20|0;c[o>>2]=n+1;if((n|0)>=0){n=0;do{q=qb(g,16)|0;c[h+1312+(n<<2)>>2]=q;if(q>>>0>2)break a;p=$a[c[(c[336+(q<<2)>>2]|0)+4>>2]&15](b,g)|0;c[h+1568+(n<<2)>>2]=p;n=n+1|0;if(!p)break a}while((n|0)<(c[o>>2]|0));o=qb(g,6)|0;n=h+12|0;c[n>>2]=o+1;if((o|0)>=0){o=(c[88]|0)+4|0;p=0;do{q=qb(g,16)|0;c[h+288+(p<<2)>>2]=q;if(q)break a;q=$a[c[o>>2]&15](b,g)|0;c[h+544+(p<<2)>>2]=q;p=p+1|0;if(!q)break a}while((p|0)<(c[n>>2]|0));p=qb(g,6)|0;o=h+8|0;c[o>>2]=p+1;if((p|0)>=0){p=0;do{q=h+32+(p<<2)|0;c[q>>2]=zd(1,16)|0;r=qb(g,1)|0;c[c[q>>2]>>2]=r;r=qb(g,16)|0;c[(c[q>>2]|0)+4>>2]=r;r=qb(g,16)|0;c[(c[q>>2]|0)+8>>2]=r;r=qb(g,8)|0;s=c[q>>2]|0;c[s+12>>2]=r;if((c[s+4>>2]|0)>0)break a;if((c[s+8>>2]|0)>0)break a;p=p+1|0;if((r|0)<0?1:(r|0)>=(c[n>>2]|0))break a}while((p|0)<(c[o>>2]|0));if((qb(g,1)|0)==1){j=0;i=f;return j|0}}}}}}}while(0);Yb(b);j=-133;i=f;return j|0}else if((k|0)==1){if(!(c[e+8>>2]|0)){j=-133;i=f;return j|0}e=b+8|0;if(c[e>>2]|0){j=-133;i=f;return j|0}h=c[b+28>>2]|0;if(!h){j=-129;i=f;return j|0}m=qb(g,32)|0;c[b>>2]=m;if(m){j=-134;i=f;return j|0}m=b+4|0;c[m>>2]=qb(g,8)|0;c[e>>2]=qb(g,32)|0;c[b+12>>2]=qb(g,32)|0;c[b+16>>2]=qb(g,32)|0;c[b+20>>2]=qb(g,32)|0;c[h>>2]=1<<(qb(g,4)|0);l=1<<(qb(g,4)|0);c[h+4>>2]=l;if((((c[e>>2]|0)>=1?(c[m>>2]|0)>=1:0)?(m=c[h>>2]|0,!((l|0)>8192|((m|0)<64|(l|0)<(m|0)))):0)?(qb(g,1)|0)==1:0){j=0;i=f;return j|0}Yb(b);j=-133;i=f;return j|0}else if((k|0)==3){if(!(c[b+8>>2]|0)){j=-133;i=f;return j|0}b=qb(g,32)|0;b:do if((b|0)>=0?(k=g+16|0,(b|0)<=((c[k>>2]|0)+-8|0)):0){m=zd(b+1|0,1)|0;c[d+12>>2]=m;if(b){l=m;m=b;while(1){m=m+-1|0;a[l>>0]=qb(g,8)|0;if(!m)break;else l=l+1|0}}l=qb(g,32)|0;if((l|0)>=0?(m=c[k>>2]|0,(l|0)<=(m-(rb(g)|0)>>2|0)):0){m=d+8|0;c[m>>2]=l;h=l+1|0;c[d>>2]=zd(h,4)|0;e=d+4|0;c[e>>2]=zd(h,4)|0;if((l|0)>0){l=0;do{h=qb(g,32)|0;if((h|0)<0){t=d;break b}o=c[k>>2]|0;if((h|0)>(o-(rb(g)|0)|0)){t=d;break b}c[(c[e>>2]|0)+(l<<2)>>2]=h;o=zd(h+1|0,1)|0;c[(c[d>>2]|0)+(l<<2)>>2]=o;if(h){o=c[(c[d>>2]|0)+(l<<2)>>2]|0;p=h;while(1){p=p+-1|0;a[o>>0]=qb(g,8)|0;if(!p)break;else o=o+1|0}}l=l+1|0}while((l|0)<(c[m>>2]|0))}if((qb(g,1)|0)==1){j=0;i=f;return j|0}else t=d}else u=28}else u=28;while(0);do if((u|0)==28)if(!d){j=-133;i=f;return j|0}else{t=d;break}while(0);u=c[t>>2]|0;if(u){g=d+8|0;b=c[g>>2]|0;if((b|0)>0){m=u;l=b;b=0;while(1){e=c[m+(b<<2)>>2]|0;if(!e)v=l;else{yd(e);v=c[g>>2]|0}e=b+1|0;if((e|0)>=(v|0))break;m=c[t>>2]|0;l=v;b=e}w=c[d>>2]|0}else w=u;yd(w)}w=c[d+4>>2]|0;if(w)yd(w);w=c[d+12>>2]|0;if(w)yd(w);c[d>>2]=0;c[d+4>>2]=0;c[d+8>>2]=0;c[d+12>>2]=0;j=-133;i=f;return j|0}else{j=-133;i=f;return j|0}return 0}function _b(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0.0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0.0,$a=0.0,ab=0,bb=0,cb=0.0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0;f=i;i=i+4912|0;h=f+264|0;j=f+3856|0;k=f+4388|0;l=f;m=f+4128|0;n=f+4648|0;o=f+4908|0;p=f+4120|0;q=f+4116|0;r=f+3848|0;s=f+3852|0;t=f+4124|0;u=c[b+1296>>2]|0;v=c[b+1288>>2]|0;w=c[b+1284>>2]|0;x=(w|0)>0;if(x){y=0;do{c[j+(y<<2)>>2]=-200;y=y+1|0}while((y|0)!=(w|0));if(x){y=0;do{c[k+(y<<2)>>2]=-200;y=y+1|0}while((y|0)!=(w|0));if(x){Fd(l|0,0,w<<2|0)|0;y=0;do{c[m+(y<<2)>>2]=1;y=y+1|0}while((y|0)!=(w|0));if(x){Fd(n|0,-1,w<<2|0)|0;if((w|0)<=1){z=0;i=f;return z|0}x=v+-1|0;y=u+1112|0;A=w+-1|0;B=c[b>>2]|0;C=0;D=0;while(1){E=C;C=C+1|0;F=B;B=c[b+(C<<2)>>2]|0;G=h+(E*56|0)|0;H=G;I=H+56|0;do{c[H>>2]=0;H=H+4|0}while((H|0)<(I|0));c[G>>2]=F;c[h+(E*56|0)+4>>2]=B;J=(B|0)<(v|0)?B:x;if((J|0)<(F|0)){K=0;L=0;M=0;N=0;O=0;P=0;Q=0;R=0;S=0;T=0;U=0;V=0}else{W=F;X=0;Y=0;Z=0;$=0;aa=0;ba=0;ca=0;da=0;ea=0;fa=0;ga=0;ha=0;while(1){ia=+g[e+(W<<2)>>2];ja=~~(ia*7.314285755157471+1023.5);ka=(ja|0)>1023?1023:(ja|0)<0?0:ja;do if(ka)if(!(+g[y>>2]+ +g[d+(W<<2)>>2]>=ia)){la=X;ma=Y+1|0;na=Z;oa=(_(W,W)|0)+$|0;pa=aa;qa=W+ba|0;ra=ca;sa=(_(ka,W)|0)+da|0;ta=ea;ua=(_(ka,ka)|0)+fa|0;va=ga;wa=ka+ha|0;break}else{la=X+1|0;ma=Y;na=(_(W,W)|0)+Z|0;oa=$;pa=W+aa|0;qa=ba;ra=(_(ka,W)|0)+ca|0;sa=da;ta=(_(ka,ka)|0)+ea|0;ua=fa;va=ka+ga|0;wa=ha;break}else{la=X;ma=Y;na=Z;oa=$;pa=aa;qa=ba;ra=ca;sa=da;ta=ea;ua=fa;va=ga;wa=ha}while(0);if((W|0)<(J|0)){W=W+1|0;X=la;Y=ma;Z=na;$=oa;aa=pa;ba=qa;ca=ra;da=sa;ea=ta;fa=ua;ga=va;ha=wa}else{K=la;L=ma;M=na;N=oa;O=pa;P=qa;Q=ra;R=sa;S=ta;T=ua;U=va;V=wa;break}}}c[h+(E*56|0)+8>>2]=O;c[h+(E*56|0)+12>>2]=U;c[h+(E*56|0)+16>>2]=M;c[h+(E*56|0)+20>>2]=S;c[h+(E*56|0)+24>>2]=Q;c[h+(E*56|0)+28>>2]=K;c[h+(E*56|0)+32>>2]=P;c[h+(E*56|0)+36>>2]=V;c[h+(E*56|0)+40>>2]=N;c[h+(E*56|0)+44>>2]=T;c[h+(E*56|0)+48>>2]=R;c[h+(E*56|0)+52>>2]=L;ha=K+D|0;if((C|0)==(A|0)){xa=ha;break}else D=ha}}else ya=9}else ya=9}else ya=9}else ya=9;if((ya|0)==9){if(w){z=0;i=f;return z|0}D=h+4|0;H=h;I=H+56|0;do{c[H>>2]=0;H=H+4|0}while((H|0)<(I|0));c[D>>2]=v;if((v|0)<1){za=0;Aa=0;Ba=0;Ca=0;Da=0;Ea=0;Fa=0;Ga=0;Ha=0;Ia=0;Ja=0;Ka=0}else{D=u+1112|0;H=0;I=0;A=0;C=0;K=0;L=0;R=0;T=0;N=0;V=0;P=0;Q=0;S=0;while(1){ia=+g[e+(H<<2)>>2];M=~~(ia*7.314285755157471+1023.5);U=(M|0)>1023?1023:(M|0)<0?0:M;do if(U)if(!(+g[D>>2]+ +g[d+(H<<2)>>2]>=ia)){La=I;Ma=A+1|0;Na=C;Oa=(_(H,H)|0)+K|0;Pa=L;Qa=H+R|0;Ra=T;Sa=(_(U,H)|0)+N|0;Ua=V;Va=(_(U,U)|0)+P|0;Wa=Q;Xa=U+S|0;break}else{La=I+1|0;Ma=A;Na=(_(H,H)|0)+C|0;Oa=K;Pa=H+L|0;Qa=R;Ra=(_(U,H)|0)+T|0;Sa=N;Ua=(_(U,U)|0)+V|0;Va=P;Wa=U+Q|0;Xa=S;break}else{La=I;Ma=A;Na=C;Oa=K;Pa=L;Qa=R;Ra=T;Sa=N;Ua=V;Va=P;Wa=Q;Xa=S}while(0);H=H+1|0;if((H|0)==(v|0)){za=La;Aa=Ma;Ba=Na;Ca=Oa;Da=Pa;Ea=Qa;Fa=Ra;Ga=Sa;Ha=Ua;Ia=Va;Ja=Wa;Ka=Xa;break}else{I=La;A=Ma;C=Na;K=Oa;L=Pa;R=Qa;T=Ra;N=Sa;V=Ua;P=Va;Q=Wa;S=Xa}}}c[h+8>>2]=Da;c[h+12>>2]=Ja;c[h+16>>2]=Ba;c[h+20>>2]=Ha;c[h+24>>2]=Fa;c[h+28>>2]=za;c[h+32>>2]=Ea;c[h+36>>2]=Ka;c[h+40>>2]=Ca;c[h+44>>2]=Ia;c[h+48>>2]=Ga;c[h+52>>2]=Aa;xa=za}if(!xa){z=0;i=f;return z|0}c[o>>2]=-200;c[p>>2]=-200;Oc(h,w+-1|0,o,p,u)|0;xa=c[o>>2]|0;c[j>>2]=xa;c[k>>2]=xa;o=c[p>>2]|0;p=k+4|0;c[p>>2]=o;za=j+4|0;c[za>>2]=o;o=(w|0)>2;do if(o){Aa=u+1112|0;Ga=u+1096|0;Ia=u+1100|0;Ca=u+1104|0;Ka=2;a:while(1){Ea=c[b+520+(Ka<<2)>>2]|0;Fa=c[l+(Ea<<2)>>2]|0;Ha=c[m+(Ea<<2)>>2]|0;Ba=n+(Fa<<2)|0;b:do if((c[Ba>>2]|0)!=(Ha|0)){Ja=c[b+520+(Fa<<2)>>2]|0;Da=c[b+520+(Ha<<2)>>2]|0;c[Ba>>2]=Ha;Xa=c[u+836+(Fa<<2)>>2]|0;S=c[u+836+(Ha<<2)>>2]|0;Wa=c[j+(Fa<<2)>>2]|0;Q=k+(Fa<<2)|0;Va=c[Q>>2]|0;if((Wa|0)>=0)if((Va|0)<0)Ya=Wa;else Ya=Va+Wa>>1;else Ya=Va;Va=j+(Ha<<2)|0;Wa=c[Va>>2]|0;P=c[k+(Ha<<2)>>2]|0;if((Wa|0)>=0)if((P|0)<0)Za=Wa;else Za=P+Wa>>1;else Za=P;if((Ya|0)==-1|(Za|0)==-1){ya=38;break a}P=Za-Ya|0;Wa=S-Xa|0;Ua=(P|0)/(Wa|0)|0;V=P>>31|1;ia=+g[e+(Xa<<2)>>2];Sa=~~(ia*7.314285755157471+1023.5);N=(Sa|0)>1023?1023:(Sa|0)<0?0:Sa;Sa=_(Ua,Wa)|0;Ra=((P|0)>-1?P:0-P|0)-((Sa|0)>-1?Sa:0-Sa|0)|0;Sa=Ya-N|0;P=_(Sa,Sa)|0;_a=+g[Aa>>2];if(_a+ +g[d+(Xa<<2)>>2]>=ia){ia=+(Ya|0);$a=+(N|0);if(!(+g[Ga>>2]+ia<$a)?!(ia-+g[Ia>>2]>$a):0)ya=42}else ya=42;c:do if((ya|0)==42){ya=0;N=Xa+1|0;if((N|0)<(S|0)){Sa=N;N=0;T=P;Qa=1;R=Ya;while(1){Pa=N+Ra|0;L=(Pa|0)<(Wa|0);N=Pa-(L?0:Wa)|0;R=R+Ua+(L?0:V)|0;$a=+g[e+(Sa<<2)>>2];L=~~($a*7.314285755157471+1023.5);Pa=(L|0)>1023?1023:(L|0)<0?0:L;L=R-Pa|0;Oa=(_(L,L)|0)+T|0;L=Qa+1|0;if((Pa|0)!=0?+g[d+(Sa<<2)>>2]+_a>=$a:0){$a=+(R|0);ia=+(Pa|0);if(+g[Ga>>2]+$a<ia)break c;if($a-+g[Ia>>2]>ia)break c}Sa=Sa+1|0;if((Sa|0)>=(S|0)){ab=Oa;bb=L;break}else{T=Oa;Qa=L}}}else{ab=P;bb=1}ia=+g[Ga>>2];$a=+(bb|0);cb=+g[Ca>>2];if((!(ia*ia/$a>cb)?(ia=+g[Ia>>2],!(ia*ia/$a>cb)):0)?+((ab|0)/(bb|0)|0|0)>cb:0)break;c[j+(Ka<<2)>>2]=-200;c[k+(Ka<<2)>>2]=-200;break b}while(0);c[q>>2]=-200;c[r>>2]=-200;c[s>>2]=-200;c[t>>2]=-200;P=Oc(h+(Ja*56|0)|0,Ea-Ja|0,q,r,u)|0;S=Oc(h+(Ea*56|0)|0,Da-Ea|0,s,t,u)|0;V=(P|0)!=0;if(V){c[q>>2]=Ya;c[r>>2]=c[s>>2]}if((S|0)!=0?(c[s>>2]=c[r>>2],c[t>>2]=Za,V):0){c[j+(Ka<<2)>>2]=-200;c[k+(Ka<<2)>>2]=-200;break}V=c[q>>2]|0;c[Q>>2]=V;if(!Fa)c[j>>2]=V;V=c[r>>2]|0;c[j+(Ka<<2)>>2]=V;S=c[s>>2]|0;c[k+(Ka<<2)>>2]=S;P=c[t>>2]|0;c[Va>>2]=P;if((Ha|0)==1)c[p>>2]=P;if((S&V|0)>-1){d:do if((Ea|0)>0){V=Ea;do{S=V;V=V+-1|0;P=m+(V<<2)|0;if((c[P>>2]|0)!=(Ha|0))break d;c[P>>2]=Ka}while((S|0)>1)}while(0);Va=Ea+1|0;if((Va|0)<(w|0)){Q=Va;do{Va=l+(Q<<2)|0;if((c[Va>>2]|0)!=(Fa|0))break b;c[Va>>2]=Ka;Q=Q+1|0}while((Q|0)<(w|0))}}}while(0);Ka=Ka+1|0;if((Ka|0)>=(w|0)){ya=68;break}}if((ya|0)==38)Ta(1);else if((ya|0)==68){db=c[j>>2]|0;eb=c[k>>2]|0;break}}else{db=xa;eb=xa}while(0);xa=Ab(a,w<<2)|0;if((db|0)>=0)if((eb|0)<0)fb=db;else fb=eb+db>>1;else fb=eb;c[xa>>2]=fb;fb=c[za>>2]|0;za=c[p>>2]|0;if((fb|0)>=0)if((za|0)<0)gb=fb;else gb=za+fb>>1;else gb=za;c[xa+4>>2]=gb;if(o)hb=2;else{z=xa;i=f;return z|0}do{o=hb+-2|0;gb=c[b+1032+(o<<2)>>2]|0;za=c[b+780+(o<<2)>>2]|0;o=c[u+836+(gb<<2)>>2]|0;fb=c[xa+(gb<<2)>>2]&32767;gb=(c[xa+(za<<2)>>2]&32767)-fb|0;p=(_((gb|0)>-1?gb:0-gb|0,(c[u+836+(hb<<2)>>2]|0)-o|0)|0)/((c[u+836+(za<<2)>>2]|0)-o|0)|0;o=((gb|0)<0?0-p|0:p)+fb|0;fb=c[j+(hb<<2)>>2]|0;p=c[k+(hb<<2)>>2]|0;if((fb|0)>=0)if((p|0)<0)ib=fb;else ib=p+fb>>1;else ib=p;c[xa+(hb<<2)>>2]=(ib|0)<0|(o|0)==(ib|0)?o|32768:ib;hb=hb+1|0}while((hb|0)!=(w|0));z=xa;i=f;return z|0}function $b(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=c[b+1284>>2]|0;if(!((d|0)!=0&(e|0)!=0)){h=0;return h|0}b=Ab(a,g<<2)|0;if((g|0)<=0){h=b;return h|0}a=65536-f|0;i=0;do{j=d+(i<<2)|0;k=_(c[j>>2]&32767,a)|0;l=e+(i<<2)|0;m=k+32768+(_(c[l>>2]&32767,f)|0)>>16;k=b+(i<<2)|0;c[k>>2]=m;if((c[j>>2]&32768|0)!=0?(c[l>>2]&32768|0)!=0:0)c[k>>2]=m|32768;i=i+1|0}while((i|0)!=(g|0));h=b;return h|0}function ac(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0;g=i;i=i+336|0;h=g+64|0;j=g+32|0;k=g;l=c[d+1296>>2]|0;m=d+1284|0;n=c[m>>2]|0;o=c[(c[(c[b+64>>2]|0)+4>>2]|0)+28>>2]|0;p=c[o+2848>>2]|0;if(!e){lb(a,0,1);Fd(f|0,0,((c[b+36>>2]|0)/2|0)<<2|0)|0;q=0;i=g;return q|0}if((n|0)>0){r=l+832|0;s=0;do{t=e+(s<<2)|0;u=c[t>>2]|0;v=u&32767;w=c[r>>2]|0;if((w|0)==3)x=(v>>>0)/12|0;else if((w|0)==4)x=v>>>4;else if((w|0)==1)x=v>>>2;else if((w|0)==2)x=v>>>3;else x=v;c[t>>2]=u&32768|x;s=s+1|0}while((s|0)!=(n|0))}c[h>>2]=c[e>>2];s=h+4|0;c[s>>2]=c[e+4>>2];x=d+1292|0;if((n|0)>2){r=2;do{u=r+-2|0;t=c[d+1032+(u<<2)>>2]|0;v=c[d+780+(u<<2)>>2]|0;u=c[l+836+(t<<2)>>2]|0;w=e+(t<<2)|0;t=e+(v<<2)|0;y=c[w>>2]&32767;z=(c[t>>2]&32767)-y|0;A=(_((z|0)>-1?z:0-z|0,(c[l+836+(r<<2)>>2]|0)-u|0)|0)/((c[l+836+(v<<2)>>2]|0)-u|0)|0;u=((z|0)<0?0-A|0:A)+y|0;A=e+(r<<2)|0;z=c[A>>2]|0;if((z&32768|0)!=0|(z|0)==(u|0)){c[A>>2]=u|32768;c[h+(r<<2)>>2]=0}else{A=(c[x>>2]|0)-u|0;v=(A|0)<(u|0)?A:u;A=z-u|0;do if((A|0)<0)if((A|0)<(0-v|0)){B=v+~A|0;break}else{B=~(A<<1);break}else if((v|0)>(A|0)){B=A<<1;break}else{B=v+A|0;break}while(0);c[h+(r<<2)>>2]=B;c[w>>2]=y;c[t>>2]=c[t>>2]&32767}r=r+1|0}while((r|0)!=(n|0))}lb(a,1,1);n=d+1308|0;c[n>>2]=(c[n>>2]|0)+1;n=(c[x>>2]|0)+-1|0;r=(n|0)==0;if(!r){B=n;A=0;while(1){v=A+1|0;B=B>>>1;if(!B){C=v;break}else A=v}A=d+1304|0;c[A>>2]=(c[A>>2]|0)+(C<<1);C=c[h>>2]|0;if(r){D=C;E=A;F=0}else{r=n;n=0;while(1){B=n+1|0;r=r>>>1;if(!r){D=C;E=A;F=B;break}else n=B}}}else{D=c[h>>2]|0;E=d+1304|0;F=0}lb(a,D,F);F=c[s>>2]|0;s=(c[x>>2]|0)+-1|0;if(!s)G=0;else{x=s;s=0;while(1){D=s+1|0;x=x>>>1;if(!x){G=D;break}else s=D}}lb(a,F,G);if((c[l>>2]|0)>0){G=d+1300|0;F=0;s=2;while(1){x=c[l+4+(F<<2)>>2]|0;D=c[l+128+(x<<2)>>2]|0;n=c[l+192+(x<<2)>>2]|0;A=1<<n;c[j>>2]=0;c[j+4>>2]=0;c[j+8>>2]=0;c[j+12>>2]=0;c[j+16>>2]=0;c[j+20>>2]=0;c[j+24>>2]=0;c[j+28>>2]=0;if(n){C=(n|0)==31;if(!C){r=0;do{B=c[l+320+(x<<5)+(r<<2)>>2]|0;if((B|0)<0)H=1;else H=c[(c[o+1824+(B<<2)>>2]|0)+4>>2]|0;c[k+(r<<2)>>2]=H;r=r+1|0}while((r|0)<(A|0))}a:do if((D|0)>0){if(C){r=0;t=0;y=0;while(1){w=c[j+(y<<2)>>2]<<r|t;y=y+1|0;if((y|0)==(D|0)){I=w;break a}else{r=r+31|0;t=w}}}else{J=0;K=0;L=0}while(1){t=c[h+(L+s<<2)>>2]|0;r=0;while(1){if((t|0)<(c[k+(r<<2)>>2]|0)){M=r;N=37;break}r=r+1|0;if((r|0)>=(A|0)){N=39;break}}if((N|0)==37){N=0;c[j+(L<<2)>>2]=M;O=M}else if((N|0)==39){N=0;O=c[j+(L<<2)>>2]|0}r=O<<J|K;L=L+1|0;if((L|0)==(D|0)){I=r;break}else{J=J+n|0;K=r}}}else I=0;while(0);n=oc(p+((c[l+256+(x<<2)>>2]|0)*56|0)|0,I,a)|0;c[G>>2]=(c[G>>2]|0)+n}if((D|0)>0){n=0;do{A=c[l+320+(x<<5)+(c[j+(n<<2)>>2]<<2)>>2]|0;if((A|0)>-1?(C=c[h+(n+s<<2)>>2]|0,(C|0)<(c[p+(A*56|0)+4>>2]|0)):0){r=oc(p+(A*56|0)|0,C,a)|0;c[E>>2]=(c[E>>2]|0)+r}n=n+1|0}while((n|0)!=(D|0))}F=F+1|0;if((F|0)>=(c[l>>2]|0))break;else s=D+s|0}}s=l+832|0;F=_(c[s>>2]|0,c[e>>2]|0)|0;E=(c[o+(c[b+28>>2]<<2)>>2]|0)/2|0;if((c[m>>2]|0)>1){o=0;a=1;p=0;h=F;while(1){j=c[d+260+(a<<2)>>2]|0;G=c[e+(j<<2)>>2]|0;if((G&32767|0)==(G|0)){I=_(c[s>>2]|0,G)|0;G=c[l+836+(j<<2)>>2]|0;j=I-h|0;K=G-p|0;J=(j|0)/(K|0)|0;L=j>>31|1;O=_(J,K)|0;N=((j|0)>-1?j:0-j|0)-((O|0)>-1?O:0-O|0)|0;O=(E|0)>(G|0)?G:E;if((O|0)>(p|0))c[f+(p<<2)>>2]=h;j=p+1|0;if((j|0)<(O|0)){M=j;j=0;k=h;while(1){H=j+N|0;n=(H|0)<(K|0);k=k+J+(n?0:L)|0;c[f+(M<<2)>>2]=k;M=M+1|0;if((M|0)==(O|0)){P=G;Q=G;R=I;break}else j=H-(n?0:K)|0}}else{P=G;Q=G;R=I}}else{P=o;Q=p;R=h}a=a+1|0;if((a|0)>=(c[m>>2]|0)){S=P;T=R;break}else{o=P;p=Q;h=R}}}else{S=0;T=F}F=b+36|0;if((S|0)<((c[F>>2]|0)/2|0|0))U=S;else{q=1;i=g;return q|0}do{c[f+(U<<2)>>2]=T;U=U+1|0}while((U|0)<((c[F>>2]|0)/2|0|0));q=1;i=g;return q|0}function bc(a){a=a|0;if(a)yd(a);return}function cc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;if(!a)return;b=a+4|0;d=c[b>>2]|0;e=a+20|0;if((d|0)>0){f=d;d=0;while(1){g=c[(c[e>>2]|0)+(d<<2)>>2]|0;if(!g)h=f;else{yd(g);h=c[b>>2]|0}d=d+1|0;if((d|0)>=(h|0))break;else f=h}}yd(c[e>>2]|0);e=a+24|0;h=a+28|0;if((c[e>>2]|0)>0){f=0;do{yd(c[(c[h>>2]|0)+(f<<2)>>2]|0);f=f+1|0}while((f|0)<(c[e>>2]|0))}yd(c[h>>2]|0);yd(a);return}function dc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;lb(b,c[a>>2]|0,24);lb(b,c[a+4>>2]|0,24);lb(b,(c[a+8>>2]|0)+-1|0,24);d=a+12|0;lb(b,(c[d>>2]|0)+-1|0,6);lb(b,c[a+20>>2]|0,8);if((c[d>>2]|0)<=0)return;e=a+24|0;f=0;g=0;while(1){h=e+(g<<2)|0;i=c[h>>2]|0;if(i){j=i;k=0;while(1){j=j>>>1;if(!j){l=k;break}else k=k+1|0}if((l|0)>2){lb(b,i,3);lb(b,1,1);lb(b,c[h>>2]>>3,5)}else m=9}else m=9;if((m|0)==9){m=0;lb(b,i,4)}k=c[h>>2]|0;if(!k)n=0;else{j=k;k=0;while(1){o=(j&1)+k|0;j=j>>>1;if(!j){n=o;break}else k=o}}k=n+f|0;g=g+1|0;if((g|0)>=(c[d>>2]|0)){p=k;break}else f=k}if((p|0)<=0)return;f=a+280|0;a=0;do{lb(b,c[f+(a<<2)>>2]|0,8);a=a+1|0}while((a|0)!=(p|0));return}function ec(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;d=zd(1,2840)|0;e=c[a+28>>2]|0;c[d>>2]=qb(b,24)|0;c[d+4>>2]=qb(b,24)|0;c[d+8>>2]=(qb(b,24)|0)+1;a=qb(b,6)|0;f=d+12|0;c[f>>2]=a+1;g=qb(b,8)|0;h=d+20|0;c[h>>2]=g;a:do if((g|0)>=0){if((a|0)>-1){i=d+24|0;j=0;k=0;while(1){l=qb(b,3)|0;m=qb(b,1)|0;if((m|0)<0){n=26;break a}if(!m)o=l;else{m=qb(b,5)|0;if((m|0)<0){n=26;break a}o=m<<3|l}c[i+(k<<2)>>2]=o;if(!o)p=0;else{l=o;m=0;while(1){q=(l&1)+m|0;l=l>>>1;if(!l){p=q;break}else m=q}}m=p+j|0;k=k+1|0;if((k|0)>=(c[f>>2]|0)){r=m;break}else j=m}j=(r|0)>0;if(j){k=d+280|0;i=0;while(1){m=qb(b,8)|0;if((m|0)<0)break a;c[k+(i<<2)>>2]=m;i=i+1|0;if((i|0)>=(r|0)){s=j;t=r;break}}}else{s=0;t=r}}else{s=0;t=0}j=c[h>>2]|0;i=c[e+24>>2]|0;if((j|0)<(i|0)){if(s){k=d+280|0;m=0;do{l=c[k+(m<<2)>>2]|0;if((l|0)>=(i|0))break a;m=m+1|0;if(!(c[(c[e+1824+(l<<2)>>2]|0)+12>>2]|0))break a}while((m|0)<(t|0))}m=c[e+1824+(j<<2)>>2]|0;i=c[m+4>>2]|0;k=c[m>>2]|0;if((k|0)>=1){m=c[f>>2]|0;l=k;k=1;while(1){q=_(m,k)|0;if((q|0)>(i|0))break a;if((l|0)>1){l=l+-1|0;k=q}else{u=q;break}}c[d+16>>2]=u;v=d;return v|0}}}else n=26;while(0);if((n|0)==26?(d|0)==0:0){v=0;return v|0}yd(d);v=0;return v|0}function fc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;d=zd(1,44)|0;e=c[(c[a+4>>2]|0)+28>>2]|0;c[d>>2]=b;a=c[b+12>>2]|0;c[d+4>>2]=a;f=e+2848|0;e=c[f>>2]|0;c[d+12>>2]=e;g=e+((c[b+20>>2]|0)*56|0)|0;c[d+16>>2]=g;e=c[g>>2]|0;g=zd(a,4)|0;c[d+20>>2]=g;if((a|0)>0){h=b+24|0;i=b+280|0;b=0;j=0;k=0;while(1){l=c[h+(j<<2)>>2]|0;if(l){m=l;n=0;while(1){o=n+1|0;m=m>>>1;if(!m){p=o;q=n;break}else n=o}if(p){n=(p|0)>(k|0)?p:k;c[g+(j<<2)>>2]=zd(p,4)|0;if((q|0)>-1){m=g+(j<<2)|0;o=b;r=0;while(1){if(!(l&1<<r))s=o;else{c[(c[m>>2]|0)+(r<<2)>>2]=(c[f>>2]|0)+((c[i+(o<<2)>>2]|0)*56|0);s=o+1|0}r=r+1|0;if((r|0)>=(p|0)){t=s;u=n;break}else o=s}}else{t=b;u=n}}else{t=b;u=k}}else{t=b;u=k}j=j+1|0;if((j|0)>=(a|0)){v=u;break}else{b=t;k=u}}}else v=0;u=d+24|0;c[u>>2]=1;k=(e|0)>0;if(k){t=1;b=0;while(1){j=_(t,a)|0;b=b+1|0;if((b|0)==(e|0)){w=j;break}else t=j}c[u>>2]=w;x=w}else x=1;c[d+8>>2]=v;v=xd(x<<2)|0;w=d+28|0;c[w>>2]=v;if((x|0)<=0)return d|0;u=e<<2;if(!k){k=0;do{c[v+(k<<2)>>2]=xd(u)|0;k=k+1|0}while((k|0)<(x|0));return d|0}k=c[w>>2]|0;w=0;do{c[v+(w<<2)>>2]=xd(u)|0;t=c[k+(w<<2)>>2]|0;b=x;j=0;s=w;do{b=(b|0)/(a|0)|0;p=(s|0)/(b|0)|0;s=s-(_(p,b)|0)|0;c[t+(j<<2)>>2]=p;j=j+1|0}while((j|0)!=(e|0));w=w+1|0}while((w|0)<(x|0));return d|0}function gc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;if((f|0)>0){g=0;h=0}else return 0;while(1){if(!(c[e+(g<<2)>>2]|0))i=h;else{c[d+(h<<2)>>2]=c[d+(g<<2)>>2];i=h+1|0}g=g+1|0;if((g|0)==(f|0)){j=i;break}else h=i}if(!j)return 0;Pc(a,b,d,j,3);return 0}function hc(a,b,d,e,f,g,h,i){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0;if((g|0)>0){j=0;k=0}else return 0;while(1){if(!(c[f+(j<<2)>>2]|0))l=k;else{c[e+(k<<2)>>2]=c[e+(j<<2)>>2];l=k+1|0}j=j+1|0;if((j|0)==(g|0)){m=l;break}else k=l}if(!m)return 0;Qc(a,d,e,m,h);return 0}function ic(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0.0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;if((f|0)>0){g=0;h=0}else{i=0;return i|0}while(1){if(!(c[e+(g<<2)>>2]|0))j=h;else{c[d+(h<<2)>>2]=c[d+(g<<2)>>2];j=h+1|0}g=g+1|0;if((g|0)==(f|0)){k=j;break}else h=j}if(!k){i=0;return i|0}j=c[b>>2]|0;h=c[j+8>>2]|0;f=c[j+12>>2]|0;g=((c[j+4>>2]|0)-(c[j>>2]|0)|0)/(h|0)|0;e=Ab(a,k<<2)|0;l=100.0/+(h|0);m=(k|0)>0;if(m){n=g<<2;o=0;do{p=Ab(a,n)|0;c[e+(o<<2)>>2]=p;Fd(p|0,0,n|0)|0;o=o+1|0}while((o|0)!=(k|0))}if((g|0)>0){o=(h|0)>0;n=f+-1|0;a=(f|0)>1;f=0;do{p=_(f,h)|0;q=(c[j>>2]|0)+p|0;if(m){p=0;do{if(o){r=c[d+(p<<2)>>2]|0;s=0;t=0;u=0;while(1){v=c[r+(q+t<<2)>>2]|0;w=(v|0)>-1?v:0-v|0;v=(w|0)>(u|0)?w:u;x=w+s|0;t=t+1|0;if((t|0)==(h|0)){y=x;z=v;break}else{s=x;u=v}}}else{y=0;z=0}u=~~(+(y|0)*l);a:do if(a){s=0;while(1){if((z|0)<=(c[j+2328+(s<<2)>>2]|0)?(t=c[j+2584+(s<<2)>>2]|0,(t|0)<0|(u|0)<(t|0)):0){A=s;break a}t=s+1|0;if((t|0)<(n|0))s=t;else{A=t;break}}}else A=0;while(0);c[(c[e+(p<<2)>>2]|0)+(f<<2)>>2]=A;p=p+1|0}while((p|0)!=(k|0))}f=f+1|0}while((f|0)!=(g|0))}g=b+40|0;c[g>>2]=(c[g>>2]|0)+1;i=e;return i|0}function jc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0;if((f|0)>0){g=0;h=0}else return 0;while(1){if(!(c[e+(g<<2)>>2]|0))i=h;else{c[d+(h<<2)>>2]=c[d+(g<<2)>>2];i=h+1|0}g=g+1|0;if((g|0)==(f|0)){j=i;break}else h=i}if(!j)return 0;Pc(a,b,d,j,4);return 0}function kc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;if((f|0)>0){g=0;h=0}else{i=0;return i|0}while(1){j=((c[e+(g<<2)>>2]|0)!=0&1)+h|0;g=g+1|0;if((g|0)==(f|0)){k=j;break}else h=j}if(!k){i=0;return i|0}k=c[b>>2]|0;h=c[k+8>>2]|0;g=c[k+12>>2]|0;e=((c[k+4>>2]|0)-(c[k>>2]|0)|0)/(h|0)|0;j=Ab(a,4)|0;l=e<<2;m=Ab(a,l)|0;c[j>>2]=m;Fd(m|0,0,l|0)|0;if((e|0)>0){l=(h|0)>0;m=g+-1|0;a=(g|0)>1;g=c[j>>2]|0;n=(f|0)>1;o=0;p=(c[k>>2]|0)/(f|0)|0;while(1){if(l){q=c[d>>2]|0;r=0;s=0;t=p;u=0;while(1){v=c[q+(t<<2)>>2]|0;w=(v|0)>-1?v:0-v|0;v=(w|0)>(u|0)?w:u;if(n){w=r;x=1;while(1){y=c[(c[d+(x<<2)>>2]|0)+(t<<2)>>2]|0;z=(y|0)>-1?y:0-y|0;y=(z|0)>(w|0)?z:w;x=x+1|0;if((x|0)==(f|0)){A=y;break}else w=y}}else A=r;w=t+1|0;s=s+f|0;if((s|0)>=(h|0)){B=A;C=w;D=v;break}else{r=A;t=w;u=v}}}else{B=0;C=p;D=0}a:do if(a){u=0;while(1){if((D|0)<=(c[k+2328+(u<<2)>>2]|0)?(B|0)<=(c[k+2584+(u<<2)>>2]|0):0){E=u;break a}t=u+1|0;if((t|0)<(m|0))u=t;else{E=t;break}}}else E=0;while(0);c[g+(o<<2)>>2]=E;o=o+1|0;if((o|0)==(e|0))break;else p=C}}C=b+40|0;c[C>>2]=(c[C>>2]|0)+1;i=j;return i|0}function lc(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;j=i;i=i+16|0;k=j;l=c[b+36>>2]|0;m=(l|0)/2|0;n=Ab(b,_(g<<2,m)|0)|0;c[k>>2]=n;if((g|0)<=0){i=j;return 0}b=(l|0)>1;l=0;o=0;while(1){p=c[e+(l<<2)>>2]|0;q=((c[f+(l<<2)>>2]|0)!=0&1)+o|0;if(b){r=0;s=l;while(1){c[n+(s<<2)>>2]=c[p+(r<<2)>>2];r=r+1|0;if((r|0)>=(m|0))break;else s=s+g|0}}l=l+1|0;if((l|0)==(g|0)){t=q;break}else o=q}if(!t){i=j;return 0}Qc(a,d,k,1,h);i=j;return 0}function mc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;g=c[b>>2]|0;h=c[g+8>>2]|0;i=b+16|0;j=c[c[i>>2]>>2]|0;k=(_(c[a+36>>2]|0,f)|0)>>1;l=c[g+4>>2]|0;m=((l|0)<(k|0)?l:k)-(c[g>>2]|0)|0;if((m|0)<=0)return 0;k=(m|0)/(h|0)|0;m=Ab(a,((j+-1+k|0)/(j|0)|0)<<2)|0;a:do if((f|0)>0){l=0;while(1){if(c[e+(l<<2)>>2]|0){n=l;break a}o=l+1|0;if((o|0)<(f|0))l=o;else{n=o;break}}}else n=0;while(0);if((n|0)==(f|0))return 0;n=b+8|0;e=c[n>>2]|0;if((e|0)<=0)return 0;l=(k|0)>0;o=a+4|0;a=g+16|0;p=b+28|0;q=(j|0)>0;r=b+20|0;b=e;e=0;b:while(1){if(l){s=(e|0)==0;t=1<<e;u=0;v=0;while(1){if(s){w=pc(c[i>>2]|0,o)|0;if((w|0)==-1){x=23;break b}if((w|0)>=(c[a>>2]|0)){x=23;break b}y=c[(c[p>>2]|0)+(w<<2)>>2]|0;c[m+(v<<2)>>2]=y;if(!y){x=23;break b}}if(q&(u|0)<(k|0)){y=m+(v<<2)|0;w=u;z=0;while(1){A=c[(c[y>>2]|0)+(z<<2)>>2]|0;if(((c[g+24+(A<<2)>>2]&t|0)!=0?(B=c[(c[(c[r>>2]|0)+(A<<2)>>2]|0)+(e<<2)>>2]|0,(B|0)!=0):0)?(A=_(w,h)|0,(tc(B,d,(c[g>>2]|0)+A|0,f,o,h)|0)==-1):0){x=23;break b}z=z+1|0;A=w+1|0;if(!((z|0)<(j|0)&(A|0)<(k|0))){C=A;break}else w=A}}else C=u;if((C|0)<(k|0)){u=C;v=v+1|0}else break}D=c[n>>2]|0}else D=b;e=e+1|0;if((e|0)>=(D|0)){x=23;break}else b=D}if((x|0)==23)return 0;return 0}function nc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;b=zd(1,40)|0;c[b+36>>2]=1;a:do if(((qb(a,24)|0)==5653314?(c[b>>2]=qb(a,16)|0,d=qb(a,24)|0,e=b+4|0,c[e>>2]=d,(d|0)!=-1):0)?(d=uc(c[b>>2]|0)|0,((uc(c[e>>2]|0)|0)+d|0)<=24):0){d=qb(a,1)|0;b:do if(!d){f=qb(a,1)|0;g=(f|0)!=0;f=(_(g?1:5,c[e>>2]|0)|0)+7>>3;h=c[a+16>>2]|0;if((f|0)>(h-(rb(a)|0)|0))break a;h=c[e>>2]|0;f=b+8|0;c[f>>2]=xd(h<<2)|0;i=(h|0)>0;if(!g){if(i)j=0;else break;while(1){g=qb(a,5)|0;if((g|0)==-1)break a;c[(c[f>>2]|0)+(j<<2)>>2]=g+1;j=j+1|0;if((j|0)>=(c[e>>2]|0))break b}}if(i){g=0;do{if(!(qb(a,1)|0))c[(c[f>>2]|0)+(g<<2)>>2]=0;else{h=qb(a,5)|0;if((h|0)==-1)break a;c[(c[f>>2]|0)+(g<<2)>>2]=h+1}g=g+1|0}while((g|0)<(c[e>>2]|0))}}else if((d|0)==1){g=(qb(a,5)|0)+1|0;if(!g)break a;f=c[e>>2]|0;i=b+8|0;c[i>>2]=xd(f<<2)|0;if((f|0)>0){h=f;f=0;k=g;while(1){g=qb(a,uc(h-f|0)|0)|0;if((k|0)>32|(g|0)==-1)break a;l=c[e>>2]|0;if((g|0)>(l-f|0))break a;if((g|0)>0){if((g+-1>>k+-1|0)>1)break a;m=c[i>>2]|0;n=f;o=0;while(1){c[m+(n<<2)>>2]=k;o=o+1|0;if((o|0)==(g|0))break;else n=n+1|0}p=c[e>>2]|0;q=g+f|0}else{p=l;q=f}if((p|0)>(q|0)){h=p;f=q;k=k+1|0}else break}}}else break a;while(0);d=qb(a,4)|0;k=b+12|0;c[k>>2]=d;if(!d){r=b;return r|0}else if(!((d|0)==2|(d|0)==1))break;c[b+16>>2]=qb(a,32)|0;c[b+20>>2]=qb(a,32)|0;d=b+24|0;c[d>>2]=(qb(a,4)|0)+1;f=qb(a,1)|0;c[b+28>>2]=f;if((f|0)!=-1){f=c[k>>2]|0;if((f|0)==1)if(!(c[b>>2]|0))s=0;else s=wc(b)|0;else if((f|0)==2)s=_(c[b>>2]|0,c[e>>2]|0)|0;else s=0;f=(_(c[d>>2]|0,s)|0)+7>>3;k=c[a+16>>2]|0;if((f|0)<=(k-(rb(a)|0)|0)){k=xd(s<<2)|0;f=b+32|0;c[f>>2]=k;if((s|0)>0){h=0;do{i=qb(a,c[d>>2]|0)|0;n=c[f>>2]|0;c[n+(h<<2)>>2]=i;h=h+1|0}while((h|0)!=(s|0));t=n}else t=k;if(!s){r=b;return r|0}if((c[t+(s+-1<<2)>>2]|0)!=-1){r=b;return r|0}}}}while(0);yc(b);r=0;return r|0}function oc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0;if((b|0)<0){e=0;return e|0}f=a+12|0;g=c[f>>2]|0;if((c[g+4>>2]|0)<=(b|0)){e=0;return e|0}lb(d,c[(c[a+20>>2]|0)+(b<<2)>>2]|0,c[(c[g+8>>2]|0)+(b<<2)>>2]|0);e=c[(c[(c[f>>2]|0)+8>>2]|0)+(b<<2)>>2]|0;return e|0}function pc(a,b){a=a|0;b=b|0;var d=0,e=0;if((c[a+8>>2]|0)<=0){d=-1;return d|0}e=Rc(a,b)|0;if((e|0)<=-1){d=-1;return d|0}d=c[(c[a+24>>2]|0)+(e<<2)>>2]|0;return d|0}function qc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;f=i;if((c[a+8>>2]|0)<=0){h=0;i=f;return h|0}j=c[a>>2]|0;k=(e|0)/(j|0)|0;e=i;i=i+((1*(k<<2)|0)+15&-16)|0;l=(k|0)>0;a:do if(l){m=a+16|0;n=0;while(1){o=Rc(a,d)|0;if((o|0)==-1){h=-1;break}p=c[a>>2]|0;c[e+(n<<2)>>2]=(c[m>>2]|0)+((_(p,o)|0)<<2);n=n+1|0;if((n|0)>=(k|0)){q=p;break a}}i=f;return h|0}else q=j;while(0);if((q|0)<1|l^1){h=0;i=f;return h|0}else{r=0;s=0}while(1){l=0;do{j=b+(l+s<<2)|0;g[j>>2]=+g[j>>2]+ +g[(c[e+(l<<2)>>2]|0)+(r<<2)>>2];l=l+1|0}while((l|0)!=(k|0));r=r+1|0;if((r|0)>=(q|0)){h=0;break}else s=s+k|0}i=f;return h|0}function rc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0;if((c[a+8>>2]|0)<=0){f=0;return f|0}if((c[a>>2]|0)>8){if((e|0)<=0){f=0;return f|0}h=a+16|0;i=0;while(1){j=Rc(a,d)|0;if((j|0)==-1){f=-1;k=29;break}l=c[h>>2]|0;m=c[a>>2]|0;n=_(m,j)|0;if((m|0)>0){j=(m|0)>1?m:1;o=i;p=0;while(1){q=b+(o<<2)|0;g[q>>2]=+g[q>>2]+ +g[l+(p+n<<2)>>2];p=p+1|0;if((p|0)>=(m|0))break;else o=o+1|0}r=i+j|0}else r=i;if((r|0)<(e|0))i=r;else{f=0;k=29;break}}if((k|0)==29)return f|0}r=a+16|0;if((e|0)>0)s=0;else{f=0;return f|0}a:while(1){b:while(1){i=Rc(a,d)|0;if((i|0)==-1){f=-1;k=29;break a}h=c[r>>2]|0;switch(c[a>>2]|0){case 6:{t=i;u=h;k=15;break b;break}case 5:{v=i;w=h;k=17;break b;break}case 4:{x=i;y=h;k=19;break b;break}case 1:{z=i;A=h;B=s;C=0;break b;break}case 7:{D=i;E=h;k=13;break b;break}case 2:{F=i;G=h;k=23;break b;break}case 8:{H=h;I=i;k=12;break b;break}case 3:{J=i;K=h;k=21;break b;break}default:{}}}if((k|0)==12){k=0;j=I<<3;h=b+(s<<2)|0;g[h>>2]=+g[h>>2]+ +g[H+(j<<2)>>2];L=j;M=H;N=s+1|0;O=1;k=14}else if((k|0)==13){k=0;L=D*7|0;M=E;N=s;O=0;k=14}else if((k|0)==15){k=0;P=t*6|0;Q=u;R=s;S=0;k=16}else if((k|0)==17){k=0;T=v*5|0;U=w;V=s;W=0;k=18}else if((k|0)==19){k=0;X=x<<2;Y=y;Z=s;$=0;k=20}else if((k|0)==21){k=0;aa=J*3|0;ba=K;ca=s;da=0;k=22}else if((k|0)==23){k=0;ea=F<<1;fa=G;ga=s;ha=0;k=24}if((k|0)==14){k=0;j=b+(N<<2)|0;g[j>>2]=+g[j>>2]+ +g[M+(O+L<<2)>>2];P=L;Q=M;R=N+1|0;S=O+1|0;k=16}if((k|0)==16){k=0;j=b+(R<<2)|0;g[j>>2]=+g[j>>2]+ +g[Q+(S+P<<2)>>2];T=P;U=Q;V=R+1|0;W=S+1|0;k=18}if((k|0)==18){k=0;j=b+(V<<2)|0;g[j>>2]=+g[j>>2]+ +g[U+(W+T<<2)>>2];X=T;Y=U;Z=V+1|0;$=W+1|0;k=20}if((k|0)==20){k=0;j=b+(Z<<2)|0;g[j>>2]=+g[j>>2]+ +g[Y+($+X<<2)>>2];aa=X;ba=Y;ca=Z+1|0;da=$+1|0;k=22}if((k|0)==22){k=0;j=b+(ca<<2)|0;g[j>>2]=+g[j>>2]+ +g[ba+(da+aa<<2)>>2];ea=aa;fa=ba;ga=ca+1|0;ha=da+1|0;k=24}if((k|0)==24){k=0;j=b+(ga<<2)|0;g[j>>2]=+g[j>>2]+ +g[fa+(ha+ea<<2)>>2];z=ea;A=fa;B=ga+1|0;C=ha+1|0}s=B+1|0;j=b+(B<<2)|0;g[j>>2]=+g[j>>2]+ +g[A+(C+z<<2)>>2];if((s|0)>=(e|0)){f=0;k=29;break}}if((k|0)==29)return f|0;return 0}function sc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=(e|0)>0;if((c[a+8>>2]|0)<=0){if(!f){g=0;return g|0}Fd(b|0,0,e<<2|0)|0;g=0;return g|0}if(!f){g=0;return g|0}f=a+16|0;h=0;while(1){i=Rc(a,d)|0;if((i|0)==-1){g=-1;j=11;break}k=c[f>>2]|0;l=c[a>>2]|0;m=_(l,i)|0;a:do if((h|0)<(e|0)){i=h;n=0;while(1){if((n|0)>=(l|0)){o=i;break a}p=i+1|0;c[b+(i<<2)>>2]=c[k+(n+m<<2)>>2];if((p|0)<(e|0)){i=p;n=n+1|0}else{o=p;break}}}else o=h;while(0);if((o|0)<(e|0))h=o;else{g=0;j=11;break}}if((j|0)==11)return g|0;return 0}function tc(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;if((c[a+8>>2]|0)<=0){i=0;return i|0}j=(d|0)/(e|0)|0;k=(h+d|0)/(e|0)|0;if((j|0)>=(k|0)){i=0;return i|0}d=a+16|0;h=0;l=j;while(1){j=Rc(a,f)|0;if((j|0)==-1){i=-1;m=8;break}n=c[d>>2]|0;o=c[a>>2]|0;p=_(o,j)|0;if((o|0)>0){j=h;q=l;r=0;while(1){s=j+1|0;t=(c[b+(j<<2)>>2]|0)+(q<<2)|0;g[t>>2]=+g[t>>2]+ +g[n+(r+p<<2)>>2];t=(s|0)==(e|0);u=(t&1)+q|0;v=t?0:s;r=r+1|0;if((r|0)>=(o|0)){w=v;x=u;break}else{j=v;q=u}}}else{w=h;x=l}if((x|0)<(k|0)){h=w;l=x}else{i=0;m=8;break}}if((m|0)==8)return i|0;return 0}function uc(a){a=a|0;var b=0,c=0,d=0;if(!a)b=0;else{c=a;a=0;while(1){d=a+1|0;c=c>>>1;if(!c){b=d;break}else a=d}}return b|0}function vc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;e=i;i=i+144|0;f=e;g=(d|0)!=0;h=xd((g?d:b)<<2)|0;Fd(f|0,0,132)|0;j=(b|0)>0;a:do if(j){k=f+4|0;l=(d|0)==0&1;m=0;n=0;b:while(1){o=c[a+(n<<2)>>2]|0;c:do if((o|0)>0){p=c[f+(o<<2)>>2]|0;if(!((o|0)>31|(p>>>o|0)==0))break b;c[h+(m<<2)>>2]=p;q=f+(o<<2)|0;d:do if(!(p&1)){r=p;s=q;t=o;while(1){c[s>>2]=r+1;u=t+-1|0;if((t|0)<=1)break d;r=c[f+(u<<2)>>2]|0;v=f+(u<<2)|0;if(r&1){w=v;x=u;y=8;break}else{s=v;t=u}}}else{w=q;x=o;y=8}while(0);do if((y|0)==8){y=0;if((x|0)==1){c[k>>2]=(c[k>>2]|0)+1;break}else{c[w>>2]=c[f+(x+-1<<2)>>2]<<1;break}}while(0);q=o+1|0;if((q|0)<33){t=p;s=o;r=q;while(1){q=f+(r<<2)|0;u=t;t=c[q>>2]|0;if((t>>>1|0)!=(u|0)){z=1;break c}c[q>>2]=c[f+(s<<2)>>2]<<1;q=r+1|0;if((q|0)>=33){z=1;break}else{u=r;r=q;s=u}}}else z=1}else z=l;while(0);n=n+1|0;if((n|0)>=(b|0))break a;else m=m+z|0}yd(h);A=0;i=e;return A|0}while(0);e:do if((d|0)!=1){z=1;while(1){if(c[f+(z<<2)>>2]&-1>>>(32-z|0))break;z=z+1|0;if((z|0)>=33)break e}yd(h);A=0;i=e;return A|0}while(0);if(!j){A=h;i=e;return A|0}if(g){B=0;C=0}else{g=0;j=0;while(1){f=c[a+(j<<2)>>2]|0;if((f|0)>0){d=c[h+(g<<2)>>2]|0;z=0;x=0;while(1){w=d>>>z&1|x<<1;z=z+1|0;if((z|0)>=(f|0)){D=w;break}else x=w}}else D=0;c[h+(g<<2)>>2]=D;j=j+1|0;if((j|0)==(b|0)){A=h;break}else g=g+1|0}i=e;return A|0}while(1){g=c[a+(C<<2)>>2]|0;if((g|0)>0){j=c[h+(B<<2)>>2]|0;D=0;x=0;while(1){f=j>>>D&1|x<<1;D=D+1|0;if((D|0)>=(g|0)){E=f;break}else x=f}}else E=0;if(!g)F=B;else{c[h+(B<<2)>>2]=E;F=B+1|0}C=C+1|0;if((C|0)==(b|0)){A=h;break}else B=F}i=e;return A|0}function wc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;b=c[a+4>>2]|0;d=c[a>>2]|0;if((d|0)<=0)while(1){}a=~~+M(+(+P(+(+(b|0)),+(1.0/+(d|0)))));while(1){e=a+1|0;f=1;g=1;h=0;while(1){i=_(f,a)|0;j=_(g,e)|0;h=h+1|0;if((h|0)>=(d|0)){k=i;l=j;break}else{f=i;g=j}}if((k|0)<=(b|0)&(l|0)>(b|0)){m=a;break}a=a+((k|0)>(b|0)?-1:1)|0}return m|0}function xc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,i=0.0,j=0.0,k=0.0,l=0,m=0,n=0,o=0,p=0.0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0.0,C=0.0,D=0,E=0,F=0,G=0,H=0;e=c[a+12>>2]|0;if((e+-1|0)>>>0>=2){f=0;return f|0}h=c[a+16>>2]|0;i=+(h&2097151|0);j=+qd((h|0)<0?-i:i,(h>>>21&1023)+-788|0);h=c[a+20>>2]|0;i=+(h&2097151|0);k=+qd((h|0)<0?-i:i,(h>>>21&1023)+-788|0);h=c[a>>2]|0;l=zd(_(h,b)|0,4)|0;if((e|0)==2){b=c[a+4>>2]|0;if((b|0)<=0){f=l;return f|0}m=(d|0)!=0;n=a+8|0;o=a+32|0;i=k;p=j;q=a+28|0;r=(h|0)>0;s=0;t=0;while(1){if(m?(c[(c[n>>2]|0)+(t<<2)>>2]|0)==0:0)u=s;else{if(r){v=c[o>>2]|0;w=(c[q>>2]|0)==0;x=d+(s<<2)|0;y=_(h,t)|0;z=_(h,s)|0;A=0;B=0.0;while(1){C=B+p+ +N(+(+(c[v+(y+A<<2)>>2]|0)))*i;if(m)g[l+((_(c[x>>2]|0,h)|0)+A<<2)>>2]=C;else g[l+(z+A<<2)>>2]=C;A=A+1|0;if((A|0)>=(h|0))break;else B=w?B:C}}u=s+1|0}t=t+1|0;if((t|0)>=(b|0)){f=l;break}else s=u}return f|0}else if((e|0)==1){e=c[a+4>>2]|0;if((h|0)<=0)while(1){}u=~~+M(+(+P(+(+(e|0)),+(1.0/+(h|0)))));while(1){s=u+1|0;b=1;t=1;m=0;while(1){q=_(b,u)|0;o=_(t,s)|0;m=m+1|0;if((m|0)==(h|0)){D=q;E=o;break}else{b=q;t=o}}if((E|0)>(e|0)&(D|0)<=(e|0)){F=u;break}u=((D|0)>(e|0)?-1:1)+u|0}if((e|0)<=0){f=l;return f|0}u=(d|0)==0;D=a+8|0;E=a+32|0;i=k;k=j;t=a+28|0;a=0;b=0;while(1){if(u){m=c[E>>2]|0;s=_(h,a)|0;if(!(c[t>>2]|0)){o=1;q=0;do{g[l+(s+q<<2)>>2]=k+ +N(+(+(c[m+((((b|0)/(o|0)|0|0)%(F|0)|0)<<2)>>2]|0)))*i;o=_(o,F)|0;q=q+1|0}while((q|0)<(h|0));G=21}else{q=1;o=0;j=0.0;do{j=j+k+ +N(+(+(c[m+((((b|0)/(q|0)|0|0)%(F|0)|0)<<2)>>2]|0)))*i;g[l+(s+o<<2)>>2]=j;q=_(q,F)|0;o=o+1|0}while((o|0)<(h|0));G=21}}else if(!(c[(c[D>>2]|0)+(b<<2)>>2]|0))H=a;else{o=c[E>>2]|0;q=(c[t>>2]|0)==0;s=_(c[d+(a<<2)>>2]|0,h)|0;m=1;r=0;j=0.0;while(1){p=j+k+ +N(+(+(c[o+((((b|0)/(m|0)|0|0)%(F|0)|0)<<2)>>2]|0)))*i;g[l+(s+r<<2)>>2]=p;m=_(m,F)|0;r=r+1|0;if((r|0)>=(h|0)){G=21;break}else j=q?j:p}}if((G|0)==21){G=0;H=a+1|0}b=b+1|0;if((b|0)>=(e|0)){f=l;break}else a=H}return f|0}else{f=l;return f|0}return 0}function yc(a){a=a|0;var b=0;if(!(c[a+36>>2]|0))return;b=c[a+32>>2]|0;if(b)yd(b);b=c[a+8>>2]|0;if(b)yd(b);yd(a);return}function zc(a){a=a|0;var b=0;b=c[a+16>>2]|0;if(b)yd(b);b=c[a+20>>2]|0;if(b)yd(b);b=c[a+24>>2]|0;if(b)yd(b);b=c[a+28>>2]|0;if(b)yd(b);b=c[a+32>>2]|0;if(b)yd(b);b=a;a=b+56|0;do{c[b>>2]=0;b=b+4|0}while((b|0)<(a|0));return}function Ac(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0.0;d=a;e=d+56|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(e|0));c[a+12>>2]=b;d=b+4|0;e=c[d>>2]|0;c[a+4>>2]=e;c[a+8>>2]=e;c[a>>2]=c[b>>2];c[a+20>>2]=vc(c[b+8>>2]|0,e,0)|0;e=c[d>>2]|0;d=c[b>>2]|0;if((d|0)<=0)while(1){}f=~~+M(+(+P(+(+(e|0)),+(1.0/+(d|0)))));while(1){g=f+1|0;h=1;i=1;j=0;while(1){k=_(h,f)|0;l=_(i,g)|0;j=j+1|0;if((j|0)==(d|0)){m=k;n=l;break}else{h=k;i=l}}if((n|0)>(e|0)&(m|0)<=(e|0)){o=f;break}f=((m|0)>(e|0)?-1:1)+f|0}c[a+44>>2]=o;o=c[b+16>>2]|0;p=+(o&2097151|0);c[a+48>>2]=~~+ud(+qd((o|0)<0?-p:p,(o>>>21&1023)+-788|0));o=c[b+20>>2]|0;p=+(o&2097151|0);c[a+52>>2]=~~+ud(+qd((o|0)<0?-p:p,(o>>>21&1023)+-788|0));return 0}function Bc(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;e=i;f=b;g=f+56|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));h=d+4|0;j=c[h>>2]|0;if((j|0)>0){k=c[d+8>>2]|0;l=0;m=0;while(1){n=((c[k+(l<<2)>>2]|0)>0&1)+m|0;l=l+1|0;if((l|0)>=(j|0)){o=n;break}else m=n}}else o=0;c[b+4>>2]=j;m=b+8|0;c[m>>2]=o;c[b>>2]=c[d>>2];if((o|0)<=0){p=0;i=e;return p|0}l=d+8|0;k=vc(c[l>>2]|0,j,o)|0;j=o<<2;n=i;i=i+((1*j|0)+15&-16)|0;if(!k){q=c[b+16>>2]|0;if(q)yd(q);q=c[b+20>>2]|0;if(q)yd(q);q=c[b+24>>2]|0;if(q)yd(q);q=c[b+28>>2]|0;if(q)yd(q);q=c[b+32>>2]|0;if(q)yd(q);f=b;g=f+56|0;do{c[f>>2]=0;f=f+4|0}while((f|0)<(g|0));p=-1;i=e;return p|0}else r=0;do{f=k+(r<<2)|0;g=c[f>>2]|0;q=g>>>16|g<<16;g=q>>>8&16711935|q<<8&-16711936;q=g>>>4&252645135|g<<4&-252645136;g=q>>>2&858993459|q<<2&-858993460;c[f>>2]=g>>>1&1431655765|g<<1&-1431655766;c[n+(r<<2)>>2]=f;r=r+1|0}while((r|0)!=(o|0));rd(n,o,4,11);r=i;i=i+((1*j|0)+15&-16)|0;f=xd(j)|0;g=b+20|0;c[g>>2]=f;q=k;s=0;do{c[r+((c[n+(s<<2)>>2]|0)-q>>2<<2)>>2]=s;s=s+1|0}while((s|0)!=(o|0));t=0;do{c[f+(c[r+(t<<2)>>2]<<2)>>2]=c[k+(t<<2)>>2];t=t+1|0}while((t|0)!=(o|0));yd(k);c[b+16>>2]=xc(d,o,r)|0;o=xd(j)|0;c[b+24>>2]=o;j=c[h>>2]|0;d=(j|0)>0;if(d){k=c[l>>2]|0;t=0;f=0;while(1){if((c[k+(t<<2)>>2]|0)>0){c[o+(c[r+(f<<2)>>2]<<2)>>2]=t;u=f+1|0}else u=f;t=t+1|0;if((t|0)>=(j|0)){v=u;break}else f=u}u=b+28|0;c[u>>2]=xd(v)|0;if(d){d=j;j=0;v=0;while(1){f=c[(c[l>>2]|0)+(j<<2)>>2]|0;if((f|0)>0){a[(c[u>>2]|0)+(c[r+(v<<2)>>2]|0)>>0]=f;w=c[h>>2]|0;x=v+1|0}else{w=d;x=v}j=j+1|0;if((j|0)>=(w|0)){y=u;z=x;break}else{d=w;v=x}}}else{y=u;z=0}}else{u=b+28|0;c[u>>2]=xd(0)|0;y=u;z=0}u=c[m>>2]|0;if(!u)A=-4;else{m=u;u=0;while(1){m=m>>>1;if(!m){B=u;break}else u=u+1|0}A=B+-3|0}B=b+36|0;u=(A|0)<5?5:A;A=(u|0)>8?8:u;c[B>>2]=A;u=1<<A;m=zd(u,4)|0;c[b+32>>2]=m;x=b+40|0;c[x>>2]=0;a:do if((z|0)>0){b=c[y>>2]|0;v=0;w=A;d=0;while(1){j=b+d|0;h=a[j>>0]|0;r=h<<24>>24;if((v|0)<(r|0)){c[x>>2]=r;C=a[j>>0]|0}else C=h;h=C<<24>>24;if((w|0)>=(h|0)?(r=c[(c[g>>2]|0)+(d<<2)>>2]|0,l=r>>>16|r<<16,r=l>>>8&16711935|l<<8&-16711936,l=r>>>4&252645135|r<<4&-252645136,r=l>>>2&858993459|l<<2&-858993460,l=r>>>1&1431655765|r<<1&-1431655766,(w-h|0)!=31):0){r=d+1|0;f=h;h=0;do{c[m+((l|h<<f)<<2)>>2]=r;h=h+1|0;t=c[B>>2]|0;f=a[j>>0]|0}while((h|0)<(1<<t-f|0));D=t}else D=w;f=d+1|0;if((f|0)==(z|0)){E=D;break a}v=c[x>>2]|0;w=D;d=f}}else E=A;while(0);D=-2<<31-E;if((A|0)==31){p=0;i=e;return p|0}else{F=E;G=0;H=0;I=0}while(1){E=H<<32-F;A=E>>>16|E<<16;x=A>>>8&16711935|A<<8&-16711936;A=x>>>4&252645135|x<<4&-252645136;x=A>>>2&858993459|A<<2&-858993460;A=m+((x>>>1&1431655765|x<<1&-1431655766)<<2)|0;if(!(c[A>>2]|0)){x=I;while(1){C=x+1|0;if((C|0)>=(z|0)){J=x;break}if((c[(c[g>>2]|0)+(C<<2)>>2]|0)>>>0>E>>>0){J=x;break}else x=C}b:do if((z|0)>(G|0)){x=c[g>>2]|0;C=G;while(1){if(E>>>0<(c[x+(C<<2)>>2]&D)>>>0){K=C;break b}y=C+1|0;if((z|0)>(y|0))C=y;else{K=y;break}}}else K=G;while(0);E=z-K|0;c[A>>2]=(J>>>0>32767?-1073774592:J<<15|-2147483648)|(E>>>0>32767?32767:E);L=K;M=J}else{L=G;M=I}E=H+1|0;if((E|0)>=(u|0)){p=0;break}F=c[B>>2]|0;G=L;H=E;I=M}i=e;return p|0}function Cc(a){a=a|0;var b=0;b=a;a=b+48|0;do{c[b>>2]=0;b=b+4|0}while((b|0)<(a|0));return}function Dc(a){a=a|0;return (c[(c[(c[a+64>>2]|0)+104>>2]|0)+80>>2]|0)!=0|0}function Ec(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,h=0,i=0,j=0.0,k=0,l=0.0,m=0.0,n=0,o=0.0,p=0,q=0.0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0.0,I=0.0,J=0.0,K=0,L=0.0,M=0.0,N=0,O=0,P=0,Q=0,R=0.0,S=0.0,T=0,U=0,V=0,W=0.0,X=0.0,Y=0.0,Z=0.0,$=0.0,aa=0.0,ba=0.0,ca=0.0,da=0.0;e=a+-6|0;if((a|0)>6){a=b;f=c+(d+-8<<2)|0;h=c+((d>>1)+-8<<2)|0;while(1){i=f+24|0;j=+g[i>>2];k=h+24|0;l=+g[k>>2];m=j-l;n=f+28|0;o=+g[n>>2];p=h+28|0;q=o-+g[p>>2];g[i>>2]=l+j;g[n>>2]=+g[p>>2]+o;n=a+4|0;g[k>>2]=+g[a>>2]*m+ +g[n>>2]*q;g[p>>2]=+g[a>>2]*q-+g[n>>2]*m;n=f+16|0;m=+g[n>>2];p=h+16|0;q=+g[p>>2];o=m-q;k=f+20|0;j=+g[k>>2];i=h+20|0;l=j-+g[i>>2];g[n>>2]=q+m;g[k>>2]=+g[i>>2]+j;k=a+20|0;n=a+16|0;g[p>>2]=+g[n>>2]*o+ +g[k>>2]*l;g[i>>2]=+g[n>>2]*l-+g[k>>2]*o;k=f+8|0;o=+g[k>>2];n=h+8|0;l=+g[n>>2];j=o-l;i=f+12|0;m=+g[i>>2];p=h+12|0;q=m-+g[p>>2];g[k>>2]=l+o;g[i>>2]=+g[p>>2]+m;i=a+36|0;k=a+32|0;g[n>>2]=+g[k>>2]*j+ +g[i>>2]*q;g[p>>2]=+g[k>>2]*q-+g[i>>2]*j;j=+g[f>>2];q=+g[h>>2];m=j-q;i=f+4|0;o=+g[i>>2];k=h+4|0;l=o-+g[k>>2];g[f>>2]=q+j;g[i>>2]=+g[k>>2]+o;i=a+52|0;p=a+48|0;g[h>>2]=+g[p>>2]*m+ +g[i>>2]*l;g[k>>2]=+g[p>>2]*l-+g[i>>2]*m;h=h+-32|0;if(h>>>0<c>>>0)break;else{a=a+64|0;f=f+-32|0}}}if((e|0)>1){f=1;do{a=1<<f;if((f|0)!=31){h=d>>f;i=4<<f;p=h+-8|0;k=(h>>1)+-8|0;n=i+1|0;r=i<<1;s=r|1;t=i*3|0;u=t+1|0;v=i<<2;w=0;do{x=_(w,h)|0;y=c+(x<<2)|0;z=b;A=c+(p+x<<2)|0;B=c+(k+x<<2)|0;while(1){x=A+24|0;m=+g[x>>2];C=B+24|0;l=+g[C>>2];o=m-l;D=A+28|0;j=+g[D>>2];E=B+28|0;q=j-+g[E>>2];g[x>>2]=l+m;g[D>>2]=+g[E>>2]+j;D=z+4|0;g[C>>2]=+g[z>>2]*o+ +g[D>>2]*q;g[E>>2]=+g[z>>2]*q-+g[D>>2]*o;D=z+(i<<2)|0;E=A+16|0;o=+g[E>>2];C=B+16|0;q=+g[C>>2];j=o-q;x=A+20|0;m=+g[x>>2];F=B+20|0;l=m-+g[F>>2];g[E>>2]=q+o;g[x>>2]=+g[F>>2]+m;x=z+(n<<2)|0;g[C>>2]=+g[D>>2]*j+ +g[x>>2]*l;g[F>>2]=+g[D>>2]*l-+g[x>>2]*j;x=z+(r<<2)|0;D=A+8|0;j=+g[D>>2];F=B+8|0;l=+g[F>>2];m=j-l;C=A+12|0;o=+g[C>>2];E=B+12|0;q=o-+g[E>>2];g[D>>2]=l+j;g[C>>2]=+g[E>>2]+o;C=z+(s<<2)|0;g[F>>2]=+g[x>>2]*m+ +g[C>>2]*q;g[E>>2]=+g[x>>2]*q-+g[C>>2]*m;C=z+(t<<2)|0;m=+g[A>>2];q=+g[B>>2];o=m-q;x=A+4|0;j=+g[x>>2];E=B+4|0;l=j-+g[E>>2];g[A>>2]=q+m;g[x>>2]=+g[E>>2]+j;x=z+(u<<2)|0;g[B>>2]=+g[C>>2]*o+ +g[x>>2]*l;g[E>>2]=+g[C>>2]*l-+g[x>>2]*o;B=B+-32|0;if(B>>>0<y>>>0)break;else{z=z+(v<<2)|0;A=A+-32|0}}w=w+1|0}while((w|0)<(a|0))}f=f+1|0}while((f|0)!=(e|0))}if((d|0)>0)G=0;else return;do{e=c+(G<<2)|0;f=c+((G|30)<<2)|0;o=+g[f>>2];b=c+((G|14)<<2)|0;l=+g[b>>2];a=c+((G|31)<<2)|0;j=+g[a>>2];w=c+((G|15)<<2)|0;m=+g[w>>2];g[f>>2]=l+o;g[a>>2]=m+j;g[b>>2]=o-l;g[w>>2]=j-m;v=c+((G|28)<<2)|0;m=+g[v>>2];u=c+((G|12)<<2)|0;j=+g[u>>2];l=m-j;t=c+((G|29)<<2)|0;o=+g[t>>2];s=c+((G|13)<<2)|0;q=+g[s>>2];H=o-q;g[v>>2]=j+m;g[t>>2]=q+o;g[u>>2]=l*.9238795042037964-H*.3826834261417389;g[s>>2]=H*.9238795042037964+l*.3826834261417389;r=c+((G|26)<<2)|0;l=+g[r>>2];n=c+((G|10)<<2)|0;H=+g[n>>2];o=l-H;i=c+((G|27)<<2)|0;q=+g[i>>2];k=c+((G|11)<<2)|0;m=+g[k>>2];j=q-m;g[r>>2]=H+l;g[i>>2]=m+q;g[n>>2]=(o-j)*.7071067690849304;g[k>>2]=(j+o)*.7071067690849304;p=c+((G|24)<<2)|0;o=+g[p>>2];h=c+((G|8)<<2)|0;j=+g[h>>2];q=o-j;A=c+((G|25)<<2)|0;m=+g[A>>2];z=c+((G|9)<<2)|0;l=+g[z>>2];H=m-l;g[p>>2]=j+o;g[A>>2]=l+m;m=q*.3826834261417389-H*.9238795042037964;l=H*.3826834261417389+q*.9238795042037964;y=c+((G|22)<<2)|0;q=+g[y>>2];B=c+((G|6)<<2)|0;H=+g[B>>2];o=q-H;x=c+((G|7)<<2)|0;j=+g[x>>2];C=c+((G|23)<<2)|0;I=+g[C>>2];J=j-I;g[y>>2]=H+q;g[C>>2]=I+j;g[B>>2]=J;g[x>>2]=o;E=c+((G|4)<<2)|0;j=+g[E>>2];F=c+((G|20)<<2)|0;I=+g[F>>2];q=j-I;D=c+((G|5)<<2)|0;H=+g[D>>2];K=c+((G|21)<<2)|0;L=+g[K>>2];M=H-L;g[F>>2]=I+j;g[K>>2]=L+H;H=M*.9238795042037964+q*.3826834261417389;L=M*.3826834261417389-q*.9238795042037964;N=c+((G|2)<<2)|0;q=+g[N>>2];O=c+((G|18)<<2)|0;M=+g[O>>2];j=q-M;P=c+((G|3)<<2)|0;I=+g[P>>2];Q=c+((G|19)<<2)|0;R=+g[Q>>2];S=I-R;g[O>>2]=M+q;g[Q>>2]=R+I;I=(S+j)*.7071067690849304;R=(S-j)*.7071067690849304;j=+g[e>>2];T=c+((G|16)<<2)|0;S=+g[T>>2];q=j-S;U=c+((G|1)<<2)|0;M=+g[U>>2];V=c+((G|17)<<2)|0;W=+g[V>>2];X=M-W;Y=S+j;g[T>>2]=Y;j=W+M;g[V>>2]=j;M=X*.3826834261417389+q*.9238795042037964;W=X*.9238795042037964-q*.3826834261417389;q=W-l;X=M-m;S=M+m;m=W+l;l=X+q;W=q-X;X=+g[k>>2];q=R-X;M=+g[n>>2];Z=M-I;$=M+I;I=X+R;R=+g[u>>2];X=R-H;M=+g[s>>2];aa=M-L;ba=R+H;H=M+L;L=X-aa;M=aa+X;X=+g[b>>2];aa=X-J;R=+g[w>>2];ca=R-o;da=J+X;X=o+R;R=aa+q;o=aa-q;q=(L+l)*.7071067690849304;aa=(L-l)*.7071067690849304;g[B>>2]=q+R;g[E>>2]=R-q;q=(M-W)*.7071067690849304;R=ca-Z;g[e>>2]=q+o;g[N>>2]=o-q;q=(M+W)*.7071067690849304;W=ca+Z;g[P>>2]=R+aa;g[U>>2]=R-aa;g[x>>2]=W+q;g[D>>2]=W-q;q=da+$;W=da-$;$=S+ba;da=ba-S;g[b>>2]=q+$;g[u>>2]=q-$;$=H-m;q=X-I;g[h>>2]=W+$;g[n>>2]=W-$;$=H+m;m=X+I;g[k>>2]=q+da;g[z>>2]=q-da;g[w>>2]=m+$;g[s>>2]=m-$;$=+g[A>>2];m=j-$;da=+g[p>>2];q=Y-da;I=da+Y;Y=$+j;j=q+m;$=m-q;q=+g[Q>>2];m=+g[i>>2];da=q-m;X=+g[r>>2];H=+g[O>>2];W=X-H;S=H+X;X=m+q;q=+g[v>>2];m=+g[F>>2];H=q-m;ba=+g[t>>2];aa=+g[K>>2];R=ba-aa;Z=m+q;q=aa+ba;ba=H-R;aa=R+H;H=+g[f>>2];R=+g[y>>2];m=H-R;ca=+g[a>>2];M=+g[C>>2];o=ca-M;l=R+H;H=M+ca;ca=m+da;M=m-da;da=(ba+j)*.7071067690849304;m=(ba-j)*.7071067690849304;g[y>>2]=da+ca;g[F>>2]=ca-da;da=(aa-$)*.7071067690849304;ca=o-W;g[T>>2]=da+M;g[O>>2]=M-da;da=(aa+$)*.7071067690849304;$=o+W;g[Q>>2]=ca+m;g[V>>2]=ca-m;g[C>>2]=$+da;g[K>>2]=$-da;da=l+S;$=l-S;S=Z+I;l=Z-I;g[f>>2]=da+S;g[v>>2]=da-S;S=q-Y;da=H-X;g[p>>2]=$+S;g[r>>2]=$-S;S=q+Y;Y=H+X;g[i>>2]=da+l;g[A>>2]=da-l;g[a>>2]=Y+S;g[t>>2]=Y-S;G=G+32|0}while((G|0)<(d|0));return}function Fc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,i=0,j=0,k=0.0,l=0.0,m=0.0,n=0.0,o=0.0,p=0.0,q=0.0,r=0.0,s=0.0,t=0.0,u=0;f=a>>1;h=b+(a<<2)|0;a=d;d=e;b=e+(f<<2)|0;while(1){i=(c[a>>2]|0)+f|0;j=(c[a+4>>2]|0)+f|0;k=+g[e+(i+1<<2)>>2];l=+g[e+(j+1<<2)>>2];m=k-l;n=+g[e+(i<<2)>>2];o=+g[e+(j<<2)>>2];p=o+n;q=+g[h>>2];r=+g[h+4>>2];s=r*m+p*q;t=r*p-q*m;j=b;b=b+-16|0;m=(l+k)*.5;k=(n-o)*.5;g[d>>2]=s+m;g[j+-8>>2]=m-s;g[d+4>>2]=t+k;g[j+-4>>2]=t-k;i=(c[a+8>>2]|0)+f|0;u=(c[a+12>>2]|0)+f|0;k=+g[e+(i+1<<2)>>2];t=+g[e+(u+1<<2)>>2];s=k-t;m=+g[e+(i<<2)>>2];o=+g[e+(u<<2)>>2];n=o+m;l=+g[h+8>>2];q=+g[h+12>>2];p=q*s+n*l;r=q*n-l*s;s=(t+k)*.5;k=(m-o)*.5;g[d+8>>2]=p+s;g[b>>2]=s-p;g[d+12>>2]=r+k;g[j+-12>>2]=r-k;d=d+16|0;if(d>>>0>=b>>>0)break;else{h=h+16|0;a=a+16|0}}return}function Gc(a,b,c,d,e,f,h){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;h=h|0;var i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0.0,v=0,w=0,x=0.0,y=0,z=0,A=0.0,B=0.0,C=0.0,D=0.0,E=0,F=0.0,G=0.0,H=0.0,I=0.0;i=_(b,a)|0;j=i<<1;k=(b|0)>0;if(k){l=(a<<2)+-1|0;m=a<<1;n=0;o=i;p=i*3|0;q=0;r=j;while(1){s=c+(o<<2)|0;t=c+(p<<2)|0;u=+g[t>>2]+ +g[s>>2];v=c+(q<<2)|0;w=c+(r<<2)|0;x=+g[w>>2]+ +g[v>>2];y=q<<2;g[d+(y<<2)>>2]=x+u;g[d+(l+y<<2)>>2]=x-u;z=y+m|0;g[d+(z+-1<<2)>>2]=+g[v>>2]-+g[w>>2];g[d+(z<<2)>>2]=+g[t>>2]-+g[s>>2];n=n+1|0;if((n|0)==(b|0))break;else{o=o+a|0;p=p+a|0;q=q+a|0;r=r+a|0}}}if((a|0)<2)return;if((a|0)!=2){if(k){r=a<<1;q=0;p=0;while(1){o=p<<2;n=2;m=p;l=o;s=o+r|0;do{o=m;m=m+2|0;t=l;l=l+2|0;z=s;s=s+-2|0;w=m+i|0;v=n+-2|0;u=+g[e+(v<<2)>>2];x=+g[c+(w+-1<<2)>>2];y=n+-1|0;A=+g[e+(y<<2)>>2];B=+g[c+(w<<2)>>2];C=B*A+x*u;D=B*u-A*x;E=w+i|0;x=+g[f+(v<<2)>>2];A=+g[c+(E+-1<<2)>>2];u=+g[f+(y<<2)>>2];B=+g[c+(E<<2)>>2];F=B*u+A*x;G=B*x-u*A;w=E+i|0;A=+g[h+(v<<2)>>2];u=+g[c+(w+-1<<2)>>2];x=+g[h+(y<<2)>>2];B=+g[c+(w<<2)>>2];H=B*x+u*A;I=B*A-x*u;u=H+C;x=H-C;C=I+D;H=D-I;I=+g[c+(m<<2)>>2];D=I+G;A=I-G;G=+g[c+(o+1<<2)>>2];I=G+F;B=G-F;g[d+((t|1)<<2)>>2]=u+I;g[d+(l<<2)>>2]=C+D;g[d+(z+-3<<2)>>2]=B-H;g[d+(s<<2)>>2]=x-A;z=l+r|0;g[d+(z+-1<<2)>>2]=H+B;g[d+(z<<2)>>2]=x+A;z=s+r|0;g[d+(z+-1<<2)>>2]=I-u;g[d+(z<<2)>>2]=C-D;n=n+2|0}while((n|0)<(a|0));q=q+1|0;if((q|0)==(b|0))break;else p=p+a|0}}if(a&1)return}p=a+-1+i|0;q=a<<2;r=a<<1;if(!k)return;k=0;h=p;f=p+j|0;j=a;p=a;while(1){D=+g[c+(h<<2)>>2];C=+g[c+(f<<2)>>2];u=(C+D)*-.7071067690849304;I=(D-C)*.7071067690849304;e=c+(p+-1<<2)|0;g[d+(j+-1<<2)>>2]=I+ +g[e>>2];n=j+r|0;g[d+(n+-1<<2)>>2]=+g[e>>2]-I;e=c+(h+i<<2)|0;g[d+(j<<2)>>2]=u-+g[e>>2];g[d+(n<<2)>>2]=+g[e>>2]+u;k=k+1|0;if((k|0)==(b|0))break;else{h=h+a|0;f=f+a|0;j=j+q|0;p=p+a|0}}return}function Hc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0.0,x=0.0,y=0.0,z=0.0,A=0.0,B=0.0;h=_(b,a)|0;i=a<<1;j=(b|0)>0;if(j){k=i+-1|0;l=0;m=0;n=h;while(1){o=d+(m<<2)|0;p=d+(n<<2)|0;q=m<<1;g[e+(q<<2)>>2]=+g[p>>2]+ +g[o>>2];g[e+(k+q<<2)>>2]=+g[o>>2]-+g[p>>2];l=l+1|0;if((l|0)==(b|0))break;else{m=m+a|0;n=n+a|0}}}if((a|0)<2)return;if((a|0)!=2){if(j){n=0;m=0;l=h;while(1){k=m<<1;p=2;o=l;q=k+i|0;r=m;s=k;do{k=o;o=o+2|0;t=q;q=q+-2|0;u=r;r=r+2|0;v=s;s=s+2|0;w=+g[f+(p+-2<<2)>>2];x=+g[d+(k+1<<2)>>2];y=+g[f+(p+-1<<2)>>2];z=+g[d+(o<<2)>>2];A=z*y+x*w;B=z*w-y*x;k=d+(r<<2)|0;g[e+(s<<2)>>2]=B+ +g[k>>2];g[e+(q<<2)>>2]=B-+g[k>>2];k=d+(u+1<<2)|0;g[e+((v|1)<<2)>>2]=+g[k>>2]+A;g[e+(t+-3<<2)>>2]=+g[k>>2]-A;p=p+2|0}while((p|0)<(a|0));n=n+1|0;if((n|0)==(b|0))break;else{m=m+a|0;l=l+a|0}}}if(((a|0)%2|0|0)==1)return}l=a+-1|0;if(!j)return;j=0;m=a;n=h+l|0;h=l;while(1){g[e+(m<<2)>>2]=-+g[d+(n<<2)>>2];c[e+(m+-1<<2)>>2]=c[d+(h<<2)>>2];j=j+1|0;if((j|0)==(b|0))break;else{m=m+i|0;n=n+a|0;h=h+a|0}}return}function Ic(a,b,d,e,f,h,i,j,k,l){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;h=h|0;i=i|0;j=j|0;k=k|0;l=l|0;var m=0.0,n=0.0,o=0.0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0.0,N=0.0,O=0.0,P=0.0;m=6.2831854820251465/+(b|0);n=+Q(+m);o=+R(+m);p=b+1>>1;q=a+-1>>1;r=_(d,a)|0;s=_(b,a)|0;t=(a|0)==1;a:do if(!t){if((e|0)>0){u=0;do{c[k+(u<<2)>>2]=c[i+(u<<2)>>2];u=u+1|0}while((u|0)!=(e|0))}u=(b|0)>1;if(u){v=(d|0)>0;w=1;x=0;do{x=x+r|0;if(v){y=0;z=x;while(1){c[j+(z<<2)>>2]=c[h+(z<<2)>>2];y=y+1|0;if((y|0)==(d|0))break;else z=z+a|0}}w=w+1|0}while((w|0)!=(b|0))}w=0-a|0;if((q|0)>(d|0)){if(u){x=(d|0)>0;v=(a|0)>2;z=w;y=1;A=0;do{A=A+r|0;z=z+a|0;if(x){B=z+-1|0;C=0;D=A-a|0;do{D=D+a|0;if(v){E=2;F=B;G=D;do{H=F;F=F+2|0;I=l+(H+1<<2)|0;H=G+1|0;G=G+2|0;J=h+(H<<2)|0;K=l+(F<<2)|0;L=h+(G<<2)|0;g[j+(H<<2)>>2]=+g[L>>2]*+g[K>>2]+ +g[J>>2]*+g[I>>2];g[j+(G<<2)>>2]=+g[L>>2]*+g[I>>2]-+g[J>>2]*+g[K>>2];E=E+2|0}while((E|0)<(a|0))}C=C+1|0}while((C|0)!=(d|0))}y=y+1|0}while((y|0)!=(b|0))}}else if(u){y=(a|0)>2;v=(d|0)>0;A=w;z=1;x=0;do{A=A+a|0;x=x+r|0;if(y){C=2;D=A+-1|0;B=x;do{E=D;D=D+2|0;B=B+2|0;if(v){G=l+(E+1<<2)|0;E=l+(D<<2)|0;F=0;K=B;while(1){J=K+-1|0;I=h+(J<<2)|0;L=h+(K<<2)|0;g[j+(J<<2)>>2]=+g[L>>2]*+g[E>>2]+ +g[I>>2]*+g[G>>2];g[j+(K<<2)>>2]=+g[L>>2]*+g[G>>2]-+g[I>>2]*+g[E>>2];F=F+1|0;if((F|0)==(d|0))break;else K=K+a|0}}C=C+2|0}while((C|0)<(a|0))}z=z+1|0}while((z|0)!=(b|0))}z=_(r,b)|0;v=(p|0)>1;if((q|0)>=(d|0)){if(!v)break;x=(d|0)>0;A=(a|0)>2;y=1;w=0;u=z;while(1){w=w+r|0;u=u-r|0;if(x){C=0;B=w;D=u;while(1){if(A){K=2;F=B;E=D;do{G=F;F=F+2|0;I=G+1|0;G=j+(I<<2)|0;L=E+1|0;E=E+2|0;J=j+(L<<2)|0;g[h+(I<<2)>>2]=+g[J>>2]+ +g[G>>2];I=j+(F<<2)|0;H=j+(E<<2)|0;g[h+(L<<2)>>2]=+g[I>>2]-+g[H>>2];g[h+(F<<2)>>2]=+g[H>>2]+ +g[I>>2];g[h+(E<<2)>>2]=+g[J>>2]-+g[G>>2];K=K+2|0}while((K|0)<(a|0))}C=C+1|0;if((C|0)==(d|0))break;else{B=B+a|0;D=D+a|0}}}y=y+1|0;if((y|0)==(p|0))break a}}if(v){y=(a|0)>2;A=(d|0)>0;u=1;w=0;x=z;do{w=w+r|0;x=x-r|0;if(y){D=2;B=w;C=x;do{B=B+2|0;C=C+2|0;if(A){K=0;E=B-a|0;F=C-a|0;do{E=E+a|0;F=F+a|0;G=E+-1|0;J=j+(G<<2)|0;I=F+-1|0;H=j+(I<<2)|0;g[h+(G<<2)>>2]=+g[H>>2]+ +g[J>>2];G=j+(E<<2)|0;L=j+(F<<2)|0;g[h+(I<<2)>>2]=+g[G>>2]-+g[L>>2];g[h+(E<<2)>>2]=+g[L>>2]+ +g[G>>2];g[h+(F<<2)>>2]=+g[H>>2]-+g[J>>2];K=K+1|0}while((K|0)!=(d|0))}D=D+2|0}while((D|0)<(a|0))}u=u+1|0}while((u|0)!=(p|0))}}while(0);l=(e|0)>0;if(l){u=0;do{c[i+(u<<2)>>2]=c[k+(u<<2)>>2];u=u+1|0}while((u|0)!=(e|0))}u=_(e,b)|0;A=(p|0)>1;if(A){x=(d|0)>0;w=1;y=0;z=u;do{y=y+r|0;z=z-r|0;if(x){v=0;D=y-a|0;C=z-a|0;do{D=D+a|0;C=C+a|0;B=j+(D<<2)|0;K=j+(C<<2)|0;g[h+(D<<2)>>2]=+g[K>>2]+ +g[B>>2];g[h+(C<<2)>>2]=+g[K>>2]-+g[B>>2];v=v+1|0}while((v|0)!=(d|0))}w=w+1|0}while((w|0)!=(p|0));w=_(b+-1|0,e)|0;if(A){h=(p|0)>2;m=0.0;M=1.0;z=1;y=0;x=u;do{y=y+e|0;x=x-e|0;N=M;M=M*n-m*o;m=N*o+m*n;if(l){u=0;v=y;C=x;D=w;B=e;while(1){g[k+(v<<2)>>2]=+g[i+(B<<2)>>2]*M+ +g[i+(u<<2)>>2];g[k+(C<<2)>>2]=+g[i+(D<<2)>>2]*m;u=u+1|0;if((u|0)==(e|0))break;else{v=v+1|0;C=C+1|0;D=D+1|0;B=B+1|0}}}if(h){N=m;O=M;B=2;D=e;C=w;do{D=D+e|0;C=C-e|0;P=O;O=O*M-N*m;N=P*m+N*M;if(l){v=0;u=y;K=x;F=D;E=C;while(1){J=k+(u<<2)|0;g[J>>2]=+g[J>>2]+ +g[i+(F<<2)>>2]*O;J=k+(K<<2)|0;g[J>>2]=+g[J>>2]+ +g[i+(E<<2)>>2]*N;v=v+1|0;if((v|0)==(e|0))break;else{u=u+1|0;K=K+1|0;F=F+1|0;E=E+1|0}}}B=B+1|0}while((B|0)!=(p|0))}z=z+1|0}while((z|0)!=(p|0));if(A){z=1;x=0;do{x=x+e|0;if(l){y=0;w=x;while(1){h=k+(y<<2)|0;g[h>>2]=+g[h>>2]+ +g[i+(w<<2)>>2];y=y+1|0;if((y|0)==(e|0))break;else w=w+1|0}}z=z+1|0}while((z|0)!=(p|0))}}}if((a|0)<(d|0)){if((a|0)>0){z=(d|0)>0;e=0;do{if(z){i=0;k=e;x=e;while(1){c[f+(x<<2)>>2]=c[j+(k<<2)>>2];i=i+1|0;if((i|0)==(d|0))break;else{k=k+a|0;x=x+s|0}}}e=e+1|0}while((e|0)!=(a|0))}}else if((d|0)>0){e=(a|0)>0;z=0;x=0;k=0;while(1){if(e){i=0;l=x;w=k;while(1){c[f+(w<<2)>>2]=c[j+(l<<2)>>2];i=i+1|0;if((i|0)==(a|0))break;else{l=l+1|0;w=w+1|0}}}z=z+1|0;if((z|0)==(d|0))break;else{x=x+a|0;k=k+s|0}}}k=a<<1;x=_(r,b)|0;if(A){b=(d|0)>0;z=1;e=0;w=0;l=x;do{e=e+k|0;w=w+r|0;l=l-r|0;if(b){i=0;y=e;h=w;B=l;while(1){c[f+(y+-1<<2)>>2]=c[j+(h<<2)>>2];c[f+(y<<2)>>2]=c[j+(B<<2)>>2];i=i+1|0;if((i|0)==(d|0))break;else{y=y+s|0;h=h+a|0;B=B+a|0}}}z=z+1|0}while((z|0)!=(p|0))}if(t)return;t=0-a|0;if((q|0)>=(d|0)){if(!A)return;q=(d|0)<1|(a|0)<3;z=1;l=t;w=0;e=0;b=x;do{l=l+k|0;w=w+k|0;e=e+r|0;b=b-r|0;if(!q){B=0;h=l;y=w;i=e;C=b;while(1){D=2;do{E=D+i|0;F=j+(E+-1<<2)|0;K=D+C|0;u=j+(K+-1<<2)|0;v=D+y|0;g[f+(v+-1<<2)>>2]=+g[u>>2]+ +g[F>>2];J=a-D+h|0;g[f+(J+-1<<2)>>2]=+g[F>>2]-+g[u>>2];u=j+(E<<2)|0;E=j+(K<<2)|0;g[f+(v<<2)>>2]=+g[E>>2]+ +g[u>>2];g[f+(J<<2)>>2]=+g[E>>2]-+g[u>>2];D=D+2|0}while((D|0)<(a|0));B=B+1|0;if((B|0)==(d|0))break;else{h=h+s|0;y=y+s|0;i=i+a|0;C=C+a|0}}}z=z+1|0}while((z|0)!=(p|0));return}if(!A)return;A=(a|0)>2;z=(d|0)>0;b=1;e=t;t=0;w=0;l=x;do{e=e+k|0;t=t+k|0;w=w+r|0;l=l-r|0;if(A?(x=e+a|0,z):0){q=2;do{C=0;i=x-q|0;y=q+t|0;h=q+w|0;B=q+l|0;while(1){D=j+(h+-1<<2)|0;u=j+(B+-1<<2)|0;g[f+(y+-1<<2)>>2]=+g[u>>2]+ +g[D>>2];g[f+(i+-1<<2)>>2]=+g[D>>2]-+g[u>>2];u=j+(h<<2)|0;D=j+(B<<2)|0;g[f+(y<<2)>>2]=+g[D>>2]+ +g[u>>2];g[f+(i<<2)>>2]=+g[D>>2]-+g[u>>2];C=C+1|0;if((C|0)==(d|0))break;else{i=i+s|0;y=y+s|0;h=h+a|0;B=B+a|0}}q=q+2|0}while((q|0)<(a|0))}b=b+1|0}while((b|0)!=(p|0));return}function Jc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;e=c[b+28>>2]|0;if(!e){f=1;return f|0}g=c[e+3656>>2]|0;h=a;i=h+112|0;do{c[h>>2]=0;h=h+4|0}while((h|0)<(i|0));h=zd(1,136)|0;c[a+104>>2]=h;c[a+4>>2]=b;i=c[e+8>>2]|0;j=i+-1|0;if((i|0)==0|(j|0)==0)k=0;else{i=j;j=0;while(1){l=j+1|0;i=i>>>1;if(!i){k=l;break}else j=l}}c[h+44>>2]=k;k=zd(1,4)|0;c[h+12>>2]=k;j=zd(1,4)|0;i=h+16|0;c[i>>2]=j;l=zd(1,20)|0;c[k>>2]=l;c[j>>2]=zd(1,20)|0;sb(l,c[e>>2]>>g);l=e+4|0;sb(c[c[i>>2]>>2]|0,c[l>>2]>>g);g=c[e>>2]|0;i=g+-1|0;if((g|0)==0|(i|0)==0)m=0;else{j=i;i=0;while(1){k=i+1|0;j=j>>>1;if(!j){m=k;break}else i=k}}c[h+4>>2]=m+-6;m=c[l>>2]|0;i=m+-1|0;if((m|0)==0|(i|0)==0)n=0;else{m=i;i=0;while(1){j=i+1|0;m=m>>>1;if(!m){n=j;break}else i=j}}c[h+8>>2]=n+-6;a:do if(!d){n=e+2848|0;if((c[n>>2]|0)==0?(i=e+24|0,c[n>>2]=zd(c[i>>2]|0,56)|0,m=c[i>>2]|0,(m|0)>0):0){j=m;m=0;while(1){k=e+1824+(m<<2)|0;o=c[k>>2]|0;if(!o){p=j;break}if(Bc((c[n>>2]|0)+(m*56|0)|0,o)|0){q=23;break}yc(c[k>>2]|0);c[k>>2]=0;m=m+1|0;j=c[i>>2]|0;if((m|0)>=(j|0))break a}if((q|0)==23)p=c[i>>2]|0;if((p|0)>0){j=p;m=0;while(1){n=e+1824+(m<<2)|0;k=c[n>>2]|0;if(!k)r=j;else{yc(k);c[n>>2]=0;r=c[i>>2]|0}m=m+1|0;if((m|0)>=(r|0))break;else j=r}}Db(a);f=-1;return f|0}}else{xb(h+20|0,g);xb(h+32|0,c[l>>2]|0);j=e+2848|0;if(((c[j>>2]|0)==0?(m=e+24|0,i=zd(c[m>>2]|0,56)|0,c[j>>2]=i,(c[m>>2]|0)>0):0)?(Ac(i,c[e+1824>>2]|0)|0,(c[m>>2]|0)>1):0){i=1;do{Ac((c[j>>2]|0)+(i*56|0)|0,c[e+1824+(i<<2)>>2]|0)|0;i=i+1|0}while((i|0)<(c[m>>2]|0))}m=e+28|0;i=zd(c[m>>2]|0,52)|0;j=h+56|0;c[j>>2]=i;b:do if((c[m>>2]|0)>0){n=e+2868|0;k=b+8|0;o=i;s=0;while(1){t=c[e+2852+(s<<2)>>2]|0;Pb(o+(s*52|0)|0,t,n,(c[e+(c[t>>2]<<2)>>2]|0)/2|0,c[k>>2]|0);t=s+1|0;if((t|0)>=(c[m>>2]|0))break b;o=c[j>>2]|0;s=t}}while(0);c[a>>2]=1}while(0);g=c[l>>2]|0;c[a+16>>2]=g;r=c[b+4>>2]|0;b=r<<2;p=xd(b)|0;q=a+8|0;c[q>>2]=p;c[a+12>>2]=xd(b)|0;if((r|0)>0?(c[p>>2]=zd(g,4)|0,(r|0)>1):0){p=1;do{b=c[q>>2]|0;c[b+(p<<2)>>2]=zd(g,4)|0;p=p+1|0}while((p|0)<(r|0))}c[a+36>>2]=0;c[a+40>>2]=0;r=(c[l>>2]|0)/2|0;c[a+48>>2]=r;c[a+20>>2]=r;r=e+16|0;l=h+48|0;c[l>>2]=zd(c[r>>2]|0,4)|0;p=e+20|0;g=h+52|0;c[g>>2]=zd(c[p>>2]|0,4)|0;if((c[r>>2]|0)>0){h=0;do{q=$a[c[(c[328+(c[e+800+(h<<2)>>2]<<2)>>2]|0)+8>>2]&15](a,c[e+1056+(h<<2)>>2]|0)|0;c[(c[l>>2]|0)+(h<<2)>>2]=q;h=h+1|0}while((h|0)<(c[r>>2]|0))}if((c[p>>2]|0)>0)u=0;else{f=0;return f|0}do{r=$a[c[(c[336+(c[e+1312+(u<<2)>>2]<<2)>>2]|0)+8>>2]&15](a,c[e+1568+(u<<2)>>2]|0)|0;c[(c[g>>2]|0)+(u<<2)>>2]=r;u=u+1|0}while((u|0)<(c[p>>2]|0));f=0;return f|0}function Kc(a,b,d,e,f){a=a|0;b=+b;d=d|0;e=+e;f=+f;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0.0,v=0,w=0.0,x=0.0,y=0.0,z=0.0,A=0.0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,N=0,O=0.0,P=0;h=i;i=i+32480|0;j=h+32256|0;k=h+1792|0;l=h;m=i;i=i+((1*(d<<2)|0)+15&-16)|0;n=xd(68)|0;Fd(k|0,0,30464)|0;o=e>0.0;p=e<0.0;q=0;do{r=q<<2;s=0;do{t=s+r|0;if((t|0)<88)u=+g[408+(t<<2)>>2];else u=-30.0;v=t+1|0;if((v|0)<88){w=+g[408+(v<<2)>>2];if(u>w)x=w;else x=u}else if(u>-30.0)x=-30.0;else x=u;v=t+2|0;if((v|0)<88){w=+g[408+(v<<2)>>2];if(x>w)y=w;else y=x}else if(x>-30.0)y=-30.0;else y=x;v=t+3|0;if((v|0)<88){w=+g[408+(v<<2)>>2];if(y>w)z=w;else z=y}else if(y>-30.0)z=-30.0;else z=y;g[j+(s<<2)>>2]=z;s=s+1|0}while((s|0)!=56);s=33552+(q*1344|0)|0;Jd(k+(q*1792|0)+448|0,s|0,224)|0;Jd(k+(q*1792|0)+672|0,33552+(q*1344|0)+224|0,224)|0;Jd(k+(q*1792|0)+896|0,33552+(q*1344|0)+448|0,224)|0;Jd(k+(q*1792|0)+1120|0,33552+(q*1344|0)+672|0,224)|0;Jd(k+(q*1792|0)+1344|0,33552+(q*1344|0)+896|0,224)|0;Jd(k+(q*1792|0)+1568|0,33552+(q*1344|0)+1120|0,224)|0;Jd(k+(q*1792|0)|0,s|0,224)|0;Jd(k+(q*1792|0)+224|0,s|0,224)|0;if(o){s=0;do{if(p){r=0;do{v=16-r|0;w=+(((v|0)>-1?v:0-v|0)|0)*f+e;A=w<0.0?0.0:w;v=k+(q*1792|0)+(s*224|0)+(r<<2)|0;g[v>>2]=+g[v>>2]+(A>0.0?0.0:A);r=r+1|0}while((r|0)!=56)}else{r=0;do{v=16-r|0;A=+(((v|0)>-1?v:0-v|0)|0)*f+e;v=k+(q*1792|0)+(s*224|0)+(r<<2)|0;g[v>>2]=+g[v>>2]+(A<0.0?0.0:A);r=r+1|0}while((r|0)!=56)}s=s+1|0}while((s|0)!=8)}else{s=0;do{if(p){r=0;do{v=16-r|0;A=+(((v|0)>-1?v:0-v|0)|0)*f+e;v=k+(q*1792|0)+(s*224|0)+(r<<2)|0;g[v>>2]=+g[v>>2]+(A>0.0?0.0:A);r=r+1|0}while((r|0)!=56)}else{r=0;do{v=16-r|0;t=k+(q*1792|0)+(s*224|0)+(r<<2)|0;g[t>>2]=+g[t>>2]+(+(((v|0)>-1?v:0-v|0)|0)*f+e);r=r+1|0}while((r|0)!=56)}s=s+1|0}while((s|0)!=8)}A=+g[a+(q<<2)>>2];s=0;do{w=((s|0)<2?50.0:70.0-+(s|0)*10.0)+A;r=0;do{v=k+(q*1792|0)+(s*224|0)+(r<<2)|0;g[v>>2]=+g[v>>2]+w;r=r+1|0}while((r|0)!=56);Jd(l+(s*224|0)|0,j|0,224)|0;w=70.0-+(s|0)*10.0;r=0;do{v=l+(s*224|0)+(r<<2)|0;g[v>>2]=w+ +g[v>>2];r=r+1|0}while((r|0)!=56);B=0;do{w=+g[k+(q*1792|0)+(s*224|0)+(B<<2)>>2];r=l+(s*224|0)+(B<<2)|0;if(w>+g[r>>2])g[r>>2]=w;B=B+1|0}while((B|0)!=56);s=s+1|0}while((s|0)!=8);C=1;do{s=C+-1|0;r=0;do{A=+g[l+(s*224|0)+(r<<2)>>2];v=l+(C*224|0)+(r<<2)|0;if(A<+g[v>>2])g[v>>2]=A;r=r+1|0}while((r|0)!=56);D=0;do{A=+g[l+(C*224|0)+(D<<2)>>2];r=k+(q*1792|0)+(C*224|0)+(D<<2)|0;if(A<+g[r>>2])g[r>>2]=A;D=D+1|0}while((D|0)!=56);C=C+1|0}while((C|0)!=8);q=q+1|0}while((q|0)!=17);e=b;q=(d|0)>0;C=~d;D=0;do{l=xd(32)|0;c[n+(D<<2)>>2]=l;f=+(D|0);z=f*.5;B=~~+M(+(+X(+(f*.34657350182533264+4.135165354540845))/e));j=~~+Z(+(+Y(+(+(B|0)*b+1.0))*2.885390043258667+-11.931568145751953));a=~~+M(+(+Y(+(+(B+1|0)*b))*2.885390043258667+-11.931568145751953));B=(j|0)>(D|0)?D:j;j=(B|0)<0?0:B;B=(a|0)>16?16:a;a=(j|0)>(B|0);D=D+1|0;p=(D|0)<17;f=z+3.9657840728759766;o=0;do{r=xd(232)|0;c[l+(o<<2)>>2]=r;if(q){s=0;do{g[m+(s<<2)>>2]=999.0;s=s+1|0}while((s|0)!=(d|0))}if(!a){s=j;while(1){y=+(s|0)*.5;v=0;t=0;while(1){x=+(v|0)*.125+y;E=~~(+X(+((x+3.9032840728759766)*.6931470036506653))/e);F=~~(+X(+((x+4.028284072875977)*.6931470036506653))/e+1.0);G=(E|0)<0?0:E;H=(G|0)>(d|0)?d:G;G=(H|0)<(t|0)?H:t;H=(F|0)<0?0:F;if((G|0)<(d|0)?(G|0)<(((H|0)>(d|0)?d:H)|0):0){x=+g[k+(s*1792|0)+(o*224|0)+(v<<2)>>2];H=~((t|0)<(d|0)?t:d);I=(E|0)>0?~E:-1;E=(I|0)<(H|0)?H:I;I=(F|0)>0?~F:-1;F=((I|0)<(C|0)?C:I)-E|0;I=~(E+d);H=~E-(F>>>0>I>>>0?F:I)|0;I=G;do{F=m+(I<<2)|0;if(+g[F>>2]>x)g[F>>2]=x;I=I+1|0}while((I|0)!=(H|0));J=H}else J=G;v=v+1|0;if((v|0)==56){K=J;break}else t=J}if((K|0)<(d|0)){y=+g[k+(s*1792|0)+(o*224|0)+220>>2];t=K;do{v=m+(t<<2)|0;if(+g[v>>2]>y)g[v>>2]=y;t=t+1|0}while((t|0)!=(d|0))}if((s|0)<(B|0))s=s+1|0;else break}}if(p){s=0;t=0;while(1){y=+(s|0)*.125+z;v=~~(+X(+((y+3.9032840728759766)*.6931470036506653))/e);H=~~(+X(+((y+4.028284072875977)*.6931470036506653))/e+1.0);I=(v|0)<0?0:v;F=(I|0)>(d|0)?d:I;I=(F|0)<(t|0)?F:t;F=(H|0)<0?0:H;if((I|0)<(d|0)?(I|0)<(((F|0)>(d|0)?d:F)|0):0){y=+g[k+(D*1792|0)+(o*224|0)+(s<<2)>>2];F=~((t|0)<(d|0)?t:d);E=(v|0)>0?~v:-1;v=(E|0)<(F|0)?F:E;E=(H|0)>0?~H:-1;H=((E|0)<(C|0)?C:E)-v|0;E=~(v+d);F=~v-(H>>>0>E>>>0?H:E)|0;E=I;do{H=m+(E<<2)|0;if(+g[H>>2]>y)g[H>>2]=y;E=E+1|0}while((E|0)!=(F|0));L=F}else L=I;s=s+1|0;if((s|0)==56){N=L;break}else t=L}if((N|0)<(d|0)){y=+g[k+(D*1792|0)+(o*224|0)+220>>2];t=N;do{s=m+(t<<2)|0;if(+g[s>>2]>y)g[s>>2]=y;t=t+1|0}while((t|0)!=(d|0))}}t=l+(o<<2)|0;s=l+(o<<2)|0;F=l+(o<<2)|0;E=0;do{H=~~(+X(+((f+ +(E|0)*.125)*.6931470036506653))/e);do if((H|0)>=0)if((H|0)<(d|0)){c[(c[s>>2]|0)+(E+2<<2)>>2]=c[m+(H<<2)>>2];break}else{g[(c[F>>2]|0)+(E+2<<2)>>2]=-999.0;break}else g[(c[t>>2]|0)+(E+2<<2)>>2]=-999.0;while(0);E=E+1|0}while((E|0)!=56);do if(!(+g[r+8>>2]>-200.0))if(!(+g[r+12>>2]>-200.0))if(!(+g[r+16>>2]>-200.0))if(!(+g[r+20>>2]>-200.0))if(!(+g[r+24>>2]>-200.0))if(!(+g[r+28>>2]>-200.0))if(!(+g[r+32>>2]>-200.0))if(!(+g[r+36>>2]>-200.0))if(!(+g[r+40>>2]>-200.0))if(!(+g[r+44>>2]>-200.0))if(!(+g[r+48>>2]>-200.0))if(!(+g[r+52>>2]>-200.0))if(!(+g[r+56>>2]>-200.0))if(+g[r+60>>2]>-200.0)O=13.0;else{if(+g[r+64>>2]>-200.0){O=14.0;break}if(+g[r+68>>2]>-200.0){O=15.0;break}O=16.0}else O=12.0;else O=11.0;else O=10.0;else O=9.0;else O=8.0;else O=7.0;else O=6.0;else O=5.0;else O=4.0;else O=3.0;else O=2.0;else O=1.0;else O=0.0;while(0);g[r>>2]=O;E=55;while(1){if(+g[r+(E+2<<2)>>2]>-200.0){P=E;break}t=E+-1|0;if((t|0)>17)E=t;else{P=t;break}}g[r+4>>2]=+(P|0);o=o+1|0}while((o|0)!=8)}while((D|0)!=17);i=h;return n|0}function Lc(a,b,d,e,f,h){a=a|0;b=b|0;d=d|0;e=e|0;f=+f;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0.0,r=0.0,s=0.0,t=0.0,u=0.0,v=0.0,w=0.0,x=0.0,y=0.0,z=0,A=0.0,B=0.0,C=0.0,D=0,E=0.0,F=0,G=0,H=0,I=0.0,J=0.0,K=0.0,L=0,M=0.0,N=0.0,O=0.0,P=0.0,Q=0,R=0.0,S=0.0,T=0.0,U=0.0,V=0,W=0.0,X=0,Y=0.0;j=i;k=a<<2;l=i;i=i+((1*k|0)+15&-16)|0;m=i;i=i+((1*k|0)+15&-16)|0;n=i;i=i+((1*k|0)+15&-16)|0;o=i;i=i+((1*k|0)+15&-16)|0;p=i;i=i+((1*k|0)+15&-16)|0;q=+g[d>>2]+f;r=q<1.0?1.0:q;q=r*r*.5;s=q*r;g[l>>2]=q;g[m>>2]=q;g[n>>2]=0.0;g[o>>2]=s;g[p>>2]=0.0;if((a|0)>1){k=1;r=q;t=q;q=0.0;u=0.0;v=s;s=1.0;while(1){w=+g[d+(k<<2)>>2]+f;x=w<1.0?1.0:w;w=x*x;r=w+r;y=w*s;t=y+t;q=y*s+q;v=w*x+v;u=y*x+u;g[l+(k<<2)>>2]=r;g[m+(k<<2)>>2]=t;g[n+(k<<2)>>2]=q;g[o+(k<<2)>>2]=v;g[p+(k<<2)>>2]=u;k=k+1|0;if((k|0)==(a|0))break;else s=s+1.0}}k=c[b>>2]|0;d=k>>16;if((d|0)>-1){z=k;A=0.0;B=0.0;C=1.0;D=0;E=0.0}else{F=k;k=d;d=0;s=0.0;while(1){G=F&65535;H=0-k|0;u=+g[l+(H<<2)>>2]+ +g[l+(G<<2)>>2];v=+g[m+(G<<2)>>2]-+g[m+(H<<2)>>2];q=+g[n+(H<<2)>>2]+ +g[n+(G<<2)>>2];t=+g[o+(H<<2)>>2]+ +g[o+(G<<2)>>2];r=+g[p+(G<<2)>>2]-+g[p+(H<<2)>>2];x=t*q-r*v;y=r*u-t*v;t=q*u-v*v;v=(y*s+x)/t;g[e+(d<<2)>>2]=(v<0.0?0.0:v)-f;H=d+1|0;v=s+1.0;G=c[b+(H<<2)>>2]|0;k=G>>16;if((k|0)>-1){z=G;A=x;B=y;C=t;D=H;E=v;break}else{F=G;d=H;s=v}}}d=z&65535;if((d|0)<(a|0)){F=z;z=d;d=D;s=E;while(1){k=F>>16;v=+g[l+(z<<2)>>2]-+g[l+(k<<2)>>2];t=+g[m+(z<<2)>>2]-+g[m+(k<<2)>>2];y=+g[n+(z<<2)>>2]-+g[n+(k<<2)>>2];x=+g[o+(z<<2)>>2]-+g[o+(k<<2)>>2];u=+g[p+(z<<2)>>2]-+g[p+(k<<2)>>2];q=x*y-u*t;r=u*v-x*t;x=y*v-t*t;t=(r*s+q)/x;g[e+(d<<2)>>2]=(t<0.0?0.0:t)-f;k=d+1|0;t=s+1.0;F=c[b+(k<<2)>>2]|0;z=F&65535;if((z|0)>=(a|0)){I=q;J=r;K=x;L=k;M=t;break}else{d=k;s=t}}}else{I=A;J=B;K=C;L=D;M=E}if((L|0)<(a|0)){D=L;E=M;while(1){M=(E*J+I)/K;g[e+(D<<2)>>2]=(M<0.0?0.0:M)-f;D=D+1|0;if((D|0)==(a|0))break;else E=E+1.0}}if((h|0)<1){i=j;return}D=(h|0)/2|0;L=D-h|0;if((L|0)>-1){N=I;O=J;P=K;Q=0;R=0.0}else{d=h-D|0;z=D;F=L;L=0;K=0.0;while(1){b=0-F|0;J=+g[l+(b<<2)>>2]+ +g[l+(z<<2)>>2];I=+g[m+(z<<2)>>2]-+g[m+(b<<2)>>2];E=+g[n+(b<<2)>>2]+ +g[n+(z<<2)>>2];M=+g[o+(b<<2)>>2]+ +g[o+(z<<2)>>2];C=+g[p+(z<<2)>>2]-+g[p+(b<<2)>>2];B=M*E-C*I;A=C*J-M*I;M=E*J-I*I;I=(A*K+B)/M-f;b=e+(L<<2)|0;if(I<+g[b>>2])g[b>>2]=I;L=L+1|0;I=K+1.0;b=D+L|0;if((L|0)==(d|0)){N=B;O=A;P=M;Q=d;R=I;break}else{z=b;F=b-h|0;K=I}}}F=Q+D|0;if((F|0)<(a|0)){z=a-D|0;d=F;F=Q;K=R;while(1){L=d-h|0;I=+g[l+(d<<2)>>2]-+g[l+(L<<2)>>2];M=+g[m+(d<<2)>>2]-+g[m+(L<<2)>>2];A=+g[n+(d<<2)>>2]-+g[n+(L<<2)>>2];B=+g[o+(d<<2)>>2]-+g[o+(L<<2)>>2];J=+g[p+(d<<2)>>2]-+g[p+(L<<2)>>2];E=B*A-J*M;C=J*I-B*M;B=A*I-M*M;M=(C*K+E)/B-f;L=e+(F<<2)|0;if(M<+g[L>>2])g[L>>2]=M;L=F+1|0;M=K+1.0;if((L|0)==(z|0)){S=E;T=C;U=B;V=z;W=M;break}else{d=L+D|0;F=L;K=M}}}else{S=N;T=O;U=P;V=Q;W=R}if((V|0)<(a|0)){X=V;Y=W}else{i=j;return}while(1){W=(Y*T+S)/U-f;V=e+(X<<2)|0;if(W<+g[V>>2])g[V>>2]=W;X=X+1|0;if((X|0)==(a|0))break;else Y=Y+1.0}i=j;return}function Mc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,h=0,j=0,k=0,l=0,m=0.0,n=0,o=0.0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;e=i;f=d<<2;h=i;i=i+((1*f|0)+15&-16)|0;j=i;i=i+((1*f|0)+15&-16)|0;if((d|0)>0){k=0;l=0}else{i=e;return}while(1){do if((l|0)>=2){m=+g[a+(k<<2)>>2];f=l;while(1){n=f+-1|0;o=+g[j+(n<<2)>>2];if(m<o){p=f;q=8;break}if(!((f|0)>1?(k|0)<((c[h+(n<<2)>>2]|0)+b|0):0)){r=f;q=12;break}s=f+-2|0;if(!(o<=+g[j+(s<<2)>>2])){r=f;q=12;break}if((k|0)<((c[h+(s<<2)>>2]|0)+b|0))f=n;else{r=f;q=12;break}}if((q|0)==8){q=0;c[h+(p<<2)>>2]=k;g[j+(p<<2)>>2]=m;t=p;break}else if((q|0)==12){q=0;c[h+(r<<2)>>2]=k;g[j+(r<<2)>>2]=m;t=r;break}}else{c[h+(l<<2)>>2]=k;c[j+(l<<2)>>2]=c[a+(k<<2)>>2];t=l}while(0);f=t+1|0;k=k+1|0;if((k|0)==(d|0)){u=t;v=f;break}else l=f}if((u|0)<=-1){i=e;return}l=b+1|0;b=0;t=0;while(1){if((b|0)<(u|0)?(k=b+1|0,+g[j+(k<<2)>>2]>+g[j+(b<<2)>>2]):0)w=c[h+(k<<2)>>2]|0;else w=l+(c[h+(b<<2)>>2]|0)|0;if((t|0)<(((w|0)>(d|0)?d:w)|0)){k=c[j+(b<<2)>>2]|0;r=(w|0)<(d|0)?w:d;q=t;do{c[a+(q<<2)>>2]=k;q=q+1|0}while((q|0)!=(r|0));x=r}else x=t;b=b+1|0;if((b|0)==(v|0))break;else t=x}i=e;return}function Nc(a,b,d,e,f,j,l,m,n){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;j=j|0;l=l|0;m=m|0;n=n|0;var o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0.0,w=0,x=0.0,y=0.0,z=0,A=0.0,B=0.0,C=0,D=0.0,E=0,F=0.0,G=0,H=0.0;o=i;p=i;i=i+((1*(m<<2)|0)+15&-16)|0;if(!(c[a+500>>2]|0))q=m;else q=(c[a+504>>2]|0)-l|0;if((((q|0)>(m|0)?m:q)|0)>0){r=(j|0)==0;s=(q|0)<(m|0)?q:m;q=0;do{if(!(!r?(c[j+(q<<2)>>2]|0)!=0:0))t=9;do if((t|0)==9){t=0;u=+g[d+(q<<2)>>2]<0.0;v=+td(+O(+(+g[e+(q<<2)>>2]/+g[f+(q<<2)>>2])));if(u){c[n+(q<<2)>>2]=~~-v;break}else{c[n+(q<<2)>>2]=~~v;break}}while(0);q=q+1|0}while((q|0)!=(s|0));w=s}else w=0;if((w|0)>=(m|0)){x=0.0;i=o;return +x}s=(j|0)!=0;q=b-l|0;v=0.0;l=0;b=w;while(1){if(s?(c[j+(b<<2)>>2]|0)!=0:0){y=v;z=l}else t=15;do if((t|0)==15){t=0;w=e+(b<<2)|0;r=f+(b<<2)|0;A=+g[w>>2]/+g[r>>2];if(!(A<.25)|s&(b|0)<(q|0)){u=+g[d+(b<<2)>>2]<0.0;B=+td(+O(+A));C=~~(u?-B:B);c[n+(b<<2)>>2]=C;B=+(_(C,C)|0);g[w>>2]=B*+g[r>>2];y=v;z=l;break}else{c[p+(l<<2)>>2]=w;y=A+v;z=l+1|0;break}}while(0);b=b+1|0;if((b|0)==(m|0)){D=y;E=z;break}else{v=y;l=z}}if(!E){x=D;i=o;return +x}rd(p,E,4,12);if((E|0)<=0){x=D;i=o;return +x}z=e;y=+h[a+512>>3];v=D;a=0;while(1){e=c[p+(a<<2)>>2]|0;l=e-z>>2;if(!(v>=y)){F=v;G=0;H=0.0}else{F=v+-1.0;G=~~(c[k>>2]=c[d+(l<<2)>>2]&-2147483648|1065353216,+g[k>>2]);H=+g[f+(l<<2)>>2]}c[n+(l<<2)>>2]=G;g[e>>2]=H;a=a+1|0;if((a|0)==(E|0)){x=F;break}else v=F}i=o;return +x}function Oc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var h=0,i=0,j=0.0,k=0.0,l=0.0,m=0.0,n=0.0,o=0.0,p=0,q=0,r=0.0,s=0.0,t=0.0,u=0.0,v=0.0,w=0.0,x=0.0,y=0.0,z=0.0,A=0.0,B=0.0,C=0.0,D=0.0,E=0.0,F=0.0,G=0.0,H=0.0,I=0.0,J=0.0,K=0.0,L=0.0,M=0,N=0,O=0,P=0,Q=0,R=0;h=c[a>>2]|0;i=c[a+((b+-1|0)*56|0)+4>>2]|0;if((b|0)>0){j=+g[f+1108>>2];k=0.0;f=0;l=0.0;m=0.0;n=0.0;o=0.0;while(1){p=c[a+(f*56|0)+52>>2]|0;q=c[a+(f*56|0)+28>>2]|0;r=+(q+p|0)*j/+(q+1|0)+1.0;s=+(c[a+(f*56|0)+32>>2]|0)+m+ +(c[a+(f*56|0)+8>>2]|0)*r;t=+(c[a+(f*56|0)+36>>2]|0)+o+ +(c[a+(f*56|0)+12>>2]|0)*r;u=+(c[a+(f*56|0)+40>>2]|0)+l+ +(c[a+(f*56|0)+16>>2]|0)*r;v=+(c[a+(f*56|0)+48>>2]|0)+n+ +(c[a+(f*56|0)+24>>2]|0)*r;w=+(p|0)+k+r*+(q|0);f=f+1|0;if((f|0)==(b|0)){x=w;y=u;z=s;A=v;B=t;break}else{k=w;l=u;m=s;n=v;o=t}}}else{x=0.0;y=0.0;z=0.0;A=0.0;B=0.0}b=c[d>>2]|0;if((b|0)>-1){C=x+1.0;D=y+ +(_(h,h)|0);E=z+ +(h|0);F=+(_(b,h)|0)+A;G=+(b|0)+B}else{C=x;D=y;E=z;F=A;G=B}b=c[e>>2]|0;if((b|0)>-1){H=C+1.0;I=D+ +(_(i,i)|0);J=E+ +(i|0);K=+(_(b,i)|0)+F;L=+(b|0)+G}else{H=C;I=D;J=E;K=F;L=G}G=I*H-J*J;if(!(G>0.0)){c[d>>2]=0;c[e>>2]=0;M=1;return M|0}F=(L*I-J*K)/G;I=(K*H-J*L)/G;c[d>>2]=~~+td(I*+(h|0)+F);h=~~+td(I*+(i|0)+F);c[e>>2]=h;i=c[d>>2]|0;if((i|0)>1023){c[d>>2]=1023;N=c[e>>2]|0;O=1023}else{N=h;O=i}if((N|0)>1023){c[e>>2]=1023;P=c[d>>2]|0;Q=1023}else{P=O;Q=N}if((P|0)<0){c[d>>2]=0;R=c[e>>2]|0}else R=Q;if((R|0)>=0){M=0;return M|0}c[e>>2]=0;M=0;return M|0}function Pc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0;g=i;h=c[b>>2]|0;j=c[h+8>>2]|0;k=b+16|0;l=c[c[k>>2]>>2]|0;m=c[a+36>>2]>>1;n=c[h+4>>2]|0;o=((n|0)<(m|0)?n:m)-(c[h>>2]|0)|0;if((o|0)<=0){i=g;return}m=(o|0)/(j|0)|0;o=i;i=i+((1*(e<<2)|0)+15&-16)|0;n=(e|0)>0;if(n){p=((l+-1+m|0)/(l|0)|0)<<2;q=0;do{c[o+(q<<2)>>2]=Ab(a,p)|0;q=q+1|0}while((q|0)!=(e|0))}q=b+8|0;if((c[q>>2]|0)<=0){i=g;return}p=(m|0)>0;r=a+4|0;a=h+16|0;s=b+28|0;t=(l|0)>0;u=b+20|0;b=n^1;v=0;a:while(1){if(p){w=1<<v;x=(v|0)!=0|b;y=0;z=0;while(1){if(!x){A=0;do{B=pc(c[k>>2]|0,r)|0;if((B|0)==-1){C=25;break a}if((B|0)>=(c[a>>2]|0)){C=25;break a}D=c[(c[s>>2]|0)+(B<<2)>>2]|0;c[(c[o+(A<<2)>>2]|0)+(z<<2)>>2]=D;A=A+1|0;if(!D){C=25;break a}}while((A|0)<(e|0))}b:do if(t&(y|0)<(m|0)){if(n){E=y;F=0}else{A=y;D=0;while(1){D=D+1|0;B=A+1|0;if(!((D|0)<(l|0)&(B|0)<(m|0))){G=B;break b}else A=B}}while(1){A=_(E,j)|0;D=0;do{B=(c[h>>2]|0)+A|0;H=c[(c[(c[o+(D<<2)>>2]|0)+(z<<2)>>2]|0)+(F<<2)>>2]|0;if(((c[h+24+(H<<2)>>2]&w|0)!=0?(I=c[(c[(c[u>>2]|0)+(H<<2)>>2]|0)+(v<<2)>>2]|0,(I|0)!=0):0)?(Va[f&7](I,(c[d+(D<<2)>>2]|0)+(B<<2)|0,r,j)|0)==-1:0){C=25;break a}D=D+1|0}while((D|0)<(e|0));F=F+1|0;D=E+1|0;if(!((F|0)<(l|0)&(D|0)<(m|0))){G=D;break}else E=D}}else G=y;while(0);if((G|0)<(m|0)){y=G;z=z+1|0}else break}}v=v+1|0;if((v|0)>=(c[q>>2]|0)){C=25;break}}if((C|0)==25){i=g;return}}function Qc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0;g=i;i=i+1088|0;h=g+1056|0;j=g+1024|0;k=g+512|0;l=g;m=c[b>>2]|0;n=c[m+8>>2]|0;o=c[m+12>>2]|0;p=b+16|0;q=c[c[p>>2]>>2]|0;r=((c[m+4>>2]|0)-(c[m>>2]|0)|0)/(n|0)|0;Fd(k|0,0,512)|0;Fd(l|0,0,512)|0;s=b+8|0;t=c[s>>2]|0;if((t|0)<=0){i=g;return}u=(r|0)>0;v=(e|0)>0;w=(q|0)>1;x=b+36|0;y=(q|0)>0;z=b+20|0;A=b+32|0;b=0-q|0;B=t;t=0;while(1){if(u){C=(t|0)==0;D=1<<t;E=C&v;F=0;while(1){a:do if(E){if(w)G=0;else{H=0;while(1){I=c[(c[f+(H<<2)>>2]|0)+(F<<2)>>2]|0;J=c[p>>2]|0;if((I|0)<(c[J+4>>2]|0)){K=oc(J,I,a)|0;c[x>>2]=(c[x>>2]|0)+K}H=H+1|0;if((H|0)==(e|0))break a}}do{H=c[f+(G<<2)>>2]|0;K=1;I=c[H+(F<<2)>>2]|0;while(1){J=_(I,o)|0;L=K+F|0;if((L|0)<(r|0))M=(c[H+(L<<2)>>2]|0)+J|0;else M=J;K=K+1|0;if((K|0)==(q|0)){N=M;break}else I=M}I=c[p>>2]|0;if((N|0)<(c[I+4>>2]|0)){K=oc(I,N,a)|0;c[x>>2]=(c[x>>2]|0)+K}G=G+1|0}while((G|0)!=(e|0))}while(0);if(y&(F|0)<(r|0)){K=F-r|0;I=K>>>0<b>>>0?b:K;K=0-I|0;H=F;J=0;while(1){L=_(H,n)|0;O=(c[m>>2]|0)+L|0;if(v){L=0;do{P=f+(L<<2)|0;Q=c[P>>2]|0;R=c[Q+(H<<2)>>2]|0;if(C){S=l+(R<<2)|0;c[S>>2]=(c[S>>2]|0)+n}if((c[m+24+(R<<2)>>2]&D|0)!=0?(S=c[(c[(c[z>>2]|0)+(R<<2)>>2]|0)+(t<<2)>>2]|0,(S|0)!=0):0){R=c[d+(L<<2)>>2]|0;T=c[S>>2]|0;U=(n|0)/(T|0)|0;if((U|0)>0){V=S+48|0;W=S+52|0;X=S+44|0;Y=S+12|0;Z=S+4|0;$=T;aa=0;ba=0;while(1){ca=(_(ba,T)|0)+O|0;da=R+(ca<<2)|0;ea=c[V>>2]|0;fa=c[W>>2]|0;ga=c[X>>2]|0;ha=ga>>1;c[h>>2]=0;c[h+4>>2]=0;c[h+8>>2]=0;c[h+12>>2]=0;c[h+16>>2]=0;c[h+20>>2]=0;c[h+24>>2]=0;c[h+28>>2]=0;ia=($|0)>0;do if((fa|0)==1){if(!ia){ja=0;break}ka=ga+-1|0;la=0;ma=0;na=$;while(1){na=na+-1|0;oa=c[R+(ca+na<<2)>>2]|0;pa=oa-ea|0;if((pa|0)<(ha|0))qa=(ha-pa<<1)+-1|0;else qa=pa-ha<<1;pa=_(ma,ga)|0;ra=((qa|0)<0?0:(qa|0)>=(ga|0)?ka:qa)+pa|0;c[h+(na<<2)>>2]=oa;la=la+1|0;if((la|0)==($|0)){ja=ra;break}else ma=ra}}else{if(!ia){ja=0;break}ma=(fa>>1)-ea|0;la=ga+-1|0;na=0;ka=0;ra=$;while(1){ra=ra+-1|0;oa=(ma+(c[R+(ca+ra<<2)>>2]|0)|0)/(fa|0)|0;if((oa|0)<(ha|0))sa=(ha-oa<<1)+-1|0;else sa=oa-ha<<1;pa=_(ka,ga)|0;ta=((sa|0)<0?0:(sa|0)>=(ga|0)?la:sa)+pa|0;c[h+(ra<<2)>>2]=(_(oa,fa)|0)+ea;na=na+1|0;if((na|0)==($|0)){ja=ta;break}else ka=ta}}while(0);ha=c[(c[Y>>2]|0)+8>>2]|0;do if((c[ha+(ja<<2)>>2]|0)<1){c[j>>2]=0;c[j+4>>2]=0;c[j+8>>2]=0;c[j+12>>2]=0;c[j+16>>2]=0;c[j+20>>2]=0;c[j+24>>2]=0;c[j+28>>2]=0;ka=(_(ga+-1|0,fa)|0)+ea|0;na=c[Z>>2]|0;if((na|0)>0){ua=-1;va=0;wa=ja}else{xa=ja;break}while(1){do if((c[ha+(va<<2)>>2]|0)>0){if(ia){ra=0;la=0;while(1){ma=(c[j+(ra<<2)>>2]|0)-(c[R+(ca+ra<<2)>>2]|0)|0;ta=(_(ma,ma)|0)+la|0;ra=ra+1|0;if((ra|0)==($|0)){ya=ta;break}else la=ta}}else ya=0;if(!((ua|0)==-1|(ya|0)<(ua|0))){za=ua;Aa=wa;break};c[h>>2]=c[j>>2];c[h+4>>2]=c[j+4>>2];c[h+8>>2]=c[j+8>>2];c[h+12>>2]=c[j+12>>2];c[h+16>>2]=c[j+16>>2];c[h+20>>2]=c[j+20>>2];c[h+24>>2]=c[j+24>>2];c[h+28>>2]=c[j+28>>2];za=ya;Aa=va}else{za=ua;Aa=wa}while(0);la=c[j>>2]|0;if((la|0)<(ka|0)){Ba=j;Ca=la}else{la=j;ra=0;while(1){ra=ra+1|0;c[la>>2]=0;ta=j+(ra<<2)|0;ma=c[ta>>2]|0;if((ma|0)<(ka|0)){Ba=ta;Ca=ma;break}else la=ta}}if((Ca|0)>-1){la=Ca+fa|0;c[Ba>>2]=la;Da=la}else Da=Ca;c[Ba>>2]=0-Da;va=va+1|0;if((va|0)==(na|0)){xa=Aa;break}else{ua=za;wa=Aa}}}else xa=ja;while(0);if(ia&(xa|0)>-1){fa=da;ca=0;while(1){c[fa>>2]=(c[fa>>2]|0)-(c[h+(ca<<2)>>2]|0);ca=ca+1|0;if((ca|0)==($|0))break;else fa=fa+4|0}}fa=(oc(S,xa,a)|0)+aa|0;ca=ba+1|0;if((ca|0)==(U|0)){Ea=fa;break}$=c[S>>2]|0;aa=fa;ba=ca}Fa=c[P>>2]|0;Ga=Ea}else{Fa=Q;Ga=0}c[A>>2]=(c[A>>2]|0)+Ga;ba=k+(c[Fa+(H<<2)>>2]<<2)|0;c[ba>>2]=(c[ba>>2]|0)+Ga}L=L+1|0}while((L|0)!=(e|0))}J=J+1|0;if((J|0)==(K|0))break;else H=H+1|0}Ha=F-I|0}else Ha=F;if((Ha|0)<(r|0))F=Ha;else break}Ia=c[s>>2]|0}else Ia=B;t=t+1|0;if((t|0)>=(Ia|0))break;else B=Ia}i=g;return}function Rc(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;e=c[b+40>>2]|0;f=ob(d,c[b+36>>2]|0)|0;do if((f|0)>-1){g=c[(c[b+32>>2]|0)+(f<<2)>>2]|0;if((g|0)<0){h=(c[b+8>>2]|0)-(g&32767)|0;i=g>>>15&32767;break}j=g+-1|0;pb(d,a[(c[b+28>>2]|0)+j>>0]|0);k=j;return k|0}else{h=c[b+8>>2]|0;i=0}while(0);f=ob(d,e)|0;j=(f|0)<0;if(j&(e|0)>1){g=e;while(1){l=g+-1|0;m=ob(d,l)|0;n=(m|0)<0;if(n&(l|0)>1)g=l;else{o=n;p=m;q=l;break}}}else{o=j;p=f;q=e}if(o){k=-1;return k|0}o=p>>>16|p<<16;p=o>>>8&16711935|o<<8&-16711936;o=p>>>4&252645135|p<<4&-252645136;p=o>>>2&858993459|o<<2&-858993460;o=p>>>1&1431655765|p<<1&-1431655766;p=h-i|0;if((p|0)>1){e=c[b+20>>2]|0;f=p;p=h;h=i;while(1){j=f>>1;g=(c[e+(j+h<<2)>>2]|0)>>>0>o>>>0;l=(g?0:j)+h|0;p=p-(g?j:0)|0;f=p-l|0;if((f|0)<=1){r=l;break}else h=l}}else r=i;i=a[(c[b+28>>2]|0)+r>>0]|0;if((i|0)>(q|0)){pb(d,q);k=-1;return k|0}else{pb(d,i);k=r;return k|0}return 0}function Sc(a,b){a=a|0;b=b|0;var d=0;d=c[c[a>>2]>>2]|0;a=c[c[b>>2]>>2]|0;return (d>>>0>a>>>0&1)-(d>>>0<a>>>0&1)|0}function Tc(a,b){a=a|0;b=b|0;var d=0.0,e=0.0;d=+g[c[a>>2]>>2];e=+g[c[b>>2]>>2];return (d<e&1)-(d>e&1)|0}function Uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;d=a+836|0;e=c[a+840>>2]|0;lb(b,c[a>>2]|0,5);if((c[a>>2]|0)>0){f=a+4|0;g=0;h=-1;while(1){i=f+(g<<2)|0;lb(b,c[i>>2]|0,4);j=c[i>>2]|0;i=(h|0)<(j|0)?j:h;g=g+1|0;if((g|0)>=(c[a>>2]|0)){k=i;break}else h=i}if((k|0)>-1){h=a+128|0;g=a+192|0;f=a+256|0;i=a+320|0;j=0;while(1){lb(b,(c[h+(j<<2)>>2]|0)+-1|0,3);l=g+(j<<2)|0;lb(b,c[l>>2]|0,2);if(!((c[l>>2]|0)!=0?(lb(b,c[f+(j<<2)>>2]|0,8),(c[l>>2]|0)==31):0)){m=0;n=8}if((n|0)==8)while(1){n=0;lb(b,(c[i+(j<<5)+(m<<2)>>2]|0)+1|0,8);m=m+1|0;if((m|0)>=(1<<c[l>>2]|0))break;else n=8}if((j|0)==(k|0))break;else j=j+1|0}}}lb(b,(c[a+832>>2]|0)+-1|0,2);j=e+-1|0;if((e|0)==0|(j|0)==0){lb(b,0,4);o=0}else{e=j;k=0;while(1){n=k+1|0;e=e>>>1;if(!e){p=n;break}else k=n}lb(b,p,4);p=j;j=0;while(1){k=j+1|0;p=p>>>1;if(!p){o=k;break}else j=k}}j=c[a>>2]|0;if((j|0)<=0)return;p=a+4|0;k=a+128|0;e=j;j=0;n=0;m=0;while(1){j=(c[k+(c[p+(n<<2)>>2]<<2)>>2]|0)+j|0;if((m|0)<(j|0)){i=m;do{lb(b,c[d+(i+2<<2)>>2]|0,o);i=i+1|0}while((i|0)!=(j|0));q=c[a>>2]|0;r=j}else{q=e;r=m}n=n+1|0;if((n|0)>=(q|0))break;else{e=q;m=r}}return}function Vc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;d=i;i=i+272|0;e=d;f=c[a+28>>2]|0;a=zd(1,1120)|0;g=qb(b,5)|0;c[a>>2]=g;a:do if((g|0)>0){h=a+4|0;j=0;k=-1;while(1){l=qb(b,4)|0;c[h+(j<<2)>>2]=l;if((l|0)<0)break a;m=(k|0)<(l|0)?l:k;j=j+1|0;if((j|0)>=(c[a>>2]|0)){n=m;break}else k=m}if((n|0)>-1){k=a+128|0;j=a+192|0;h=a+256|0;m=f+24|0;l=a+320|0;o=0;while(1){c[k+(o<<2)>>2]=(qb(b,3)|0)+1;p=qb(b,2)|0;q=j+(o<<2)|0;c[q>>2]=p;if((p|0)<0)break a;if(!p)r=c[h+(o<<2)>>2]|0;else{p=qb(b,8)|0;c[h+(o<<2)>>2]=p;r=p}if((r|0)<0)break a;if((r|0)>=(c[m>>2]|0))break a;if((c[q>>2]|0)!=31){p=0;do{s=qb(b,8)|0;c[l+(o<<5)+(p<<2)>>2]=s+-1;if((s|0)<0)break a;p=p+1|0;if((s|0)>(c[m>>2]|0))break a}while((p|0)<(1<<c[q>>2]|0))}if((o|0)<(n|0))o=o+1|0;else{t=18;break}}}else t=18}else t=18;while(0);b:do if((t|0)==18?(c[a+832>>2]=(qb(b,2)|0)+1,n=qb(b,4)|0,(n|0)>=0):0){r=c[a>>2]|0;if((r|0)>0){f=a+4|0;g=a+128|0;o=a+836|0;m=1<<n;l=r;r=0;h=0;j=0;while(1){k=(c[g+(c[f+(h<<2)>>2]<<2)>>2]|0)+r|0;if((k|0)>63)break b;if((j|0)<(k|0)){q=j;while(1){p=qb(b,n)|0;c[o+(q+2<<2)>>2]=p;if(!((p|0)>-1&(p|0)<(m|0)))break b;p=q+1|0;if((p|0)<(k|0))q=p;else{u=p;break}}v=c[a>>2]|0;w=u}else{v=l;w=j}h=h+1|0;if((h|0)>=(v|0)){x=o;y=m;z=k;break}else{l=v;r=k;j=w}}}else{x=a+836|0;y=1<<n;z=0}c[x>>2]=0;c[a+840>>2]=y;j=z+2|0;if((z|0)>-2){r=0;do{c[e+(r<<2)>>2]=x+(r<<2);r=r+1|0}while((r|0)<(j|0))}rd(e,j,4,13);c:do if((j|0)>1){r=c[c[e>>2]>>2]|0;n=1;while(1){l=r;r=c[c[e+(n<<2)>>2]>>2]|0;n=n+1|0;if((l|0)==(r|0))break;if((n|0)>=(j|0))break c}if(!a)A=0;else break b;i=d;return A|0}while(0);A=a;i=d;return A|0}while(0);yd(a);A=0;i=d;return A|0}function Wc(a,b){a=a|0;b=b|0;return (c[c[a>>2]>>2]|0)-(c[c[b>>2]>>2]|0)|0}function Xc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;a=i;i=i+272|0;d=a;e=zd(1,1312)|0;c[e+1296>>2]=b;f=b+836|0;g=e+1288|0;c[g>>2]=c[b+840>>2];h=c[b>>2]|0;if((h|0)>0){j=b+4|0;k=b+128|0;l=0;m=0;while(1){n=(c[k+(c[j+(l<<2)>>2]<<2)>>2]|0)+m|0;l=l+1|0;if((l|0)>=(h|0)){o=n;break}else m=n}m=o+2|0;c[e+1284>>2]=m;if((o|0)>-2){p=m;q=o;r=7}else{rd(d,m,4,13);s=o}}else{c[e+1284>>2]=2;p=2;q=0;r=7}if((r|0)==7){r=0;do{c[d+(r<<2)>>2]=f+(r<<2);r=r+1|0}while((r|0)<(p|0));rd(d,p,4,13);r=f;o=e+260|0;m=0;do{c[o+(m<<2)>>2]=(c[d+(m<<2)>>2]|0)-r>>2;m=m+1|0}while((m|0)<(p|0));m=e+260|0;r=e+520|0;d=0;do{c[r+(c[m+(d<<2)>>2]<<2)>>2]=d;d=d+1|0}while((d|0)<(p|0));d=e+260|0;m=0;do{c[e+(m<<2)>>2]=c[f+(c[d+(m<<2)>>2]<<2)>>2];m=m+1|0}while((m|0)<(p|0));s=q}q=c[b+832>>2]|0;if((q|0)==2)c[e+1292>>2]=128;else if((q|0)==1)c[e+1292>>2]=256;else if((q|0)==3)c[e+1292>>2]=86;else if((q|0)==4)c[e+1292>>2]=64;if((s|0)<=0){i=a;return e|0}q=e+1032|0;b=e+780|0;p=0;do{m=p+2|0;d=c[f+(m<<2)>>2]|0;r=1;o=c[g>>2]|0;h=0;l=0;j=0;while(1){k=c[f+(h<<2)>>2]|0;n=(k|0)>(j|0)&(k|0)<(d|0);t=n?h:l;u=(k|0)<(o|0)&(k|0)>(d|0);v=u?h:r;h=h+1|0;if((h|0)>=(m|0)){w=v;x=t;break}else{r=v;o=u?k:o;l=t;j=n?k:j}}c[q+(p<<2)>>2]=x;c[b+(p<<2)>>2]=w;p=p+1|0}while((p|0)!=(s|0));i=a;return e|0}function Yc(a){a=a|0;if(a)yd(a);return}function Zc(a){a=a|0;if(a)yd(a);return}function _c(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;d=c[b+1296>>2]|0;e=c[(c[(c[(c[a+64>>2]|0)+4>>2]|0)+28>>2]|0)+2848>>2]|0;f=a+4|0;if((qb(f,1)|0)!=1){g=0;return g|0}h=b+1284|0;i=Ab(a,c[h>>2]<<2)|0;a=b+1292|0;j=(c[a>>2]|0)+-1|0;if(!j)k=0;else{l=j;j=0;while(1){m=j+1|0;l=l>>>1;if(!l){k=m;break}else j=m}}c[i>>2]=qb(f,k)|0;k=(c[a>>2]|0)+-1|0;if(!k)n=0;else{j=k;k=0;while(1){l=k+1|0;j=j>>>1;if(!j){n=l;break}else k=l}}c[i+4>>2]=qb(f,n)|0;a:do if((c[d>>2]|0)>0){n=0;k=2;b:while(1){j=c[d+4+(n<<2)>>2]|0;l=c[d+128+(j<<2)>>2]|0;m=c[d+192+(j<<2)>>2]|0;o=1<<m;if(m){p=pc(e+((c[d+256+(j<<2)>>2]|0)*56|0)|0,f)|0;if((p|0)==-1){g=0;q=29;break}else r=p}else r=0;if((l|0)>0){p=o+-1|0;o=r;s=0;do{t=c[d+320+(j<<5)+((o&p)<<2)>>2]|0;o=o>>m;if((t|0)>-1){u=pc(e+(t*56|0)|0,f)|0;c[i+(s+k<<2)>>2]=u;if((u|0)==-1){g=0;q=29;break b}}else c[i+(s+k<<2)>>2]=0;s=s+1|0}while((s|0)<(l|0))}n=n+1|0;if((n|0)>=(c[d>>2]|0))break a;else k=l+k|0}if((q|0)==29)return g|0}while(0);if((c[h>>2]|0)<=2){g=i;return g|0}q=b+1032|0;f=b+780|0;b=2;do{e=b+-2|0;r=q+(e<<2)|0;k=c[r>>2]|0;n=c[d+836+(k<<2)>>2]|0;s=f+(e<<2)|0;e=c[s>>2]|0;m=c[i+(k<<2)>>2]&32767;k=(c[i+(e<<2)>>2]&32767)-m|0;o=(_((k|0)>-1?k:0-k|0,(c[d+836+(b<<2)>>2]|0)-n|0)|0)/((c[d+836+(e<<2)>>2]|0)-n|0)|0;n=((k|0)<0?0-o|0:o)+m|0;m=(c[a>>2]|0)-n|0;o=i+(b<<2)|0;k=c[o>>2]|0;if(!k)c[o>>2]=n|32768;else{do if((k|0)<(((m|0)<(n|0)?m:n)<<1|0))if(!(k&1)){v=k>>1;break}else{v=0-(k+1>>1)|0;break}else if((m|0)>(n|0)){v=k-n|0;break}else{v=~(k-m);break}while(0);c[o>>2]=v+n&32767;m=i+(c[r>>2]<<2)|0;c[m>>2]=c[m>>2]&32767;m=i+(c[s>>2]<<2)|0;c[m>>2]=c[m>>2]&32767}b=b+1|0}while((b|0)<(c[h>>2]|0));g=i;return g|0}function $c(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0.0;f=c[b+1296>>2]|0;h=(c[(c[(c[(c[a+64>>2]|0)+4>>2]|0)+28>>2]|0)+(c[a+28>>2]<<2)>>2]|0)/2|0;if(!d){Fd(e|0,0,h<<2|0)|0;i=0;return i|0}a=c[f+832>>2]|0;j=_(a,c[d>>2]|0)|0;k=(j|0)<0?0:(j|0)>255?255:j;j=c[b+1284>>2]|0;if((j|0)>1){l=b+260|0;b=0;m=1;n=0;o=k;while(1){p=c[l+(m<<2)>>2]|0;q=c[d+(p<<2)>>2]|0;if((q&32767|0)==(q|0)){r=c[f+836+(p<<2)>>2]|0;p=_(a,q)|0;q=(p|0)<0?0:(p|0)>255?255:p;p=q-o|0;s=r-n|0;t=(p|0)/(s|0)|0;u=p>>31|1;v=_(t,s)|0;w=((p|0)>-1?p:0-p|0)-((v|0)>-1?v:0-v|0)|0;v=(h|0)>(r|0)?r:h;if((v|0)>(n|0)){p=e+(n<<2)|0;g[p>>2]=+g[p>>2]*+g[56400+(o<<2)>>2]}p=n+1|0;if((p|0)<(v|0)){x=p;p=0;y=o;while(1){z=p+w|0;A=(z|0)<(s|0);y=y+t+(A?0:u)|0;B=e+(x<<2)|0;g[B>>2]=+g[B>>2]*+g[56400+(y<<2)>>2];x=x+1|0;if((x|0)==(v|0)){C=r;D=r;E=q;break}else p=z-(A?0:s)|0}}else{C=r;D=r;E=q}}else{C=b;D=n;E=o}m=m+1|0;if((m|0)>=(j|0)){F=C;G=E;break}else{b=C;n=D;o=E}}}else{F=0;G=k}if((F|0)>=(h|0)){i=1;return i|0}H=+g[56400+(G<<2)>>2];G=F;do{F=e+(G<<2)|0;g[F>>2]=+g[F>>2]*H;G=G+1|0}while((G|0)!=(h|0));i=1;return i|0}function ad(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;d=c[a+28>>2]|0;a=xd(96)|0;e=qb(b,8)|0;c[a>>2]=e;f=qb(b,16)|0;c[a+4>>2]=f;g=qb(b,16)|0;c[a+8>>2]=g;c[a+12>>2]=qb(b,6)|0;c[a+16>>2]=qb(b,8)|0;h=qb(b,4)|0;i=a+20|0;c[i>>2]=h+1;a:do if((e|0)<1){if(!a){j=0;return j|0}}else if((f|0)>=1?!((h|0)<0|(g|0)<1):0){if((h|0)<=-1){j=a;return j|0}k=a+24|0;l=d+24|0;m=0;while(1){n=qb(b,8)|0;c[k+(m<<2)>>2]=n;if((n|0)<0)break a;if((n|0)>=(c[l>>2]|0))break a;o=c[d+1824+(n<<2)>>2]|0;if(!(c[o+12>>2]|0))break a;m=m+1|0;if((c[o>>2]|0)<1)break a;if((m|0)>=(c[i>>2]|0)){j=a;break}}return j|0}while(0);yd(a);j=0;return j|0}function bd(a,b){a=a|0;b=b|0;a=zd(1,32)|0;c[a+4>>2]=c[b>>2];c[a>>2]=c[b+8>>2];c[a+20>>2]=b;c[a+8>>2]=zd(2,4)|0;return a|0}function cd(a){a=a|0;if(a)yd(a);return}function dd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0;if(!a)return;b=a+8|0;d=c[b>>2]|0;if(d){e=c[d>>2]|0;if(!e)f=d;else{yd(e);f=c[b>>2]|0}e=c[f+4>>2]|0;if(!e)g=f;else{yd(e);g=c[b>>2]|0}yd(g)}yd(a);return}function ed(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,i=0,j=0.0,k=0.0,l=0,m=0,n=0;d=c[b+20>>2]|0;e=a+4|0;f=d+12|0;h=qb(e,c[f>>2]|0)|0;if((h|0)<=0){i=0;return i|0}j=+(c[d+16>>2]|0)*(+(h|0)/+((1<<c[f>>2])+-1|0));f=d+20|0;h=qb(e,uc(c[f>>2]|0)|0)|0;if((h|0)==-1){i=0;return i|0}if((h|0)>=(c[f>>2]|0)){i=0;return i|0}f=(c[(c[(c[(c[a+64>>2]|0)+4>>2]|0)+28>>2]|0)+2848>>2]|0)+((c[d+24+(h<<2)>>2]|0)*56|0)|0;h=b+4|0;b=Ab(a,((c[f>>2]|0)+(c[h>>2]|0)<<2)+4|0)|0;if((sc(f,b,e,c[h>>2]|0)|0)==-1){i=0;return i|0}e=c[h>>2]|0;if((e|0)>0){h=0;k=0.0;while(1){a:do if((h|0)<(e|0)){a=c[f>>2]|0;d=h;l=0;while(1){if((l|0)>=(a|0)){m=d;break a}n=b+(d<<2)|0;g[n>>2]=+g[n>>2]+k;n=d+1|0;if((n|0)<(e|0)){d=n;l=l+1|0}else{m=n;break}}}else m=h;while(0);if((m|0)<(e|0)){h=m;k=+g[b+(m+-1<<2)>>2]}else break}}g[b+(e<<2)>>2]=j;i=b;return i|0}function fd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,h=0,i=0,j=0,k=0,l=0,m=0.0,n=0.0,o=0.0,p=0,q=0,r=0,s=0;f=c[b+20>>2]|0;h=c[a+28>>2]|0;i=b+8|0;j=(c[i>>2]|0)+(h<<2)|0;if(!(c[j>>2]|0)){k=c[(c[(c[(c[a+64>>2]|0)+4>>2]|0)+28>>2]|0)+(h<<2)>>2]|0;a=(k|0)/2|0;l=c[b>>2]|0;m=+(c[f+4>>2]|0);c[j>>2]=xd((a<<2)+4|0)|0;if((k|0)>1){n=m*.5/+(a|0);o=+(l|0)/(+V(+(m*m*4.624999938585006e-09))*2.240000009536743+m*4.999999873689376e-05+ +V(+(m*3.699999942909926e-04))*13.100000381469727);k=c[(c[i>>2]|0)+(h<<2)>>2]|0;j=l;l=0;while(1){m=+(l|0)*n;p=~~+M(+((+V(+(m*m*1.8499999754340024e-08))*2.240000009536743+ +V(+(m*7.399999885819852e-04))*13.100000381469727+m*9.999999747378752e-05)*o));c[k+(l<<2)>>2]=(p|0)<(j|0)?p:j+-1|0;p=l+1|0;if((p|0)>=(a|0))break;j=c[b>>2]|0;l=p}q=k;r=(a|0)>1?a:1}else{q=c[(c[i>>2]|0)+(h<<2)>>2]|0;r=0}c[q+(r<<2)>>2]=-1;c[b+12+(h<<2)>>2]=a}if(!d){Fd(e|0,0,c[b+12+(h<<2)>>2]<<2|0)|0;s=0;return s|0}else{a=c[b+4>>2]|0;Lb(e,c[(c[i>>2]|0)+(h<<2)>>2]|0,c[b+12+(h<<2)>>2]|0,c[b>>2]|0,d,a,+g[d+(a<<2)>>2],+(c[f+16>>2]|0));s=1;return s|0}return 0} +function gd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;if((c[b>>2]|0)>1){lb(d,1,1);lb(d,(c[b>>2]|0)+-1|0,4)}else lb(d,0,1);e=b+1156|0;if((c[e>>2]|0)>0){lb(d,1,1);lb(d,(c[e>>2]|0)+-1|0,8);if((c[e>>2]|0)>0){f=b+1160|0;g=a+4|0;h=b+2184|0;i=0;do{j=c[f+(i<<2)>>2]|0;k=c[g>>2]|0;l=k+-1|0;if((k|0)==0|(l|0)==0)m=0;else{k=l;l=0;while(1){n=l+1|0;k=k>>>1;if(!k){m=n;break}else l=n}}lb(d,j,m);l=c[h+(i<<2)>>2]|0;k=c[g>>2]|0;n=k+-1|0;if((k|0)==0|(n|0)==0)o=0;else{k=n;n=0;while(1){p=n+1|0;k=k>>>1;if(!k){o=p;break}else n=p}}lb(d,l,o);i=i+1|0}while((i|0)<(c[e>>2]|0))}}else lb(d,0,1);lb(d,0,2);e=c[b>>2]|0;if((e|0)>1){i=a+4|0;if((c[i>>2]|0)>0){a=b+4|0;o=0;do{lb(d,c[a+(o<<2)>>2]|0,4);o=o+1|0}while((o|0)<(c[i>>2]|0));q=c[b>>2]|0;r=17}}else{q=e;r=17}if((r|0)==17?(q|0)<=0:0)return;q=b+1028|0;r=b+1092|0;e=0;do{lb(d,0,8);lb(d,c[q+(e<<2)>>2]|0,8);lb(d,c[r+(e<<2)>>2]|0,8);e=e+1|0}while((e|0)<(c[b>>2]|0));return}function hd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;d=zd(1,3208)|0;e=c[a+28>>2]|0;Fd(d|0,0,3208)|0;f=qb(b,1)|0;a:do if((f|0)<0){if(!d){g=0;return g|0}}else{if(f){h=qb(b,4)|0;c[d>>2]=h+1;if((h|0)<0)break}else c[d>>2]=1;h=qb(b,1)|0;if((h|0)>=0){if(h){h=qb(b,8)|0;i=d+1156|0;c[i>>2]=h+1;if((h|0)<0)break;h=a+4|0;j=d+1160|0;k=d+2184|0;l=c[h>>2]|0;m=0;do{n=l+-1|0;if((l|0)==0|(n|0)==0)o=0;else{p=n;n=0;while(1){q=n+1|0;p=p>>>1;if(!p){o=q;break}else n=q}}n=qb(b,o)|0;c[j+(m<<2)>>2]=n;p=c[h>>2]|0;q=p+-1|0;if((p|0)==0|(q|0)==0)r=0;else{p=q;q=0;while(1){s=q+1|0;p=p>>>1;if(!p){r=s;break}else q=s}}q=qb(b,r)|0;c[k+(m<<2)>>2]=q;if((n|0)==(q|0)|(q|n|0)<0)break a;l=c[h>>2]|0;m=m+1|0;if(!((n|0)<(l|0)&(q|0)<(l|0)))break a}while((m|0)<(c[i>>2]|0))}if(!(qb(b,2)|0)){i=c[d>>2]|0;if((i|0)>1){m=a+4|0;if((c[m>>2]|0)>0){l=d+4|0;h=0;while(1){k=qb(b,4)|0;c[l+(h<<2)>>2]=k;j=c[d>>2]|0;h=h+1|0;if((k|0)<0|(k|0)>=(j|0))break a;if((h|0)>=(c[m>>2]|0)){t=j;u=20;break}}}}else{t=i;u=20}if((u|0)==20?(t|0)<=0:0){g=d;return g|0}m=d+1028|0;h=e+16|0;l=d+1092|0;j=e+20|0;k=0;while(1){qb(b,8)|0;q=qb(b,8)|0;c[m+(k<<2)>>2]=q;if((q|0)<0?1:(q|0)>=(c[h>>2]|0))break a;q=qb(b,8)|0;c[l+(k<<2)>>2]=q;k=k+1|0;if((q|0)<0?1:(q|0)>=(c[j>>2]|0))break a;if((k|0)>=(c[d>>2]|0)){g=d;break}}return g|0}}}while(0);yd(d);g=0;return g|0}function id(a){a=a|0;if(a)yd(a);return}function jd(a){a=a|0;var b=0,d=0,e=0,f=0,h=0,j=0,l=0,m=0,n=0,o=0,p=0,q=0.0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0.0,A=0,B=0,C=0,D=0.0,E=0,F=0,G=0.0,H=0,I=0,J=0,K=0.0,L=0.0,M=0,N=0.0,O=0,P=0.0,Q=0.0,R=0.0,S=0.0,T=0.0,U=0,V=0,W=0.0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0;b=i;d=c[a+64>>2]|0;e=c[d+4>>2]|0;f=c[e+28>>2]|0;h=c[d+104>>2]|0;d=c[a+104>>2]|0;j=c[a+36>>2]|0;l=e+4|0;e=c[l>>2]<<2;m=i;i=i+((1*e|0)+15&-16)|0;n=Ab(a,e)|0;e=Ab(a,c[l>>2]<<2)|0;o=Ab(a,c[l>>2]<<2)|0;p=d+4|0;q=+g[p>>2];r=c[l>>2]|0;s=i;i=i+((1*(r<<2)|0)+15&-16)|0;t=a+28|0;u=c[t>>2]|0;v=c[f+544+(u<<2)>>2]|0;w=(c[h+56>>2]|0)+((((u|0)!=0?2:0)+(c[d+8>>2]|0)|0)*52|0)|0;x=a+40|0;c[x>>2]=u;if((r|0)>0){r=(j|0)/2|0;y=r<<2;z=+(((g[k>>2]=4.0/+(j|0),c[k>>2]|0)&2147483647)>>>0)*7.177114298428933e-07+-764.6162109375+.345;A=h+4|0;B=a+24|0;C=a+32|0;D=z+-764.6162109375;E=j+-1|0;F=(E|0)>1;G=z+-382.30810546875;z=q;H=0;while(1){I=c[(c[a>>2]|0)+(H<<2)>>2]|0;c[e+(H<<2)>>2]=Ab(a,y)|0;J=n+(H<<2)|0;c[J>>2]=Ab(a,y)|0;Kb(I,A,f,c[B>>2]|0,c[t>>2]|0,c[C>>2]|0);vb(c[c[h+12+(c[t>>2]<<2)>>2]>>2]|0,I,c[J>>2]|0);wb(h+20+((c[t>>2]|0)*12|0)|0,I);K=D+ +((c[I>>2]&2147483647)>>>0)*7.177114298428933e-07+.345;g[I>>2]=K;J=s+(H<<2)|0;g[J>>2]=K;if(F){L=K;M=1;while(1){N=+g[I+(M<<2)>>2];O=M+1|0;P=+g[I+(O<<2)>>2];Q=G+ +(((g[k>>2]=P*P+N*N,c[k>>2]|0)&2147483647)>>>0)*3.5885571492144663e-07+.345;g[I+(O>>1<<2)>>2]=Q;if(Q>L){g[J>>2]=Q;R=Q}else R=L;M=M+2|0;if((M|0)>=(E|0)){S=R;break}else L=R}}else S=K;if(S>0.0){g[J>>2]=0.0;T=0.0}else T=S;L=T>z?T:z;H=H+1|0;if((H|0)>=(c[l>>2]|0)){U=y;V=r;W=L;break}else z=L}}else{r=(j|0)/2|0;U=r<<2;V=r;W=q}r=Ab(a,U)|0;y=Ab(a,U)|0;U=c[l>>2]|0;a:do if((U|0)>0){H=h+48|0;if((j|0)>1)X=0;else{E=0;while(1){F=c[v+4+(E<<2)>>2]|0;C=c[n+(E<<2)>>2]|0;B=c[(c[a>>2]|0)+(E<<2)>>2]|0;A=B+(V<<2)|0;c[x>>2]=u;M=Ab(a,60)|0;I=o+(E<<2)|0;c[I>>2]=M;Y=M;Z=Y+60|0;do{c[Y>>2]=0;Y=Y+4|0}while((Y|0)<(Z|0));Rb(w,A,r);Sb(w,B,y,W,+g[s+(E<<2)>>2]);Tb(w,r,y,1,B,C,A);M=v+1028+(F<<2)|0;O=c[M>>2]|0;if((c[f+800+(O<<2)>>2]|0)!=1){_=-1;break}$=_b(a,c[(c[H>>2]|0)+(O<<2)>>2]|0,A,B)|0;c[(c[I>>2]|0)+28>>2]=$;if((Dc(a)|0)!=0?(c[(c[I>>2]|0)+28>>2]|0)!=0:0){Tb(w,r,y,2,B,C,A);$=_b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,A,B)|0;c[(c[I>>2]|0)+56>>2]=$;Tb(w,r,y,0,B,C,A);$=_b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,A,B)|0;c[c[I>>2]>>2]=$;$=c[I>>2]|0;O=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[$>>2]|0,c[$+28>>2]|0,9362)|0;c[(c[I>>2]|0)+4>>2]=O;O=c[I>>2]|0;$=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[O>>2]|0,c[O+28>>2]|0,18724)|0;c[(c[I>>2]|0)+8>>2]=$;$=c[I>>2]|0;O=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[$>>2]|0,c[$+28>>2]|0,28086)|0;c[(c[I>>2]|0)+12>>2]=O;O=c[I>>2]|0;$=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[O>>2]|0,c[O+28>>2]|0,37449)|0;c[(c[I>>2]|0)+16>>2]=$;$=c[I>>2]|0;O=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[$>>2]|0,c[$+28>>2]|0,46811)|0;c[(c[I>>2]|0)+20>>2]=O;O=c[I>>2]|0;$=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[O>>2]|0,c[O+28>>2]|0,56173)|0;c[(c[I>>2]|0)+24>>2]=$;$=c[I>>2]|0;O=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[$+28>>2]|0,c[$+56>>2]|0,9362)|0;c[(c[I>>2]|0)+32>>2]=O;O=c[I>>2]|0;$=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[O+28>>2]|0,c[O+56>>2]|0,18724)|0;c[(c[I>>2]|0)+36>>2]=$;$=c[I>>2]|0;O=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[$+28>>2]|0,c[$+56>>2]|0,28086)|0;c[(c[I>>2]|0)+40>>2]=O;O=c[I>>2]|0;$=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[O+28>>2]|0,c[O+56>>2]|0,37449)|0;c[(c[I>>2]|0)+44>>2]=$;$=c[I>>2]|0;O=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[$+28>>2]|0,c[$+56>>2]|0,46811)|0;c[(c[I>>2]|0)+48>>2]=O;O=c[I>>2]|0;$=$b(a,c[(c[H>>2]|0)+(c[M>>2]<<2)>>2]|0,c[O+28>>2]|0,c[O+56>>2]|0,56173)|0;c[(c[I>>2]|0)+52>>2]=$}E=E+1|0;$=c[l>>2]|0;if((E|0)>=($|0)){aa=H;ba=$;break a}}i=b;return _|0}while(1){E=c[v+4+(X<<2)>>2]|0;J=c[n+(X<<2)>>2]|0;$=c[(c[a>>2]|0)+(X<<2)>>2]|0;O=$+(V<<2)|0;c[x>>2]=u;M=Ab(a,60)|0;ca=o+(X<<2)|0;c[ca>>2]=M;Y=M;Z=Y+60|0;do{c[Y>>2]=0;Y=Y+4|0}while((Y|0)<(Z|0));I=0;do{g[$+(I+V<<2)>>2]=+((c[J+(I<<2)>>2]&2147483647)>>>0)*7.177114298428933e-07+-764.6162109375+.345;I=I+1|0}while((I|0)<(V|0));Rb(w,O,r);Sb(w,$,y,W,+g[s+(X<<2)>>2]);Tb(w,r,y,1,$,J,O);I=v+1028+(E<<2)|0;B=c[I>>2]|0;if((c[f+800+(B<<2)>>2]|0)!=1){_=-1;break}A=_b(a,c[(c[H>>2]|0)+(B<<2)>>2]|0,O,$)|0;c[(c[ca>>2]|0)+28>>2]=A;if((Dc(a)|0)!=0?(c[(c[ca>>2]|0)+28>>2]|0)!=0:0){Tb(w,r,y,2,$,J,O);A=_b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,O,$)|0;c[(c[ca>>2]|0)+56>>2]=A;Tb(w,r,y,0,$,J,O);A=_b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,O,$)|0;c[c[ca>>2]>>2]=A;A=c[ca>>2]|0;B=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[A>>2]|0,c[A+28>>2]|0,9362)|0;c[(c[ca>>2]|0)+4>>2]=B;B=c[ca>>2]|0;A=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[B>>2]|0,c[B+28>>2]|0,18724)|0;c[(c[ca>>2]|0)+8>>2]=A;A=c[ca>>2]|0;B=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[A>>2]|0,c[A+28>>2]|0,28086)|0;c[(c[ca>>2]|0)+12>>2]=B;B=c[ca>>2]|0;A=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[B>>2]|0,c[B+28>>2]|0,37449)|0;c[(c[ca>>2]|0)+16>>2]=A;A=c[ca>>2]|0;B=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[A>>2]|0,c[A+28>>2]|0,46811)|0;c[(c[ca>>2]|0)+20>>2]=B;B=c[ca>>2]|0;A=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[B>>2]|0,c[B+28>>2]|0,56173)|0;c[(c[ca>>2]|0)+24>>2]=A;A=c[ca>>2]|0;B=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[A+28>>2]|0,c[A+56>>2]|0,9362)|0;c[(c[ca>>2]|0)+32>>2]=B;B=c[ca>>2]|0;A=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[B+28>>2]|0,c[B+56>>2]|0,18724)|0;c[(c[ca>>2]|0)+36>>2]=A;A=c[ca>>2]|0;B=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[A+28>>2]|0,c[A+56>>2]|0,28086)|0;c[(c[ca>>2]|0)+40>>2]=B;B=c[ca>>2]|0;A=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[B+28>>2]|0,c[B+56>>2]|0,37449)|0;c[(c[ca>>2]|0)+44>>2]=A;A=c[ca>>2]|0;B=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[A+28>>2]|0,c[A+56>>2]|0,46811)|0;c[(c[ca>>2]|0)+48>>2]=B;B=c[ca>>2]|0;A=$b(a,c[(c[H>>2]|0)+(c[I>>2]<<2)>>2]|0,c[B+28>>2]|0,c[B+56>>2]|0,56173)|0;c[(c[ca>>2]|0)+52>>2]=A}X=X+1|0;A=c[l>>2]|0;if((X|0)>=(A|0)){aa=H;ba=A;break a}}i=b;return _|0}else{aa=h+48|0;ba=U}while(0);g[p>>2]=W;p=ba<<2;ba=i;i=i+((1*p|0)+15&-16)|0;U=i;i=i+((1*p|0)+15&-16)|0;p=(Dc(a)|0)!=0;X=h+44|0;y=a+24|0;r=a+32|0;s=f+2868|0;V=h+52|0;h=p?0:7;while(1){p=c[d+12+(h<<2)>>2]|0;lb(p,0,1);lb(p,u,c[X>>2]|0);if(c[t>>2]|0){lb(p,c[y>>2]|0,1);lb(p,c[r>>2]|0,1)}Y=c[l>>2]|0;if((Y|0)>0){Z=0;do{c[m+(Z<<2)>>2]=ac(p,a,c[(c[aa>>2]|0)+(c[v+1028+(c[v+4+(Z<<2)>>2]<<2)>>2]<<2)>>2]|0,c[(c[o+(Z<<2)>>2]|0)+(h<<2)>>2]|0,c[e+(Z<<2)>>2]|0)|0;Z=Z+1|0;x=c[l>>2]|0}while((Z|0)<(x|0));da=x}else da=Y;Ub(h,s,w,v,n,e,m,c[f+3240+((c[t>>2]|0)*60|0)+(h<<2)>>2]|0,da);if((c[v>>2]|0)>0){Z=0;do{x=c[v+1092+(Z<<2)>>2]|0;j=c[l>>2]|0;if((j|0)>0){H=j;j=0;A=0;while(1){if((c[v+4+(A<<2)>>2]|0)==(Z|0)){c[U+(j<<2)>>2]=(c[m+(A<<2)>>2]|0)!=0&1;c[ba+(j<<2)>>2]=c[e+(A<<2)>>2];ea=c[l>>2]|0;fa=j+1|0}else{ea=H;fa=j}A=A+1|0;if((A|0)>=(ea|0)){ga=fa;break}else{H=ea;j=fa}}}else ga=0;j=f+1312+(x<<2)|0;H=ab[c[(c[336+(c[j>>2]<<2)>>2]|0)+20>>2]&7](a,c[(c[V>>2]|0)+(x<<2)>>2]|0,ba,U,ga)|0;A=c[l>>2]|0;if((A|0)>0){ca=0;$=0;while(1){if((c[v+4+($<<2)>>2]|0)==(Z|0)){c[ba+(ca<<2)>>2]=c[e+($<<2)>>2];ha=ca+1|0}else ha=ca;$=$+1|0;if(($|0)>=(A|0)){ia=ha;break}else ca=ha}}else ia=0;_a[c[(c[336+(c[j>>2]<<2)>>2]|0)+24>>2]&3](p,a,c[(c[V>>2]|0)+(x<<2)>>2]|0,ba,U,ia,H,Z)|0;Z=Z+1|0}while((Z|0)<(c[v>>2]|0))}Z=(Dc(a)|0)!=0;if((h|0)<((Z?14:7)|0))h=h+1|0;else{_=0;break}}i=b;return _|0}function kd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0.0,E=0.0,F=0;d=i;e=c[a+64>>2]|0;f=c[e+4>>2]|0;h=c[f+28>>2]|0;j=c[e+104>>2]|0;e=a+28|0;k=c[h+(c[e>>2]<<2)>>2]|0;c[a+36>>2]=k;l=f+4|0;f=c[l>>2]<<2;m=i;i=i+((1*f|0)+15&-16)|0;n=i;i=i+((1*f|0)+15&-16)|0;o=i;i=i+((1*f|0)+15&-16)|0;p=i;i=i+((1*f|0)+15&-16)|0;f=c[l>>2]|0;if((f|0)>0){q=b+4|0;r=b+1028|0;s=j+48|0;t=k<<1&2147483646;u=0;do{v=c[r+(c[q+(u<<2)>>2]<<2)>>2]|0;w=$a[c[(c[328+(c[h+800+(v<<2)>>2]<<2)>>2]|0)+20>>2]&15](a,c[(c[s>>2]|0)+(v<<2)>>2]|0)|0;c[p+(u<<2)>>2]=w;c[o+(u<<2)>>2]=(w|0)!=0&1;Fd(c[(c[a>>2]|0)+(u<<2)>>2]|0,0,t|0)|0;u=u+1|0;w=c[l>>2]|0}while((u|0)<(w|0));x=w}else x=f;f=b+1156|0;u=c[f>>2]|0;if((u|0)>0){t=b+1160|0;s=b+2184|0;q=0;do{r=o+(c[t+(q<<2)>>2]<<2)|0;w=c[s+(q<<2)>>2]|0;if(!((c[r>>2]|0)==0?(c[o+(w<<2)>>2]|0)==0:0)){c[r>>2]=1;c[o+(w<<2)>>2]=1}q=q+1|0}while((q|0)<(u|0))}if((c[b>>2]|0)>0){q=b+1092|0;s=j+52|0;t=b+4|0;w=x;x=0;while(1){if((w|0)>0){r=w;v=0;y=0;while(1){if((c[t+(y<<2)>>2]|0)==(x|0)){c[n+(v<<2)>>2]=(c[o+(y<<2)>>2]|0)!=0&1;c[m+(v<<2)>>2]=c[(c[a>>2]|0)+(y<<2)>>2];z=c[l>>2]|0;A=v+1|0}else{z=r;A=v}y=y+1|0;if((y|0)>=(z|0)){B=A;break}else{r=z;v=A}}}else B=0;v=c[q+(x<<2)>>2]|0;ab[c[(c[336+(c[h+1312+(v<<2)>>2]<<2)>>2]|0)+28>>2]&7](a,c[(c[s>>2]|0)+(v<<2)>>2]|0,m,n,B)|0;v=x+1|0;if((v|0)>=(c[b>>2]|0))break;w=c[l>>2]|0;x=v}C=c[f>>2]|0}else C=u;if((C|0)>0){u=b+1160|0;f=c[a>>2]|0;x=b+2184|0;w=(k|0)/2|0;B=(k|0)>1;k=C;do{C=k;k=k+-1|0;n=c[f+(c[u+(k<<2)>>2]<<2)>>2]|0;m=c[f+(c[x+(k<<2)>>2]<<2)>>2]|0;if(B){s=0;do{q=n+(s<<2)|0;D=+g[q>>2];A=m+(s<<2)|0;E=+g[A>>2];z=E>0.0;do if(D>0.0)if(z){g[q>>2]=D;g[A>>2]=D-E;break}else{g[A>>2]=D;g[q>>2]=E+D;break}else if(z){g[q>>2]=D;g[A>>2]=E+D;break}else{g[A>>2]=D;g[q>>2]=D-E;break}while(0);s=s+1|0}while((s|0)<(w|0))}}while((C|0)>1)}if((c[l>>2]|0)<=0){i=d;return 0}w=b+4|0;B=b+1028|0;b=j+48|0;k=0;do{x=c[B+(c[w+(k<<2)>>2]<<2)>>2]|0;Va[c[(c[328+(c[h+800+(x<<2)>>2]<<2)>>2]|0)+24>>2]&7](a,c[(c[b>>2]|0)+(x<<2)>>2]|0,c[p+(k<<2)>>2]|0,c[(c[a>>2]|0)+(k<<2)>>2]|0)|0;k=k+1|0;x=c[l>>2]|0}while((k|0)<(x|0));F=x;if((F|0)<=0){i=d;return 0}F=0;do{k=c[(c[a>>2]|0)+(F<<2)>>2]|0;ub(c[c[j+12+(c[e>>2]<<2)>>2]>>2]|0,k,k);F=F+1|0}while((F|0)<(c[l>>2]|0));i=d;return 0}function ld(){Xb(57432);Vb(57464);return}function md(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+32|0;e=d;pd(e,a,b);if(!(c[14356]|0))c[e+8>>2]=1;if(Zb(57432,57464,e)|0){Da(57704)|0;f=0;i=d;return f|0}e=(c[14356]|0)+1|0;c[14356]=e;if((e|0)<3){f=1;i=d;return f|0}Eb(57480,57432)|0;zb(57480,57592)|0;Ba(c[14359]|0,c[14360]|0);f=1;i=d;return f|0}function nd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+48|0;e=d+32|0;f=d;g=d+36|0;pd(f,a,b);b=Mb(57592,f)|0;if(!b){Fb(57480,57592)|0;f=Gb(57480,g)|0;Fa(c[g>>2]|0,c[14359]|0,f|0);Hb(57480,f)|0;h=1;i=d;return h|0}else{c[e>>2]=b;Ea(57728,e|0)|0;h=0;i=d;return h|0}return 0}function od(){if(!(c[14356]|0))return;Yb(57432);Db(57480);Cb(57592)|0;Wb(57464);return}function pd(a,b,d){a=a|0;b=b|0;d=d|0;c[a>>2]=b;c[a+4>>2]=d;d=a+8|0;c[d>>2]=0;c[d+4>>2]=0;c[d+8>>2]=0;c[d+12>>2]=0;c[d+16>>2]=0;c[d+20>>2]=0;return}function qd(a,b){a=+a;b=b|0;return +(+vd(a,b))}function rd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0;f=i;i=i+688|0;g=f+424|0;h=f+192|0;j=f;k=_(d,b)|0;if(!k){i=f;return}b=k-d|0;c[j+4>>2]=d;c[j>>2]=d;l=d;m=d;n=2;while(1){o=l+d+m|0;c[j+(n<<2)>>2]=o;if(o>>>0<k>>>0){p=m;m=o;n=n+1|0;l=p}else break}l=0-d|0;n=a+b|0;if((b|0)>0){b=(d|0)==0;m=n;k=1;p=0;o=a;q=1;while(1){do if((k&3|0)!=3){r=q+-1|0;if((c[j+(r<<2)>>2]|0)>>>0<(m-o|0)>>>0){c[h>>2]=o;a:do if((q|0)>1){s=q;t=o;u=o;v=1;while(1){w=t+l|0;x=s+-2|0;y=t+(0-((c[j+(x<<2)>>2]|0)+d))|0;if(($a[e&15](u,y)|0)>-1?($a[e&15](u,w)|0)>-1:0){z=v;break}A=v+1|0;B=h+(v<<2)|0;if(($a[e&15](y,w)|0)>-1){c[B>>2]=y;C=y;D=s+-1|0}else{c[B>>2]=w;C=w;D=x}if((D|0)<=1){z=A;break}s=D;t=C;u=c[h>>2]|0;v=A}if((z|0)>=2?(v=h+(z<<2)|0,c[v>>2]=g,!b):0){u=d;t=g;while(1){s=u>>>0>256?256:u;A=c[h>>2]|0;Jd(t|0,A|0,s|0)|0;x=A;A=0;do{w=A;A=A+1|0;B=x;x=c[h+(A<<2)>>2]|0;Jd(B|0,x|0,s|0)|0;c[h+(w<<2)>>2]=B+s}while((A|0)!=(z|0));if((u|0)==(s|0))break a;u=u-s|0;t=c[v>>2]|0}}}while(0)}else sd(o,d,e,k,p,q,0,j);if((q|0)==1){E=k<<1;F=k>>>31|p<<1;G=0;break}else{v=r>>>0>31;t=v?0:k;u=v?q+-33|0:r;E=t<<u;F=t>>>(32-u|0)|(v?k:p)<<u;G=1;break}}else{c[h>>2]=o;b:do if((q|0)>1){u=q;v=o;t=o;A=1;while(1){x=v+l|0;B=u+-2|0;w=v+(0-((c[j+(B<<2)>>2]|0)+d))|0;if(($a[e&15](t,w)|0)>-1?($a[e&15](t,x)|0)>-1:0){H=A;break}y=A+1|0;I=h+(A<<2)|0;if(($a[e&15](w,x)|0)>-1){c[I>>2]=w;J=w;K=u+-1|0}else{c[I>>2]=x;J=x;K=B}if((K|0)<=1){H=y;break}u=K;v=J;t=c[h>>2]|0;A=y}if((H|0)>=2?(A=h+(H<<2)|0,c[A>>2]=g,!b):0){t=d;v=g;while(1){u=t>>>0>256?256:t;y=c[h>>2]|0;Jd(v|0,y|0,u|0)|0;B=y;y=0;do{x=y;y=y+1|0;I=B;B=c[h+(y<<2)>>2]|0;Jd(I|0,B|0,u|0)|0;c[h+(x<<2)>>2]=I+u}while((y|0)!=(H|0));if((t|0)==(u|0))break b;t=t-u|0;v=c[A>>2]|0}}}while(0);E=k>>>2|p<<30;F=p>>>2;G=q+2|0}while(0);r=E|1;A=o+d|0;if(A>>>0<n>>>0){k=r;p=F;o=A;q=G}else{L=F;M=r;N=A;O=G;break}}}else{L=0;M=1;N=a;O=1}sd(N,d,e,M,L,O,0,j);if((L|0)==0&((M|0)==1&(O|0)==1)){i=f;return}else{P=M;Q=L;R=N;S=O}while(1){if((S|0)>=2){O=P>>>30;N=S+-2|0;L=(P<<1&2147483646|O<<31)^3;M=(O|Q<<2)>>>1;sd(R+(0-((c[j+(N<<2)>>2]|0)+d))|0,d,e,L,M,S+-1|0,1,j);a=M<<1|O&1;O=L<<1|1;L=R+l|0;sd(L,d,e,O,a,N,1,j);P=O;Q=a;R=L;S=N;continue}N=P+-1|0;do if(N){if(!(N&1)){L=N;a=0;while(1){O=a+1|0;L=L>>>1;if(L&1){T=O;break}else a=O}if(T)U=T;else V=51}else V=51;if((V|0)==51){V=0;if(!Q){W=64;V=56;break}if(!(Q&1)){X=Q;Y=0}else{Z=0;$=P;aa=Q;ba=0;break}while(1){a=Y+1|0;X=X>>>1;if(X&1){ca=a;da=Y;break}else Y=a}if(!ca){Z=0;$=P;aa=Q;ba=0;break}else U=da+33|0}if(U>>>0>31){W=U;V=56}else{Z=U;$=P;aa=Q;ba=U}}else{W=32;V=56}while(0);if((V|0)==56){V=0;Z=W+-32|0;$=Q;aa=0;ba=W}P=aa<<32-Z|$>>>Z;Q=aa>>>Z;S=ba+S|0;if((Q|0)==0&((P|0)==1&(S|0)==1))break;else R=R+l|0}i=f;return}function sd(a,b,d,e,f,g,h,j){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0;k=i;i=i+720|0;l=k+456|0;m=k+228|0;n=k;c[n>>2]=a;o=0-b|0;a:do if((f|0)!=0|(e|0)!=1?(p=a+(0-(c[j+(g<<2)>>2]|0))|0,($a[d&15](p,a)|0)>=1):0){q=a;r=g;s=h;t=p;p=f;u=1;v=e;while(1){if((s|0)==0&(r|0)>1){w=c[j+(r+-2<<2)>>2]|0;if(($a[d&15](q+o|0,t)|0)>-1){x=q;y=r;z=u;break a}if(($a[d&15](q+(0-(w+b))|0,t)|0)>-1){x=q;y=r;z=u;break a}}w=u+1|0;c[n+(u<<2)>>2]=t;A=v+-1|0;do if(A){if(!(A&1)){B=A;C=0;while(1){D=C+1|0;B=B>>>1;if(B&1){E=D;break}else C=D}if(E)F=E;else G=10}else G=10;if((G|0)==10){G=0;if(!p){H=64;G=15;break}if(!(p&1)){I=p;J=0}else{K=0;L=v;M=p;N=0;break}while(1){C=J+1|0;I=I>>>1;if(I&1){O=C;P=J;break}else J=C}if(!O){K=0;L=v;M=p;N=0;break}else F=P+33|0}if(F>>>0>31){H=F;G=15}else{K=F;L=v;M=p;N=F}}else{H=32;G=15}while(0);if((G|0)==15){G=0;K=H+-32|0;L=p;M=0;N=H}v=M<<32-K|L>>>K;p=M>>>K;A=N+r|0;if(!((p|0)!=0|(v|0)!=1)){x=t;y=A;z=w;break a}C=t+(0-(c[j+(A<<2)>>2]|0))|0;if(($a[d&15](C,c[n>>2]|0)|0)<1){Q=t;R=A;S=0;T=w;G=18;break}else{B=t;r=A;s=0;t=C;u=w;q=B}}}else{Q=a;R=g;S=h;T=1;G=18}while(0);if((G|0)==18)if(!S){x=Q;y=R;z=T}else{i=k;return}b:do if((z|0)>=2?(T=n+(z<<2)|0,c[T>>2]=l,(b|0)!=0):0){R=b;Q=l;while(1){S=R>>>0>256?256:R;G=c[n>>2]|0;Jd(Q|0,G|0,S|0)|0;h=G;G=0;do{g=G;G=G+1|0;a=h;h=c[n+(G<<2)>>2]|0;Jd(a|0,h|0,S|0)|0;c[n+(g<<2)>>2]=a+S}while((G|0)!=(z|0));if((R|0)==(S|0))break b;R=R-S|0;Q=c[T>>2]|0}}while(0);c[m>>2]=x;c:do if((y|0)>1){z=y;n=x;T=x;Q=1;while(1){R=n+o|0;G=z+-2|0;h=n+(0-((c[j+(G<<2)>>2]|0)+b))|0;if(($a[d&15](T,h)|0)>-1?($a[d&15](T,R)|0)>-1:0){U=Q;break}w=Q+1|0;a=m+(Q<<2)|0;if(($a[d&15](h,R)|0)>-1){c[a>>2]=h;V=h;W=z+-1|0}else{c[a>>2]=R;V=R;W=G}if((W|0)<=1){U=w;break}z=W;n=V;T=c[m>>2]|0;Q=w}if((U|0)>=2?(Q=m+(U<<2)|0,c[Q>>2]=l,(b|0)!=0):0){T=b;n=l;while(1){z=T>>>0>256?256:T;w=c[m>>2]|0;Jd(n|0,w|0,z|0)|0;G=w;w=0;do{R=w;w=w+1|0;a=G;G=c[m+(w<<2)>>2]|0;Jd(a|0,G|0,z|0)|0;c[m+(R<<2)>>2]=a+z}while((w|0)!=(U|0));if((T|0)==(z|0)){X=l;break c}T=T-z|0;n=c[Q>>2]|0}}else X=l}else X=l;while(0);i=k;return}function td(a){a=+a;var b=0,d=0,e=0.0,f=0.0;h[k>>3]=a;b=c[k+4>>2]|0;d=b&2146435072;if(d>>>0>1126170624|(d|0)==1126170624&0>0){e=a;return +e}d=(b|0)<0;f=d?a+-4503599627370496.0+4503599627370496.0:a+4503599627370496.0+-4503599627370496.0;if(!(f==0.0)){e=f;return +e}e=d?-0.0:0.0;return +e}function ud(a){a=+a;var b=0,d=0.0,e=0,f=0.0;b=(g[k>>2]=a,c[k>>2]|0);if((b&2130706432)>>>0>1249902592){d=a;return +d}e=(b|0)<0;f=e?a+-8388608.0+8388608.0:a+8388608.0+-8388608.0;if(!(f==0.0)){d=f;return +d}d=e?-0.0:0.0;return +d}function vd(a,b){a=+a;b=b|0;var d=0.0,e=0,f=0,g=0,i=0.0;if((b|0)>1023){d=a*8988465674311579538646525.0e283;e=b+-1023|0;if((e|0)>1023){f=b+-2046|0;g=(f|0)>1023?1023:f;i=d*8988465674311579538646525.0e283}else{g=e;i=d}}else if((b|0)<-1022){d=a*2.2250738585072014e-308;e=b+1022|0;if((e|0)<-1022){f=b+2044|0;g=(f|0)<-1022?-1022:f;i=d*2.2250738585072014e-308}else{g=e;i=d}}else{g=b;i=a}b=Gd(g+1023|0,0,52)|0;g=C;c[k>>2]=b;c[k+4>>2]=g;return +(i*+h[k>>3])}function wd(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;if(!d){e=0;return e|0}else{f=d;g=b;h=c}while(1){c=a[g>>0]|0;b=a[h>>0]|0;if(c<<24>>24!=b<<24>>24){i=c;j=b;break}f=f+-1|0;if(!f){e=0;k=5;break}else{g=g+1|0;h=h+1|0}}if((k|0)==5)return e|0;e=(i&255)-(j&255)|0;return e|0}function xd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,xa=0,ya=0,za=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ka=0,La=0,Na=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0;do if(a>>>0<245){b=a>>>0<11?16:a+11&-8;d=b>>>3;e=c[14442]|0;f=e>>>d;if(f&3){g=(f&1^1)+d|0;h=g<<1;i=57808+(h<<2)|0;j=57808+(h+2<<2)|0;h=c[j>>2]|0;k=h+8|0;l=c[k>>2]|0;do if((i|0)!=(l|0)){if(l>>>0<(c[14446]|0)>>>0)Ma();m=l+12|0;if((c[m>>2]|0)==(h|0)){c[m>>2]=i;c[j>>2]=l;break}else Ma()}else c[14442]=e&~(1<<g);while(0);l=g<<3;c[h+4>>2]=l|3;j=h+(l|4)|0;c[j>>2]=c[j>>2]|1;n=k;return n|0}j=c[14444]|0;if(b>>>0>j>>>0){if(f){l=2<<d;i=f<<d&(l|0-l);l=(i&0-i)+-1|0;i=l>>>12&16;m=l>>>i;l=m>>>5&8;o=m>>>l;m=o>>>2&4;p=o>>>m;o=p>>>1&2;q=p>>>o;p=q>>>1&1;r=(l|i|m|o|p)+(q>>>p)|0;p=r<<1;q=57808+(p<<2)|0;o=57808+(p+2<<2)|0;p=c[o>>2]|0;m=p+8|0;i=c[m>>2]|0;do if((q|0)!=(i|0)){if(i>>>0<(c[14446]|0)>>>0)Ma();l=i+12|0;if((c[l>>2]|0)==(p|0)){c[l>>2]=q;c[o>>2]=i;s=c[14444]|0;break}else Ma()}else{c[14442]=e&~(1<<r);s=j}while(0);j=r<<3;e=j-b|0;c[p+4>>2]=b|3;i=p+b|0;c[p+(b|4)>>2]=e|1;c[p+j>>2]=e;if(s){j=c[14447]|0;o=s>>>3;q=o<<1;d=57808+(q<<2)|0;f=c[14442]|0;k=1<<o;if(f&k){o=57808+(q+2<<2)|0;h=c[o>>2]|0;if(h>>>0<(c[14446]|0)>>>0)Ma();else{t=o;u=h}}else{c[14442]=f|k;t=57808+(q+2<<2)|0;u=d}c[t>>2]=j;c[u+12>>2]=j;c[j+8>>2]=u;c[j+12>>2]=d}c[14444]=e;c[14447]=i;n=m;return n|0}i=c[14443]|0;if(i){e=(i&0-i)+-1|0;i=e>>>12&16;d=e>>>i;e=d>>>5&8;j=d>>>e;d=j>>>2&4;q=j>>>d;j=q>>>1&2;k=q>>>j;q=k>>>1&1;f=c[58072+((e|i|d|j|q)+(k>>>q)<<2)>>2]|0;q=(c[f+4>>2]&-8)-b|0;k=f;j=f;while(1){f=c[k+16>>2]|0;if(!f){d=c[k+20>>2]|0;if(!d){v=q;w=j;break}else x=d}else x=f;f=(c[x+4>>2]&-8)-b|0;d=f>>>0<q>>>0;q=d?f:q;k=x;j=d?x:j}j=c[14446]|0;if(w>>>0<j>>>0)Ma();k=w+b|0;if(w>>>0>=k>>>0)Ma();q=c[w+24>>2]|0;m=c[w+12>>2]|0;do if((m|0)==(w|0)){p=w+20|0;r=c[p>>2]|0;if(!r){d=w+16|0;f=c[d>>2]|0;if(!f){y=0;break}else{z=f;A=d}}else{z=r;A=p}while(1){p=z+20|0;r=c[p>>2]|0;if(r){z=r;A=p;continue}p=z+16|0;r=c[p>>2]|0;if(!r){B=z;C=A;break}else{z=r;A=p}}if(C>>>0<j>>>0)Ma();else{c[C>>2]=0;y=B;break}}else{p=c[w+8>>2]|0;if(p>>>0<j>>>0)Ma();r=p+12|0;if((c[r>>2]|0)!=(w|0))Ma();d=m+8|0;if((c[d>>2]|0)==(w|0)){c[r>>2]=m;c[d>>2]=p;y=m;break}else Ma()}while(0);do if(q){m=c[w+28>>2]|0;j=58072+(m<<2)|0;if((w|0)==(c[j>>2]|0)){c[j>>2]=y;if(!y){c[14443]=c[14443]&~(1<<m);break}}else{if(q>>>0<(c[14446]|0)>>>0)Ma();m=q+16|0;if((c[m>>2]|0)==(w|0))c[m>>2]=y;else c[q+20>>2]=y;if(!y)break}m=c[14446]|0;if(y>>>0<m>>>0)Ma();c[y+24>>2]=q;j=c[w+16>>2]|0;do if(j)if(j>>>0<m>>>0)Ma();else{c[y+16>>2]=j;c[j+24>>2]=y;break}while(0);j=c[w+20>>2]|0;if(j)if(j>>>0<(c[14446]|0)>>>0)Ma();else{c[y+20>>2]=j;c[j+24>>2]=y;break}}while(0);if(v>>>0<16){q=v+b|0;c[w+4>>2]=q|3;j=w+(q+4)|0;c[j>>2]=c[j>>2]|1}else{c[w+4>>2]=b|3;c[w+(b|4)>>2]=v|1;c[w+(v+b)>>2]=v;j=c[14444]|0;if(j){q=c[14447]|0;m=j>>>3;j=m<<1;p=57808+(j<<2)|0;d=c[14442]|0;r=1<<m;if(d&r){m=57808+(j+2<<2)|0;f=c[m>>2]|0;if(f>>>0<(c[14446]|0)>>>0)Ma();else{D=m;E=f}}else{c[14442]=d|r;D=57808+(j+2<<2)|0;E=p}c[D>>2]=q;c[E+12>>2]=q;c[q+8>>2]=E;c[q+12>>2]=p}c[14444]=v;c[14447]=k}n=w+8|0;return n|0}else F=b}else F=b}else if(a>>>0<=4294967231){p=a+11|0;q=p&-8;j=c[14443]|0;if(j){r=0-q|0;d=p>>>8;if(d)if(q>>>0>16777215)G=31;else{p=(d+1048320|0)>>>16&8;f=d<<p;d=(f+520192|0)>>>16&4;m=f<<d;f=(m+245760|0)>>>16&2;i=14-(d|p|f)+(m<<f>>>15)|0;G=q>>>(i+7|0)&1|i<<1}else G=0;i=c[58072+(G<<2)>>2]|0;a:do if(!i){H=r;I=0;J=0;K=86}else{f=r;m=0;p=q<<((G|0)==31?0:25-(G>>>1)|0);d=i;e=0;while(1){h=c[d+4>>2]&-8;o=h-q|0;if(o>>>0<f>>>0)if((h|0)==(q|0)){L=o;M=d;N=d;K=90;break a}else{O=o;P=d}else{O=f;P=e}o=c[d+20>>2]|0;d=c[d+16+(p>>>31<<2)>>2]|0;h=(o|0)==0|(o|0)==(d|0)?m:o;if(!d){H=O;I=h;J=P;K=86;break}else{f=O;m=h;p=p<<1;e=P}}}while(0);if((K|0)==86){if((I|0)==0&(J|0)==0){i=2<<G;r=j&(i|0-i);if(!r){F=q;break}i=(r&0-r)+-1|0;r=i>>>12&16;b=i>>>r;i=b>>>5&8;k=b>>>i;b=k>>>2&4;e=k>>>b;k=e>>>1&2;p=e>>>k;e=p>>>1&1;Q=c[58072+((i|r|b|k|e)+(p>>>e)<<2)>>2]|0;R=0}else{Q=I;R=J}if(!Q){S=H;T=R}else{L=H;M=Q;N=R;K=90}}if((K|0)==90)while(1){K=0;e=(c[M+4>>2]&-8)-q|0;p=e>>>0<L>>>0;k=p?e:L;e=p?M:N;p=c[M+16>>2]|0;if(p){L=k;M=p;N=e;K=90;continue}M=c[M+20>>2]|0;if(!M){S=k;T=e;break}else{L=k;N=e;K=90}}if((T|0)!=0?S>>>0<((c[14444]|0)-q|0)>>>0:0){j=c[14446]|0;if(T>>>0<j>>>0)Ma();e=T+q|0;if(T>>>0>=e>>>0)Ma();k=c[T+24>>2]|0;p=c[T+12>>2]|0;do if((p|0)==(T|0)){b=T+20|0;r=c[b>>2]|0;if(!r){i=T+16|0;m=c[i>>2]|0;if(!m){U=0;break}else{V=m;W=i}}else{V=r;W=b}while(1){b=V+20|0;r=c[b>>2]|0;if(r){V=r;W=b;continue}b=V+16|0;r=c[b>>2]|0;if(!r){X=V;Y=W;break}else{V=r;W=b}}if(Y>>>0<j>>>0)Ma();else{c[Y>>2]=0;U=X;break}}else{b=c[T+8>>2]|0;if(b>>>0<j>>>0)Ma();r=b+12|0;if((c[r>>2]|0)!=(T|0))Ma();i=p+8|0;if((c[i>>2]|0)==(T|0)){c[r>>2]=p;c[i>>2]=b;U=p;break}else Ma()}while(0);do if(k){p=c[T+28>>2]|0;j=58072+(p<<2)|0;if((T|0)==(c[j>>2]|0)){c[j>>2]=U;if(!U){c[14443]=c[14443]&~(1<<p);break}}else{if(k>>>0<(c[14446]|0)>>>0)Ma();p=k+16|0;if((c[p>>2]|0)==(T|0))c[p>>2]=U;else c[k+20>>2]=U;if(!U)break}p=c[14446]|0;if(U>>>0<p>>>0)Ma();c[U+24>>2]=k;j=c[T+16>>2]|0;do if(j)if(j>>>0<p>>>0)Ma();else{c[U+16>>2]=j;c[j+24>>2]=U;break}while(0);j=c[T+20>>2]|0;if(j)if(j>>>0<(c[14446]|0)>>>0)Ma();else{c[U+20>>2]=j;c[j+24>>2]=U;break}}while(0);b:do if(S>>>0>=16){c[T+4>>2]=q|3;c[T+(q|4)>>2]=S|1;c[T+(S+q)>>2]=S;k=S>>>3;if(S>>>0<256){j=k<<1;p=57808+(j<<2)|0;b=c[14442]|0;i=1<<k;if(b&i){k=57808+(j+2<<2)|0;r=c[k>>2]|0;if(r>>>0<(c[14446]|0)>>>0)Ma();else{Z=k;_=r}}else{c[14442]=b|i;Z=57808+(j+2<<2)|0;_=p}c[Z>>2]=e;c[_+12>>2]=e;c[T+(q+8)>>2]=_;c[T+(q+12)>>2]=p;break}p=S>>>8;if(p)if(S>>>0>16777215)$=31;else{j=(p+1048320|0)>>>16&8;i=p<<j;p=(i+520192|0)>>>16&4;b=i<<p;i=(b+245760|0)>>>16&2;r=14-(p|j|i)+(b<<i>>>15)|0;$=S>>>(r+7|0)&1|r<<1}else $=0;r=58072+($<<2)|0;c[T+(q+28)>>2]=$;c[T+(q+20)>>2]=0;c[T+(q+16)>>2]=0;i=c[14443]|0;b=1<<$;if(!(i&b)){c[14443]=i|b;c[r>>2]=e;c[T+(q+24)>>2]=r;c[T+(q+12)>>2]=e;c[T+(q+8)>>2]=e;break}b=c[r>>2]|0;c:do if((c[b+4>>2]&-8|0)!=(S|0)){r=S<<(($|0)==31?0:25-($>>>1)|0);i=b;while(1){j=i+16+(r>>>31<<2)|0;p=c[j>>2]|0;if(!p){aa=j;ba=i;break}if((c[p+4>>2]&-8|0)==(S|0)){ca=p;break c}else{r=r<<1;i=p}}if(aa>>>0<(c[14446]|0)>>>0)Ma();else{c[aa>>2]=e;c[T+(q+24)>>2]=ba;c[T+(q+12)>>2]=e;c[T+(q+8)>>2]=e;break b}}else ca=b;while(0);b=ca+8|0;i=c[b>>2]|0;r=c[14446]|0;if(i>>>0>=r>>>0&ca>>>0>=r>>>0){c[i+12>>2]=e;c[b>>2]=e;c[T+(q+8)>>2]=i;c[T+(q+12)>>2]=ca;c[T+(q+24)>>2]=0;break}else Ma()}else{i=S+q|0;c[T+4>>2]=i|3;b=T+(i+4)|0;c[b>>2]=c[b>>2]|1}while(0);n=T+8|0;return n|0}else F=q}else F=q}else F=-1;while(0);T=c[14444]|0;if(T>>>0>=F>>>0){S=T-F|0;ca=c[14447]|0;if(S>>>0>15){c[14447]=ca+F;c[14444]=S;c[ca+(F+4)>>2]=S|1;c[ca+T>>2]=S;c[ca+4>>2]=F|3}else{c[14444]=0;c[14447]=0;c[ca+4>>2]=T|3;S=ca+(T+4)|0;c[S>>2]=c[S>>2]|1}n=ca+8|0;return n|0}ca=c[14445]|0;if(ca>>>0>F>>>0){S=ca-F|0;c[14445]=S;ca=c[14448]|0;c[14448]=ca+F;c[ca+(F+4)>>2]=S|1;c[ca+4>>2]=F|3;n=ca+8|0;return n|0}do if(!(c[14560]|0)){ca=Aa(30)|0;if(!(ca+-1&ca)){c[14562]=ca;c[14561]=ca;c[14563]=-1;c[14564]=-1;c[14565]=0;c[14553]=0;c[14560]=(Oa(0)|0)&-16^1431655768;break}else Ma()}while(0);ca=F+48|0;S=c[14562]|0;T=F+47|0;ba=S+T|0;aa=0-S|0;S=ba&aa;if(S>>>0<=F>>>0){n=0;return n|0}$=c[14552]|0;if(($|0)!=0?(_=c[14550]|0,Z=_+S|0,Z>>>0<=_>>>0|Z>>>0>$>>>0):0){n=0;return n|0}d:do if(!(c[14553]&4)){$=c[14448]|0;e:do if($){Z=58216;while(1){_=c[Z>>2]|0;if(_>>>0<=$>>>0?(U=Z+4|0,(_+(c[U>>2]|0)|0)>>>0>$>>>0):0){da=Z;ea=U;break}Z=c[Z+8>>2]|0;if(!Z){K=174;break e}}Z=ba-(c[14445]|0)&aa;if(Z>>>0<2147483647){U=wa(Z|0)|0;_=(U|0)==((c[da>>2]|0)+(c[ea>>2]|0)|0);X=_?Z:0;if(_)if((U|0)==(-1|0))fa=X;else{ga=U;ha=X;K=194;break d}else{ia=U;ja=Z;ka=X;K=184}}else fa=0}else K=174;while(0);do if((K|0)==174){$=wa(0)|0;if(($|0)!=(-1|0)){q=$;X=c[14561]|0;Z=X+-1|0;if(!(Z&q))la=S;else la=S-q+(Z+q&0-X)|0;X=c[14550]|0;q=X+la|0;if(la>>>0>F>>>0&la>>>0<2147483647){Z=c[14552]|0;if((Z|0)!=0?q>>>0<=X>>>0|q>>>0>Z>>>0:0){fa=0;break}Z=wa(la|0)|0;q=(Z|0)==($|0);X=q?la:0;if(q){ga=$;ha=X;K=194;break d}else{ia=Z;ja=la;ka=X;K=184}}else fa=0}else fa=0}while(0);f:do if((K|0)==184){X=0-ja|0;do if(ca>>>0>ja>>>0&(ja>>>0<2147483647&(ia|0)!=(-1|0))?(Z=c[14562]|0,$=T-ja+Z&0-Z,$>>>0<2147483647):0)if((wa($|0)|0)==(-1|0)){wa(X|0)|0;fa=ka;break f}else{ma=$+ja|0;break}else ma=ja;while(0);if((ia|0)==(-1|0))fa=ka;else{ga=ia;ha=ma;K=194;break d}}while(0);c[14553]=c[14553]|4;na=fa;K=191}else{na=0;K=191}while(0);if((((K|0)==191?S>>>0<2147483647:0)?(fa=wa(S|0)|0,S=wa(0)|0,fa>>>0<S>>>0&((fa|0)!=(-1|0)&(S|0)!=(-1|0))):0)?(ma=S-fa|0,S=ma>>>0>(F+40|0)>>>0,S):0){ga=fa;ha=S?ma:na;K=194}if((K|0)==194){na=(c[14550]|0)+ha|0;c[14550]=na;if(na>>>0>(c[14551]|0)>>>0)c[14551]=na;na=c[14448]|0;g:do if(na){ma=58216;do{S=c[ma>>2]|0;fa=ma+4|0;ia=c[fa>>2]|0;if((ga|0)==(S+ia|0)){oa=S;pa=fa;qa=ia;ra=ma;K=204;break}ma=c[ma+8>>2]|0}while((ma|0)!=0);if(((K|0)==204?(c[ra+12>>2]&8|0)==0:0)?na>>>0<ga>>>0&na>>>0>=oa>>>0:0){c[pa>>2]=qa+ha;ma=(c[14445]|0)+ha|0;ia=na+8|0;fa=(ia&7|0)==0?0:0-ia&7;ia=ma-fa|0;c[14448]=na+fa;c[14445]=ia;c[na+(fa+4)>>2]=ia|1;c[na+(ma+4)>>2]=40;c[14449]=c[14564];break}ma=c[14446]|0;if(ga>>>0<ma>>>0){c[14446]=ga;sa=ga}else sa=ma;ma=ga+ha|0;ia=58216;while(1){if((c[ia>>2]|0)==(ma|0)){ta=ia;ua=ia;K=212;break}ia=c[ia+8>>2]|0;if(!ia){va=58216;break}}if((K|0)==212)if(!(c[ua+12>>2]&8)){c[ta>>2]=ga;ia=ua+4|0;c[ia>>2]=(c[ia>>2]|0)+ha;ia=ga+8|0;ma=(ia&7|0)==0?0:0-ia&7;ia=ga+(ha+8)|0;fa=(ia&7|0)==0?0:0-ia&7;ia=ga+(fa+ha)|0;S=ma+F|0;ka=ga+S|0;ja=ia-(ga+ma)-F|0;c[ga+(ma+4)>>2]=F|3;h:do if((ia|0)!=(na|0)){if((ia|0)==(c[14447]|0)){T=(c[14444]|0)+ja|0;c[14444]=T;c[14447]=ka;c[ga+(S+4)>>2]=T|1;c[ga+(T+S)>>2]=T;break}T=ha+4|0;ca=c[ga+(T+fa)>>2]|0;if((ca&3|0)==1){la=ca&-8;ea=ca>>>3;i:do if(ca>>>0>=256){da=c[ga+((fa|24)+ha)>>2]|0;aa=c[ga+(ha+12+fa)>>2]|0;do if((aa|0)==(ia|0)){ba=fa|16;X=ga+(T+ba)|0;$=c[X>>2]|0;if(!$){Z=ga+(ba+ha)|0;ba=c[Z>>2]|0;if(!ba){xa=0;break}else{ya=ba;za=Z}}else{ya=$;za=X}while(1){X=ya+20|0;$=c[X>>2]|0;if($){ya=$;za=X;continue}X=ya+16|0;$=c[X>>2]|0;if(!$){Ba=ya;Ca=za;break}else{ya=$;za=X}}if(Ca>>>0<sa>>>0)Ma();else{c[Ca>>2]=0;xa=Ba;break}}else{X=c[ga+((fa|8)+ha)>>2]|0;if(X>>>0<sa>>>0)Ma();$=X+12|0;if((c[$>>2]|0)!=(ia|0))Ma();Z=aa+8|0;if((c[Z>>2]|0)==(ia|0)){c[$>>2]=aa;c[Z>>2]=X;xa=aa;break}else Ma()}while(0);if(!da)break;aa=c[ga+(ha+28+fa)>>2]|0;X=58072+(aa<<2)|0;do if((ia|0)!=(c[X>>2]|0)){if(da>>>0<(c[14446]|0)>>>0)Ma();Z=da+16|0;if((c[Z>>2]|0)==(ia|0))c[Z>>2]=xa;else c[da+20>>2]=xa;if(!xa)break i}else{c[X>>2]=xa;if(xa)break;c[14443]=c[14443]&~(1<<aa);break i}while(0);aa=c[14446]|0;if(xa>>>0<aa>>>0)Ma();c[xa+24>>2]=da;X=fa|16;Z=c[ga+(X+ha)>>2]|0;do if(Z)if(Z>>>0<aa>>>0)Ma();else{c[xa+16>>2]=Z;c[Z+24>>2]=xa;break}while(0);Z=c[ga+(T+X)>>2]|0;if(!Z)break;if(Z>>>0<(c[14446]|0)>>>0)Ma();else{c[xa+20>>2]=Z;c[Z+24>>2]=xa;break}}else{Z=c[ga+((fa|8)+ha)>>2]|0;aa=c[ga+(ha+12+fa)>>2]|0;da=57808+(ea<<1<<2)|0;do if((Z|0)!=(da|0)){if(Z>>>0<sa>>>0)Ma();if((c[Z+12>>2]|0)==(ia|0))break;Ma()}while(0);if((aa|0)==(Z|0)){c[14442]=c[14442]&~(1<<ea);break}do if((aa|0)==(da|0))Da=aa+8|0;else{if(aa>>>0<sa>>>0)Ma();X=aa+8|0;if((c[X>>2]|0)==(ia|0)){Da=X;break}Ma()}while(0);c[Z+12>>2]=aa;c[Da>>2]=Z}while(0);Ea=ga+((la|fa)+ha)|0;Fa=la+ja|0}else{Ea=ia;Fa=ja}ea=Ea+4|0;c[ea>>2]=c[ea>>2]&-2;c[ga+(S+4)>>2]=Fa|1;c[ga+(Fa+S)>>2]=Fa;ea=Fa>>>3;if(Fa>>>0<256){T=ea<<1;ca=57808+(T<<2)|0;da=c[14442]|0;X=1<<ea;do if(!(da&X)){c[14442]=da|X;Ga=57808+(T+2<<2)|0;Ha=ca}else{ea=57808+(T+2<<2)|0;$=c[ea>>2]|0;if($>>>0>=(c[14446]|0)>>>0){Ga=ea;Ha=$;break}Ma()}while(0);c[Ga>>2]=ka;c[Ha+12>>2]=ka;c[ga+(S+8)>>2]=Ha;c[ga+(S+12)>>2]=ca;break}T=Fa>>>8;do if(!T)Ia=0;else{if(Fa>>>0>16777215){Ia=31;break}X=(T+1048320|0)>>>16&8;da=T<<X;la=(da+520192|0)>>>16&4;$=da<<la;da=($+245760|0)>>>16&2;ea=14-(la|X|da)+($<<da>>>15)|0;Ia=Fa>>>(ea+7|0)&1|ea<<1}while(0);T=58072+(Ia<<2)|0;c[ga+(S+28)>>2]=Ia;c[ga+(S+20)>>2]=0;c[ga+(S+16)>>2]=0;ca=c[14443]|0;ea=1<<Ia;if(!(ca&ea)){c[14443]=ca|ea;c[T>>2]=ka;c[ga+(S+24)>>2]=T;c[ga+(S+12)>>2]=ka;c[ga+(S+8)>>2]=ka;break}ea=c[T>>2]|0;j:do if((c[ea+4>>2]&-8|0)!=(Fa|0)){T=Fa<<((Ia|0)==31?0:25-(Ia>>>1)|0);ca=ea;while(1){da=ca+16+(T>>>31<<2)|0;$=c[da>>2]|0;if(!$){Ka=da;La=ca;break}if((c[$+4>>2]&-8|0)==(Fa|0)){Na=$;break j}else{T=T<<1;ca=$}}if(Ka>>>0<(c[14446]|0)>>>0)Ma();else{c[Ka>>2]=ka;c[ga+(S+24)>>2]=La;c[ga+(S+12)>>2]=ka;c[ga+(S+8)>>2]=ka;break h}}else Na=ea;while(0);ea=Na+8|0;ca=c[ea>>2]|0;T=c[14446]|0;if(ca>>>0>=T>>>0&Na>>>0>=T>>>0){c[ca+12>>2]=ka;c[ea>>2]=ka;c[ga+(S+8)>>2]=ca;c[ga+(S+12)>>2]=Na;c[ga+(S+24)>>2]=0;break}else Ma()}else{ca=(c[14445]|0)+ja|0;c[14445]=ca;c[14448]=ka;c[ga+(S+4)>>2]=ca|1}while(0);n=ga+(ma|8)|0;return n|0}else va=58216;while(1){S=c[va>>2]|0;if(S>>>0<=na>>>0?(ka=c[va+4>>2]|0,ja=S+ka|0,ja>>>0>na>>>0):0){Pa=S;Qa=ka;Ra=ja;break}va=c[va+8>>2]|0}ma=Pa+(Qa+-39)|0;ja=Pa+(Qa+-47+((ma&7|0)==0?0:0-ma&7))|0;ma=na+16|0;ka=ja>>>0<ma>>>0?na:ja;ja=ka+8|0;S=ga+8|0;ia=(S&7|0)==0?0:0-S&7;S=ha+-40-ia|0;c[14448]=ga+ia;c[14445]=S;c[ga+(ia+4)>>2]=S|1;c[ga+(ha+-36)>>2]=40;c[14449]=c[14564];S=ka+4|0;c[S>>2]=27;c[ja>>2]=c[14554];c[ja+4>>2]=c[14555];c[ja+8>>2]=c[14556];c[ja+12>>2]=c[14557];c[14554]=ga;c[14555]=ha;c[14557]=0;c[14556]=ja;ja=ka+28|0;c[ja>>2]=7;if((ka+32|0)>>>0<Ra>>>0){ia=ja;do{ja=ia;ia=ia+4|0;c[ia>>2]=7}while((ja+8|0)>>>0<Ra>>>0)}if((ka|0)!=(na|0)){ia=ka-na|0;c[S>>2]=c[S>>2]&-2;c[na+4>>2]=ia|1;c[ka>>2]=ia;ja=ia>>>3;if(ia>>>0<256){fa=ja<<1;ca=57808+(fa<<2)|0;ea=c[14442]|0;T=1<<ja;if(ea&T){ja=57808+(fa+2<<2)|0;Z=c[ja>>2]|0;if(Z>>>0<(c[14446]|0)>>>0)Ma();else{Sa=ja;Ta=Z}}else{c[14442]=ea|T;Sa=57808+(fa+2<<2)|0;Ta=ca}c[Sa>>2]=na;c[Ta+12>>2]=na;c[na+8>>2]=Ta;c[na+12>>2]=ca;break}ca=ia>>>8;if(ca)if(ia>>>0>16777215)Ua=31;else{fa=(ca+1048320|0)>>>16&8;T=ca<<fa;ca=(T+520192|0)>>>16&4;ea=T<<ca;T=(ea+245760|0)>>>16&2;Z=14-(ca|fa|T)+(ea<<T>>>15)|0;Ua=ia>>>(Z+7|0)&1|Z<<1}else Ua=0;Z=58072+(Ua<<2)|0;c[na+28>>2]=Ua;c[na+20>>2]=0;c[ma>>2]=0;T=c[14443]|0;ea=1<<Ua;if(!(T&ea)){c[14443]=T|ea;c[Z>>2]=na;c[na+24>>2]=Z;c[na+12>>2]=na;c[na+8>>2]=na;break}ea=c[Z>>2]|0;k:do if((c[ea+4>>2]&-8|0)!=(ia|0)){Z=ia<<((Ua|0)==31?0:25-(Ua>>>1)|0);T=ea;while(1){fa=T+16+(Z>>>31<<2)|0;ca=c[fa>>2]|0;if(!ca){Va=fa;Wa=T;break}if((c[ca+4>>2]&-8|0)==(ia|0)){Xa=ca;break k}else{Z=Z<<1;T=ca}}if(Va>>>0<(c[14446]|0)>>>0)Ma();else{c[Va>>2]=na;c[na+24>>2]=Wa;c[na+12>>2]=na;c[na+8>>2]=na;break g}}else Xa=ea;while(0);ea=Xa+8|0;ia=c[ea>>2]|0;ma=c[14446]|0;if(ia>>>0>=ma>>>0&Xa>>>0>=ma>>>0){c[ia+12>>2]=na;c[ea>>2]=na;c[na+8>>2]=ia;c[na+12>>2]=Xa;c[na+24>>2]=0;break}else Ma()}}else{ia=c[14446]|0;if((ia|0)==0|ga>>>0<ia>>>0)c[14446]=ga;c[14554]=ga;c[14555]=ha;c[14557]=0;c[14451]=c[14560];c[14450]=-1;ia=0;do{ea=ia<<1;ma=57808+(ea<<2)|0;c[57808+(ea+3<<2)>>2]=ma;c[57808+(ea+2<<2)>>2]=ma;ia=ia+1|0}while((ia|0)!=32);ia=ga+8|0;ma=(ia&7|0)==0?0:0-ia&7;ia=ha+-40-ma|0;c[14448]=ga+ma;c[14445]=ia;c[ga+(ma+4)>>2]=ia|1;c[ga+(ha+-36)>>2]=40;c[14449]=c[14564]}while(0);ha=c[14445]|0;if(ha>>>0>F>>>0){ga=ha-F|0;c[14445]=ga;ha=c[14448]|0;c[14448]=ha+F;c[ha+(F+4)>>2]=ga|1;c[ha+4>>2]=F|3;n=ha+8|0;return n|0}}c[(Ja()|0)>>2]=12;n=0;return n|0}function yd(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;if(!a)return;b=a+-8|0;d=c[14446]|0;if(b>>>0<d>>>0)Ma();e=c[a+-4>>2]|0;f=e&3;if((f|0)==1)Ma();g=e&-8;h=a+(g+-8)|0;do if(!(e&1)){i=c[b>>2]|0;if(!f)return;j=-8-i|0;k=a+j|0;l=i+g|0;if(k>>>0<d>>>0)Ma();if((k|0)==(c[14447]|0)){m=a+(g+-4)|0;n=c[m>>2]|0;if((n&3|0)!=3){o=k;p=l;break}c[14444]=l;c[m>>2]=n&-2;c[a+(j+4)>>2]=l|1;c[h>>2]=l;return}n=i>>>3;if(i>>>0<256){i=c[a+(j+8)>>2]|0;m=c[a+(j+12)>>2]|0;q=57808+(n<<1<<2)|0;if((i|0)!=(q|0)){if(i>>>0<d>>>0)Ma();if((c[i+12>>2]|0)!=(k|0))Ma()}if((m|0)==(i|0)){c[14442]=c[14442]&~(1<<n);o=k;p=l;break}if((m|0)!=(q|0)){if(m>>>0<d>>>0)Ma();q=m+8|0;if((c[q>>2]|0)==(k|0))r=q;else Ma()}else r=m+8|0;c[i+12>>2]=m;c[r>>2]=i;o=k;p=l;break}i=c[a+(j+24)>>2]|0;m=c[a+(j+12)>>2]|0;do if((m|0)==(k|0)){q=a+(j+20)|0;n=c[q>>2]|0;if(!n){s=a+(j+16)|0;t=c[s>>2]|0;if(!t){u=0;break}else{v=t;w=s}}else{v=n;w=q}while(1){q=v+20|0;n=c[q>>2]|0;if(n){v=n;w=q;continue}q=v+16|0;n=c[q>>2]|0;if(!n){x=v;y=w;break}else{v=n;w=q}}if(y>>>0<d>>>0)Ma();else{c[y>>2]=0;u=x;break}}else{q=c[a+(j+8)>>2]|0;if(q>>>0<d>>>0)Ma();n=q+12|0;if((c[n>>2]|0)!=(k|0))Ma();s=m+8|0;if((c[s>>2]|0)==(k|0)){c[n>>2]=m;c[s>>2]=q;u=m;break}else Ma()}while(0);if(i){m=c[a+(j+28)>>2]|0;q=58072+(m<<2)|0;if((k|0)==(c[q>>2]|0)){c[q>>2]=u;if(!u){c[14443]=c[14443]&~(1<<m);o=k;p=l;break}}else{if(i>>>0<(c[14446]|0)>>>0)Ma();m=i+16|0;if((c[m>>2]|0)==(k|0))c[m>>2]=u;else c[i+20>>2]=u;if(!u){o=k;p=l;break}}m=c[14446]|0;if(u>>>0<m>>>0)Ma();c[u+24>>2]=i;q=c[a+(j+16)>>2]|0;do if(q)if(q>>>0<m>>>0)Ma();else{c[u+16>>2]=q;c[q+24>>2]=u;break}while(0);q=c[a+(j+20)>>2]|0;if(q)if(q>>>0<(c[14446]|0)>>>0)Ma();else{c[u+20>>2]=q;c[q+24>>2]=u;o=k;p=l;break}else{o=k;p=l}}else{o=k;p=l}}else{o=b;p=g}while(0);if(o>>>0>=h>>>0)Ma();b=a+(g+-4)|0;u=c[b>>2]|0;if(!(u&1))Ma();if(!(u&2)){if((h|0)==(c[14448]|0)){d=(c[14445]|0)+p|0;c[14445]=d;c[14448]=o;c[o+4>>2]=d|1;if((o|0)!=(c[14447]|0))return;c[14447]=0;c[14444]=0;return}if((h|0)==(c[14447]|0)){d=(c[14444]|0)+p|0;c[14444]=d;c[14447]=o;c[o+4>>2]=d|1;c[o+d>>2]=d;return}d=(u&-8)+p|0;x=u>>>3;do if(u>>>0>=256){y=c[a+(g+16)>>2]|0;w=c[a+(g|4)>>2]|0;do if((w|0)==(h|0)){v=a+(g+12)|0;r=c[v>>2]|0;if(!r){f=a+(g+8)|0;e=c[f>>2]|0;if(!e){z=0;break}else{A=e;B=f}}else{A=r;B=v}while(1){v=A+20|0;r=c[v>>2]|0;if(r){A=r;B=v;continue}v=A+16|0;r=c[v>>2]|0;if(!r){C=A;D=B;break}else{A=r;B=v}}if(D>>>0<(c[14446]|0)>>>0)Ma();else{c[D>>2]=0;z=C;break}}else{v=c[a+g>>2]|0;if(v>>>0<(c[14446]|0)>>>0)Ma();r=v+12|0;if((c[r>>2]|0)!=(h|0))Ma();f=w+8|0;if((c[f>>2]|0)==(h|0)){c[r>>2]=w;c[f>>2]=v;z=w;break}else Ma()}while(0);if(y){w=c[a+(g+20)>>2]|0;l=58072+(w<<2)|0;if((h|0)==(c[l>>2]|0)){c[l>>2]=z;if(!z){c[14443]=c[14443]&~(1<<w);break}}else{if(y>>>0<(c[14446]|0)>>>0)Ma();w=y+16|0;if((c[w>>2]|0)==(h|0))c[w>>2]=z;else c[y+20>>2]=z;if(!z)break}w=c[14446]|0;if(z>>>0<w>>>0)Ma();c[z+24>>2]=y;l=c[a+(g+8)>>2]|0;do if(l)if(l>>>0<w>>>0)Ma();else{c[z+16>>2]=l;c[l+24>>2]=z;break}while(0);l=c[a+(g+12)>>2]|0;if(l)if(l>>>0<(c[14446]|0)>>>0)Ma();else{c[z+20>>2]=l;c[l+24>>2]=z;break}}}else{l=c[a+g>>2]|0;w=c[a+(g|4)>>2]|0;y=57808+(x<<1<<2)|0;if((l|0)!=(y|0)){if(l>>>0<(c[14446]|0)>>>0)Ma();if((c[l+12>>2]|0)!=(h|0))Ma()}if((w|0)==(l|0)){c[14442]=c[14442]&~(1<<x);break}if((w|0)!=(y|0)){if(w>>>0<(c[14446]|0)>>>0)Ma();y=w+8|0;if((c[y>>2]|0)==(h|0))E=y;else Ma()}else E=w+8|0;c[l+12>>2]=w;c[E>>2]=l}while(0);c[o+4>>2]=d|1;c[o+d>>2]=d;if((o|0)==(c[14447]|0)){c[14444]=d;return}else F=d}else{c[b>>2]=u&-2;c[o+4>>2]=p|1;c[o+p>>2]=p;F=p}p=F>>>3;if(F>>>0<256){u=p<<1;b=57808+(u<<2)|0;d=c[14442]|0;E=1<<p;if(d&E){p=57808+(u+2<<2)|0;h=c[p>>2]|0;if(h>>>0<(c[14446]|0)>>>0)Ma();else{G=p;H=h}}else{c[14442]=d|E;G=57808+(u+2<<2)|0;H=b}c[G>>2]=o;c[H+12>>2]=o;c[o+8>>2]=H;c[o+12>>2]=b;return}b=F>>>8;if(b)if(F>>>0>16777215)I=31;else{H=(b+1048320|0)>>>16&8;G=b<<H;b=(G+520192|0)>>>16&4;u=G<<b;G=(u+245760|0)>>>16&2;E=14-(b|H|G)+(u<<G>>>15)|0;I=F>>>(E+7|0)&1|E<<1}else I=0;E=58072+(I<<2)|0;c[o+28>>2]=I;c[o+20>>2]=0;c[o+16>>2]=0;G=c[14443]|0;u=1<<I;a:do if(G&u){H=c[E>>2]|0;b:do if((c[H+4>>2]&-8|0)!=(F|0)){b=F<<((I|0)==31?0:25-(I>>>1)|0);d=H;while(1){h=d+16+(b>>>31<<2)|0;p=c[h>>2]|0;if(!p){J=h;K=d;break}if((c[p+4>>2]&-8|0)==(F|0)){L=p;break b}else{b=b<<1;d=p}}if(J>>>0<(c[14446]|0)>>>0)Ma();else{c[J>>2]=o;c[o+24>>2]=K;c[o+12>>2]=o;c[o+8>>2]=o;break a}}else L=H;while(0);H=L+8|0;d=c[H>>2]|0;b=c[14446]|0;if(d>>>0>=b>>>0&L>>>0>=b>>>0){c[d+12>>2]=o;c[H>>2]=o;c[o+8>>2]=d;c[o+12>>2]=L;c[o+24>>2]=0;break}else Ma()}else{c[14443]=G|u;c[E>>2]=o;c[o+24>>2]=E;c[o+12>>2]=o;c[o+8>>2]=o}while(0);o=(c[14450]|0)+-1|0;c[14450]=o;if(!o)M=58224;else return;while(1){o=c[M>>2]|0;if(!o)break;else M=o+8|0}c[14450]=-1;return}function zd(a,b){a=a|0;b=b|0;var d=0,e=0;if(a){d=_(b,a)|0;if((b|a)>>>0>65535)e=((d>>>0)/(a>>>0)|0|0)==(b|0)?d:-1;else e=d}else e=0;d=xd(e)|0;if(!d)return d|0;if(!(c[d+-4>>2]&3))return d|0;Fd(d|0,0,e|0)|0;return d|0}function Ad(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;if(!a){d=xd(b)|0;return d|0}if(b>>>0>4294967231){c[(Ja()|0)>>2]=12;d=0;return d|0}e=Bd(a+-8|0,b>>>0<11?16:b+11&-8)|0;if(e){d=e+8|0;return d|0}e=xd(b)|0;if(!e){d=0;return d|0}f=c[a+-4>>2]|0;g=(f&-8)-((f&3|0)==0?8:4)|0;Jd(e|0,a|0,(g>>>0<b>>>0?g:b)|0)|0;yd(a);d=e;return d|0}function Bd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;d=a+4|0;e=c[d>>2]|0;f=e&-8;g=a+f|0;h=c[14446]|0;i=e&3;if(!((i|0)!=1&a>>>0>=h>>>0&a>>>0<g>>>0))Ma();j=a+(f|4)|0;k=c[j>>2]|0;if(!(k&1))Ma();if(!i){if(b>>>0<256){l=0;return l|0}if(f>>>0>=(b+4|0)>>>0?(f-b|0)>>>0<=c[14562]<<1>>>0:0){l=a;return l|0}l=0;return l|0}if(f>>>0>=b>>>0){i=f-b|0;if(i>>>0<=15){l=a;return l|0}c[d>>2]=e&1|b|2;c[a+(b+4)>>2]=i|3;c[j>>2]=c[j>>2]|1;Cd(a+b|0,i);l=a;return l|0}if((g|0)==(c[14448]|0)){i=(c[14445]|0)+f|0;if(i>>>0<=b>>>0){l=0;return l|0}j=i-b|0;c[d>>2]=e&1|b|2;c[a+(b+4)>>2]=j|1;c[14448]=a+b;c[14445]=j;l=a;return l|0}if((g|0)==(c[14447]|0)){j=(c[14444]|0)+f|0;if(j>>>0<b>>>0){l=0;return l|0}i=j-b|0;if(i>>>0>15){c[d>>2]=e&1|b|2;c[a+(b+4)>>2]=i|1;c[a+j>>2]=i;m=a+(j+4)|0;c[m>>2]=c[m>>2]&-2;n=a+b|0;o=i}else{c[d>>2]=e&1|j|2;i=a+(j+4)|0;c[i>>2]=c[i>>2]|1;n=0;o=0}c[14444]=o;c[14447]=n;l=a;return l|0}if(k&2){l=0;return l|0}n=(k&-8)+f|0;if(n>>>0<b>>>0){l=0;return l|0}o=n-b|0;i=k>>>3;do if(k>>>0>=256){j=c[a+(f+24)>>2]|0;m=c[a+(f+12)>>2]|0;do if((m|0)==(g|0)){p=a+(f+20)|0;q=c[p>>2]|0;if(!q){r=a+(f+16)|0;s=c[r>>2]|0;if(!s){t=0;break}else{u=s;v=r}}else{u=q;v=p}while(1){p=u+20|0;q=c[p>>2]|0;if(q){u=q;v=p;continue}p=u+16|0;q=c[p>>2]|0;if(!q){w=u;x=v;break}else{u=q;v=p}}if(x>>>0<h>>>0)Ma();else{c[x>>2]=0;t=w;break}}else{p=c[a+(f+8)>>2]|0;if(p>>>0<h>>>0)Ma();q=p+12|0;if((c[q>>2]|0)!=(g|0))Ma();r=m+8|0;if((c[r>>2]|0)==(g|0)){c[q>>2]=m;c[r>>2]=p;t=m;break}else Ma()}while(0);if(j){m=c[a+(f+28)>>2]|0;p=58072+(m<<2)|0;if((g|0)==(c[p>>2]|0)){c[p>>2]=t;if(!t){c[14443]=c[14443]&~(1<<m);break}}else{if(j>>>0<(c[14446]|0)>>>0)Ma();m=j+16|0;if((c[m>>2]|0)==(g|0))c[m>>2]=t;else c[j+20>>2]=t;if(!t)break}m=c[14446]|0;if(t>>>0<m>>>0)Ma();c[t+24>>2]=j;p=c[a+(f+16)>>2]|0;do if(p)if(p>>>0<m>>>0)Ma();else{c[t+16>>2]=p;c[p+24>>2]=t;break}while(0);p=c[a+(f+20)>>2]|0;if(p)if(p>>>0<(c[14446]|0)>>>0)Ma();else{c[t+20>>2]=p;c[p+24>>2]=t;break}}}else{p=c[a+(f+8)>>2]|0;m=c[a+(f+12)>>2]|0;j=57808+(i<<1<<2)|0;if((p|0)!=(j|0)){if(p>>>0<h>>>0)Ma();if((c[p+12>>2]|0)!=(g|0))Ma()}if((m|0)==(p|0)){c[14442]=c[14442]&~(1<<i);break}if((m|0)!=(j|0)){if(m>>>0<h>>>0)Ma();j=m+8|0;if((c[j>>2]|0)==(g|0))y=j;else Ma()}else y=m+8|0;c[p+12>>2]=m;c[y>>2]=p}while(0);if(o>>>0<16){c[d>>2]=n|e&1|2;y=a+(n|4)|0;c[y>>2]=c[y>>2]|1;l=a;return l|0}else{c[d>>2]=e&1|b|2;c[a+(b+4)>>2]=o|3;e=a+(n|4)|0;c[e>>2]=c[e>>2]|1;Cd(a+b|0,o);l=a;return l|0}return 0}function Cd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0;d=a+b|0;e=c[a+4>>2]|0;do if(!(e&1)){f=c[a>>2]|0;if(!(e&3))return;g=a+(0-f)|0;h=f+b|0;i=c[14446]|0;if(g>>>0<i>>>0)Ma();if((g|0)==(c[14447]|0)){j=a+(b+4)|0;k=c[j>>2]|0;if((k&3|0)!=3){l=g;m=h;break}c[14444]=h;c[j>>2]=k&-2;c[a+(4-f)>>2]=h|1;c[d>>2]=h;return}k=f>>>3;if(f>>>0<256){j=c[a+(8-f)>>2]|0;n=c[a+(12-f)>>2]|0;o=57808+(k<<1<<2)|0;if((j|0)!=(o|0)){if(j>>>0<i>>>0)Ma();if((c[j+12>>2]|0)!=(g|0))Ma()}if((n|0)==(j|0)){c[14442]=c[14442]&~(1<<k);l=g;m=h;break}if((n|0)!=(o|0)){if(n>>>0<i>>>0)Ma();o=n+8|0;if((c[o>>2]|0)==(g|0))p=o;else Ma()}else p=n+8|0;c[j+12>>2]=n;c[p>>2]=j;l=g;m=h;break}j=c[a+(24-f)>>2]|0;n=c[a+(12-f)>>2]|0;do if((n|0)==(g|0)){o=16-f|0;k=a+(o+4)|0;q=c[k>>2]|0;if(!q){r=a+o|0;o=c[r>>2]|0;if(!o){s=0;break}else{t=o;u=r}}else{t=q;u=k}while(1){k=t+20|0;q=c[k>>2]|0;if(q){t=q;u=k;continue}k=t+16|0;q=c[k>>2]|0;if(!q){v=t;w=u;break}else{t=q;u=k}}if(w>>>0<i>>>0)Ma();else{c[w>>2]=0;s=v;break}}else{k=c[a+(8-f)>>2]|0;if(k>>>0<i>>>0)Ma();q=k+12|0;if((c[q>>2]|0)!=(g|0))Ma();r=n+8|0;if((c[r>>2]|0)==(g|0)){c[q>>2]=n;c[r>>2]=k;s=n;break}else Ma()}while(0);if(j){n=c[a+(28-f)>>2]|0;i=58072+(n<<2)|0;if((g|0)==(c[i>>2]|0)){c[i>>2]=s;if(!s){c[14443]=c[14443]&~(1<<n);l=g;m=h;break}}else{if(j>>>0<(c[14446]|0)>>>0)Ma();n=j+16|0;if((c[n>>2]|0)==(g|0))c[n>>2]=s;else c[j+20>>2]=s;if(!s){l=g;m=h;break}}n=c[14446]|0;if(s>>>0<n>>>0)Ma();c[s+24>>2]=j;i=16-f|0;k=c[a+i>>2]|0;do if(k)if(k>>>0<n>>>0)Ma();else{c[s+16>>2]=k;c[k+24>>2]=s;break}while(0);k=c[a+(i+4)>>2]|0;if(k)if(k>>>0<(c[14446]|0)>>>0)Ma();else{c[s+20>>2]=k;c[k+24>>2]=s;l=g;m=h;break}else{l=g;m=h}}else{l=g;m=h}}else{l=a;m=b}while(0);s=c[14446]|0;if(d>>>0<s>>>0)Ma();v=a+(b+4)|0;w=c[v>>2]|0;if(!(w&2)){if((d|0)==(c[14448]|0)){u=(c[14445]|0)+m|0;c[14445]=u;c[14448]=l;c[l+4>>2]=u|1;if((l|0)!=(c[14447]|0))return;c[14447]=0;c[14444]=0;return}if((d|0)==(c[14447]|0)){u=(c[14444]|0)+m|0;c[14444]=u;c[14447]=l;c[l+4>>2]=u|1;c[l+u>>2]=u;return}u=(w&-8)+m|0;t=w>>>3;do if(w>>>0>=256){p=c[a+(b+24)>>2]|0;e=c[a+(b+12)>>2]|0;do if((e|0)==(d|0)){k=a+(b+20)|0;n=c[k>>2]|0;if(!n){f=a+(b+16)|0;j=c[f>>2]|0;if(!j){x=0;break}else{y=j;z=f}}else{y=n;z=k}while(1){k=y+20|0;n=c[k>>2]|0;if(n){y=n;z=k;continue}k=y+16|0;n=c[k>>2]|0;if(!n){A=y;B=z;break}else{y=n;z=k}}if(B>>>0<s>>>0)Ma();else{c[B>>2]=0;x=A;break}}else{k=c[a+(b+8)>>2]|0;if(k>>>0<s>>>0)Ma();n=k+12|0;if((c[n>>2]|0)!=(d|0))Ma();f=e+8|0;if((c[f>>2]|0)==(d|0)){c[n>>2]=e;c[f>>2]=k;x=e;break}else Ma()}while(0);if(p){e=c[a+(b+28)>>2]|0;h=58072+(e<<2)|0;if((d|0)==(c[h>>2]|0)){c[h>>2]=x;if(!x){c[14443]=c[14443]&~(1<<e);break}}else{if(p>>>0<(c[14446]|0)>>>0)Ma();e=p+16|0;if((c[e>>2]|0)==(d|0))c[e>>2]=x;else c[p+20>>2]=x;if(!x)break}e=c[14446]|0;if(x>>>0<e>>>0)Ma();c[x+24>>2]=p;h=c[a+(b+16)>>2]|0;do if(h)if(h>>>0<e>>>0)Ma();else{c[x+16>>2]=h;c[h+24>>2]=x;break}while(0);h=c[a+(b+20)>>2]|0;if(h)if(h>>>0<(c[14446]|0)>>>0)Ma();else{c[x+20>>2]=h;c[h+24>>2]=x;break}}}else{h=c[a+(b+8)>>2]|0;e=c[a+(b+12)>>2]|0;p=57808+(t<<1<<2)|0;if((h|0)!=(p|0)){if(h>>>0<s>>>0)Ma();if((c[h+12>>2]|0)!=(d|0))Ma()}if((e|0)==(h|0)){c[14442]=c[14442]&~(1<<t);break}if((e|0)!=(p|0)){if(e>>>0<s>>>0)Ma();p=e+8|0;if((c[p>>2]|0)==(d|0))C=p;else Ma()}else C=e+8|0;c[h+12>>2]=e;c[C>>2]=h}while(0);c[l+4>>2]=u|1;c[l+u>>2]=u;if((l|0)==(c[14447]|0)){c[14444]=u;return}else D=u}else{c[v>>2]=w&-2;c[l+4>>2]=m|1;c[l+m>>2]=m;D=m}m=D>>>3;if(D>>>0<256){w=m<<1;v=57808+(w<<2)|0;u=c[14442]|0;C=1<<m;if(u&C){m=57808+(w+2<<2)|0;d=c[m>>2]|0;if(d>>>0<(c[14446]|0)>>>0)Ma();else{E=m;F=d}}else{c[14442]=u|C;E=57808+(w+2<<2)|0;F=v}c[E>>2]=l;c[F+12>>2]=l;c[l+8>>2]=F;c[l+12>>2]=v;return}v=D>>>8;if(v)if(D>>>0>16777215)G=31;else{F=(v+1048320|0)>>>16&8;E=v<<F;v=(E+520192|0)>>>16&4;w=E<<v;E=(w+245760|0)>>>16&2;C=14-(v|F|E)+(w<<E>>>15)|0;G=D>>>(C+7|0)&1|C<<1}else G=0;C=58072+(G<<2)|0;c[l+28>>2]=G;c[l+20>>2]=0;c[l+16>>2]=0;E=c[14443]|0;w=1<<G;if(!(E&w)){c[14443]=E|w;c[C>>2]=l;c[l+24>>2]=C;c[l+12>>2]=l;c[l+8>>2]=l;return}w=c[C>>2]|0;a:do if((c[w+4>>2]&-8|0)==(D|0))H=w;else{C=D<<((G|0)==31?0:25-(G>>>1)|0);E=w;while(1){F=E+16+(C>>>31<<2)|0;v=c[F>>2]|0;if(!v){I=F;J=E;break}if((c[v+4>>2]&-8|0)==(D|0)){H=v;break a}else{C=C<<1;E=v}}if(I>>>0<(c[14446]|0)>>>0)Ma();c[I>>2]=l;c[l+24>>2]=J;c[l+12>>2]=l;c[l+8>>2]=l;return}while(0);J=H+8|0;I=c[J>>2]|0;D=c[14446]|0;if(!(I>>>0>=D>>>0&H>>>0>=D>>>0))Ma();c[I+12>>2]=l;c[J>>2]=l;c[l+8>>2]=I;c[l+12>>2]=H;c[l+24>>2]=0;return}function Dd(){}function Ed(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=b-d>>>0;e=b-d-(c>>>0>a>>>0|0)>>>0;return (C=e,a-c>>>0|0)|0}function Fd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;g=b&3;h=d|d<<8|d<<16|d<<24;i=f&~3;if(g){g=b+4-g|0;while((b|0)<(g|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(i|0)){c[b>>2]=h;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function Gd(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b<<c|(a&(1<<c)-1<<32-c)>>>32-c;return a<<c}C=a<<c-32;return 0}function Hd(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function Id(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=a+c>>>0;return (C=b+d+(e>>>0<a>>>0|0)>>>0,e|0)|0}function Jd(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return Ia(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function Kd(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>>c;return a>>>c|(b&(1<<c)-1)<<32-c}C=0;return b>>>c-32|0}function Ld(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>c;return a>>>c|(b&(1<<c)-1)<<32-c}C=(b|0)<0?-1:0;return b>>c-32|0}function Md(b){b=b|0;var c=0;c=a[m+(b&255)>>0]|0;if((c|0)<8)return c|0;c=a[m+(b>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[m+(b>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return (a[m+(b>>>24)>>0]|0)+24|0}function Nd(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;c=a&65535;d=b&65535;e=_(d,c)|0;f=a>>>16;a=(e>>>16)+(_(d,f)|0)|0;d=b>>>16;b=_(d,c)|0;return (C=(a>>>16)+(_(d,f)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|e&65535|0)|0}function Od(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;e=b>>31|((b|0)<0?-1:0)<<1;f=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;g=d>>31|((d|0)<0?-1:0)<<1;h=((d|0)<0?-1:0)>>31|((d|0)<0?-1:0)<<1;i=Ed(e^a,f^b,e,f)|0;b=C;a=g^e;e=h^f;return Ed((Td(i,b,Ed(g^c,h^d,g,h)|0,C,0)|0)^a,C^e,a,e)|0}function Pd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+8|0;g=f|0;h=b>>31|((b|0)<0?-1:0)<<1;j=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;k=e>>31|((e|0)<0?-1:0)<<1;l=((e|0)<0?-1:0)>>31|((e|0)<0?-1:0)<<1;m=Ed(h^a,j^b,h,j)|0;b=C;Td(m,b,Ed(k^d,l^e,k,l)|0,C,g)|0;l=Ed(c[g>>2]^h,c[g+4>>2]^j,h,j)|0;j=C;i=f;return (C=j,l)|0}function Qd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;a=c;c=Nd(e,a)|0;f=C;return (C=(_(b,a)|0)+(_(d,e)|0)+f|f&0,c|0|0)|0}function Rd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return Td(a,b,c,d,0)|0}function Sd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=i;i=i+8|0;g=f|0;Td(a,b,d,e,g)|0;i=f;return (C=c[g+4>>2]|0,c[g>>2]|0)|0}function Td(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0;g=a;h=b;i=h;j=d;k=e;l=k;if(!i){m=(f|0)!=0;if(!l){if(m){c[f>>2]=(g>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(g>>>0)/(j>>>0)>>>0;return (C=n,o)|0}else{if(!m){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;o=0;return (C=n,o)|0}}m=(l|0)==0;do if(j){if(!m){p=(aa(l|0)|0)-(aa(i|0)|0)|0;if(p>>>0<=31){q=p+1|0;r=31-p|0;s=p-31>>31;t=q;u=g>>>(q>>>0)&s|i<<r;v=i>>>(q>>>0)&s;w=0;x=g<<r;break}if(!f){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return (C=n,o)|0}r=j-1|0;if(r&j){s=(aa(j|0)|0)+33-(aa(i|0)|0)|0;q=64-s|0;p=32-s|0;y=p>>31;z=s-32|0;A=z>>31;t=s;u=p-1>>31&i>>>(z>>>0)|(i<<p|g>>>(s>>>0))&A;v=A&i>>>(s>>>0);w=g<<q&y;x=(i<<q|g>>>(z>>>0))&y|g<<p&s-33>>31;break}if(f){c[f>>2]=r&g;c[f+4>>2]=0}if((j|0)==1){n=h|b&0;o=a|0|0;return (C=n,o)|0}else{r=Md(j|0)|0;n=i>>>(r>>>0)|0;o=i<<32-r|g>>>(r>>>0)|0;return (C=n,o)|0}}else{if(m){if(f){c[f>>2]=(i>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(i>>>0)/(j>>>0)>>>0;return (C=n,o)|0}if(!g){if(f){c[f>>2]=0;c[f+4>>2]=(i>>>0)%(l>>>0)}n=0;o=(i>>>0)/(l>>>0)>>>0;return (C=n,o)|0}r=l-1|0;if(!(r&l)){if(f){c[f>>2]=a|0;c[f+4>>2]=r&i|b&0}n=0;o=i>>>((Md(l|0)|0)>>>0);return (C=n,o)|0}r=(aa(l|0)|0)-(aa(i|0)|0)|0;if(r>>>0<=30){s=r+1|0;p=31-r|0;t=s;u=i<<p|g>>>(s>>>0);v=i>>>(s>>>0);w=0;x=g<<p;break}if(!f){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return (C=n,o)|0}while(0);if(!t){B=x;D=w;E=v;F=u;G=0;H=0}else{b=d|0|0;d=k|e&0;e=Id(b|0,d|0,-1,-1)|0;k=C;h=x;x=w;w=v;v=u;u=t;t=0;do{a=h;h=x>>>31|h<<1;x=t|x<<1;g=v<<1|a>>>31|0;a=v>>>31|w<<1|0;Ed(e,k,g,a)|0;i=C;l=i>>31|((i|0)<0?-1:0)<<1;t=l&1;v=Ed(g,a,l&b,(((i|0)<0?-1:0)>>31|((i|0)<0?-1:0)<<1)&d)|0;w=C;u=u-1|0}while((u|0)!=0);B=h;D=x;E=w;F=v;G=0;H=t}t=D;D=0;if(f){c[f>>2]=F;c[f+4>>2]=E}n=(t|0)>>>31|(B|D)<<1|(D<<1|t>>>31)&0|G;o=(t<<1|0>>>31)&-2|H;return (C=n,o)|0}function Ud(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;return Va[a&7](b|0,c|0,d|0,e|0)|0}function Vd(a,b){a=a|0;b=b|0;Wa[a&7](b|0)}function Wd(a,b,c){a=a|0;b=b|0;c=c|0;Xa[a&3](b|0,c|0)}function Xd(a,b){a=a|0;b=b|0;return Ya[a&1](b|0)|0}function Yd(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;Za[a&1](b|0,c|0,d|0)}function Zd(a,b,c,d,e,f,g,h,i){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;return _a[a&3](b|0,c|0,d|0,e|0,f|0,g|0,h|0,i|0)|0}function _d(a,b,c){a=a|0;b=b|0;c=c|0;return $a[a&15](b|0,c|0)|0}function $d(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;return ab[a&7](b|0,c|0,d|0,e|0,f|0)|0}function ae(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;ba(0);return 0}function be(a){a=a|0;ba(1)}function ce(a,b){a=a|0;b=b|0;ba(2)}function de(a){a=a|0;ba(3);return 0}function ee(a,b,c){a=a|0;b=b|0;c=c|0;ba(4)}function fe(a,b,c,d,e,f,g,h){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;ba(5);return 0}function ge(a,b){a=a|0;b=b|0;ba(6);return 0}function he(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;ba(7);return 0} + +// EMSCRIPTEN_END_FUNCS +var Va=[ae,$c,fd,qc,rc,ae,ae,ae];var Wa=[be,Yc,Zc,cd,dd,bc,cc,id];var Xa=[ce,Uc,dc,ce];var Ya=[de,jd];var Za=[ee,gd];var _a=[fe,hc,lc,fe];var $a=[ge,Vc,Xc,_c,ad,bd,ed,ec,fc,hd,kd,Sc,Tc,Wc,ge,ge];var ab=[he,gc,ic,jc,kc,mc,he,he];return{_i64Subtract:Ed,_free:yd,_ogv_audio_decoder_destroy:od,_ogv_audio_decoder_init:ld,_i64Add:Id,_strlen:Hd,_ogv_audio_decoder_process_header:md,_memset:Fd,_malloc:xd,_memcpy:Jd,_ogv_audio_decoder_process_audio:nd,_bitshift64Shl:Gd,runPostSets:Dd,stackAlloc:bb,stackSave:cb,stackRestore:db,establishStackSpace:eb,setThrew:fb,setTempRet0:ib,getTempRet0:jb,dynCall_iiiii:Ud,dynCall_vi:Vd,dynCall_vii:Wd,dynCall_ii:Xd,dynCall_viii:Yd,dynCall_iiiiiiiii:Zd,dynCall_iii:_d,dynCall_iiiiii:$d}}) + + +// EMSCRIPTEN_END_ASM +(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var _i64Subtract=Module["_i64Subtract"]=asm["_i64Subtract"];var _free=Module["_free"]=asm["_free"];var runPostSets=Module["runPostSets"]=asm["runPostSets"];var _ogv_audio_decoder_destroy=Module["_ogv_audio_decoder_destroy"]=asm["_ogv_audio_decoder_destroy"];var _ogv_audio_decoder_init=Module["_ogv_audio_decoder_init"]=asm["_ogv_audio_decoder_init"];var _i64Add=Module["_i64Add"]=asm["_i64Add"];var _strlen=Module["_strlen"]=asm["_strlen"];var _ogv_audio_decoder_process_header=Module["_ogv_audio_decoder_process_header"]=asm["_ogv_audio_decoder_process_header"];var _memset=Module["_memset"]=asm["_memset"];var _malloc=Module["_malloc"]=asm["_malloc"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var _ogv_audio_decoder_process_audio=Module["_ogv_audio_decoder_process_audio"]=asm["_ogv_audio_decoder_process_audio"];var _bitshift64Shl=Module["_bitshift64Shl"]=asm["_bitshift64Shl"];var dynCall_iiiii=Module["dynCall_iiiii"]=asm["dynCall_iiiii"];var dynCall_vi=Module["dynCall_vi"]=asm["dynCall_vi"];var dynCall_vii=Module["dynCall_vii"]=asm["dynCall_vii"];var dynCall_ii=Module["dynCall_ii"]=asm["dynCall_ii"];var dynCall_viii=Module["dynCall_viii"]=asm["dynCall_viii"];var dynCall_iiiiiiiii=Module["dynCall_iiiiiiiii"]=asm["dynCall_iiiiiiiii"];var dynCall_iii=Module["dynCall_iii"]=asm["dynCall_iii"];var dynCall_iiiiii=Module["dynCall_iiiiii"]=asm["dynCall_iiiiii"];Runtime.stackAlloc=asm["stackAlloc"];Runtime.stackSave=asm["stackSave"];Runtime.stackRestore=asm["stackRestore"];Runtime.establishStackSpace=asm["establishStackSpace"];Runtime.setTempRet0=asm["setTempRet0"];Runtime.getTempRet0=asm["getTempRet0"];var i64Math=(function(){var goog={math:{}};goog.math.Long=(function(low,high){this.low_=low|0;this.high_=high|0});goog.math.Long.IntCache_={};goog.math.Long.fromInt=(function(value){if(-128<=value&&value<128){var cachedObj=goog.math.Long.IntCache_[value];if(cachedObj){return cachedObj}}var obj=new goog.math.Long(value|0,value<0?-1:0);if(-128<=value&&value<128){goog.math.Long.IntCache_[value]=obj}return obj});goog.math.Long.fromNumber=(function(value){if(isNaN(value)||!isFinite(value)){return goog.math.Long.ZERO}else if(value<=-goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MIN_VALUE}else if(value+1>=goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MAX_VALUE}else if(value<0){return goog.math.Long.fromNumber(-value).negate()}else{return new goog.math.Long(value%goog.math.Long.TWO_PWR_32_DBL_|0,value/goog.math.Long.TWO_PWR_32_DBL_|0)}});goog.math.Long.fromBits=(function(lowBits,highBits){return new goog.math.Long(lowBits,highBits)});goog.math.Long.fromString=(function(str,opt_radix){if(str.length==0){throw Error("number format error: empty string")}var radix=opt_radix||10;if(radix<2||36<radix){throw Error("radix out of range: "+radix)}if(str.charAt(0)=="-"){return goog.math.Long.fromString(str.substring(1),radix).negate()}else if(str.indexOf("-")>=0){throw Error('number format error: interior "-" character: '+str)}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,8));var result=goog.math.Long.ZERO;for(var i=0;i<str.length;i+=8){var size=Math.min(8,str.length-i);var value=parseInt(str.substring(i,i+size),radix);if(size<8){var power=goog.math.Long.fromNumber(Math.pow(radix,size));result=result.multiply(power).add(goog.math.Long.fromNumber(value))}else{result=result.multiply(radixToPower);result=result.add(goog.math.Long.fromNumber(value))}}return result});goog.math.Long.TWO_PWR_16_DBL_=1<<16;goog.math.Long.TWO_PWR_24_DBL_=1<<24;goog.math.Long.TWO_PWR_32_DBL_=goog.math.Long.TWO_PWR_16_DBL_*goog.math.Long.TWO_PWR_16_DBL_;goog.math.Long.TWO_PWR_31_DBL_=goog.math.Long.TWO_PWR_32_DBL_/2;goog.math.Long.TWO_PWR_48_DBL_=goog.math.Long.TWO_PWR_32_DBL_*goog.math.Long.TWO_PWR_16_DBL_;goog.math.Long.TWO_PWR_64_DBL_=goog.math.Long.TWO_PWR_32_DBL_*goog.math.Long.TWO_PWR_32_DBL_;goog.math.Long.TWO_PWR_63_DBL_=goog.math.Long.TWO_PWR_64_DBL_/2;goog.math.Long.ZERO=goog.math.Long.fromInt(0);goog.math.Long.ONE=goog.math.Long.fromInt(1);goog.math.Long.NEG_ONE=goog.math.Long.fromInt(-1);goog.math.Long.MAX_VALUE=goog.math.Long.fromBits(4294967295|0,2147483647|0);goog.math.Long.MIN_VALUE=goog.math.Long.fromBits(0,2147483648|0);goog.math.Long.TWO_PWR_24_=goog.math.Long.fromInt(1<<24);goog.math.Long.prototype.toInt=(function(){return this.low_});goog.math.Long.prototype.toNumber=(function(){return this.high_*goog.math.Long.TWO_PWR_32_DBL_+this.getLowBitsUnsigned()});goog.math.Long.prototype.toString=(function(opt_radix){var radix=opt_radix||10;if(radix<2||36<radix){throw Error("radix out of range: "+radix)}if(this.isZero()){return"0"}if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){var radixLong=goog.math.Long.fromNumber(radix);var div=this.div(radixLong);var rem=div.multiply(radixLong).subtract(this);return div.toString(radix)+rem.toInt().toString(radix)}else{return"-"+this.negate().toString(radix)}}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,6));var rem=this;var result="";while(true){var remDiv=rem.div(radixToPower);var intval=rem.subtract(remDiv.multiply(radixToPower)).toInt();var digits=intval.toString(radix);rem=remDiv;if(rem.isZero()){return digits+result}else{while(digits.length<6){digits="0"+digits}result=""+digits+result}}});goog.math.Long.prototype.getHighBits=(function(){return this.high_});goog.math.Long.prototype.getLowBits=(function(){return this.low_});goog.math.Long.prototype.getLowBitsUnsigned=(function(){return this.low_>=0?this.low_:goog.math.Long.TWO_PWR_32_DBL_+this.low_});goog.math.Long.prototype.getNumBitsAbs=(function(){if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){return 64}else{return this.negate().getNumBitsAbs()}}else{var val=this.high_!=0?this.high_:this.low_;for(var bit=31;bit>0;bit--){if((val&1<<bit)!=0){break}}return this.high_!=0?bit+33:bit+1}});goog.math.Long.prototype.isZero=(function(){return this.high_==0&&this.low_==0});goog.math.Long.prototype.isNegative=(function(){return this.high_<0});goog.math.Long.prototype.isOdd=(function(){return(this.low_&1)==1});goog.math.Long.prototype.equals=(function(other){return this.high_==other.high_&&this.low_==other.low_});goog.math.Long.prototype.notEquals=(function(other){return this.high_!=other.high_||this.low_!=other.low_});goog.math.Long.prototype.lessThan=(function(other){return this.compare(other)<0});goog.math.Long.prototype.lessThanOrEqual=(function(other){return this.compare(other)<=0});goog.math.Long.prototype.greaterThan=(function(other){return this.compare(other)>0});goog.math.Long.prototype.greaterThanOrEqual=(function(other){return this.compare(other)>=0});goog.math.Long.prototype.compare=(function(other){if(this.equals(other)){return 0}var thisNeg=this.isNegative();var otherNeg=other.isNegative();if(thisNeg&&!otherNeg){return-1}if(!thisNeg&&otherNeg){return 1}if(this.subtract(other).isNegative()){return-1}else{return 1}});goog.math.Long.prototype.negate=(function(){if(this.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.MIN_VALUE}else{return this.not().add(goog.math.Long.ONE)}});goog.math.Long.prototype.add=(function(other){var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.subtract=(function(other){return this.add(other.negate())});goog.math.Long.prototype.multiply=(function(other){if(this.isZero()){return goog.math.Long.ZERO}else if(other.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){return other.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}else if(other.equals(goog.math.Long.MIN_VALUE)){return this.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().multiply(other.negate())}else{return this.negate().multiply(other).negate()}}else if(other.isNegative()){return this.multiply(other.negate()).negate()}if(this.lessThan(goog.math.Long.TWO_PWR_24_)&&other.lessThan(goog.math.Long.TWO_PWR_24_)){return goog.math.Long.fromNumber(this.toNumber()*other.toNumber())}var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.div=(function(other){if(other.isZero()){throw Error("division by zero")}else if(this.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){if(other.equals(goog.math.Long.ONE)||other.equals(goog.math.Long.NEG_ONE)){return goog.math.Long.MIN_VALUE}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ONE}else{var halfThis=this.shiftRight(1);var approx=halfThis.div(other).shiftLeft(1);if(approx.equals(goog.math.Long.ZERO)){return other.isNegative()?goog.math.Long.ONE:goog.math.Long.NEG_ONE}else{var rem=this.subtract(other.multiply(approx));var result=approx.add(rem.div(other));return result}}}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().div(other.negate())}else{return this.negate().div(other).negate()}}else if(other.isNegative()){return this.div(other.negate()).negate()}var res=goog.math.Long.ZERO;var rem=this;while(rem.greaterThanOrEqual(other)){var approx=Math.max(1,Math.floor(rem.toNumber()/other.toNumber()));var log2=Math.ceil(Math.log(approx)/Math.LN2);var delta=log2<=48?1:Math.pow(2,log2-48);var approxRes=goog.math.Long.fromNumber(approx);var approxRem=approxRes.multiply(other);while(approxRem.isNegative()||approxRem.greaterThan(rem)){approx-=delta;approxRes=goog.math.Long.fromNumber(approx);approxRem=approxRes.multiply(other)}if(approxRes.isZero()){approxRes=goog.math.Long.ONE}res=res.add(approxRes);rem=rem.subtract(approxRem)}return res});goog.math.Long.prototype.modulo=(function(other){return this.subtract(this.div(other).multiply(other))});goog.math.Long.prototype.not=(function(){return goog.math.Long.fromBits(~this.low_,~this.high_)});goog.math.Long.prototype.and=(function(other){return goog.math.Long.fromBits(this.low_&other.low_,this.high_&other.high_)});goog.math.Long.prototype.or=(function(other){return goog.math.Long.fromBits(this.low_|other.low_,this.high_|other.high_)});goog.math.Long.prototype.xor=(function(other){return goog.math.Long.fromBits(this.low_^other.low_,this.high_^other.high_)});goog.math.Long.prototype.shiftLeft=(function(numBits){numBits&=63;if(numBits==0){return this}else{var low=this.low_;if(numBits<32){var high=this.high_;return goog.math.Long.fromBits(low<<numBits,high<<numBits|low>>>32-numBits)}else{return goog.math.Long.fromBits(0,low<<numBits-32)}}});goog.math.Long.prototype.shiftRight=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>numBits)}else{return goog.math.Long.fromBits(high>>numBits-32,high>=0?0:-1)}}});goog.math.Long.prototype.shiftRightUnsigned=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>>numBits)}else if(numBits==32){return goog.math.Long.fromBits(high,0)}else{return goog.math.Long.fromBits(high>>>numBits-32,0)}}});var navigator={appName:"Modern Browser"};var dbits;var canary=0xdeadbeefcafe;var j_lm=(canary&16777215)==15715070;function BigInteger(a,b,c){if(a!=null)if("number"==typeof a)this.fromNumber(a,b,c);else if(b==null&&"string"!=typeof a)this.fromString(a,256);else this.fromString(a,b)}function nbi(){return new BigInteger(null)}function am1(i,x,w,j,c,n){while(--n>=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}if(j_lm&&navigator.appName=="Microsoft Internet Explorer"){BigInteger.prototype.am=am2;dbits=30}else if(j_lm&&navigator.appName!="Netscape"){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz";var BI_RC=new Array;var rr,vv;rr="0".charCodeAt(0);for(vv=0;vv<=9;++vv)BI_RC[rr++]=vv;rr="a".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;rr="A".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;function int2char(n){return BI_RM.charAt(n)}function intAt(s,i){var c=BI_RC[s.charCodeAt(i)];return c==null?-1:c}function bnpCopyTo(r){for(var i=this.t-1;i>=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{this.fromRadix(s,b);return}this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)this[this.t++]=x;else if(sh+k>this.DB){this[this.t-1]|=(x&(1<<this.DB-sh)-1)<<sh;this[this.t++]=x>>this.DB-sh}else this[this.t-1]|=x<<sh;sh+=k;if(sh>=this.DB)sh-=this.DB}if(k==8&&(s[0]&128)!=0){this.s=-1;if(sh>0)this[this.t-1]|=(1<<this.DB-sh)-1<<sh}this.clamp();if(mi)BigInteger.ZERO.subTo(this,this)}function bnpClamp(){var c=this.s&this.DM;while(this.t>0&&this[this.t-1]==c)--this.t}function bnToString(b){if(this.s<0)return"-"+this.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return this.toRadix(b);var km=(1<<k)-1,d,m=false,r="",i=this.t;var p=this.DB-i*this.DB%k;if(i-->0){if(p<this.DB&&(d=this[i]>>p)>0){m=true;r=int2char(d)}while(i>=0){if(p<k){d=(this[i]&(1<<p)-1)<<k-p;d|=this[--i]>>(p+=this.DB-k)}else{d=this[i]>>(p-=k)&km;if(p<=0){p+=this.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i<this.t;++i)r[i-n]=this[i];r.t=Math.max(this.t-n,0);r.s=this.s}function bnpLShiftTo(n,r){var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<cbs)-1;var ds=Math.floor(n/this.DB),c=this.s<<bs&this.DM,i;for(i=this.t-1;i>=0;--i){r[i+ds+1]=this[i]>>cbs|c;c=(this[i]&bm)<<bs}for(i=ds-1;i>=0;--i)r[i]=0;r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp()}function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return}var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<bs)-1;r[0]=this[ds]>>bs;for(var i=ds+1;i<this.t;++i){r[i-ds-1]|=(this[i]&bm)<<cbs;r[i-ds]=this[i]>>bs}if(bs>0)r[this.t-ds-1]|=(this.s&bm)<<cbs;r.t=this.t-ds;r.clamp()}function bnpSubTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]-a[i];r[i++]=c&this.DM;c>>=this.DB}if(a.t<this.t){c-=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB}c+=this.s}else{c+=this.s;while(i<a.t){c-=a[i];r[i++]=c&this.DM;c>>=this.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=this.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i<y.t;++i)r[i+x.t]=x.am(0,y[i],r,i,0,x.t);r.s=0;r.clamp();if(this.s!=a.s)BigInteger.ZERO.subTo(r,r)}function bnpSquareTo(r){var x=this.abs();var i=r.t=2*x.t;while(--i>=0)r[i]=0;for(i=0;i<x.t-1;++i){var c=x.am(i,x[i],r,2*i,0,1);if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1))>=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0)return;var pt=this.abs();if(pt.t<pm.t){if(q!=null)q.fromInt(0);if(r!=null)this.copyTo(r);return}if(r==null)r=nbi();var y=nbi(),ts=this.s,ms=m.s;var nsh=this.DB-nbits(pm[pm.t-1]);if(nsh>0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<<this.F1)+(ys>1?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<<this.F1)/yt,e=1<<this.F2;var i=r.t,j=i-ys,t=q==null?nbi():q;y.dlShiftTo(j,t);if(r.compareTo(t)>=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t<ys)y[y.t++]=0;while(--j>=0){var qd=r[--i]==y0?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))<qd){y.dlShiftTo(j,t);r.subTo(t,r);while(r[i]<--qd)r.subTo(t,r)}}if(q!=null){r.drShiftTo(ys,q);if(ts!=ms)BigInteger.ZERO.subTo(q,q)}r.t=ys;r.clamp();if(nsh>0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<m.DB-15)-1;this.mt2=2*m.t}function montConvert(x){var r=nbi();x.abs().dlShiftTo(this.m.t,r);r.divRemTo(this.m,null,r);if(x.s<0&&r.compareTo(BigInteger.ZERO)>0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i<this.m.t;++i){var j=x[i]&32767;var u0=j*this.mpl+((j*this.mph+(x[i]>>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<<i)>0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnpFromRadix(s,b){this.fromInt(0);if(b==null)b=10;var cs=this.chunkSize(b);var d=Math.pow(b,cs),mi=false,j=0,w=0;for(var i=0;i<s.length;++i){var x=intAt(s,i);if(x<0){if(s.charAt(i)=="-"&&this.signum()==0)mi=true;continue}w=b*w+x;if(++j>=cs){this.dMultiply(d);this.dAddOffset(w,0);j=0;w=0}}if(j>0){this.dMultiply(Math.pow(b,j));this.dAddOffset(w,0)}if(mi)BigInteger.ZERO.subTo(this,this)}function bnpChunkSize(r){return Math.floor(Math.LN2*this.DB/Math.log(r))}function bnSigNum(){if(this.s<0)return-1;else if(this.t<=0||this.t==1&&this[0]<=0)return 0;else return 1}function bnpDMultiply(n){this[this.t]=this.am(0,n-1,this,0,0,this.t);++this.t;this.clamp()}function bnpDAddOffset(n,w){if(n==0)return;while(this.t<=w)this[this.t++]=0;this[w]+=n;while(this[w]>=this.DV){this[w]-=this.DV;if(++w>=this.t)this[this.t++]=0;++this[w]}}function bnpToRadix(b){if(b==null)b=10;if(this.signum()==0||b<2||b>36)return"0";var cs=this.chunkSize(b);var a=Math.pow(b,cs);var d=nbv(a),y=nbi(),z=nbi(),r="";this.divRemTo(d,y,z);while(y.signum()>0){r=(a+z.intValue()).toString(b).substr(1)+r;y.divRemTo(d,y,z)}return z.intValue().toString(b)+r}function bnIntValue(){if(this.s<0){if(this.t==1)return this[0]-this.DV;else if(this.t==0)return-1}else if(this.t==1)return this[0];else if(this.t==0)return 0;return(this[1]&(1<<32-this.DB)-1)<<this.DB|this[0]}function bnpAddTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]+a[i];r[i++]=c&this.DM;c>>=this.DB}if(a.t<this.t){c+=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB}c+=this.s}else{c+=this.s;while(i<a.t){c+=a[i];r[i++]=c&this.DM;c>>=this.DB}c+=a.s}r.s=c<0?-1:0;if(c>0)r[i++]=c;else if(c<-1)r[i++]=this.DV+c;r.t=i;r.clamp()}BigInteger.prototype.fromRadix=bnpFromRadix;BigInteger.prototype.chunkSize=bnpChunkSize;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.dMultiply=bnpDMultiply;BigInteger.prototype.dAddOffset=bnpDAddOffset;BigInteger.prototype.toRadix=bnpToRadix;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.addTo=bnpAddTo;var Wrapper={abs:(function(l,h){var x=new goog.math.Long(l,h);var ret;if(x.isNegative()){ret=x.negate()}else{ret=x}HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_}),ensureTemps:(function(){if(Wrapper.ensuredTemps)return;Wrapper.ensuredTemps=true;Wrapper.two32=new BigInteger;Wrapper.two32.fromString("4294967296",10);Wrapper.two64=new BigInteger;Wrapper.two64.fromString("18446744073709551616",10);Wrapper.temp1=new BigInteger;Wrapper.temp2=new BigInteger}),lh2bignum:(function(l,h){var a=new BigInteger;a.fromString(h.toString(),10);var b=new BigInteger;a.multiplyTo(Wrapper.two32,b);var c=new BigInteger;c.fromString(l.toString(),10);var d=new BigInteger;c.addTo(b,d);return d}),stringify:(function(l,h,unsigned){var ret=(new goog.math.Long(l,h)).toString();if(unsigned&&ret[0]=="-"){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(ret,10);ret=new BigInteger;Wrapper.two64.addTo(bignum,ret);ret=ret.toString(10)}return ret}),fromString:(function(str,base,min,max,unsigned){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(str,base);var bigmin=new BigInteger;bigmin.fromString(min,10);var bigmax=new BigInteger;bigmax.fromString(max,10);if(unsigned&&bignum.compareTo(BigInteger.ZERO)<0){var temp=new BigInteger;bignum.addTo(Wrapper.two64,temp);bignum=temp}var error=false;if(bignum.compareTo(bigmin)<0){bignum=bigmin;error=true}else if(bignum.compareTo(bigmax)>0){bignum=bigmax;error=true}var ret=goog.math.Long.fromString(bignum.toString());HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_;if(error)throw"range error"})};return Wrapper})();function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){assert(runDependencies==0,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");assert(__ATPRERUN__.length==0,"cannot call main when preRun functions remain to be called");args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]),"i8",ALLOC_NORMAL)];pad();for(var i=0;i<argc-1;i=i+1){argv.push(allocate(intArrayFromString(args[i]),"i8",ALLOC_NORMAL));pad()}argv.push(0);argv=allocate(argv,"i32",ALLOC_NORMAL);initialStackTop=STACKTOP;try{var ret=Module["_main"](argc,argv,0);exit(ret,true)}catch(e){if(e instanceof ExitStatus){return}else if(e=="SimulateInfiniteLoop"){Module["noExitRuntime"]=true;return}else{if(e&&typeof e==="object"&&e.stack)Module.printErr("exception thrown: "+[e,e.stack]);throw e}}finally{calledMain=true}};function run(args){args=args||Module["arguments"];if(preloadStartTime===null)preloadStartTime=Date.now();if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(ENVIRONMENT_IS_WEB&&preloadStartTime!==null){Module.printErr("pre-main prep time: "+(Date.now()-preloadStartTime)+" ms")}if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(Module["_main"]&&shouldRunNow)Module["callMain"](args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["stdout"]["once"]("drain",(function(){process["exit"](status)}));console.log(" ");setTimeout((function(){process["exit"](status)}),500)}else if(ENVIRONMENT_IS_SHELL&&typeof quit==="function"){quit(status)}throw new ExitStatus(status)}Module["exit"]=Module.exit=exit;var abortDecorators=[];function abort(what){if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=false;if(Module["noInitialRun"]){shouldRunNow=false}Module["noExitRuntime"]=true;run();var inputBuffer,inputBufferSize;function reallocInputBuffer(size){if(inputBuffer&&inputBufferSize>=size){return inputBuffer}if(inputBuffer){Module._free(inputBuffer)}inputBufferSize=size;inputBuffer=Module._malloc(inputBufferSize);return inputBuffer}Module.loadedMetadata=!!options.audioFormat;Module.audioFormat=options.audioFormat||null;Module.audioBuffer=null;Object.defineProperty(Module,"processing",{get:function getProcessing(){return false}});Module.init=(function(callback){Module._ogv_audio_decoder_init();callback()});Module.processHeader=(function(data,callback){var len=data.byteLength;var buffer=reallocInputBuffer(len);Module.HEAPU8.set(new Uint8Array(data),buffer);var ret=Module._ogv_audio_decoder_process_header(buffer,len);callback(ret)});Module.processAudio=(function(data,callback){var len=data.byteLength;var buffer=reallocInputBuffer(len);Module.HEAPU8.set(new Uint8Array(data),buffer);var ret=Module._ogv_audio_decoder_process_audio(buffer,len);callback(ret)}) + + + + + + return Module; +}; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-video-theora.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-video-theora.js new file mode 100644 index 00000000..3421de39 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-decoder-video-theora.js @@ -0,0 +1,22 @@ +var OGVDecoderVideoTheora = function(Module) { + Module = Module || {}; + +var options=Module;Module={print:(function(str){console.log(str)})};var Module;if(!Module)Module=(typeof OGVDecoderVideoTheora!=="undefined"?OGVDecoderVideoTheora:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB;var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath["normalize"](filename);var ret=nodeFS["readFileSync"](filename);if(!ret&&filename!=nodePath["resolve"](filename)){filename=path.join(__dirname,"..","src",filename);ret=nodeFS["readFileSync"](filename)}if(ret&&!binary)ret=ret.toString();return ret};Module["readBinary"]=function readBinary(filename){return Module["read"](filename,true)};Module["load"]=function load(f){globalEval(read(f))};if(!Module["thisProgram"]){if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}else{Module["thisProgram"]="unknown-program"}}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function read(){throw"no read() available (jsc?)"}}Module["readBinary"]=function readBinary(f){if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}var data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function printErr(x){console.log(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WORKER){Module["load"]=importScripts}if(typeof Module["setWindowTitle"]==="undefined"){Module["setWindowTitle"]=(function(title){document.title=title})}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}if(!Module["thisProgram"]){Module["thisProgram"]="./this.program"}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}var Runtime={setTempRet0:(function(value){tempRet0=value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),STACK_ALIGN:16,prepVararg:(function(ptr,type){if(type==="double"||type==="i64"){if(ptr&7){assert((ptr&7)===4);ptr+=4}}else{assert((ptr&3)===0)}return ptr}),getAlignSize:(function(type,size,vararg){if(!vararg&&(type=="i64"||type=="double"))return 8;if(!type)return Math.min(size,8);return Math.min(size||(type?Runtime.getNativeFieldSize(type):0),Runtime.QUANTUM_SIZE)}),dynCall:(function(sig,ptr,args){if(args&&args.length){if(!args.splice)args=Array.prototype.slice.call(args);args.splice(0,0,ptr);return Module["dynCall_"+sig].apply(null,args)}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i<Runtime.functionPointers.length;i++){if(!Runtime.functionPointers[i]){Runtime.functionPointers[i]=func;return 2*(1+i)}}throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."}),removeFunction:(function(index){Runtime.functionPointers[(index-2)/2]=null}),warnOnce:(function(text){if(!Runtime.warnOnce.shown)Runtime.warnOnce.shown={};if(!Runtime.warnOnce.shown[text]){Runtime.warnOnce.shown[text]=1;Module.printErr(text)}}),funcWrappers:{},getFuncWrapper:(function(func,sig){assert(sig);if(!Runtime.funcWrappers[sig]){Runtime.funcWrappers[sig]={}}var sigCache=Runtime.funcWrappers[sig];if(!sigCache[func]){sigCache[func]=function dynCall_wrapper(){return Runtime.dynCall(sig,func,arguments)}}return sigCache[func]}),getCompilerSetting:(function(name){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"}),stackAlloc:(function(size){var ret=STACKTOP;STACKTOP=STACKTOP+size|0;STACKTOP=STACKTOP+15&-16;return ret}),staticAlloc:(function(size){var ret=STATICTOP;STATICTOP=STATICTOP+size|0;STATICTOP=STATICTOP+15&-16;return ret}),dynamicAlloc:(function(size){var ret=DYNAMICTOP;DYNAMICTOP=DYNAMICTOP+size|0;DYNAMICTOP=DYNAMICTOP+15&-16;if(DYNAMICTOP>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){DYNAMICTOP=ret;return 0}}return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:16))*(quantum?quantum:16);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var __THREW__=0;var ABORT=false;var EXITSTATUS=0;var undef=0;var tempValue,tempInt,tempBigInt,tempInt2,tempBigInt2,tempPair,tempBigIntI,tempBigIntR,tempBigIntS,tempBigIntP,tempBigIntD,tempDouble,tempFloat;var tempI64,tempI64b;var tempRet0,tempRet1,tempRet2,tempRet3,tempRet4,tempRet5,tempRet6,tempRet7,tempRet8,tempRet9;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var globalScope=this;function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var JSfuncs={"stackSave":(function(){Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore()}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=Runtime.stackAlloc((str.length<<2)+1);writeStringToMemory(str,ret)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args,opts){var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=Runtime.stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);if(returnType==="string")ret=Pointer_stringify(ret);if(stack!==0){if(opts&&opts.async){EmterpreterAsync.asyncFinalizers.push((function(){Runtime.stackRestore(stack)}));return}Runtime.stackRestore(stack)}return ret};var sourceRegex=/^function\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/;function parseJSFunc(jsfunc){var parsed=jsfunc.toString().match(sourceRegex).slice(1);return{arguments:parsed[0],body:parsed[1],returnValue:parsed[2]}}var JSsource={};for(var fun in JSfuncs){if(JSfuncs.hasOwnProperty(fun)){JSsource[fun]=parseJSFunc(JSfuncs[fun])}}cwrap=function cwrap(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident);var numericArgs=argTypes.every((function(type){return type==="number"}));var numericRet=returnType!=="string";if(numericRet&&numericArgs){return cfunc}var argNames=argTypes.map((function(x,i){return"$"+i}));var funcstr="(function("+argNames.join(",")+") {";var nargs=argTypes.length;if(!numericArgs){funcstr+="var stack = "+JSsource["stackSave"].body+";";for(var i=0;i<nargs;i++){var arg=argNames[i],type=argTypes[i];if(type==="number")continue;var convertCode=JSsource[type+"ToC"];funcstr+="var "+convertCode.arguments+" = "+arg+";";funcstr+=convertCode.body+";";funcstr+=arg+"="+convertCode.returnValue+";"}}var cfuncname=parseJSFunc((function(){return cfunc})).returnValue;funcstr+="var ret = "+cfuncname+"("+argNames.join(",")+");";if(!numericRet){var strgfy=parseJSFunc((function(){return Pointer_stringify})).returnValue;funcstr+="ret = "+strgfy+"(ret);"}if(!numericArgs){funcstr+=JSsource["stackRestore"].body.replace("()","(stack)")+";"}funcstr+="return ret})";return eval(funcstr)}}))();Module["cwrap"]=cwrap;Module["ccall"]=ccall;function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr<stop;ptr+=4){HEAP32[ptr>>2]=0}stop=ret+size;while(ptr<stop){HEAP8[ptr++>>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i<size){var curr=slab[i];if(typeof curr==="function"){curr=Runtime.getFunctionIndex(curr)}type=singleType||types[i];if(type===0){i++;continue}if(type=="i64")type="i32";setValue(ret+i,curr,type);if(previousType!==type){typeSize=Runtime.getNativeTypeSize(type);previousType=type}i+=typeSize}return ret}Module["allocate"]=allocate;function getMemory(size){if(!staticSealed)return Runtime.staticAlloc(size);if(typeof _sbrk!=="undefined"&&!_sbrk.called||!runtimeInitialized)return Runtime.dynamicAlloc(size);return _malloc(size)}Module["getMemory"]=getMemory;function Pointer_stringify(ptr,length){if(length===0||!ptr)return"";var hasUtf=0;var t;var i=0;while(1){t=HEAPU8[ptr+i>>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return Module["UTF8ToString"](ptr)}Module["Pointer_stringify"]=Pointer_stringify;function AsciiToString(ptr){var str="";while(1){var ch=HEAP8[ptr++>>0];if(!ch)return str;str+=String.fromCharCode(ch)}}Module["AsciiToString"]=AsciiToString;function stringToAscii(str,outPtr){return writeAsciiToMemory(str,outPtr,false)}Module["stringToAscii"]=stringToAscii;function UTF8ArrayToString(u8Array,idx){var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}Module["UTF8ArrayToString"]=UTF8ArrayToString;function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}Module["UTF8ToString"]=UTF8ToString;function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}Module["stringToUTF8Array"]=stringToUTF8Array;function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}Module["stringToUTF8"]=stringToUTF8;function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}Module["lengthBytesUTF8"]=lengthBytesUTF8;function UTF16ToString(ptr){var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}Module["UTF16ToString"]=UTF16ToString;function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}Module["stringToUTF16"]=stringToUTF16;function lengthBytesUTF16(str){return str.length*2}Module["lengthBytesUTF16"]=lengthBytesUTF16;function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}Module["UTF32ToString"]=UTF32ToString;function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}Module["stringToUTF32"]=stringToUTF32;function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}Module["lengthBytesUTF32"]=lengthBytesUTF32;function demangle(func){var hasLibcxxabi=!!Module["___cxa_demangle"];if(hasLibcxxabi){try{var buf=_malloc(func.length);writeStringToMemory(func.substr(1),buf);var status=_malloc(4);var ret=Module["___cxa_demangle"](buf,0,0,status);if(getValue(status,"i32")===0&&ret){return Pointer_stringify(ret)}}catch(e){}finally{if(buf)_free(buf);if(status)_free(status);if(ret)_free(ret)}}var i=3;var basicTypes={"v":"void","b":"bool","c":"char","s":"short","i":"int","l":"long","f":"float","d":"double","w":"wchar_t","a":"signed char","h":"unsigned char","t":"unsigned short","j":"unsigned int","m":"unsigned long","x":"long long","y":"unsigned long long","z":"..."};var subs=[];var first=true;function dump(x){if(x)Module.print(x);Module.print(func);var pre="";for(var a=0;a<i;a++)pre+=" ";Module.print(pre+"^")}function parseNested(){i++;if(func[i]==="K")i++;var parts=[];while(func[i]!=="E"){if(func[i]==="S"){i++;var next=func.indexOf("_",i);var num=func.substring(i,next)||0;parts.push(subs[num]||"?");i=next+1;continue}if(func[i]==="C"){parts.push(parts[parts.length-1]);i+=2;continue}var size=parseInt(func.substr(i));var pre=size.toString().length;if(!size||!pre){i--;break}var curr=func.substr(i+pre,size);parts.push(curr);subs.push(curr);i+=pre+size}i++;return parts}function parse(rawList,limit,allowVoid){limit=limit||Infinity;var ret="",list=[];function flushList(){return"("+list.join(", ")+")"}var name;if(func[i]==="N"){name=parseNested().join("::");limit--;if(limit===0)return rawList?[name]:name}else{if(func[i]==="K"||first&&func[i]==="L")i++;var size=parseInt(func.substr(i));if(size){var pre=size.toString().length;name=func.substr(i+pre,size);i+=pre+size}}first=false;if(func[i]==="I"){i++;var iList=parse(true);var iRet=parse(true,1,true);ret+=iRet[0]+" "+name+"<"+iList.join(", ")+">"}else{ret=name}paramLoop:while(i<func.length&&limit-->0){var c=func[i++];if(c in basicTypes){list.push(basicTypes[c])}else{switch(c){case"P":list.push(parse(true,1,true)[0]+"*");break;case"R":list.push(parse(true,1,true)[0]+"&");break;case"L":{i++;var end=func.indexOf("E",i);var size=end-i;list.push(func.substr(i,size));i+=size+2;break};case"A":{var size=parseInt(func.substr(i));i+=size.toString().length;if(func[i]!=="_")throw"?";i++;list.push(parse(true,1,true)[0]+" ["+size+"]");break};case"E":break paramLoop;default:ret+="?"+c;break paramLoop}}}if(!allowVoid&&list.length===1&&list[0]==="void")list=[];if(rawList){if(ret){list.push(ret+"?")}return list}else{return ret+flushList()}}var parsed=func;try{if(func=="Object._main"||func=="_main"){return"main()"}if(typeof func==="number")func=Pointer_stringify(func);if(func[0]!=="_")return func;if(func[1]!=="_")return func;if(func[2]!=="Z")return func;switch(func[3]){case"n":return"operator new()";case"d":return"operator delete()"}parsed=parse()}catch(e){parsed+="?"}if(parsed.indexOf("?")>=0&&!hasLibcxxabi){Runtime.warnOnce("warning: a problem occurred in builtin C++ name demangling; build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling")}return parsed}function demangleAll(text){return text.replace(/__Z[\w\d_]+/g,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){return demangleAll(jsStackTrace())}Module["stackTrace"]=stackTrace;var PAGE_SIZE=4096;function alignMemoryPage(x){if(x%4096>0){x+=4096-x%4096}return x}var HEAP;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var STATIC_BASE=0,STATICTOP=0,staticSealed=false;var STACK_BASE=0,STACKTOP=0,STACK_MAX=0;var DYNAMIC_BASE=0,DYNAMICTOP=0;function enlargeMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.")}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||33554432;var totalMemory=64*1024;while(totalMemory<TOTAL_MEMORY||totalMemory<2*TOTAL_STACK){if(totalMemory<16*1024*1024){totalMemory*=2}else{totalMemory+=16*1024*1024}}if(totalMemory!==TOTAL_MEMORY){Module.printErr("increasing TOTAL_MEMORY to "+totalMemory+" to be compliant with the asm.js spec (and given that TOTAL_STACK="+TOTAL_STACK+")");TOTAL_MEMORY=totalMemory}assert(typeof Int32Array!=="undefined"&&typeof Float64Array!=="undefined"&&!!(new Int32Array(1))["subarray"]&&!!(new Int32Array(1))["set"],"JS engine does not provide full typed array support");var buffer;buffer=new ArrayBuffer(TOTAL_MEMORY);HEAP8=new Int8Array(buffer);HEAP16=new Int16Array(buffer);HEAP32=new Int32Array(buffer);HEAPU8=new Uint8Array(buffer);HEAPU16=new Uint16Array(buffer);HEAPU32=new Uint32Array(buffer);HEAPF32=new Float32Array(buffer);HEAPF64=new Float64Array(buffer);HEAP32[0]=255;assert(HEAPU8[0]===255&&HEAPU8[3]===0,"Typed arrays 2 must be run on a little-endian system");Module["HEAP"]=HEAP;Module["buffer"]=buffer;Module["HEAP8"]=HEAP8;Module["HEAP16"]=HEAP16;Module["HEAP32"]=HEAP32;Module["HEAPU8"]=HEAPU8;Module["HEAPU16"]=HEAPU16;Module["HEAPU32"]=HEAPU32;Module["HEAPF32"]=HEAPF32;Module["HEAPF64"]=HEAPF64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Runtime.dynCall("v",func)}else{Runtime.dynCall("vi",func,[callback.arg])}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=Module.addOnPreRun=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=Module.addOnInit=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=Module.addOnPreMain=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=Module.addOnExit=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=Module.addOnPostRun=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i<array.length;i++){var chr=array[i];if(chr>255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){var array=intArrayFromString(string,dontAddNull);var i=0;while(i<array.length){var chr=array[i];HEAP8[buffer+i>>0]=chr;i=i+1}}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){for(var i=0;i<array.length;i++){HEAP8[buffer++>>0]=array[i]}}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;function unSign(value,bits,ignore){if(value>=0){return value}return bits<=32?2*Math.abs(1<<bits-1)+value:Math.pow(2,bits)+value}function reSign(value,bits,ignore){if(value<=0){return value}var half=bits<=32?Math.abs(1<<bits-1):Math.pow(2,bits-1);if(value>=half&&(bits<=32||value>half)){value=-2*half+value}return value}if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];if(!Math["clz32"])Math["clz32"]=(function(x){x=x>>>0;for(var i=0;i<32;i++){if(x&1<<31-i)return i}return 32});Math.clz32=Math["clz32"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_min=Math.min;var Math_clz32=Math.clz32;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;var ASM_CONSTS=[];STATIC_BASE=8;STATICTOP=STATIC_BASE+2448;__ATINIT__.push();allocate([0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,0,3,1,2,0,0,0,0,0,1,2,3,4,8,0,0,0,0,0,0,0,1,2,3,4,5,8,9,0,0,0,0,0,1,2,3,4,6,8,10,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,6,8,8,12,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,116,104,101,111,114,97,0,0,4,0,255,254,255,254,255,254,255,254,255,254,255,254,255,254,255,254,254,252,254,252,253,252,253,252,252,251,251,251,224,251,17,0,2,0,220,253,216,253,180,253,36,253,0,0,0,0,5,0,255,253,255,253,255,253,255,253,255,253,255,253,255,253,255,253,254,253,254,253,254,253,254,253,254,253,254,253,254,253,254,253,253,252,253,252,253,252,253,252,252,252,252,252,252,252,252,252,251,251,251,251,250,251,250,251,33,0,36,0,39,0,44,0,1,0,249,254,248,254,1,0,247,254,246,254,2,0,245,253,244,253,243,253,242,253,4,0,241,251,240,251,239,251,238,251,237,251,236,251,235,251,234,251,233,251,232,251,231,251,230,251,229,251,228,251,227,251,226,251,0,0,0,0,0,0,3,4,2,0,1,5,6,7,3,4,0,2,1,5,6,7,3,2,4,0,1,5,6,7,3,2,0,4,1,5,6,7,0,3,4,2,1,5,6,7,0,5,3,4,2,1,6,7,0,1,2,3,4,5,6,7,3,0,0,253,255,252,254,252,253,252,252,252,251,252,250,252,249,252,0,0,0,0,0,0,4,0,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,255,253,255,253,255,253,255,253,254,252,254,252,253,251,17,0,3,0,252,254,252,254,252,254,252,254,251,253,251,253,250,252,249,252,0,0,0,0,6,0,224,249,224,249,223,249,225,249,222,249,226,249,221,249,227,249,220,249,228,249,219,249,229,249,218,249,230,249,217,249,231,249,216,249,232,249,215,249,233,249,214,249,234,249,213,249,235,249,212,249,236,249,211,249,237,249,210,249,238,249,209,249,239,249,208,249,240,249,207,249,241,249,206,249,242,249,205,249,243,249,204,249,244,249,203,249,245,249,202,249,246,249,201,249,247,249,200,249,248,249,199,249,249,249,198,249,250,249,197,249,251,249,196,249,252,249,195,249,253,249,194,249,254,249,193,249,255,249,0,0,0,0,0,0,5,0,224,252,224,252,224,252,224,252,223,252,223,252,223,252,223,252,225,252,225,252,225,252,225,252,222,251,222,251,226,251,226,251,221,251,221,251,227,251,227,251,33,0,36,0,39,0,42,0,45,0,50,0,55,0,60,0,65,0,74,0,83,0,92,0,1,0,220,254,228,254,1,0,219,254,229,254,1,0,218,254,230,254,1,0,217,254,231,254,2,0,216,253,232,253,215,253,233,253,2,0,214,253,234,253,213,253,235,253,2,0,212,253,236,253,211,253,237,253,2,0,210,253,238,253,209,253,239,253,3,0,208,252,240,252,207,252,241,252,206,252,242,252,205,252,243,252,3,0,204,252,244,252,203,252,245,252,202,252,246,252,201,252,247,252,3,0,200,252,248,252,199,252,249,252,198,252,250,252,197,252,251,252,3,0,196,252,252,252,195,252,253,252,194,252,254,252,193,252,255,252,0,0,0,0,0,0,12,4,3,3,4,4,5,5,8,8,8,8,3,3,6,0,0,0,0,0,0,16,0,0,0,0,160,1,0,0,144,1,0,0,160,2,0,0,144,2,0,0,160,4,0,0,144,4,0,0,160,8,0,0,160,40,0,0,144,8,0,0,144,40,10,0,32,0,10,0,224,255,0,0,240,255,0,1,0,0,0,2,0,0,0,3,0,0,1,0,32,0,1,0,224,255,2,0,32,0,2,0,224,255,3,0,32,0,3,0,224,255,4,0,32,0,4,0,224,255,5,0,32,0,5,0,224,255,1,0,64,0,1,0,96,0,1,0,192,255,1,0,160,255,6,0,32,0,7,0,32,0,8,0,32,0,9,0,32,0,6,0,224,255,7,0,224,255,8,0,224,255,9,0,224,255,2,0,64,0,3,0,64,0,2,0,96,0,3,0,96,0,2,0,192,255,3,0,192,255,2,0,160,255,3,0,160,255,0,0,240,255,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,0,0,32,0,0,0,224,255,0,0,64,0,0,0,192,255,0,0,96,0,0,0,160,255,0,0,128,0,0,0,128,255,0,0,160,0,0,0,96,255,0,0,192,0,0,0,64,255,0,0,224,0,0,0,0,1,0,0,32,255,0,0,0,255,0,0,32,1,0,0,64,1,0,0,96,1,0,0,128,1,0,0,224,254,0,0,192,254,0,0,160,254,0,0,128,254,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,12,0,0,0,13,0,0,0,14,0,0,0,15,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,1,6,15,28,64,0,0,0,0,0,0,2,3,0,0,3,0,0,0,0,0,1,1,1,1,2,3,1,1,1,2,1,1,1,1,1,3,1,2,3,15,16,17,88,80,1,0,48,14,56,57,58,59,60,62,64,66,68,72,2,4,6,8,18,20,22,24,26,32,12,28,40,16,0,0,0,32,0,0,0,8,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,3,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,241,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,0,249,249,249,249,250,250,250,250,251,251,251,251,252,252,252,252,253,253,253,253,254,254,254,254,255,255,255,255,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,255,255,255,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,24,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,69,114,114,111,114,32,112,97,114,115,105,110,103,32,116,104,101,111,114,97,32,104,101,97,100,101,114,115,58,32,37,100,46,10,0,0,0,0,0,0,84,104,101,111,114,97,32,100,101,99,111,100,101,114,32,102,97,105,108,101,100,32,109,121,115,116,101,114,105,111,117,115,108,121,63,32,37,100,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=Runtime.alignMemory(allocate(12,"i8",ALLOC_STATIC),8);assert(tempDoublePtr%8==0);function copyTempFloat(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3]}function copyTempDouble(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3];HEAP8[tempDoublePtr+4]=HEAP8[ptr+4];HEAP8[tempDoublePtr+5]=HEAP8[ptr+5];HEAP8[tempDoublePtr+6]=HEAP8[ptr+6];HEAP8[tempDoublePtr+7]=HEAP8[ptr+7]}Module["_i64Subtract"]=_i64Subtract;Module["_i64Add"]=_i64Add;Module["_memset"]=_memset;Module["_bitshift64Shl"]=_bitshift64Shl;function _abort(){Module["abort"]()}function _ogvjs_callback_frame(bufferY,strideY,bufferCb,strideCb,bufferCr,strideCr,width,height,hdec,vdec){var HEAPU8=Module.HEAPU8,widthColor=width>>hdec,heightColor=height>>vdec,countBytesY=strideY*height,countBytesCb=strideCb*heightColor,countBytesCr=strideCr*heightColor,bytesY=HEAPU8.subarray(bufferY,bufferY+countBytesY),bytesCb=HEAPU8.subarray(bufferCb,bufferCb+countBytesCb),bytesCr=HEAPU8.subarray(bufferCr,bufferCr+countBytesCr);Module.frameBuffer={bytesY:bytesY,bytesCb:bytesCb,bytesCr:bytesCr,strideY:strideY,strideCb:strideCb,strideCr:strideCr,width:width,height:height,hdec:hdec,vdec:vdec}}var FS=undefined;var ___errno_state=0;function ___setErrNo(value){HEAP32[___errno_state>>2]=value;return value}var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};var SOCKFS=undefined;function _send(fd,buf,len,flags){var sock=SOCKFS.getSocket(fd);if(!sock){___setErrNo(ERRNO_CODES.EBADF);return-1}return _write(fd,buf,len)}function _pwrite(fildes,buf,nbyte,offset){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte,offset)}catch(e){FS.handleFSError(e);return-1}}function _write(fildes,buf,nbyte){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte)}catch(e){FS.handleFSError(e);return-1}}function _fileno(stream){stream=FS.getStreamFromPtr(stream);if(!stream)return-1;return stream.fd}function _fwrite(ptr,size,nitems,stream){var bytesToWrite=nitems*size;if(bytesToWrite==0)return 0;var fd=_fileno(stream);var bytesWritten=_write(fd,ptr,bytesToWrite);if(bytesWritten==-1){var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=true;return 0}else{return bytesWritten/size|0}}Module["_strlen"]=_strlen;function __reallyNegative(x){return x<0||x===0&&1/x===-Infinity}function __formatString(format,varargs){assert((varargs&3)===0);var textIndex=format;var argIndex=0;function getNextArg(type){var ret;argIndex=Runtime.prepVararg(argIndex,type);if(type==="double"){ret=(HEAP32[tempDoublePtr>>2]=HEAP32[varargs+argIndex>>2],HEAP32[tempDoublePtr+4>>2]=HEAP32[varargs+(argIndex+4)>>2],+HEAPF64[tempDoublePtr>>3]);argIndex+=8}else if(type=="i64"){ret=[HEAP32[varargs+argIndex>>2],HEAP32[varargs+(argIndex+4)>>2]];argIndex+=8}else{assert((argIndex&3)===0);type="i32";ret=HEAP32[varargs+argIndex>>2];argIndex+=4}return ret}var ret=[];var curr,next,currArg;while(1){var startTextIndex=textIndex;curr=HEAP8[textIndex>>0];if(curr===0)break;next=HEAP8[textIndex+1>>0];if(curr==37){var flagAlwaysSigned=false;var flagLeftAlign=false;var flagAlternative=false;var flagZeroPad=false;var flagPadSign=false;flagsLoop:while(1){switch(next){case 43:flagAlwaysSigned=true;break;case 45:flagLeftAlign=true;break;case 35:flagAlternative=true;break;case 48:if(flagZeroPad){break flagsLoop}else{flagZeroPad=true;break};case 32:flagPadSign=true;break;default:break flagsLoop}textIndex++;next=HEAP8[textIndex+1>>0]}var width=0;if(next==42){width=getNextArg("i32");textIndex++;next=HEAP8[textIndex+1>>0]}else{while(next>=48&&next<=57){width=width*10+(next-48);textIndex++;next=HEAP8[textIndex+1>>0]}}var precisionSet=false,precision=-1;if(next==46){precision=0;precisionSet=true;textIndex++;next=HEAP8[textIndex+1>>0];if(next==42){precision=getNextArg("i32");textIndex++}else{while(1){var precisionChr=HEAP8[textIndex+1>>0];if(precisionChr<48||precisionChr>57)break;precision=precision*10+(precisionChr-48);textIndex++}}next=HEAP8[textIndex+1>>0]}if(precision<0){precision=6;precisionSet=false}var argSize;switch(String.fromCharCode(next)){case"h":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==104){textIndex++;argSize=1}else{argSize=2}break;case"l":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==108){textIndex++;argSize=8}else{argSize=4}break;case"L":case"q":case"j":argSize=8;break;case"z":case"t":case"I":argSize=4;break;default:argSize=null}if(argSize)textIndex++;next=HEAP8[textIndex+1>>0];switch(String.fromCharCode(next)){case"d":case"i":case"u":case"o":case"x":case"X":case"p":{var signed=next==100||next==105;argSize=argSize||4;var currArg=getNextArg("i"+argSize*8);var origArg=currArg;var argText;if(argSize==8){currArg=Runtime.makeBigInt(currArg[0],currArg[1],next==117)}if(argSize<=4){var limit=Math.pow(256,argSize)-1;currArg=(signed?reSign:unSign)(currArg&limit,argSize*8)}var currAbsArg=Math.abs(currArg);var prefix="";if(next==100||next==105){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],null);else argText=reSign(currArg,8*argSize,1).toString(10)}else if(next==117){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],true);else argText=unSign(currArg,8*argSize,1).toString(10);currArg=Math.abs(currArg)}else if(next==111){argText=(flagAlternative?"0":"")+currAbsArg.toString(8)}else if(next==120||next==88){prefix=flagAlternative&&currArg!=0?"0x":"";if(argSize==8&&i64Math){if(origArg[1]){argText=(origArg[1]>>>0).toString(16);var lower=(origArg[0]>>>0).toString(16);while(lower.length<8)lower="0"+lower;argText+=lower}else{argText=(origArg[0]>>>0).toString(16)}}else if(currArg<0){currArg=-currArg;argText=(currAbsArg-1).toString(16);var buffer=[];for(var i=0;i<argText.length;i++){buffer.push((15-parseInt(argText[i],16)).toString(16))}argText=buffer.join("");while(argText.length<argSize*2)argText="f"+argText}else{argText=currAbsArg.toString(16)}if(next==88){prefix=prefix.toUpperCase();argText=argText.toUpperCase()}}else if(next==112){if(currAbsArg===0){argText="(nil)"}else{prefix="0x";argText=currAbsArg.toString(16)}}if(precisionSet){while(argText.length<precision){argText="0"+argText}}if(currArg>=0){if(flagAlwaysSigned){prefix="+"+prefix}else if(flagPadSign){prefix=" "+prefix}}if(argText.charAt(0)=="-"){prefix="-"+prefix;argText=argText.substr(1)}while(prefix.length+argText.length<width){if(flagLeftAlign){argText+=" "}else{if(flagZeroPad){argText="0"+argText}else{prefix=" "+prefix}}}argText=prefix+argText;argText.split("").forEach((function(chr){ret.push(chr.charCodeAt(0))}));break};case"f":case"F":case"e":case"E":case"g":case"G":{var currArg=getNextArg("double");var argText;if(isNaN(currArg)){argText="nan";flagZeroPad=false}else if(!isFinite(currArg)){argText=(currArg<0?"-":"")+"inf";flagZeroPad=false}else{var isGeneral=false;var effectivePrecision=Math.min(precision,20);if(next==103||next==71){isGeneral=true;precision=precision||1;var exponent=parseInt(currArg.toExponential(effectivePrecision).split("e")[1],10);if(precision>exponent&&exponent>=-4){next=(next==103?"f":"F").charCodeAt(0);precision-=exponent+1}else{next=(next==103?"e":"E").charCodeAt(0);precision--}effectivePrecision=Math.min(precision,20)}if(next==101||next==69){argText=currArg.toExponential(effectivePrecision);if(/[eE][-+]\d$/.test(argText)){argText=argText.slice(0,-1)+"0"+argText.slice(-1)}}else if(next==102||next==70){argText=currArg.toFixed(effectivePrecision);if(currArg===0&&__reallyNegative(currArg)){argText="-"+argText}}var parts=argText.split("e");if(isGeneral&&!flagAlternative){while(parts[0].length>1&&parts[0].indexOf(".")!=-1&&(parts[0].slice(-1)=="0"||parts[0].slice(-1)==".")){parts[0]=parts[0].slice(0,-1)}}else{if(flagAlternative&&argText.indexOf(".")==-1)parts[0]+=".";while(precision>effectivePrecision++)parts[0]+="0"}argText=parts[0]+(parts.length>1?"e"+parts[1]:"");if(next==69)argText=argText.toUpperCase();if(currArg>=0){if(flagAlwaysSigned){argText="+"+argText}else if(flagPadSign){argText=" "+argText}}}while(argText.length<width){if(flagLeftAlign){argText+=" "}else{if(flagZeroPad&&(argText[0]=="-"||argText[0]=="+")){argText=argText[0]+"0"+argText.slice(1)}else{argText=(flagZeroPad?"0":" ")+argText}}}if(next<97)argText=argText.toUpperCase();argText.split("").forEach((function(chr){ret.push(chr.charCodeAt(0))}));break};case"s":{var arg=getNextArg("i8*");var argLength=arg?_strlen(arg):"(null)".length;if(precisionSet)argLength=Math.min(argLength,precision);if(!flagLeftAlign){while(argLength<width--){ret.push(32)}}if(arg){for(var i=0;i<argLength;i++){ret.push(HEAPU8[arg++>>0])}}else{ret=ret.concat(intArrayFromString("(null)".substr(0,argLength),true))}if(flagLeftAlign){while(argLength<width--){ret.push(32)}}break};case"c":{if(flagLeftAlign)ret.push(getNextArg("i8"));while(--width>0){ret.push(32)}if(!flagLeftAlign)ret.push(getNextArg("i8"));break};case"n":{var ptr=getNextArg("i32*");HEAP32[ptr>>2]=ret.length;break};case"%":{ret.push(curr);break};default:{for(var i=startTextIndex;i<textIndex+2;i++){ret.push(HEAP8[i>>0])}}}textIndex+=2}else{ret.push(curr);textIndex+=1}}return ret}function _fprintf(stream,format,varargs){var result=__formatString(format,varargs);var stack=Runtime.stackSave();var ret=_fwrite(allocate(result,"i8",ALLOC_STACK),1,result.length,stream);Runtime.stackRestore(stack);return ret}function _printf(format,varargs){var result=__formatString(format,varargs);var string=intArrayToString(result);if(string[string.length-1]==="\n")string=string.substr(0,string.length-1);Module.print(string);return result.length}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}Module["_memcpy"]=_memcpy;function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 85:return totalMemory/PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 79:return 0;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(ERRNO_CODES.EINVAL);return-1}function _sbrk(bytes){var self=_sbrk;if(!self.called){DYNAMICTOP=alignMemoryPage(DYNAMICTOP);self.called=true;assert(Runtime.dynamicAlloc);self.alloc=Runtime.dynamicAlloc;Runtime.dynamicAlloc=(function(){abort("cannot dynamically allocate, sbrk now has control")})}var ret=DYNAMICTOP;if(bytes!=0){var success=self.alloc(bytes);if(!success)return-1>>>0}return ret}function ___errno_location(){return ___errno_state}function _ogvjs_callback_init_video(frameWidth,frameHeight,hdec,vdec,fps,picWidth,picHeight,picX,picY,displayWidth,displayHeight){Module.videoFormat={frameWidth:frameWidth,frameHeight:frameHeight,hdec:hdec,vdec:vdec,fps:fps,picWidth:picWidth,picHeight:picHeight,picX:picX,picY:picY,displayWidth:displayWidth,displayHeight:displayHeight};Module.loadedMetadata=true}function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}___errno_state=Runtime.staticAlloc(4);HEAP32[___errno_state>>2]=0;STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP);staticSealed=true;STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=DYNAMICTOP=Runtime.alignMemory(STACK_MAX);assert(DYNAMIC_BASE<TOTAL_MEMORY,"TOTAL_MEMORY not big enough for stack");var cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_DYNAMIC);function invoke_vii(index,a1,a2){try{Module["dynCall_vii"](index,a1,a2)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_viiii(index,a1,a2,a3,a4){try{Module["dynCall_viiii"](index,a1,a2,a3,a4)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}Module.asmGlobalArg={"Math":Math,"Int8Array":Int8Array,"Int16Array":Int16Array,"Int32Array":Int32Array,"Uint8Array":Uint8Array,"Uint16Array":Uint16Array,"Uint32Array":Uint32Array,"Float32Array":Float32Array,"Float64Array":Float64Array,"NaN":NaN,"Infinity":Infinity};Module.asmLibraryArg={"abort":abort,"assert":assert,"invoke_vii":invoke_vii,"invoke_viiii":invoke_viiii,"_ogvjs_callback_init_video":_ogvjs_callback_init_video,"__formatString":__formatString,"_ogvjs_callback_frame":_ogvjs_callback_frame,"_send":_send,"_pwrite":_pwrite,"_abort":_abort,"___setErrNo":___setErrNo,"_fwrite":_fwrite,"_sbrk":_sbrk,"_printf":_printf,"_fprintf":_fprintf,"__reallyNegative":__reallyNegative,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_fileno":_fileno,"_write":_write,"_time":_time,"_sysconf":_sysconf,"___errno_location":___errno_location,"STACKTOP":STACKTOP,"STACK_MAX":STACK_MAX,"tempDoublePtr":tempDoublePtr,"ABORT":ABORT,"cttz_i8":cttz_i8};// EMSCRIPTEN_START_ASM +var asm=(function(global,env,buffer) { +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=env.cttz_i8|0;var n=0;var o=0;var p=0;var q=0;var r=global.NaN,s=global.Infinity;var t=0,u=0,v=0,w=0,x=0.0,y=0,z=0,A=0,B=0.0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=0;var M=global.Math.floor;var N=global.Math.abs;var O=global.Math.sqrt;var P=global.Math.pow;var Q=global.Math.cos;var R=global.Math.sin;var S=global.Math.tan;var T=global.Math.acos;var U=global.Math.asin;var V=global.Math.atan;var W=global.Math.atan2;var X=global.Math.exp;var Y=global.Math.log;var Z=global.Math.ceil;var _=global.Math.imul;var $=global.Math.min;var aa=global.Math.clz32;var ba=env.abort;var ca=env.assert;var da=env.invoke_vii;var ea=env.invoke_viiii;var fa=env._ogvjs_callback_init_video;var ga=env.__formatString;var ha=env._ogvjs_callback_frame;var ia=env._send;var ja=env._pwrite;var ka=env._abort;var la=env.___setErrNo;var ma=env._fwrite;var na=env._sbrk;var oa=env._printf;var pa=env._fprintf;var qa=env.__reallyNegative;var ra=env._emscripten_memcpy_big;var sa=env._fileno;var ta=env._write;var ua=env._time;var va=env._sysconf;var wa=env.___errno_location;var xa=0.0; +// EMSCRIPTEN_START_FUNCS +function Aa(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function Ba(){return i|0}function Ca(a){a=a|0;i=a}function Da(a,b){a=a|0;b=b|0;i=a;j=b}function Ea(a,b){a=a|0;b=b|0;if(!n){n=a;o=b}}function Fa(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Ga(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ha(a){a=a|0;C=a}function Ia(){return C|0}function Ja(a,b,d){a=a|0;b=b|0;d=d|0;c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;c[a+4>>2]=b;c[a>>2]=b+d;return}function Ka(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;e=a+8|0;f=a+12|0;g=c[f>>2]|0;if(!b){h=0;return h|0}i=c[e>>2]|0;if((g|0)<(b|0)){j=c[a>>2]|0;k=a+4|0;l=c[k>>2]|0;m=32-g|0;n=l>>>0<j>>>0;if(m>>>0>7&n){o=l-j|0;p=(24-g|0)>>>3;q=~p;r=o>>>0>q>>>0?o:q;q=l+(0-r)|0;s=~p;p=0-(o>>>0>s>>>0?o:s)|0;s=l;o=m;t=i;while(1){o=o+-8|0;u=s;s=s+1|0;v=(d[u>>0]|0)<<o|t;if((s|0)==(q|0)){w=v;break}else t=v}x=(l+p|0)>>>0<j>>>0;y=q;z=m+(r<<3)|0;A=w}else{x=n;y=l;z=m;A=i}c[k>>2]=y;k=32-z|0;do if((k|0)<(b|0))if(x){B=k;C=(d[y>>0]|0)>>>(k&7)|A;break}else{c[a+16>>2]=1;B=1073741824;C=A;break}else{B=k;C=A}while(0);c[f>>2]=B;D=B;E=C}else{D=g;E=i}c[e>>2]=E<<1<<b+-1;c[f>>2]=D-b;h=E>>>(32-b|0);return h|0}function La(a){a=a|0;var b=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;b=a+8|0;e=c[b>>2]|0;f=a+12|0;g=c[f>>2]|0;if((g|0)>=1){h=g;i=e;j=i>>>31;k=h+-1|0;l=i<<1;c[b>>2]=l;c[f>>2]=k;return j|0}m=c[a>>2]|0;n=a+4|0;o=c[n>>2]|0;p=32-g|0;q=o>>>0<m>>>0;if(p>>>0>7&q){r=o-m|0;s=(24-g|0)>>>3;g=~s;t=r>>>0>g>>>0?r:g;g=o+(0-t)|0;u=~s;s=0-(r>>>0>u>>>0?r:u)|0;u=o;r=p;v=e;while(1){r=r+-8|0;w=u;u=u+1|0;x=(d[w>>0]|0)<<r|v;if((u|0)==(g|0)){y=x;break}else v=x}z=(o+s|0)>>>0<m>>>0;A=g;B=p+(t<<3)|0;C=y}else{z=q;A=o;B=p;C=e}c[n>>2]=A;n=32-B|0;do if((n|0)<1)if(z){D=n;E=(d[A>>0]|0)>>>(n&7)|C;break}else{c[a+16>>2]=1;D=1073741824;E=C;break}else{D=n;E=C}while(0);c[f>>2]=D;h=D;i=E;j=i>>>31;k=h+-1|0;l=i<<1;c[b>>2]=l;c[f>>2]=k;return j|0}function Ma(a){a=a|0;var b=0;if(c[a+16>>2]|0){b=-1;return b|0}b=(c[a>>2]|0)-(c[a+4>>2]|0)+(c[a+12>>2]>>3)|0;return b|0}function Na(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;h=i;i=i+32|0;j=h+20|0;k=h;if(!g){l=-20;i=h;return l|0}if(!b){l=-1;i=h;return l|0}Ja(k,c[g>>2]|0,c[g+4>>2]|0);m=Ka(k,8)|0;if((((m&128|0)==0?(c[b+4>>2]|0)!=0:0)?(c[e+12>>2]|0)!=0:0)?(c[f>>2]|0)!=0:0)n=0;else o=7;a:do if((o|0)==7){a[j>>0]=Ka(k,8)|0;a[j+1>>0]=Ka(k,8)|0;a[j+2>>0]=Ka(k,8)|0;a[j+3>>0]=Ka(k,8)|0;a[j+4>>0]=Ka(k,8)|0;a[j+5>>0]=Ka(k,8)|0;if(!(Nb(j,216,6)|0))if((m|0)==128){if(!(c[g+8>>2]|0)){n=-20;break}p=b+4|0;if(c[p>>2]|0){n=-20;break}a[b>>0]=Ka(k,8)|0;q=b+1|0;a[q>>0]=Ka(k,8)|0;a[b+2>>0]=Ka(k,8)|0;r=a[b>>0]|0;do if((r&255)<=3){if(r<<24>>24==3?(d[q>>0]|0)>2:0){s=-22;break}c[p>>2]=(Ka(k,16)|0)<<4;t=b+8|0;c[t>>2]=(Ka(k,16)|0)<<4;u=b+12|0;c[u>>2]=Ka(k,24)|0;v=b+16|0;c[v>>2]=Ka(k,24)|0;w=b+20|0;c[w>>2]=Ka(k,8)|0;x=b+24|0;c[x>>2]=Ka(k,8)|0;y=b+28|0;c[y>>2]=Ka(k,32)|0;z=Ka(k,32)|0;c[b+32>>2]=z;A=c[p>>2]|0;if(((((((A|0)!=0?(B=c[t>>2]|0,(B|0)!=0):0)?((c[w>>2]|0)+(c[u>>2]|0)|0)>>>0<=A>>>0:0)?(A=c[v>>2]|0,v=c[x>>2]|0,(v+A|0)>>>0<=B>>>0):0)?!((z|0)==0|(c[y>>2]|0)==0):0)?(c[x>>2]=B-A-v,c[b+36>>2]=Ka(k,24)|0,c[b+40>>2]=Ka(k,24)|0,c[b+44>>2]=Ka(k,8)|0,c[b+52>>2]=Ka(k,24)|0,c[b+56>>2]=Ka(k,6)|0,c[b+60>>2]=Ka(k,5)|0,v=Ka(k,2)|0,c[b+48>>2]=v,(v|0)!=1):0)?(Ka(k,3)|0)==0:0){v=(Ma(k)|0)>>31&-20;if((v|0)<0)s=v;else{n=3;break a}}else s=-20}else s=-22;while(0);eb(b);n=s;break}else if((m|0)==129){if(!e){n=-1;break}if(!(c[b+4>>2]|0)){n=-20;break}p=e+12|0;if(c[p>>2]|0){n=-20;break}q=Ka(k,8)|0;r=Ka(k,8)|0;v=Ka(k,8)|0;A=r<<8|q|v<<16|(Ka(k,8)|0)<<24;b:do if((A|0)>=0?(A|0)<=(Ma(k)|0):0){v=Ob(A+1|0)|0;c[p>>2]=v;if(!v)C=-1;else{if(!A)D=v;else{q=A;r=v;while(1){q=q+-1|0;a[r>>0]=Ka(k,8)|0;if(!q)break;else r=r+1|0}D=c[p>>2]|0}a[D+A>>0]=0;r=Ka(k,8)|0;q=Ka(k,8)|0;v=Ka(k,8)|0;B=q<<8|r|v<<16|(Ka(k,8)|0)<<24;v=e+8|0;c[v>>2]=B;if(B>>>0<=536870911?(B<<2|0)<=(Ma(k)|0):0){B=c[v>>2]|0;r=B<<2;q=Ob(r)|0;x=e+4|0;c[x>>2]=q;y=Ob(r)|0;c[e>>2]=y;if((q|0)==0|(y|0)==0){c[v>>2]=0;C=-1;break}c:do if((B|0)>0){y=0;while(1){q=Ka(k,8)|0;r=Ka(k,8)|0;z=Ka(k,8)|0;u=r<<8|q|z<<16|(Ka(k,8)|0)<<24;if((u|0)<0){E=y;o=40;break}if((u|0)>(Ma(k)|0)){E=y;o=40;break}c[(c[x>>2]|0)+(y<<2)>>2]=u;z=Ob(u+1|0)|0;c[(c[e>>2]|0)+(y<<2)>>2]=z;z=c[(c[e>>2]|0)+(y<<2)>>2]|0;if(!z){F=y;o=42;break}if(!u)G=z;else{q=u;r=z;while(1){q=q+-1|0;a[r>>0]=Ka(k,8)|0;if(!q)break;else r=r+1|0}G=c[(c[e>>2]|0)+(y<<2)>>2]|0}a[G+u>>0]=0;y=y+1|0;if((y|0)>=(c[v>>2]|0))break c}if((o|0)==40){c[v>>2]=E;C=-20;break b}else if((o|0)==42){c[v>>2]=F;C=-1;break b}}while(0);x=(Ma(k)|0)>>31&-20;if((x|0)<0){C=x;break}else{n=2;break a}}c[v>>2]=0;C=-20}}else C=-20;while(0);gb(e);n=C;break}else if((m|0)==130){if((e|0)==0|(f|0)==0){n=-1;break}if(!(c[b+4>>2]|0)){n=-20;break}if(!(c[e+12>>2]|0)){n=-20;break}if(c[f>>2]|0){n=-20;break}A=Qb(1,712)|0;if(!A){n=-1;break}p=A+320|0;x=Ta(k,p)|0;if((x|0)>=0){B=_a(k,A)|0;if((B|0)<0)H=B;else{c[f>>2]=A;n=1;break}}else H=x;Ua(p);ab(A);Pb(A);n=H;break}else{n=-20;break}else n=-21}while(0);l=n;i=h;return l|0}function Oa(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0;e=c[b+2936+(d<<2)>>2]|0;f=c[b+2948+(d<<2)>>2]|0;g=c[a+72+(d<<5)>>2]|0;h=c[a+168>>2]|0;if((f|0)<=(e|0)){i=0;j=b+2840+(d<<2)|0;c[j>>2]=i;k=f-e|0;l=_(k,g)|0;m=l-i|0;n=b+2852+(d<<2)|0;c[n>>2]=m;return}o=(g|0)>0;p=1-g|0;q=~g;r=(c[a+72+(d<<5)+8>>2]|0)+(_(g,e)|0)|0;a=e;s=0;while(1){if(!a)if(o){t=r;u=0;v=s;while(1){w=h+(t<<2)|0;x=c[w>>2]|0;if(!(x&1))y=v;else{z=b+2960+(d<<4)+((x>>>6&3)<<2)|0;A=(c[z>>2]<<16)+x|0;c[w>>2]=A;c[z>>2]=A>>16;y=v+1|0}u=u+1|0;if((u|0)==(g|0)){B=y;break}else{t=t+1|0;v=y}}C=g+r|0;D=B}else{C=r;D=s}else if(o){v=r;t=0;u=-1;A=s;z=(c[h+(r-g<<2)>>2]|0)>>>6&3;w=-1;while(1){t=t+1|0;if((t|0)<(g|0))E=(c[h+(p+v<<2)>>2]|0)>>>6&3;else E=-1;x=h+(v<<2)|0;F=c[x>>2]|0;if(!(F&1)){G=-1;H=A}else{I=F>>>6&3;do switch(((w|0)==(I|0)&1)<<1|(u|0)==(I|0)|((z|0)==(I|0)&1)<<2|((E|0)==(I|0)&1)<<3|0){case 13:case 11:case 9:{J=(((c[h+(p+v<<2)>>2]>>16)*53|0)+((c[h+(v+-1<<2)>>2]>>16)*75|0)|0)/128|0;break}case 5:{J=((c[h+(v-g<<2)>>2]>>16)+(c[h+(v+-1<<2)>>2]>>16)|0)/2|0;break}case 12:case 6:case 4:{J=c[h+(v-g<<2)>>2]>>16;break}case 10:{J=((c[h+(p+v<<2)>>2]>>16)+(c[h+(v+q<<2)>>2]>>16)|0)/2|0;break}case 14:{J=((((c[h+(p+v<<2)>>2]>>16)+(c[h+(v+q<<2)>>2]>>16)|0)*3|0)+((c[h+(v-g<<2)>>2]>>16)*10|0)|0)/16|0;break}case 15:case 7:{K=v+-1|0;L=c[h+(K<<2)>>2]>>16;M=c[h+(K-g<<2)>>2]>>16;K=c[h+(v-g<<2)>>2]>>16;N=(((K+L|0)*29|0)+(_(M,-26)|0)|0)/32|0;O=N-K|0;if((((O|0)>-1?O:0-O|0)|0)<=128){O=N-L|0;if((((O|0)>-1?O:0-O|0)|0)>128)J=L;else{L=N-M|0;J=(((L|0)>-1?L:0-L|0)|0)>128?M:N}}else J=K;break}case 8:{J=c[h+(p+v<<2)>>2]>>16;break}case 3:case 1:{J=c[h+(v+-1<<2)>>2]>>16;break}case 2:{J=c[h+(v+q<<2)>>2]>>16;break}default:J=c[b+2960+(d<<4)+(I<<2)>>2]|0}while(0);K=F+(J<<16)|0;c[x>>2]=K;c[b+2960+(d<<4)+(I<<2)>>2]=K>>16;G=I;H=A+1|0}if((t|0)==(g|0)){P=H;break}else{K=z;v=v+1|0;u=G;A=H;z=E;w=K}}C=g+r|0;D=P}else{C=r;D=s}a=a+1|0;if((a|0)==(f|0)){i=D;break}else{r=C;s=D}}j=b+2840+(d<<2)|0;c[j>>2]=i;k=f-e|0;l=_(k,g)|0;m=l-i|0;n=b+2852+(d<<2)|0;c[n>>2]=m;return}function Pa(b,d){b=b|0;d=d|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;if((b|0)==0|(d|0)==0){f=0;return f|0}g=ib(57136,16)|0;do if((g|0)!=0?(mb(g,b,3)|0)>=0:0){h=g+51656|0;if(($a(h,d)|0)<0){nb(g);break}i=Ob((c[g+180>>2]|0)*129|0)|0;c[g+53512>>2]=i;if(!i){ab(h);nb(g);break}else j=0;do{c[g+880+(j*24|0)>>2]=g+2416+(j*768|0);c[g+880+(j*24|0)+4>>2]=g+2416+(j*768|0)+128;c[g+880+(j*24|0)+8>>2]=g+2416+(j*768|0)+256;c[g+880+(j*24|0)+12>>2]=g+2416+(j*768|0)+384;c[g+880+(j*24|0)+16>>2]=g+2416+(j*768|0)+512;c[g+880+(j*24|0)+20>>2]=g+2416+(j*768|0)+640;j=j+1|0}while((j|0)!=64);lb(g+880|0,g+53528|0,d+320|0);h=0;do{i=c[g+880+(h*24|0)>>2]|0;k=c[g+880+(h*24|0)+8>>2]|0;l=c[g+880+(h*24|0)+16>>2]|0;m=c[g+880+(h*24|0)+4>>2]|0;n=c[g+880+(h*24|0)+12>>2]|0;o=c[g+880+(h*24|0)+20>>2]|0;c[g+53784+(h<<2)>>2]=0-((e[k+34>>1]|0)+(e[k+24>>1]|0)+(e[k+36>>1]|0)+(e[k+48>>1]|0)+(e[l+24>>1]|0)+(e[l+34>>1]|0)+(e[l+36>>1]|0)+(e[l+48>>1]|0)+(e[n+24>>1]|0)+(e[n+34>>1]|0)+(e[n+36>>1]|0)+(e[n+48>>1]|0)+(e[o+24>>1]|0)+(e[o+34>>1]|0)+(e[o+36>>1]|0)+(e[o+48>>1]|0)+((e[i+34>>1]|0)+(e[i+24>>1]|0)+(e[i+36>>1]|0)+(e[i+48>>1]|0)+(e[m+24>>1]|0)+(e[m+34>>1]|0)+(e[m+36>>1]|0)+(e[m+48>>1]|0)<<1)>>11);h=h+1|0}while((h|0)!=64);h=g+51568|0;m=d+576|0;i=h+64|0;do{a[h>>0]=a[m>>0]|0;h=h+1|0;m=m+1|0}while((h|0)<(i|0));c[g+53524>>2]=0;c[g+54040>>2]=0;c[g+54044>>2]=0;c[g+54048>>2]=0;c[g+54104>>2]=0;c[g+54108>>2]=0;m=g+856|0;c[m>>2]=0;c[m+4>>2]=0;f=g;return f|0}while(0);jb(g);f=0;return f|0}function Qa(a){a=a|0;if(!a)return;Pb(c[a+54048>>2]|0);Pb(c[a+54044>>2]|0);Pb(c[a+54040>>2]|0);Pb(c[a+53512>>2]|0);ab(a+51656|0);nb(a);jb(a);return}function Ra(f,g,h){f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ma=0,Na=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,ib=0,jb=0,lb=0,mb=0,nb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0,Eb=0,Fb=0,Gb=0,Hb=0,Ib=0,Jb=0,Kb=0,Lb=0,Mb=0,Nb=0,Qb=0,Rb=0,Wb=0,Yb=0,Zb=0,_b=0,$b=0,ac=0,bc=0,cc=0,dc=0,ec=0,fc=0,gc=0,hc=0,ic=0,jc=0,kc=0,lc=0,mc=0,nc=0,oc=0,pc=0,qc=0,rc=0,sc=0,tc=0,uc=0,vc=0,wc=0,xc=0,yc=0,zc=0,Ac=0,Bc=0,Cc=0,Dc=0,Ec=0,Fc=0,Gc=0,Hc=0,Ic=0,Jc=0,Kc=0,Lc=0,Mc=0,Nc=0,Oc=0,Pc=0,Qc=0,Rc=0,Sc=0,Tc=0,Uc=0,Vc=0,Wc=0,Xc=0,Yc=0,Zc=0,_c=0,$c=0,ad=0,bd=0,cd=0,dd=0,ed=0,fd=0,gd=0,hd=0,id=0,jd=0,kd=0,ld=0,md=0,nd=0,od=0,pd=0,qd=0,rd=0,sd=0,td=0,ud=0,vd=0,wd=0,xd=0,yd=0,zd=0,Ad=0,Bd=0,Cd=0,Dd=0,Ed=0,Fd=0,Gd=0,Hd=0,Id=0,Jd=0,Kd=0,Ld=0,Md=0,Nd=0,Od=0,Pd=0,Qd=0,Rd=0,Sd=0,Td=0,Ud=0;j=i;i=i+1088|0;k=j;l=j+312|0;m=j+304|0;n=j+256|0;if((f|0)==0|(g|0)==0){o=-1;i=j;return o|0}p=c[g+4>>2]|0;do if(!p){q=f+872|0;a[q>>0]=1;c[f+232>>2]=0;r=q;s=0}else{q=f+51636|0;Ja(q,c[g>>2]|0,p);if(La(q)|0){o=-24;i=j;return o|0}t=f+872|0;a[t>>0]=La(q)|0;a[f+875>>0]=Ka(q,6)|0;do if(La(q)|0){a[f+876>>0]=Ka(q,6)|0;if(!(La(q)|0)){a[f+874>>0]=2;break}else{a[f+877>>0]=Ka(q,6)|0;a[f+874>>0]=3;break}}else a[f+874>>0]=1;while(0);if(!(a[t>>0]|0)){if(Ka(q,3)|0){o=-23;i=j;return o|0}if(!(a[t>>0]|0)){u=c[f+216>>2]|0;v=c[f+184>>2]|0;w=c[f+188>>2]|0;x=c[f+168>>2]|0;y=0;z=0;A=0;B=0;while(1){y=(c[f+72+(z<<5)+28>>2]|0)+y|0;if(B>>>0<y>>>0){D=A;E=B;while(1){F=w+E|0;G=D;H=0;while(1){if((d[F>>0]|0)>>>2&15&1<<H){I=c[v+(E<<6)+(H<<4)>>2]|0;if((I|0)>-1){J=x+(I<<2)|0;c[J>>2]=c[J>>2]&-1986|385;c[u+(G<<2)>>2]=I;K=G+1|0}else K=G;I=c[v+(E<<6)+(H<<4)+4>>2]|0;if((I|0)>-1){J=x+(I<<2)|0;c[J>>2]=c[J>>2]&-1986|385;c[u+(K<<2)>>2]=I;L=K+1|0}else L=K;I=c[v+(E<<6)+(H<<4)+8>>2]|0;if((I|0)>-1){J=x+(I<<2)|0;c[J>>2]=c[J>>2]&-1986|385;c[u+(L<<2)>>2]=I;M=L+1|0}else M=L;I=c[v+(E<<6)+(H<<4)+12>>2]|0;if((I|0)>-1){J=x+(I<<2)|0;c[J>>2]=c[J>>2]&-1986|385;c[u+(M<<2)>>2]=I;N=M+1|0}else N=M}else N=G;H=H+1|0;if((H|0)==4){O=N;break}else G=N}E=E+1|0;if((E|0)==(y|0)){P=O;Q=y;break}else D=O}}else{P=A;Q=B}c[f+220+(z<<2)>>2]=P-A;z=z+1|0;if((z|0)==3){R=P;break}else{A=P;B=Q}}c[f+232>>2]=R;r=t;s=R;break}}B=La(q)|0;A=f+188|0;z=c[A>>2]|0;y=f+192|0;u=c[y>>2]|0;if(u){x=B;B=0;v=0;while(1){w=bb(q,224)|0;if((w|0)>15){D=w&31;S=D+6+(Ka(q,w-D>>4)|0)|0}else S=w;w=(x&255)<<1&2;D=0-S|0;E=v+1|0;G=v-(u>>>0>E>>>0?u:E)|0;E=G>>>0<D>>>0?D:G;G=v;v=v-E|0;do{D=z+G|0;a[D>>0]=a[D>>0]&-4|w;G=G+1|0}while((G|0)!=(v|0));G=_(E,x)|0;w=v>>>0<u>>>0;D=B-G|0;if(S>>>0>4128&w)T=La(q)|0;else T=(x|0)==0&1;if(!w){U=G;V=D;W=B;break}else{x=T;B=D}}B=c[y>>2]|0;a:do if(V>>>0<B>>>0){x=c[A>>2]|0;u=0;while(1)if(!(a[x+u>>0]&2)){X=u;break}else u=u+1|0;u=La(q)|0;E=X;while(1){v=bb(q,224)|0;if((v|0)>15){z=v&31;Y=z+6+(Ka(q,v-z>>4)|0)|0}else Y=v;if(E>>>0>=B>>>0)break a;v=u&1;z=Y;D=E;while(1){G=x+D|0;w=a[G>>0]|0;if(!(w&2)){if(!z){Z=D;break}a[G>>0]=w&-2|v;$=z+-1|0}else $=z;D=D+1|0;if(D>>>0>=B>>>0)break a;else z=$}if(Y>>>0<4129){u=(u|0)==0&1;E=Z;continue}else{u=La(q)|0;E=Z;continue}}}while(0);if((W|0)!=(U|0))aa=(La(q)|0)==0&1;else aa=0}else aa=0;B=c[f+184>>2]|0;y=c[A>>2]|0;E=c[f+200>>2]|0;u=c[f+168>>2]|0;x=c[f+216>>2]|0;z=c[f+180>>2]|0;D=aa;v=0;w=0;G=0;H=0;F=0;I=0;while(1){w=(c[f+72+(H<<5)+28>>2]|0)+w|0;if(I>>>0<w>>>0){J=(H|0)==0;ba=D;ca=v;da=G;ea=F;fa=I;while(1){ga=y+fa|0;ha=fa<<2;if(J){ia=ba;ja=ca;ka=da;la=0;ma=ea;while(1){if(!((d[ga>>0]|0)>>>2&15&1<<la)){na=ia;oa=ja;pa=ka;qa=ma}else{ra=0;sa=ia;ta=ja;ua=ka;va=0;wa=ma;while(1){xa=c[B+(fa<<6)+(la<<4)+(ra<<2)>>2]|0;if((xa|0)>-1){Aa=a[ga>>0]|0;do if(!(Aa&1)){if(Aa&2){if((wa|0)<1){Ba=(sa|0)==0&1;Ca=bb(q,272)|0}else{Ba=sa;Ca=wa}Da=Ca+-1|0;if(!Ba){Ea=0;Fa=Da}else{Ga=Ba;Ha=Ba;Ia=Da;Ma=67;break}}else{Ea=sa;Fa=wa}c[x+(z+~ua<<2)>>2]=xa;Na=0;Pa=Ea;Qa=ta;Ra=ua+1|0;Sa=Fa}else{Ga=1;Ha=sa;Ia=wa;Ma=67}while(0);if((Ma|0)==67){Ma=0;c[x+(ta<<2)>>2]=xa;Na=Ga;Pa=Ha;Qa=ta+1|0;Ra=ua;Sa=Ia}Aa=u+(xa<<2)|0;c[Aa>>2]=Na&1|c[Aa>>2]&-194|192;Ta=Pa;Ua=Qa;Wa=Ra;Xa=Na|va;Ya=Sa}else{Ta=sa;Ua=ta;Wa=ua;Xa=va;Ya=wa}ra=ra+1|0;if((ra|0)==4){Za=Ta;_a=Ua;$a=Wa;ab=Xa;cb=Ya;break}else{sa=Ta;ta=Ua;ua=Wa;va=Xa;wa=Ya}}a[E+(la|ha)>>0]=ab;na=Za;oa=_a;pa=$a;qa=cb}la=la+1|0;if((la|0)==4){db=na;eb=oa;fb=pa;gb=qa;break}else{ia=na;ja=oa;ka=pa;ma=qa}}}else{ma=ba;ka=ca;ja=da;ia=0;la=ea;while(1){if(!((d[ga>>0]|0)>>>2&15&1<<ia)){hb=ma;ib=ka;jb=ja;lb=la}else{ha=0;wa=ma;va=ka;ua=ja;ta=la;while(1){sa=c[B+(fa<<6)+(ia<<4)+(ha<<2)>>2]|0;if((sa|0)>-1){ra=a[ga>>0]|0;do if(!(ra&1)){if(ra&2){if((ta|0)<1){mb=(wa|0)==0&1;nb=bb(q,272)|0}else{mb=wa;nb=ta}Aa=nb+-1|0;if(!mb){wb=0;xb=Aa}else{yb=mb;zb=mb;Ab=Aa;Ma=79;break}}else{wb=wa;xb=ta}c[x+(z+~ua<<2)>>2]=sa;Bb=0;Cb=wb;Db=va;Eb=ua+1|0;Fb=xb}else{yb=1;zb=wa;Ab=ta;Ma=79}while(0);if((Ma|0)==79){Ma=0;c[x+(va<<2)>>2]=sa;Bb=yb;Cb=zb;Db=va+1|0;Eb=ua;Fb=Ab}ra=u+(sa<<2)|0;c[ra>>2]=Bb&1|c[ra>>2]&-194|192;Gb=Cb;Hb=Db;Ib=Eb;Jb=Fb}else{Gb=wa;Hb=va;Ib=ua;Jb=ta}ha=ha+1|0;if((ha|0)==4){hb=Gb;ib=Hb;jb=Ib;lb=Jb;break}else{wa=Gb;va=Hb;ua=Ib;ta=Jb}}}ia=ia+1|0;if((ia|0)==4){db=hb;eb=ib;fb=jb;gb=lb;break}else{ma=hb;ka=ib;ja=jb;la=lb}}}fa=fa+1|0;if((fa|0)==(w|0)){Kb=db;Lb=eb;Mb=fb;Nb=gb;Qb=w;break}else{ba=db;ca=eb;da=fb;ea=gb}}}else{Kb=D;Lb=v;Mb=G;Nb=F;Qb=I}c[f+220+(H<<2)>>2]=Lb-v;H=H+1|0;if((H|0)==3){Rb=Lb;break}else{D=Kb;v=Lb;G=Mb;F=Nb;I=Qb}}c[f+232>>2]=Rb;r=t;s=Rb}while(0);do if(!(a[r>>0]|0))Wb=s;else{Rb=f+524|0;Qb=f+528|0;if((c[Rb>>2]|0)>=0?(c[Qb>>2]|0)>=0:0){Wb=s;break}c[Rb>>2]=0;c[Qb>>2]=0;c[f+532>>2]=0;Qb=c[f+248>>2]|0;c[f+556>>2]=Qb;c[f+552>>2]=Qb;c[f+548>>2]=Qb;Yb=f+54056|0;Zb=f+236|0;_b=Yb+48|0;do{c[Yb>>2]=c[Zb>>2];Yb=Yb+4|0;Zb=Zb+4|0}while((Yb|0)<(_b|0));t=c[f+576>>2]|0;Rb=(t|0)>-1?t:0-t|0;t=c[f+8>>2]|0;Nb=t+32|0;Mb=c[f+580>>2]|0;Ub(Qb+(-16-(_(Rb,t+15|0)|0))|0,-128,(_(Rb,Nb)|0)+16+(_(((Mb|0)>-1?Mb:0-Mb|0)<<1,Nb>>((c[f+48>>2]|0)>>>1&1^1))|0)|0)|0;Wb=c[f+232>>2]|0}while(0);s=f+232|0;if((Wb|0)<1){Wb=f+848|0;Nb=c[Wb>>2]|0;Mb=c[Wb+4>>2]|0;Wb=Tb(d[f+873>>0]|0,0,Nb|0,Mb|0)|0;Rb=Vb(Wb|0,C|0,c[f+60>>2]|0)|0;Wb=C;t=f+856|0;Lb=t;Kb=c[Lb>>2]|0;gb=c[Lb+4>>2]|0;Lb=Sb(Kb|0,gb|0,Nb|0,Mb|0)|0;Mb=Tb(Lb|0,C|0,Rb|0,Wb|0)|0;Wb=C;Rb=f+864|0;c[Rb>>2]=Mb;c[Rb+4>>2]=Wb;Rb=Tb(Kb|0,gb|0,1,0)|0;gb=t;c[gb>>2]=Rb;c[gb+4>>2]=C;if(!h){o=1;i=j;return o|0}gb=h;c[gb>>2]=Mb;c[gb+4>>2]=Wb;o=1;i=j;return o|0}Wb=f+528|0;gb=f+524|0;Mb=c[gb>>2]|0;Rb=c[Wb>>2]|0;t=0;while(1)if((t|0)==(Mb|0)|(t|0)==(Rb|0))t=t+1|0;else{$b=t;break}t=f+532|0;c[t>>2]=$b;Rb=f+548|0;Mb=f+556|0;c[Mb>>2]=c[f+236+($b*48|0)+12>>2];if(a[r>>0]|0){Kb=f+51636|0;Lb=Ka(Kb,3)|0;if(!Lb){Nb=k;c[Nb>>2]=0;c[Nb+4>>2]=0;a[k+(Ka(Kb,3)|0)>>0]=0;a[k+(Ka(Kb,3)|0)>>0]=1;a[k+(Ka(Kb,3)|0)>>0]=2;a[k+(Ka(Kb,3)|0)>>0]=3;a[k+(Ka(Kb,3)|0)>>0]=4;a[k+(Ka(Kb,3)|0)>>0]=5;a[k+(Ka(Kb,3)|0)>>0]=6;a[k+(Ka(Kb,3)|0)>>0]=7;ac=k}else ac=400+(Lb+-1<<3)|0;Nb=(Lb|0)==7?456:480;Lb=f+200|0;fb=c[Lb>>2]|0;eb=f+212|0;db=c[eb>>2]|0;if(db){lb=0;do{jb=fb+lb|0;if((a[jb>>0]|0)>0)a[jb>>0]=a[ac+(bb(Kb,Nb)|0)>>0]|0;lb=lb+1|0}while((lb|0)!=(db|0))}db=f+48|0;lb=c[200+(c[db>>2]<<2)>>2]|0;Nb=(La(Kb)|0)!=0;ac=Nb?536:672;Nb=c[db>>2]|0;db=a[192+Nb>>0]|0;fb=db&255;jb=c[f+168>>2]|0;ib=c[f+176>>2]|0;hb=c[f+196>>2]|0;Jb=c[Lb>>2]|0;Lb=c[eb>>2]|0;if(Lb){eb=(db&255)>4;db=l+2|0;Ib=l+4|0;Hb=l+6|0;Gb=0;Fb=0;Eb=0;while(1){Db=a[Jb+Fb>>0]|0;Cb=Db<<24>>24;if(Db<<24>>24==7){Bb=c[hb+(Fb*48|0)>>2]|0;Ab=jb+(Bb<<2)|0;zb=c[Ab>>2]|0;if(!(zb&1)){b[l>>1]=0;bc=Gb}else{c[Ab>>2]=zb&-1985|1856;zb=(bb(Kb,ac)|0)+224|0;Ab=(((bb(Kb,ac)|0)<<8)+57344|zb&255)&65535;b[l>>1]=Ab;b[ib+(Bb<<1)>>1]=Ab;bc=Ab}Ab=c[hb+(Fb*48|0)+4>>2]|0;Bb=jb+(Ab<<2)|0;zb=c[Bb>>2]|0;if(!(zb&1)){b[db>>1]=0;cc=bc}else{c[Bb>>2]=zb&-1985|1856;zb=(bb(Kb,ac)|0)+224|0;Bb=(((bb(Kb,ac)|0)<<8)+57344|zb&255)&65535;b[db>>1]=Bb;b[ib+(Ab<<1)>>1]=Bb;cc=Bb}Bb=c[hb+(Fb*48|0)+8>>2]|0;Ab=jb+(Bb<<2)|0;zb=c[Ab>>2]|0;if(!(zb&1)){b[Ib>>1]=0;dc=cc}else{c[Ab>>2]=zb&-1985|1856;zb=(bb(Kb,ac)|0)+224|0;Ab=(((bb(Kb,ac)|0)<<8)+57344|zb&255)&65535;b[Ib>>1]=Ab;b[ib+(Bb<<1)>>1]=Ab;dc=Ab}Ab=c[hb+(Fb*48|0)+12>>2]|0;Bb=jb+(Ab<<2)|0;zb=c[Bb>>2]|0;if(!(zb&1)){b[Hb>>1]=0;ec=dc}else{c[Bb>>2]=zb&-1985|1856;zb=(bb(Kb,ac)|0)+224|0;Bb=(((bb(Kb,ac)|0)<<8)+57344|zb&255)&65535;b[Hb>>1]=Bb;b[ib+(Ab<<1)>>1]=Bb;ec=Bb}ya[lb&7](k,l);if(eb){Bb=4;do{Ab=d[144+(Nb*12|0)+Bb>>0]|0;zb=Ab&3;yb=c[hb+(Fb*48|0)+(Ab>>>2<<4)+(zb<<2)>>2]|0;Ab=jb+(yb<<2)|0;xb=c[Ab>>2]|0;if(xb&1){c[Ab>>2]=xb&-1985|1856;b[ib+(yb<<1)>>1]=b[k+(zb<<1)>>1]|0}Bb=Bb+1|0}while((Bb|0)<(fb|0));fc=ec;gc=Gb}else{fc=ec;gc=Gb}}else if(Db<<24>>24==-1){fc=Gb;gc=Eb}else{if((Cb|0)==2){Bb=(bb(Kb,ac)|0)+224|0;Qb=(((bb(Kb,ac)|0)<<8)+57344|Bb&255)&65535;hc=Qb;ic=Qb;jc=Gb}else if((Cb|0)==4){hc=Eb;ic=Eb;jc=Gb}else if((Cb|0)==6){Qb=(bb(Kb,ac)|0)+224|0;hc=Gb;ic=(((bb(Kb,ac)|0)<<8)+57344|Qb&255)&65535;jc=Eb}else if((Cb|0)==3){hc=Gb;ic=Gb;jc=Eb}else{hc=Gb;ic=0;jc=Eb}Qb=268505377>>>(Cb<<2)<<6&192|Cb<<8&1792;Bb=0;do{zb=d[144+(Nb*12|0)+Bb>>0]|0;yb=c[hb+(Fb*48|0)+(zb>>>2<<4)+((zb&3)<<2)>>2]|0;zb=jb+(yb<<2)|0;xb=c[zb>>2]|0;if(xb&1){c[zb>>2]=Qb|xb&-1985;b[ib+(yb<<1)>>1]=ic}Bb=Bb+1|0}while((Bb|0)<(fb|0));fc=hc;gc=jc}Fb=Fb+1|0;if((Fb|0)==(Lb|0))break;else{Gb=fc;Eb=gc}}}}else{gc=f+856|0;Eb=c[gc+4>>2]|0;fc=f+848|0;c[fc>>2]=c[gc>>2];c[fc+4>>2]=Eb}Eb=c[s>>2]|0;b:do if((Eb|0)>=1){s=c[f+168>>2]|0;fc=c[f+216>>2]|0;gc=f+874|0;if((a[gc>>0]|0)==1){Gb=0;while(1){Lb=s+(c[fc+(Gb<<2)>>2]<<2)|0;c[Lb>>2]=c[Lb>>2]&-61;Gb=Gb+1|0;if((Gb|0)==(Eb|0))break b}}Gb=f+51636|0;Lb=La(Gb)|0;Fb=0;jc=0;while(1){hc=bb(Gb,224)|0;if((hc|0)>15){fb=hc&31;kc=fb+6+(Ka(Gb,hc-fb>>4)|0)|0}else kc=hc;hc=(kc|0)>4128;fb=Lb<<2&60;ic=Fb;ib=jc;jb=kc;while(1){hb=ic+1|0;Nb=s+(c[fc+(ic<<2)>>2]<<2)|0;c[Nb>>2]=c[Nb>>2]&-61|fb;Nb=ib+Lb|0;if((jb|0)<=1){lc=hb;mc=Nb;break}if((hb|0)<(Eb|0)){ic=hb;ib=Nb;jb=jb+-1|0}else{lc=hb;mc=Nb;break}}jb=(lc|0)<(Eb|0);if(hc&jb)nc=La(Gb)|0;else nc=(Lb|0)==0&1;if(jb){Lb=nc;Fb=lc;jc=mc}else{oc=mc;break}}if((oc|0)>0&(a[gc>>0]|0)==3){jc=0;while(1)if(!(c[s+(c[fc+(jc<<2)>>2]<<2)>>2]&60))jc=jc+1|0;else{pc=jc;break}jc=La(Gb)|0;gc=pc;while(1){Fb=bb(Gb,224)|0;if((Fb|0)>15){Lb=Fb&31;qc=Lb+6+(Ka(Gb,Fb-Lb>>4)|0)|0}else qc=Fb;if((gc|0)<(Eb|0)){rc=gc;sc=qc}else break b;while(1){Fb=s+(c[fc+(rc<<2)>>2]<<2)|0;Lb=c[Fb>>2]|0;jb=Lb>>>2;if(!(jb&15))tc=sc;else{if((sc|0)<1){uc=rc;break}c[Fb>>2]=jb+jc<<2&60|Lb&-61;tc=sc+-1|0}rc=rc+1|0;if((rc|0)>=(Eb|0))break b;else sc=tc}if((qc|0)<4129){jc=(jc|0)==0&1;gc=uc;continue}else{jc=La(Gb)|0;gc=uc;continue}}}}while(0);uc=f+220|0;qc=c[uc>>2]|0;tc=0;do{c[l+(tc<<2)>>2]=qc;tc=tc+1|0}while((tc|0)!=64);tc=f+224|0;qc=c[tc>>2]|0;sc=0;do{c[l+256+(sc<<2)>>2]=qc;sc=sc+1|0}while((sc|0)!=64);sc=f+228|0;qc=c[sc>>2]|0;Eb=0;do{c[l+512+(Eb<<2)>>2]=qc;Eb=Eb+1|0}while((Eb|0)!=64);Eb=f+51636|0;c[m>>2]=Ka(Eb,4)|0;qc=m+4|0;c[qc>>2]=Ka(Eb,4)|0;c[f+52744>>2]=0;rc=f+53512|0;pc=c[rc>>2]|0;oc=f+168|0;mc=c[oc>>2]|0;lc=f+216|0;nc=c[lc>>2]|0;kc=k+252|0;gc=0;Gb=0;jc=0;fc=0;s=0;while(1){hc=c[f+220+(fc<<2)>>2]|0;Lb=jc;jc=hc+jc|0;Ub(k|0,0,256)|0;c[f+52744+(fc<<8)>>2]=gc;c[f+51976+(fc<<8)>>2]=s;jb=jc-Gb|0;Fb=(jb|0)<(gc|0)?jb:gc;jb=gc-Fb|0;if((Fb|0)>0){ib=Gb+~Lb-hc|0;ic=~gc;fb=(ib|0)>(ic|0)?ib:ic;ic=Fb;ib=Gb;while(1){Nb=mc+(c[nc+(ib<<2)>>2]<<2)|0;c[Nb>>2]=c[Nb>>2]&65535;if((ic|0)>1){ic=ic+-1|0;ib=ib+1|0}else break}vc=Gb+1-fb+((fb|0)>-2?fb:-2)|0}else vc=Gb;c:do if((jc|0)>(vc|0)){ib=~Lb-hc|0;ic=f+51656+(c[m+(fc+1>>1<<2)>>2]<<2)|0;Nb=Fb;hb=vc;ac=s;while(1){Kb=hb;ec=ac;while(1){eb=bb(Eb,c[ic>>2]|0)|0;lb=ec+1|0;a[pc+ec>>0]=eb;if((eb|0)<15){Hb=Ka(Eb,d[880+eb>>0]|0)|0;dc=ec+2|0;a[pc+lb>>0]=Hb;if(!eb){a[pc+dc>>0]=Hb>>>8;wc=ec+3|0}else wc=dc;xc=Hb<<((eb|0)<2?-13:0)+((eb|0)<12?21:0);yc=wc}else{xc=0;yc=lb}lb=(c[896+(eb<<2)>>2]|0)+xc|0;eb=(lb|0)==0?2147483647:lb>>>8&4095;if(eb){zc=eb;Ac=Kb;Bc=yc;break}eb=lb&255;Hb=k+(eb<<2)|0;c[Hb>>2]=(c[Hb>>2]|0)+1;Hb=Kb+1|0;dc=mc+(c[nc+(Kb<<2)>>2]<<2)|0;c[dc>>2]=c[dc>>2]&65535|((eb|0)!=0?0:(lb^0-(lb&1048576))>>21<<16);if((jc|0)>(Hb|0)){Kb=Hb;ec=yc}else{Cc=Nb;Dc=0;Ec=Hb;Fc=yc;break c}}ec=jc-Ac|0;Kb=(ec|0)<(zc|0)?ec-zc|0:0;ec=Kb+zc|0;Hb=ec+Nb|0;if((ec|0)>0){lb=Ac+ib|0;eb=~zc;dc=(lb|0)>(eb|0)?lb:eb;eb=ec;ec=Ac;while(1){lb=mc+(c[nc+(ec<<2)>>2]<<2)|0;c[lb>>2]=c[lb>>2]&65535;if((eb|0)>1){eb=eb+-1|0;ec=ec+1|0}else break}Gc=Ac+1-dc+((dc|0)>-2?dc:-2)|0}else Gc=Ac;if((jc|0)>(Gc|0)){Nb=Hb;hb=Gc;ac=Bc}else{Hc=Kb;Ic=Hb;Jc=Gc;Kc=Bc;break}}Cc=Ic;Dc=0-Hc|0;Ec=Jc;Fc=Kc}else{Cc=Fb;Dc=jb;Ec=vc;Fc=s}while(0);jb=(c[kc>>2]|0)+Cc|0;c[kc>>2]=jb;Fb=62;hc=jb;while(1){jb=k+(Fb<<2)|0;hc=(c[jb>>2]|0)+hc|0;c[jb>>2]=hc;if((Fb|0)<=0){Lc=63;break}else Fb=Fb+-1|0}while(1){Fb=l+(fc<<8)+(Lc<<2)|0;c[Fb>>2]=(c[Fb>>2]|0)-(c[k+(Lc<<2)>>2]|0);if((Lc|0)>0)Lc=Lc+-1|0;else break}fc=fc+1|0;if((fc|0)==3){Mc=Dc;Nc=Fc;break}else{gc=Dc;Gb=Ec;s=Fc}}Fc=f+53520|0;c[Fc>>2]=Nc;Nc=Ka(Eb,4)|0;c[m>>2]=Nc;s=Ka(Eb,4)|0;c[qc>>2]=s;Ec=Nc;Nc=s;s=Mc;Mc=1;Gb=1;while(1){Ec=Ec+16|0;c[m>>2]=Ec;Nc=Nc+16|0;c[qc>>2]=Nc;Dc=d[1264+Mc>>0]|0;if((Gb|0)<(Dc|0)){gc=Gb+1|0;fc=c[Fc>>2]|0;Lc=s;Cc=Gb;while(1){vc=c[rc>>2]|0;Kc=64-Cc|0;Jc=(Kc|0)>0;Hc=Lc;Ic=0;Bc=fc;while(1){c[f+52744+(Ic<<8)+(Cc<<2)>>2]=Hc;c[f+51976+(Ic<<8)+(Cc<<2)>>2]=Bc;Gc=c[l+(Ic<<8)+(Cc<<2)>>2]|0;Ub(k|0,0,256)|0;if(Hc>>>0<Gc>>>0){jc=f+51656+(c[m+(Ic+1>>1<<2)>>2]<<2)|0;Ac=Hc;nc=Hc;mc=0;zc=Bc;while(1){yc=mc+Ac|0;xc=bb(Eb,c[jc>>2]|0)|0;wc=zc+1|0;a[vc+zc>>0]=xc;if((xc|0)<15){pc=Ka(Eb,d[880+xc>>0]|0)|0;Fb=zc+2|0;a[vc+wc>>0]=pc;if(!xc){a[vc+Fb>>0]=pc>>>8;Oc=zc+3|0}else Oc=Fb;Pc=pc<<((xc|0)<2?-13:0)+((xc|0)<12?21:0);Qc=Oc}else{Pc=0;Qc=wc}wc=(c[896+(xc<<2)>>2]|0)+Pc|0;xc=(wc|0)==0?2147483647:wc>>>8&4095;if(!xc){pc=k+((wc&255)<<2)|0;c[pc>>2]=(c[pc>>2]|0)+1;Rc=0;Sc=nc+1|0}else{Rc=xc;Sc=nc}nc=Rc+Sc|0;if(nc>>>0>=Gc>>>0){Tc=Rc;Uc=yc;Vc=Sc;Wc=Qc;break}else{Ac=Rc;mc=yc;zc=Qc}}Xc=Tc;Yc=c[kc>>2]|0;Zc=Uc;_c=Vc;$c=Wc}else{Xc=Hc;Yc=0;Zc=0;_c=0;$c=Bc}zc=Gc-_c|0;mc=Zc+Yc+zc|0;c[kc>>2]=mc;Ac=62;nc=mc;while(1){mc=k+(Ac<<2)|0;nc=(c[mc>>2]|0)+nc|0;c[mc>>2]=nc;if((Ac|0)<=0)break;else Ac=Ac+-1|0}Ac=Xc-zc|0;if(Jc){nc=Kc;do{Gc=nc;nc=nc+-1|0;mc=l+(Ic<<8)+(nc+Cc<<2)|0;c[mc>>2]=(c[mc>>2]|0)-(c[k+(nc<<2)>>2]|0)}while((Gc|0)>1)}Ic=Ic+1|0;if((Ic|0)==3){ad=Ac;bd=$c;break}else{Hc=Ac;Bc=$c}}c[Fc>>2]=bd;Bc=Cc+1|0;if((Bc|0)==(Dc|0)){cd=ad;break}else{fc=bd;Lc=ad;Cc=Bc}}dd=cd;ed=(gc|0)>(Dc|0)?gc:Dc}else{dd=s;ed=Gb}Mc=Mc+1|0;if((Mc|0)==5)break;else{s=dd;Gb=ed}}ed=f+848|0;Gb=c[ed>>2]|0;dd=c[ed+4>>2]|0;ed=Tb(d[f+873>>0]|0,0,Gb|0,dd|0)|0;s=Vb(ed|0,C|0,c[f+60>>2]|0)|0;ed=C;Mc=f+856|0;cd=Mc;ad=c[cd>>2]|0;bd=c[cd+4>>2]|0;cd=Sb(ad|0,bd|0,Gb|0,dd|0)|0;dd=Tb(cd|0,C|0,s|0,ed|0)|0;ed=C;s=f+864|0;c[s>>2]=dd;c[s+4>>2]=ed;s=Tb(ad|0,bd|0,1,0)|0;bd=Mc;c[bd>>2]=s;c[bd+4>>2]=C;if(h){bd=h;c[bd>>2]=dd;c[bd+4>>2]=ed}ed=f+54112|0;bd=f+48|0;dd=f+57120|0;c[dd>>2]=4<<((c[bd>>2]|0)>>>1&1^1);Xb(f+54624|0,f+51976|0,768)|0;Xb(f+56160|0,f+52744|0,768)|0;h=c[lc>>2]|0;s=f+180|0;Mc=c[s>>2]|0;c[f+56928>>2]=h;c[f+56940>>2]=h+(Mc<<2);ad=c[uc>>2]|0;cd=ad-(c[f+84>>2]|0)+Mc|0;c[f+56932>>2]=h+(ad<<2);c[f+56944>>2]=h+(cd<<2);Mc=c[tc>>2]|0;Gb=h+(Mc-(c[f+116>>2]|0)+cd<<2)|0;c[f+56936>>2]=h+(Mc+ad<<2);c[f+56948>>2]=Gb;Gb=a[f+874>>0]|0;if(Gb<<24>>24){ad=Gb&255;Gb=0;do{Mc=f+875+Gb|0;c[f+56976+(Gb<<3)>>2]=c[f+880+((d[Mc>>0]|0)*24|0)>>2];c[f+56976+(Gb<<3)+4>>2]=c[f+880+((d[Mc>>0]|0)*24|0)+4>>2];Gb=Gb+1|0}while((Gb|0)!=(ad|0));fd=0;do{Gb=f+875+fd|0;c[f+57e3+(fd<<3)>>2]=c[f+880+((d[Gb>>0]|0)*24|0)+8>>2];c[f+57e3+(fd<<3)+4>>2]=c[f+880+((d[Gb>>0]|0)*24|0)+12>>2];fd=fd+1|0}while((fd|0)!=(ad|0));gd=0;do{fd=f+875+gd|0;c[f+57024+(gd<<3)>>2]=c[f+880+((d[fd>>0]|0)*24|0)+16>>2];c[f+57024+(gd<<3)+4>>2]=c[f+880+((d[fd>>0]|0)*24|0)+20>>2];gd=gd+1|0}while((gd|0)!=(ad|0))}Yb=f+57072|0;_b=Yb+48|0;do{c[Yb>>2]=0;Yb=Yb+4|0}while((Yb|0)<(_b|0));ad=f+875|0;gd=a[(d[ad>>0]|0)+(f+51568)>>0]|0;fd=gd<<24>>24!=0;Gb=f+57124|0;c[Gb>>2]=fd&1;if(fd)rb(f+54368|0,gd&255);gd=f+53524|0;fd=c[gd>>2]|0;Mc=f+54040|0;h=c[Mc>>2]|0;cd=(h|0)==0;d:do if((fd|0)<1)if(cd)Ma=245;else{Pb(h);c[Mc>>2]=0;Fc=f+54044|0;Pb(c[Fc>>2]|0);c[Fc>>2]=0;Fc=f+54048|0;Pb(c[Fc>>2]|0);c[Fc>>2]=0;Ma=245}else{if(!cd){Fc=c[lc>>2]|0;$c=(c[tc>>2]|0)+(c[uc>>2]|0)+(c[sc>>2]|0)|0;l=a[ad>>0]|0;if(($c|0)>0){Xc=0;do{a[h+(c[Fc+(Xc<<2)>>2]|0)>>0]=l;Xc=Xc+1|0}while((Xc|0)!=($c|0));hd=c[gd>>2]|0}else hd=fd}else{if(a[r>>0]|0){Ma=245;break}$c=c[s>>2]|0;Xc=Ob($c)|0;c[Mc>>2]=Xc;if(!Xc){Ma=245;break}Ub(Xc|0,a[ad>>0]|0,$c|0)|0;hd=fd}$c=f+54044|0;Xc=c[$c>>2]|0;l=(Xc|0)==0;if((hd|0)<2){if(l){Ma=245;break}Pb(Xc);c[$c>>2]=0;Xc=f+54048|0;Pb(c[Xc>>2]|0);c[Xc>>2]=0;Ma=245;break}do if(l){Xc=c[f+4>>2]|0;Fc=c[f+8>>2]|0;Dc=_(Fc,Xc)|0;gc=c[bd>>2]|0;kc=Ob((_(Xc>>>(gc&1^1)<<1,Fc>>>(gc>>>1&1^1))|0)+Dc|0)|0;Dc=f+54048|0;c[Dc>>2]=kc;gc=Ob(c[s>>2]<<2)|0;c[$c>>2]=gc;if((kc|0)==0|(gc|0)==0){Pb(kc);c[Dc>>2]=0;Pb(c[$c>>2]|0);c[$c>>2]=0;Ma=245;break d}else{Dc=f+54052|0;c[Dc>>2]=0;id=Dc;jd=Xc;kd=Fc;Ma=238;break}}else{Fc=f+54052|0;if((c[Fc>>2]|0)==(((hd|0)>4?2:1)|0))ld=hd;else{id=Fc;jd=c[f+4>>2]|0;kd=c[f+8>>2]|0;Ma=238}}while(0);if((Ma|0)==238){if((hd|0)<5){c[f+54056>>2]=jd;c[f+54060>>2]=kd;l=0-jd|0;c[f+54064>>2]=l;c[f+54068>>2]=(c[f+54048>>2]|0)+(_(1-kd|0,l)|0);md=hd}else{l=_(jd,kd)|0;Fc=c[bd>>2]|0;Xc=jd>>>(Fc&1^1);Dc=kd>>>(Fc>>>1&1^1);Fc=_(Dc,Xc)|0;kc=f+54056|0;c[kc>>2]=jd;c[f+54060>>2]=kd;c[f+54064>>2]=jd;gc=c[f+54048>>2]|0;c[f+54068>>2]=gc;c[f+54072>>2]=Xc;c[f+54076>>2]=Dc;c[f+54080>>2]=Xc;Yc=gc;c[f+54084>>2]=Yc+l;c[f+54088>>2]=Xc;c[f+54092>>2]=Dc;c[f+54096>>2]=Xc;c[f+54100>>2]=Yc+(Fc+l);kb(kc,kc);md=c[gd>>2]|0}c[id>>2]=(md|0)>4?2:1;ld=md}if((ld|0)<5){kc=f+54072|0;l=f+236+((c[t>>2]|0)*48|0)+16|0;c[kc>>2]=c[l>>2];c[kc+4>>2]=c[l+4>>2];c[kc+8>>2]=c[l+8>>2];c[kc+12>>2]=c[l+12>>2];c[kc+16>>2]=c[l+16>>2];c[kc+20>>2]=c[l+20>>2];c[kc+24>>2]=c[l+24>>2];c[kc+28>>2]=c[l+28>>2]}l=f+57128|0;c[l>>2]=c[gd>>2];nd=l;od=$c}while(0);if((Ma|0)==245){ld=f+57128|0;c[ld>>2]=0;Yb=f+54056|0;Zb=f+236+((c[t>>2]|0)*48|0)|0;_b=Yb+48|0;do{c[Yb>>2]=c[Zb>>2];Yb=Yb+4|0;Zb=Zb+4|0}while((Yb|0)<(_b|0));nd=ld;od=f+54044|0}Yb=ed;_b=Yb+128|0;do{b[Yb>>1]=0;Yb=Yb+2|0}while((Yb|0)<(_b|0));kb(n,f+54056|0);Yb=f+76|0;_b=f+64|0;ld=k+2|0;Zb=f+552|0;md=f+172|0;id=f+54368|0;jd=f+54108|0;kd=f+54104|0;hd=c[dd>>2]|0;s=0;fd=0;while(1){ad=c[Yb>>2]|0;h=(hd+fd|0)<(ad|0);sc=h&1;uc=ad;tc=ad;ad=0;while(1){lc=(ad|0)!=0;if(lc)pd=(c[bd>>2]&2|0)==0;else pd=0;cd=pd&1;l=fd>>cd;kc=f+57048+(ad<<2)|0;c[kc>>2]=l;Fc=f+72+(ad<<5)+4|0;Yc=c[Fc>>2]|0;Xc=(c[dd>>2]>>cd)+l|0;l=f+57060+(ad<<2)|0;c[l>>2]=(Xc|0)<(Yc|0)?Xc:Yc;Oa(f,ed,ad);Yc=c[rc>>2]|0;Xc=c[_b>>2]|0;Dc=c[oc>>2]|0;gc=f+56928+(ad<<2)|0;Zc=c[gc>>2]|0;_c=c[f+56952+(ad<<2)>>2]|0;b[k>>1]=b[c[f+56976+(ad*24|0)>>2]>>1]|0;b[ld>>1]=b[c[f+56976+(ad*24|0)+4>>2]>>1]|0;if((_c|0)>0){Wc=0;do{Vc=c[Zc+(Wc<<2)>>2]|0;Uc=Dc+(Vc<<2)|0;Tc=c[Uc>>2]|0;Qc=(Tc&1792|0)!=256&1;Rc=c[f+56976+(ad*24|0)+((Tc>>>2&15)<<3)+(Qc<<2)>>2]|0;Tc=0;while(1){Sc=f+56160+(ad<<8)+(Tc<<2)|0;Pc=c[Sc>>2]|0;if(Pc){qd=Sc;rd=Pc;sd=Tc;Ma=257;break}Pc=f+54624+(ad<<8)+(Tc<<2)|0;Oc=c[Pc>>2]|0;Eb=Oc+1|0;m=a[Yc+Oc>>0]|0;Nc=c[896+((m&255)<<2)>>2]|0;do if((m&255)<15){qc=Oc+2|0;Ec=(d[Yc+Eb>>0]<<((m&255)<2?-13:0)+((m&255)<12?21:0))+Nc|0;Cc=Ec>>>8&4095;if(m<<24>>24){td=Ec;ud=Cc;vd=qc;break}Lc=(d[Yc+qc>>0]<<8)+Cc|0;td=Ec;ud=(Lc|0)==0?2147483647:Lc;vd=Oc+3|0}else{td=Nc;ud=Nc>>>8&4095;vd=Eb}while(0);c[Sc>>2]=ud;c[Pc>>2]=vd;Eb=(td&255)+Tc|0;Nc=(_(e[Rc+(Eb<<1)>>1]|0,(td^0-(td&1048576))>>21)|0)&65535;b[f+54112+(d[Xc+Eb>>0]<<1)>>1]=Nc;Nc=((ud|0)==0&1)+Eb|0;if((Nc|0)<64)Tc=Nc;else{wd=Tc;break}}if((Ma|0)==257){Ma=0;c[qd>>2]=rd+-1;wd=sd}b[ed>>1]=(c[Uc>>2]|0)>>>16;qb(f,Vc,ad,ed,wd,b[k+(Qc<<1)>>1]|0);Wc=Wc+1|0}while((Wc|0)!=(_c|0));xd=c[gc>>2]|0}else xd=Zc;c[gc>>2]=xd+(_c<<2);Wc=c[f+56964+(ad<<2)>>2]|0;if((Wc|0)>0){Xc=f+56940+(ad<<2)|0;Yc=(c[Xc>>2]|0)+(0-Wc<<2)|0;c[Xc>>2]=Yc;Va(c[Mb>>2]|0,c[Zb>>2]|0,c[f+576+(ad<<2)>>2]|0,Yc,Wc,c[md>>2]|0)}if(!(c[Gb>>2]|0)){yd=0;zd=0}else{sb(f,id,2,ad,(c[kc>>2]|0)-s|0,(c[l>>2]|0)-sc|0);yd=sc;zd=s}ob(f,$b,ad,((c[kc>>2]|0)-zd<<3)-(zd<<1)|0,((c[l>>2]|0)-yd<<3)-(yd<<1)|0);Wc=lc?3:0;do if((c[nd>>2]|0)<(Wc+2|0))if(!(c[Gb>>2]|0)){Ad=yd;Bd=zd}else{Ad=yd+sc|0;Bd=zd+s|0}else{Yc=zd+s|0;Xc=yd+sc|0;Dc=(c[kc>>2]|0)-Yc|0;Tc=c[l>>2]|0;Rc=Tc-Xc|0;Ac=f+72+(ad<<5)|0;Nc=c[Ac>>2]|0;Eb=f+72+(ad<<5)+8|0;Oc=c[Eb>>2]|0;m=_(Nc,Dc)|0;Lc=Oc+m|0;Ec=c[od>>2]|0;Cc=Ec+(Lc<<2)|0;qc=c[Mc>>2]|0;fc=qc+Lc|0;Bc=(Dc|0)>0;Hc=(c[Fc>>2]|0)>(Rc|0);Ic=Hc&1;Ub(Ec+(Lc+(Bc?Nc:0)<<2)|0,0,_(Nc<<2,Rc-Dc+(Bc<<31>>31)+Ic|0)|0)|0;Lc=(Bc&1)<<2|Dc<<3;Dc=f+54056+(ad<<4)+8|0;Bc=c[Dc>>2]|0;Kc=c[f+236+($b*48|0)+(ad<<4)+8>>2]|0;Jc=f+54056+(ad<<4)+12|0;vc=c[Jc>>2]|0;nc=_(Bc,Lc)|0;zc=vc+nc|0;Gc=c[f+236+($b*48|0)+(ad<<4)+12>>2]|0;mc=_(Kc,Lc)|0;jc=Gc+mc|0;Hb=f+54056+(ad<<4)|0;Kb=c[Hb>>2]|0;if((Lc|0)<4){dc=Kc<<2;yc=zc;xc=jc;pc=Lc;while(1){Xb(yc|0,xc|0,Kb|0)|0;pc=pc+1|0;if((pc|0)==4)break;else{yc=yc+Bc|0;xc=xc+Kc|0}}xc=Bc<<2;Cd=dc;Dd=xc;Ed=vc+xc|0;Fd=Gc+dc|0;Gd=4}else{Cd=mc;Dd=nc;Ed=zc;Fd=jc;Gd=Lc}xc=Ic^1;yc=Rc-xc<<3;if((Gd|0)<(yc|0)){pc=0-Kc|0;Qc=Bc<<3;Vc=Kc<<3;Uc=Nc+1|0;wc=-4-(Bc<<2)|0;if((Kb|0)>8){Fb=(Kb+-9|0)>>>3;hc=Fb+2|0;jb=(Rc<<3)+-1-(xc<<3)-Gd|0;Lb=Oc+Fb+m|0;fb=((Tc-xc-Xc<<3)+-1-Gd|0)>>>3;ac=Ec+(Lb+2<<2)+(_(fb,(Fb<<2)+8|0)|0)|0;Fb=Lb+(_(fb,hc)|0)|0;fb=fc;Lb=Ed;hb=Fd;Nb=Cc;ib=Gd;while(1){ic=c[f+53528+(d[fb>>0]<<2)>>2]|0;tb(Lb,Bc,hb+pc|0,Kc,ic,ic*3>>2,Nb,Nb+(Nc<<2)|0);ic=fb;ec=Nb;eb=8;do{lb=ec;ec=ec+4|0;ic=ic+1|0;Ib=c[f+53528+(d[ic>>0]<<2)>>2]|0;cc=Ib*3>>2;tb(Lb+eb|0,Bc,hb+(eb-Kc)|0,Kc,Ib,cc,ec,lb+(Uc<<2)|0);ub(Lb+(wc+eb)|0,Bc,Ib,cc,lb);eb=eb+8|0}while((eb|0)<(Kb|0));ib=ib+8|0;if((ib|0)>=(yc|0))break;else{fb=fb+hc|0;Lb=Lb+Qc|0;hb=hb+Vc|0;Nb=Nb+(hc<<2)|0}}Hd=Fb+2|0;Id=jb&-8;Jd=ac}else{hc=((Rc<<3)+-1-(xc<<3)-Gd|0)>>>3;Nb=Oc+1+m+hc|0;hb=fc;Lb=Ed;fb=Fd;ib=Cc;wc=Gd;while(1){Uc=c[f+53528+(d[hb>>0]<<2)>>2]|0;tb(Lb,Bc,fb+pc|0,Kc,Uc,Uc*3>>2,ib,ib+(Nc<<2)|0);wc=wc+8|0;if((wc|0)>=(yc|0))break;else{hb=hb+1|0;Lb=Lb+Qc|0;fb=fb+Vc|0;ib=ib+4|0}}Hd=Nb;Id=hc<<3;Jd=Ec+(Nb<<2)|0}ib=Id+8|0;Kd=qc+Hd|0;Ld=vc+((_(ib,Bc)|0)+Dd)|0;Md=Gc+((_(ib,Kc)|0)+Cd)|0;Nd=Jd;Od=Gd+8+Id|0}else{Kd=fc;Ld=Ed;Md=Fd;Nd=Cc;Od=Gd}do if(!Hc){ib=c[f+54056+(ad<<4)+4>>2]|0;if((ib|0)>(Od|0)){Vc=ib-Od|0;fb=Ld;Qc=Md;Lb=Od;while(1){Xb(fb|0,Qc|0,Kb|0)|0;Lb=Lb+1|0;if((Lb|0)==(ib|0))break;else{fb=fb+Bc|0;Qc=Qc+Kc|0}}Pd=Ld+(_(Vc,Bc)|0)|0}else Pd=Ld;if((Kb|0)<=8)break;Qc=-4-(Bc<<3)|0;fb=Kd;ib=Nd;Lb=8;while(1){fb=fb+1|0;hb=c[f+53528+(d[fb>>0]<<2)>>2]|0;ub(Pd+(Qc+Lb)|0,Bc,hb,hb*3>>2,ib);Lb=Lb+8|0;if((Lb|0)>=(Kb|0))break;else ib=ib+4|0}}while(0);if((c[nd>>2]|0)<(Wc+3|0)){Ad=Xc;Bd=Yc;break}Kb=Yc+s|0;Bc=Xc+sc|0;Kc=(c[kc>>2]|0)-Kb|0;Hc=c[Ac>>2]|0;Cc=(c[Eb>>2]|0)+(_(Hc,Kc)|0)|0;fc=(c[gd>>2]|0)>=((lc?7:4)|0);Gc=lc?3840:1920;vc=Kc<<3;Kc=c[Dc>>2]|0;qc=(c[l>>2]|0)-Bc<<3;Nb=c[Hb>>2]|0;Ec=c[f+54056+(ad<<4)+4>>2]|0;if((vc|0)>=(qc|0)){Ad=Bc;Bd=Kb;break}hc=(c[Jc>>2]|0)+(_(Kc,vc)|0)|0;ib=(Nb|0)>0;Lb=Kc<<3;Qc=0-Hc|0;fb=((Nb+-1|0)>>>3)+1|0;Vc=(c[oc>>2]|0)+(Cc<<2)|0;hb=hc;hc=(c[od>>2]|0)+(Cc<<2)|0;Cc=vc;while(1){if(ib){vc=(Cc|0)<1;yc=Cc+8|0;wc=(yc|0)>=(Ec|0);Nc=(wc&1)<<3|(vc&1)<<2;pc=Vc;m=hc;Oc=0;while(1){xc=d[((c[pc>>2]|0)>>>2&15)+(f+875)>>0]|0;Rc=c[m>>2]|0;ac=(Oc|0)<1;jb=Oc;Oc=Oc+8|0;Fb=(Oc|0)>=(Nb|0);Uc=Nc|ac&1|(Fb&1)<<1;e:do if(fc&(Rc|0)>(Gc|0)){Tc=hb+jb|0;Ic=f+53528+(xc<<2)|0;Lc=f+53784+(xc<<2)|0;vb(Tc,Kc,Uc,c[Ic>>2]|0,c[Lc>>2]|0,1);do if(!lc){if(!ac?(c[m+-4>>2]|0)>3840:0)break;if(!Fb?(c[m+4>>2]|0)>3840:0)break;if(!vc?(c[m+(Qc<<2)>>2]|0)>3840:0)break;if(wc)break e;if((c[m+(Hc<<2)>>2]|0)<=3840)break e}while(0);vb(Tc,Kc,Uc,c[Ic>>2]|0,c[Lc>>2]|0,1);vb(Tc,Kc,Uc,c[Ic>>2]|0,c[Lc>>2]|0,1)}else{if((Rc|0)>1536){vb(hb+jb|0,Kc,Uc,c[f+53528+(xc<<2)>>2]|0,c[f+53784+(xc<<2)>>2]|0,1);break}if((Rc|0)<=384)break;vb(hb+jb|0,Kc,Uc,c[f+53528+(xc<<2)>>2]|0,c[f+53784+(xc<<2)>>2]|0,0)}while(0);if((Oc|0)>=(Nb|0))break;else{pc=pc+4|0;m=m+4|0}}Qd=yc;Rd=Vc+(fb<<2)|0;Sd=hc+(fb<<2)|0}else{Qd=Cc+8|0;Rd=Vc;Sd=hc}if((Qd|0)<(qc|0)){Vc=Rd;hb=hb+Lb|0;hc=Sd;Cc=Qd}else{Ad=Bc;Bd=Kb;break}}}while(0);lc=(c[kc>>2]|0)-Bd<<cd;Wc=(lc|0)<(uc|0)?lc:uc;lc=(c[l>>2]|0)-Ad<<cd;Fc=(lc|0)<(tc|0)?lc:tc;ad=ad+1|0;if((ad|0)==3){Td=Wc;Ud=Fc;break}else{uc=Wc;tc=Fc}}tc=c[jd>>2]|0;if(tc){uc=c[Yb>>2]|0;za[tc&7](c[kd>>2]|0,n,uc-Ud|0,uc-Td|0)}uc=c[dd>>2]|0;if(h){hd=uc;s=1;fd=uc+fd|0}else break}pb(f,$b,0);pb(f,$b,1);pb(f,$b,2);$b=(a[r>>0]|0)==0;r=c[t>>2]|0;c[Wb>>2]=r;if($b){c[gb>>2]=r;r=c[Mb>>2]|0;c[Zb>>2]=r;c[Rb>>2]=r}else c[Zb>>2]=c[Mb>>2];o=0;i=j;return o|0}function Sa(a,b){a=a|0;b=b|0;var c=0;if((a|0)==0|(b|0)==0){c=-1;return c|0}kb(b,a+54056|0);c=0;return c|0}function Ta(d,e){d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;f=i;i=i+512|0;g=f+256|0;h=f;j=Ka(d,3)|0;k=0;do{a[e+256+k>>0]=Ka(d,j)|0;k=k+1|0}while((k|0)!=64);k=(Ka(d,4)|0)+1|0;j=0;do{b[e+128+(j<<1)>>1]=Ka(d,k)|0;j=j+1|0}while((j|0)!=64);j=(Ka(d,4)|0)+1|0;k=0;do{b[e+(k<<1)>>1]=Ka(d,j)|0;k=k+1|0}while((k|0)!=64);k=Ka(d,9)|0;j=k+1|0;l=Ob(j<<6)|0;if(!l){m=-1;i=f;return m|0}if((k|0)>-1){n=0;do{o=0;do{a[l+(n<<6)+o>>0]=Ka(d,8)|0;o=o+1|0}while((o|0)!=64);n=n+1|0}while((n|0)<(j|0))}n=hb(k)|0;k=0;a:while(1){o=(k|0)/3|0;p=(k|0)%3|0;q=e+320+(o*36|0)+(p*12|0)|0;if((k|0)>0?(La(d)|0)==0:0){do if((k|0)>2)if(!(La(d)|0)){r=k+-1|0;s=(r|0)%3|0;t=(r|0)/3|0;break}else{s=p;t=o+-1|0;break}else{r=k+-1|0;s=(r|0)%3|0;t=(r|0)/3|0}while(0);r=e+320+(t*36|0)+(s*12|0)|0;c[q>>2]=c[r>>2];c[q+4>>2]=c[r+4>>2];c[q+8>>2]=c[r+8>>2]}else u=21;b:do if((u|0)==21){u=0;c[h>>2]=Ka(d,n)|0;r=0;v=0;while(1){w=(Ka(d,hb(62-r|0)|0)|0)+1|0;c[g+(v<<2)>>2]=w;x=w+r|0;w=Ka(d,n)|0;y=v+1|0;c[h+(y<<2)>>2]=w;if((x|0)<63){r=x;v=y}else{z=x;A=w;B=y;break}}if((z|0)>63){u=24;break a}c[q>>2]=B;v=B<<2;r=Ob(v)|0;c[e+320+(o*36|0)+(p*12|0)+4>>2]=r;if(!r){u=26;break a}Xb(r|0,g|0,v|0)|0;v=Ob((B<<6)+64|0)|0;if(!v){u=28;break a}c[e+320+(o*36|0)+(p*12|0)+8>>2]=v;if((A|0)<(j|0)){C=A;D=B}else{u=30;break a}while(1){r=v+(D<<6)|0;y=l+(C<<6)|0;w=r+64|0;do{a[r>>0]=a[y>>0]|0;r=r+1|0;y=y+1|0}while((r|0)<(w|0));if((D|0)<=0)break b;D=D+-1|0;C=c[h+(D<<2)>>2]|0;if((C|0)>=(j|0)){u=30;break a}}}while(0);k=k+1|0;if((k|0)>=6){u=34;break}}if((u|0)==24){Pb(l);m=-20;i=f;return m|0}else if((u|0)==26){Pb(l);m=-1;i=f;return m|0}else if((u|0)==28){Pb(l);m=-1;i=f;return m|0}else if((u|0)==30){Pb(l);m=-20;i=f;return m|0}else if((u|0)==34){Pb(l);m=0;i=f;return m|0}return 0}function Ua(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0;b=5;d=6;while(1){e=(b|0)/3|0;f=(b|0)%3|0;if((d|0)>1){g=d+-2|0;h=(g|0)/3|0;i=(g|0)%3|0;g=a+320+(e*36|0)+(f*12|0)+4|0;if((c[g>>2]|0)==(c[a+320+(h*36|0)+(i*12|0)+4>>2]|0))c[g>>2]=0;g=a+320+(e*36|0)+(f*12|0)+8|0;if((c[g>>2]|0)==(c[a+320+(h*36|0)+(i*12|0)+8>>2]|0))c[g>>2]=0}if((b|0)>2){g=a+356+(f*12|0)+4|0;if((c[g>>2]|0)==(c[a+320+(f*12|0)+4>>2]|0))c[g>>2]=0;g=a+356+(f*12|0)+8|0;if((c[g>>2]|0)==(c[a+320+(f*12|0)+8>>2]|0))c[g>>2]=0}Pb(c[a+320+(e*36|0)+(f*12|0)+4>>2]|0);Pb(c[a+320+(e*36|0)+(f*12|0)+8>>2]|0);if((b|0)>0){f=b;b=b+-1|0;d=f}else break}return}function Va(b,e,f,g,h,i){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;if((h|0)<=0)return;j=f<<1;k=f*3|0;l=f<<2;m=f*5|0;n=f*6|0;o=f*7|0;p=0;do{q=c[i+(c[g+(p<<2)>>2]<<2)>>2]|0;r=e+q|0;s=r;t=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=r+4|0;r=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=b+q|0;u=s;a[u>>0]=t;a[u+1>>0]=t>>8;a[u+2>>0]=t>>16;a[u+3>>0]=t>>24;t=s+4|0;a[t>>0]=r;a[t+1>>0]=r>>8;a[t+2>>0]=r>>16;a[t+3>>0]=r>>24;r=q+f|0;t=e+r|0;s=t;u=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=t+4|0;t=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=b+r|0;r=s;a[r>>0]=u;a[r+1>>0]=u>>8;a[r+2>>0]=u>>16;a[r+3>>0]=u>>24;u=s+4|0;a[u>>0]=t;a[u+1>>0]=t>>8;a[u+2>>0]=t>>16;a[u+3>>0]=t>>24;t=q+j|0;u=e+t|0;s=u;r=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=u+4|0;u=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=b+t|0;t=s;a[t>>0]=r;a[t+1>>0]=r>>8;a[t+2>>0]=r>>16;a[t+3>>0]=r>>24;r=s+4|0;a[r>>0]=u;a[r+1>>0]=u>>8;a[r+2>>0]=u>>16;a[r+3>>0]=u>>24;u=q+k|0;r=e+u|0;s=r;t=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=r+4|0;r=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=b+u|0;u=s;a[u>>0]=t;a[u+1>>0]=t>>8;a[u+2>>0]=t>>16;a[u+3>>0]=t>>24;t=s+4|0;a[t>>0]=r;a[t+1>>0]=r>>8;a[t+2>>0]=r>>16;a[t+3>>0]=r>>24;r=q+l|0;t=e+r|0;s=t;u=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=t+4|0;t=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=b+r|0;r=s;a[r>>0]=u;a[r+1>>0]=u>>8;a[r+2>>0]=u>>16;a[r+3>>0]=u>>24;u=s+4|0;a[u>>0]=t;a[u+1>>0]=t>>8;a[u+2>>0]=t>>16;a[u+3>>0]=t>>24;t=q+m|0;u=e+t|0;s=u;r=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=u+4|0;u=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=b+t|0;t=s;a[t>>0]=r;a[t+1>>0]=r>>8;a[t+2>>0]=r>>16;a[t+3>>0]=r>>24;r=s+4|0;a[r>>0]=u;a[r+1>>0]=u>>8;a[r+2>>0]=u>>16;a[r+3>>0]=u>>24;u=q+n|0;r=e+u|0;s=r;t=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=r+4|0;r=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;s=b+u|0;u=s;a[u>>0]=t;a[u+1>>0]=t>>8;a[u+2>>0]=t>>16;a[u+3>>0]=t>>24;t=s+4|0;a[t>>0]=r;a[t+1>>0]=r>>8;a[t+2>>0]=r>>16;a[t+3>>0]=r>>24;r=q+o|0;q=e+r|0;t=q;s=d[t>>0]|d[t+1>>0]<<8|d[t+2>>0]<<16|d[t+3>>0]<<24;t=q+4|0;q=d[t>>0]|d[t+1>>0]<<8|d[t+2>>0]<<16|d[t+3>>0]<<24;t=b+r|0;r=t;a[r>>0]=s;a[r+1>>0]=s>>8;a[r+2>>0]=s>>16;a[r+3>>0]=s>>24;s=t+4|0;a[s>>0]=q;a[s+1>>0]=q>>8;a[s+2>>0]=q>>16;a[s+3>>0]=q>>24;p=p+1|0}while((p|0)!=(h|0));return}function Wa(c,d,e){c=c|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=c;c=0;while(1){g=c<<3;h=b[e+(g<<1)>>1]|0;i=(h<<16>>16)+128|0;a[f>>0]=h<<16>>16>-129?((i|0)>255?-1:i&255):0;i=b[e+((g|1)<<1)>>1]|0;h=(i<<16>>16)+128|0;a[f+1>>0]=i<<16>>16>-129?((h|0)>255?-1:h&255):0;h=b[e+((g|2)<<1)>>1]|0;i=(h<<16>>16)+128|0;a[f+2>>0]=h<<16>>16>-129?((i|0)>255?-1:i&255):0;i=b[e+((g|3)<<1)>>1]|0;h=(i<<16>>16)+128|0;a[f+3>>0]=i<<16>>16>-129?((h|0)>255?-1:h&255):0;h=b[e+((g|4)<<1)>>1]|0;i=(h<<16>>16)+128|0;a[f+4>>0]=h<<16>>16>-129?((i|0)>255?-1:i&255):0;i=b[e+((g|5)<<1)>>1]|0;h=(i<<16>>16)+128|0;a[f+5>>0]=i<<16>>16>-129?((h|0)>255?-1:h&255):0;h=b[e+((g|6)<<1)>>1]|0;i=(h<<16>>16)+128|0;a[f+6>>0]=h<<16>>16>-129?((i|0)>255?-1:i&255):0;i=b[e+((g|7)<<1)>>1]|0;g=(i<<16>>16)+128|0;a[f+7>>0]=i<<16>>16>-129?((g|0)>255?-1:g&255):0;c=c+1|0;if((c|0)==8)break;else f=f+d|0}return}function Xa(c,e,f,g){c=c|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0;h=e;e=c;c=0;while(1){i=c<<3;j=(d[h>>0]|0)+(b[g+(i<<1)>>1]|0)|0;a[e>>0]=(j>>>31)+255&((j|0)>255?255:j);j=(d[h+1>>0]|0)+(b[g+((i|1)<<1)>>1]|0)|0;a[e+1>>0]=(j>>>31)+255&((j|0)>255?255:j);j=(d[h+2>>0]|0)+(b[g+((i|2)<<1)>>1]|0)|0;a[e+2>>0]=(j>>>31)+255&((j|0)>255?255:j);j=(d[h+3>>0]|0)+(b[g+((i|3)<<1)>>1]|0)|0;a[e+3>>0]=(j>>>31)+255&((j|0)>255?255:j);j=(d[h+4>>0]|0)+(b[g+((i|4)<<1)>>1]|0)|0;a[e+4>>0]=(j>>>31)+255&((j|0)>255?255:j);j=(d[h+5>>0]|0)+(b[g+((i|5)<<1)>>1]|0)|0;a[e+5>>0]=(j>>>31)+255&((j|0)>255?255:j);j=(d[h+6>>0]|0)+(b[g+((i|6)<<1)>>1]|0)|0;a[e+6>>0]=(j>>>31)+255&((j|0)>255?255:j);j=(d[h+7>>0]|0)+(b[g+((i|7)<<1)>>1]|0)|0;a[e+7>>0]=(j>>>31)+255&((j|0)>255?255:j);c=c+1|0;if((c|0)==8)break;else{h=h+f|0;e=e+f|0}}return}function Ya(c,e,f,g,h){c=c|0;e=e|0;f=f|0;g=g|0;h=h|0;var i=0,j=0,k=0,l=0;i=e;e=f;f=c;c=0;while(1){j=c<<3;k=0;do{l=(((d[e+k>>0]|0)+(d[i+k>>0]|0)|0)>>>1)+(b[h+(k+j<<1)>>1]|0)|0;a[f+k>>0]=(l>>>31)+255&((l|0)>255?255:l);k=k+1|0}while((k|0)!=8);c=c+1|0;if((c|0)==8)break;else{i=i+g|0;e=e+g|0;f=f+g|0}}return}function Za(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;e=0;f=0;g=0;h=0;a:while(1){i=f;while(1){j=La(b)|0;if((Ma(b)|0)<0){k=-20;l=12;break a}if(j){m=i;break}if((i|0)>31){k=-20;l=12;break a}else i=i+1|0}if((g|0)>31){k=-20;l=12;break}g=g+1|0;i=Ka(b,5)|0;j=d[1272+i>>0]|0;n=1<<j;o=j+m&255;j=h+2|0;p=(n|0)<1?~n:-2;q=n;r=h;s=d[1304+i>>0]|0;while(1){a[c+(r<<1)>>0]=s;a[c+(r<<1)+1>>0]=o;if((q|0)>1){q=q+-1|0;r=r+1|0;s=s+1|0}else break}s=j+n+p|0;r=-2147483648>>>(m+-1|0);if((m|0)<1|(r&e|0)==0){t=e;u=r;v=m}else{q=e;o=r;r=m;while(1){i=o^q;w=o<<1;x=r+-1|0;if((r|0)<2|(w&i|0)==0){t=i;u=w;v=x;break}else{q=i;o=w;r=x}}}if((v|0)<1){k=s;l=12;break}else{e=u|t;f=v;h=s}}if((l|0)==12)return k|0;return 0}function _a(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;d=i;i=i+512|0;e=d;f=0;while(1){g=Za(a,e)|0;if((g|0)<0){h=g;break}j=wb(0,e,g)|0;if(j>>>0>32767){h=-23;break}k=Ob(j<<1)|0;if(!k){h=-1;break}wb(k,e,g)|0;c[b+(f<<2)>>2]=k;f=f+1|0;if((f|0)>=80){l=0;m=7;break}}if((m|0)==7){i=d;return l|0}l=h;i=d;return l|0}function $a(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;d=0;while(1){e=b+(d<<2)|0;f=(xb(c[e>>2]|0,0)|0)<<1;g=Ob(f)|0;c[a+(d<<2)>>2]=g;if(!g){h=d;break}Xb(g|0,c[e>>2]|0,f|0)|0;d=d+1|0;if((d|0)>=80){i=0;j=6;break}}if((j|0)==6)return i|0;if((h|0)>0)k=h;else{i=-1;return i|0}do{h=k;k=k+-1|0;Pb(c[a+(k<<2)>>2]|0)}while((h|0)>1);i=-1;return i|0}function ab(a){a=a|0;var b=0;b=0;do{Pb(c[a+(b<<2)>>2]|0);b=b+1|0}while((b|0)!=80);return}function bb(a,e){a=a|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0;f=a+4|0;g=a+8|0;h=c[a>>2]|0;i=a+12|0;a=c[i>>2]|0;j=0;k=c[f>>2]|0;l=c[g>>2]|0;while(1){m=b[e+(j<<1)>>1]|0;if((m|0)>(a|0)){n=k;o=32-a|0;p=l;while(1){if(n>>>0>=h>>>0){q=n;r=-1073741824;s=p;break}t=o+-8|0;u=n+1|0;v=d[n>>0]<<t|p;if(t>>>0>7){n=u;o=t;p=v}else{q=u;r=t;s=v;break}}w=32-r|0;x=q;y=s}else{w=a;x=k;y=l}p=b[e+(j+1+(y>>>(32-m|0))<<1)>>1]|0;o=p<<16>>16;if(p<<16>>16<1){z=o;A=w;B=x;C=y;break}a=w-m|0;j=o;k=x;l=y<<m}y=0-z|0;z=y>>8;c[f>>2]=B;c[g>>2]=C<<z;c[i>>2]=A-z;return y&255|0}function cb(a,c,d){a=a|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;e=i;i=i+128|0;f=e;if((d|0)<4){g=c+2|0;h=(b[c>>1]|0)*46341>>16;j=b[g>>1]|0;k=j*12785>>16;l=j*64277>>16;j=k*46341>>16;m=l*46341>>16;n=m+j|0;o=m-j|0;b[f>>1]=l+h;b[f+16>>1]=n+h;b[f+32>>1]=o+h;b[f+48>>1]=k+h;b[f+64>>1]=h-k;b[f+80>>1]=h-o;b[f+96>>1]=h-n;b[f+112>>1]=h-l;l=c+16|0;h=((b[l>>1]|0)*46341|0)>>>16&65535;b[f+114>>1]=h;b[f+98>>1]=h;b[f+82>>1]=h;b[f+66>>1]=h;b[f+50>>1]=h;b[f+34>>1]=h;b[f+18>>1]=h;b[f+2>>1]=h;h=0;do{n=h<<3;o=(b[f+(n<<1)>>1]|0)*46341>>16;k=b[f+((n|1)<<1)>>1]|0;n=k*12785>>16;j=k*64277>>16;k=n*46341>>16;m=j*46341>>16;p=m+k|0;q=m-k|0;b[a+(h<<1)>>1]=j+o;b[a+(h+8<<1)>>1]=p+o;b[a+(h+16<<1)>>1]=q+o;b[a+(h+24<<1)>>1]=n+o;b[a+(h+32<<1)>>1]=o-n;b[a+(h+40<<1)>>1]=o-q;b[a+(h+48<<1)>>1]=o-p;b[a+(h+56<<1)>>1]=o-j;h=h+1|0}while((h|0)!=8);r=0;do{h=a+(r<<1)|0;b[h>>1]=((b[h>>1]|0)+8|0)>>>4;r=r+1|0}while((r|0)!=64);b[l>>1]=0;b[g>>1]=0;b[c>>1]=0;i=e;return}if((d|0)>=11){yb(f,c);yb(f+2|0,c+16|0);yb(f+4|0,c+32|0);yb(f+6|0,c+48|0);yb(f+8|0,c+64|0);yb(f+10|0,c+80|0);yb(f+12|0,c+96|0);yb(f+14|0,c+112|0);yb(a,f);yb(a+2|0,f+16|0);yb(a+4|0,f+32|0);yb(a+6|0,f+48|0);yb(a+8|0,f+64|0);yb(a+10|0,f+80|0);yb(a+12|0,f+96|0);yb(a+14|0,f+112|0);d=0;do{g=a+(d<<1)|0;b[g>>1]=((b[g>>1]|0)+8|0)>>>4;d=d+1|0}while((d|0)!=64);d=c;g=d+128|0;do{b[d>>1]=0;d=d+2|0}while((d|0)<(g|0));i=e;return}d=(b[c>>1]|0)*46341>>16;g=b[c+4>>1]|0;l=g*25080>>16;r=g*60547>>16;g=b[c+2>>1]|0;h=g*12785>>16;j=b[c+6>>1]|0;o=j*36410>>16;p=j*54491>>16;j=g*64277>>16;g=h-o|0;q=(o+h<<16>>16)*46341>>16;h=p+j|0;o=(j-p<<16>>16)*46341>>16;p=l+d|0;j=d-l|0;l=r+d|0;n=d-r|0;r=o+q|0;d=o-q|0;b[f>>1]=h+l;b[f+16>>1]=r+p;b[f+32>>1]=d+j;b[f+48>>1]=g+n;b[f+64>>1]=n-g;b[f+80>>1]=j-d;b[f+96>>1]=p-r;b[f+112>>1]=l-h;h=c+16|0;l=c+18|0;r=c+20|0;p=(b[h>>1]|0)*46341>>16;d=b[r>>1]|0;j=d*25080>>16;g=d*60547>>16;d=b[l>>1]|0;n=d*12785>>16;q=d*64277>>16;d=n*46341>>16;o=q*46341>>16;k=j+p|0;m=p-j|0;j=g+p|0;s=p-g|0;g=o+d|0;p=o-d|0;b[f+2>>1]=j+q;b[f+18>>1]=g+k;b[f+34>>1]=p+m;b[f+50>>1]=s+n;b[f+66>>1]=s-n;b[f+82>>1]=m-p;b[f+98>>1]=k-g;b[f+114>>1]=j-q;q=c+32|0;j=c+34|0;g=(b[q>>1]|0)*46341>>16;k=b[j>>1]|0;p=k*12785>>16;m=k*64277>>16;k=p*46341>>16;n=m*46341>>16;s=n+k|0;d=n-k|0;b[f+4>>1]=m+g;b[f+20>>1]=s+g;b[f+36>>1]=d+g;b[f+52>>1]=p+g;b[f+68>>1]=g-p;b[f+84>>1]=g-d;b[f+100>>1]=g-s;b[f+116>>1]=g-m;m=c+48|0;g=((b[m>>1]|0)*46341|0)>>>16&65535;b[f+118>>1]=g;b[f+102>>1]=g;b[f+86>>1]=g;b[f+70>>1]=g;b[f+54>>1]=g;b[f+38>>1]=g;b[f+22>>1]=g;b[f+6>>1]=g;g=0;do{s=g<<3;d=(b[f+(s<<1)>>1]|0)*46341>>16;p=b[f+((s|2)<<1)>>1]|0;k=p*25080>>16;n=p*60547>>16;p=b[f+((s|1)<<1)>>1]|0;o=p*12785>>16;t=b[f+((s|3)<<1)>>1]|0;s=t*36410>>16;u=t*54491>>16;t=p*64277>>16;p=o-s|0;v=(s+o<<16>>16)*46341>>16;o=u+t|0;s=(t-u<<16>>16)*46341>>16;u=k+d|0;t=d-k|0;k=n+d|0;w=d-n|0;n=s+v|0;d=s-v|0;b[a+(g<<1)>>1]=o+k;b[a+(g+8<<1)>>1]=n+u;b[a+(g+16<<1)>>1]=d+t;b[a+(g+24<<1)>>1]=p+w;b[a+(g+32<<1)>>1]=w-p;b[a+(g+40<<1)>>1]=t-d;b[a+(g+48<<1)>>1]=u-n;b[a+(g+56<<1)>>1]=k-o;g=g+1|0}while((g|0)!=8);x=0;do{g=a+(x<<1)|0;b[g>>1]=((b[g>>1]|0)+8|0)>>>4;x=x+1|0}while((x|0)!=64);b[m>>1]=0;b[j>>1]=0;b[q>>1]=0;b[r>>1]=0;b[l>>1]=0;b[h>>1]=0;h=c;c=h;b[c>>1]=0;b[c+2>>1]=0>>>16;c=h+4|0;b[c>>1]=0;b[c+2>>1]=0>>>16;i=e;return}function db(b){b=b|0;var d=0,e=0;d=b;e=d+60|0;do{c[d>>2]=0;d=d+4|0}while((d|0)<(e|0));a[b>>0]=3;a[b+1>>0]=2;a[b+2>>0]=1;c[b+60>>2]=6;return}function eb(a){a=a|0;var b=0;b=a;a=b+64|0;do{c[b>>2]=0;b=b+4|0}while((b|0)<(a|0));return}function fb(a){a=a|0;c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;return}function gb(a){a=a|0;var b=0,d=0;if(!a)return;b=a+8|0;if((c[b>>2]|0)>0){d=0;do{Pb(c[(c[a>>2]|0)+(d<<2)>>2]|0);d=d+1|0}while((d|0)<(c[b>>2]|0))}Pb(c[a>>2]|0);Pb(c[a+4>>2]|0);Pb(c[a+12>>2]|0);c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;return}function hb(a){a=a|0;var b=0,c=0,d=0;if(!a)b=0;else{c=a;a=0;while(1){c=c>>>1;d=a+1|0;if(!c){b=d;break}else a=d}}return b|0}function ib(b,c){b=b|0;c=c|0;var d=0,e=0,f=0;d=c+-1|0;if(b>>>0>~c>>>0|(d&(c|-256)|0)!=0){e=0;return e|0}f=Ob(c+b|0)|0;if(!f){e=0;return e|0}b=f+-1&d;a[f+b>>0]=b;e=f+(b+1)|0;return e|0}function jb(a){a=a|0;if(!a)return;Pb(a+~(d[a+-1>>0]|0)|0);return}function kb(a,b){a=a|0;b=b|0;var d=0,e=0;c[a>>2]=c[b>>2];d=c[b+4>>2]|0;c[a+4>>2]=d;e=0-(c[b+8>>2]|0)|0;c[a+8>>2]=e;c[a+12>>2]=(c[b+12>>2]|0)+(_(1-d|0,e)|0);c[a+16>>2]=c[b+16>>2];e=c[b+20>>2]|0;c[a+20>>2]=e;d=0-(c[b+24>>2]|0)|0;c[a+24>>2]=d;c[a+28>>2]=(c[b+28>>2]|0)+(_(1-e|0,d)|0);c[a+32>>2]=c[b+32>>2];d=c[b+36>>2]|0;c[a+36>>2]=d;e=0-(c[b+40>>2]|0)|0;c[a+40>>2]=e;c[a+44>>2]=(c[b+44>>2]|0)+(_(1-d|0,e)|0);return}function lb(f,g,h){f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0;j=i;i=i+64|0;k=j;l=(g|0)==0;m=0;while(1){n=1336+(m<<2)|0;o=1344+(m<<2)|0;p=0;while(1){q=h+320+(m*36|0)+(p*12|0)|0;r=c[q>>2]|0;if((r|0)>=0){s=h+320+(m*36|0)+(p*12|0)+8|0;t=c[n>>2]|0;u=c[o>>2]|0;v=h+320+(m*36|0)+(p*12|0)+4|0;w=r;r=0;x=0;while(1){y=k;z=(c[s>>2]|0)+(x<<6)|0;A=y+64|0;do{a[y>>0]=a[z>>0]|0;y=y+1|0;z=z+1|0}while((y|0)<(A|0));if((x|0)==(w|0))B=r+1|0;else B=(c[(c[v>>2]|0)+(x<<2)>>2]|0)+r|0;z=x;x=x+1|0;a:do if(l){y=r;b:while(1){A=(((_(d[k>>0]|0,e[h+(y<<1)>>1]|0)|0)>>>0)/100|0)<<2;C=A>>>0>4096?4096:A;A=f+(y*24|0)+(p<<3)+(m<<2)|0;D=c[A>>2]|0;b[D>>1]=t-(t>>>0<C>>>0?t-C|0:0);C=h+128+(y<<1)|0;E=1;do{F=(((_(d[k+(d[8+E>>0]|0)>>0]|0,e[C>>1]|0)|0)>>>0)/100|0)<<2;G=F>>>0>4096?4096:F;b[D+(E<<1)>>1]=u-(u>>>0<G>>>0?u-G|0:0);E=E+1|0}while((E|0)!=64);H=0;c:while(1){E=(H|0)<(m|0);C=E?3:p;if((C|0)>0){G=0;do{F=c[f+(y*24|0)+(G<<3)+(H<<2)>>2]|0;if(!(Nb(D,F,128)|0)){I=F;J=13;break c}G=G+1|0}while((G|0)<(C|0))}if(E)H=H+1|0;else break}if((J|0)==13){J=0;c[A>>2]=I}D=y+1|0;if((B|0)<=(D|0)){K=D;L=w;break a}C=B-D|0;G=c[s>>2]|0;F=D-r|0;M=c[(c[v>>2]|0)+(z<<2)>>2]|0;N=M<<1;O=0;while(1){P=_(d[G+(z<<6)+O>>0]|0,C)|0;a[k+O>>0]=(((_(d[G+(x<<6)+O>>0]|0,F)|0)+P<<1)+M|0)/(N|0)|0;P=O+1|0;if((P|0)==64){y=D;continue b}else O=P}}}else{y=r;d:while(1){O=_(d[k>>0]|0,e[h+(y<<1)>>1]|0)|0;c[g+(y<<2)>>2]=(O>>>0)/160|0;D=((O>>>0)/100|0)<<2;O=D>>>0>4096?4096:D;D=f+(y*24|0)+(p<<3)+(m<<2)|0;N=c[D>>2]|0;b[N>>1]=t-(t>>>0<O>>>0?t-O|0:0);O=h+128+(y<<1)|0;M=1;do{F=(((_(d[k+(d[8+M>>0]|0)>>0]|0,e[O>>1]|0)|0)>>>0)/100|0)<<2;G=F>>>0>4096?4096:F;b[N+(M<<1)>>1]=u-(u>>>0<G>>>0?u-G|0:0);M=M+1|0}while((M|0)!=64);Q=0;e:while(1){M=(Q|0)<(m|0);O=M?3:p;if((O|0)>0){G=0;do{F=c[f+(y*24|0)+(G<<3)+(Q<<2)>>2]|0;if(!(Nb(N,F,128)|0)){R=F;J=25;break e}G=G+1|0}while((G|0)<(O|0))}if(M)Q=Q+1|0;else break}if((J|0)==25){J=0;c[D>>2]=R}N=y+1|0;if((B|0)<=(N|0)){S=N;break}O=B-N|0;G=c[s>>2]|0;E=N-r|0;F=c[(c[v>>2]|0)+(z<<2)>>2]|0;C=F<<1;A=0;while(1){P=_(d[G+(z<<6)+A>>0]|0,O)|0;a[k+A>>0]=(((_(d[G+(x<<6)+A>>0]|0,E)|0)+P<<1)+F|0)/(C|0)|0;P=A+1|0;if((P|0)==64){y=N;continue d}else A=P}}K=S;L=c[q>>2]|0}while(0);if((z|0)>=(L|0))break;else{w=L;r=K}}}p=p+1|0;if((p|0)==3)break}m=m+1|0;if((m|0)==2)break}i=j;return}function mb(b,e,f){b=b|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,ua=0,va=0,wa=0,xa=0,ya=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0,Ya=0,Za=0,_a=0,$a=0,ab=0,bb=0,cb=0,db=0,eb=0,fb=0,gb=0,hb=0,lb=0,mb=0,nb=0,ob=0,pb=0,qb=0,rb=0,sb=0,tb=0,ub=0,vb=0,wb=0,xb=0,yb=0,zb=0,Ab=0,Bb=0,Cb=0,Db=0;if(!e){g=-1;return g|0}h=c[e+4>>2]|0;if(h&15){g=-10;return g|0}i=e+8|0;j=c[i>>2]|0;if((j+-1|0)>>>0>1048574|((h+-1|0)>>>0>1048574|(j&15|0)!=0)){g=-10;return g|0}k=c[e+20>>2]|0;if(((c[e+12>>2]|0)+k|0)>>>0>h>>>0){g=-10;return g|0}h=e+24|0;l=c[h>>2]|0;m=e+16|0;n=c[m>>2]|0;if(k>>>0>255|(n+l|0)>>>0>j>>>0){g=-10;return g|0}if((j-l-n|0)>>>0>255){g=-10;return g|0}if((c[e+44>>2]|0)>>>0>2){g=-10;return g|0}if((c[e+48>>2]|0)>>>0>3){g=-10;return g|0}if(!(c[e+28>>2]|0)){g=-10;return g|0}if(!(c[e+32>>2]|0)){g=-10;return g|0}Ub(b|0,0,51632)|0;n=b;l=e;j=n+64|0;do{c[n>>2]=c[l>>2];n=n+4|0;l=l+4|0}while((n|0)<(j|0));k=b+24|0;c[k>>2]=(c[i>>2]|0)-(c[m>>2]|0)-(c[h>>2]|0);a[b+872>>0]=-1;c[b+68>>2]=0;c[b+64>>2]=8;h=b+4|0;m=(c[h>>2]|0)>>>3;i=b+8|0;o=(c[i>>2]|0)>>>3;p=b+48|0;q=c[p>>2]|0;r=q&1^1;s=q>>>1&1^1;q=(r+m|0)>>>r;r=(s+o|0)>>>s;s=_(o,m)|0;t=_(r,q)|0;u=t<<1;v=u+s|0;w=(m+3|0)>>>2;x=(o+3|0)>>>2;y=q+3>>2;z=r+3>>2;A=_(x,w)|0;B=_(z,y)|0;D=B<<1;E=D+A|0;F=A<<2;do if(!((t|0)<0|(u|0)<(t|0))?(A&1073741823|0)==(A|0)&((E>>>0<A>>>0|(D>>>0<B>>>0?1:((A>>>0)/(w>>>0)|0|0)!=(x|0)))^1):0){G=b+72|0;c[G>>2]=m;H=b+76|0;c[H>>2]=o;I=b+80|0;c[I>>2]=0;J=b+84|0;c[J>>2]=s;c[b+88>>2]=w;c[b+92>>2]=x;c[b+96>>2]=0;c[b+100>>2]=A;K=b+136|0;c[K>>2]=q;L=b+104|0;c[L>>2]=q;c[b+140>>2]=r;c[b+108>>2]=r;M=b+112|0;c[M>>2]=s;N=b+144|0;c[N>>2]=t+s;O=b+148|0;c[O>>2]=t;P=b+116|0;c[P>>2]=t;c[b+152>>2]=y;c[b+120>>2]=y;c[b+156>>2]=z;c[b+124>>2]=z;c[b+128>>2]=A;c[b+160>>2]=B+A;c[b+164>>2]=B;c[b+132>>2]=B;Q=b+180|0;c[Q>>2]=v;R=Qb(v,4)|0;S=b+168|0;c[S>>2]=R;T=Ob(v<<1)|0;c[b+176>>2]=T;c[b+192>>2]=E;U=Ob(E<<6)|0;V=b+184|0;c[V>>2]=U;W=Qb(E,1)|0;X=b+188|0;c[X>>2]=W;c[b+204>>2]=w<<1;c[b+208>>2]=x<<1;c[b+212>>2]=F;Y=Qb(F,48)|0;Z=b+196|0;c[Z>>2]=Y;$=Qb(F,1)|0;aa=b+200|0;c[aa>>2]=$;ba=Ob(v<<2)|0;c[b+216>>2]=ba;if(!((R|0)==0|(T|0)==0|(U|0)==0|(W|0)==0|(Y|0)==0)?!(($|0)==0|(ba|0)==0):0){ba=o;$=W;W=U;U=0;Y=0;T=0;while(1){R=c[b+72+(T<<5)>>2]|0;ca=R<<2;da=0;ea=0;fa=Y;while(1){ga=ba-ea|0;if((ga|0)<=4)if((ga|0)<1)break;else ha=ga;else ha=4;ga=da;ia=0;while(1){ja=R-ia|0;if((ja|0)<=4)if((ja|0)<1){ka=ga;break}else la=ja;else la=4;ja=ga+U|0;n=W+(ja<<6)|0;j=n+64|0;do{c[n>>2]=-1;n=n+4|0}while((n|0)<(j|0));ma=0;na=ia+fa|0;while(1){oa=0;do{c[W+(ja<<6)+(c[1352+(ma<<5)+(oa<<3)>>2]<<4)+(c[1352+(ma<<5)+(oa<<3)+4>>2]<<2)>>2]=oa+na;oa=oa+1|0}while((oa|0)!=(la|0));ma=ma+1|0;if((ma|0)==(ha|0))break;else na=na+R|0}na=$+ja|0;ma=a[na>>0]|0;oa=ma&-61;pa=(((ma&255)>>>2&255|(c[W+(ja<<6)>>2]|0)>>>31^1)&255)<<2&60|oa;a[na>>0]=pa;ma=(((pa&255)>>>2&255|(c[W+(ja<<6)+16>>2]|0)>>>31<<1^2)&255)<<2&60|oa;a[na>>0]=ma;pa=(((ma&255)>>>2&255|(c[W+(ja<<6)+32>>2]|0)>>>31<<2^4)&255)<<2&60|oa;a[na>>0]=pa;a[na>>0]=(((pa&255)>>>2&255|(c[W+(ja<<6)+56>>2]|0)>>>31<<3^8)&255)<<2&60|oa;ga=ga+1|0;ia=ia+4|0}da=ka;ea=ea+4|0;fa=fa+ca|0}ca=T+1|0;if((ca|0)==3)break;ba=c[b+72+(ca<<5)+4>>2]|0;$=c[X>>2]|0;W=c[V>>2]|0;U=c[b+72+(ca<<5)+24>>2]|0;Y=c[b+72+(ca<<5)+8>>2]|0;T=ca}T=c[Z>>2]|0;Y=c[aa>>2]|0;U=c[1480+(c[p>>2]<<2)>>2]|0;V=c[H>>2]|0;if((V|0)>0){W=c[G>>2]|0;X=V;V=0;$=0;while(1){if((W|0)>0){ba=V;ca=0;while(1){fa=ba<<2;ea=ca|1;da=ca|2;R=ca|3;ia=0;do{ga=ia<<1|$;oa=ga|1;pa=d[136+(ia<<1)>>0]|fa;na=T+(pa*48|0)|0;n=na;j=n+48|0;do{c[n>>2]=-1;n=n+4|0}while((n|0)<(j|0));ja=c[G>>2]|0;do if((ca|0)<(ja|0)){if((ga|0)>=(c[H>>2]|0)){qa=36;break}c[na>>2]=(_(ja,ga)|0)+ca;c[T+(pa*48|0)+4>>2]=(_(c[G>>2]|0,ga)|0)+ea;c[T+(pa*48|0)+8>>2]=(_(c[G>>2]|0,oa)|0)+ca;c[T+(pa*48|0)+12>>2]=(_(c[G>>2]|0,oa)|0)+ea;za[U&7](na,G,ca,ga)}else qa=36;while(0);if((qa|0)==36){qa=0;a[Y+pa>>0]=-1}na=d[136+(ia<<1)+1>>0]|fa;ja=T+(na*48|0)|0;n=ja;j=n+48|0;do{c[n>>2]=-1;n=n+4|0}while((n|0)<(j|0));pa=c[G>>2]|0;do if((da|0)<(pa|0)){if((ga|0)>=(c[H>>2]|0)){qa=43;break}c[ja>>2]=(_(pa,ga)|0)+da;c[T+(na*48|0)+4>>2]=(_(c[G>>2]|0,ga)|0)+R;c[T+(na*48|0)+8>>2]=(_(c[G>>2]|0,oa)|0)+da;c[T+(na*48|0)+12>>2]=(_(c[G>>2]|0,oa)|0)+R;za[U&7](ja,G,da,ga)}else qa=43;while(0);if((qa|0)==43){qa=0;a[Y+na>>0]=-1}ia=ia+1|0}while((ia|0)!=2);ca=ca+4|0;ia=ba+1|0;da=c[G>>2]|0;if((ca|0)>=(da|0)){ra=ia;sa=da;break}else ba=ia}ta=c[H>>2]|0;ua=sa;va=ra}else{ta=X;ua=W;va=V}$=$+4|0;if(($|0)>=(ta|0))break;else{W=ua;X=ta;V=va}}}V=b+588|0;c[V>>2]=0;X=c[S>>2]|0;W=b+20|0;$=b+12|0;H=b+16|0;G=X;Y=0;U=X;while(1){X=c[W>>2]|0;T=(c[$>>2]|0)+X|0;aa=c[k>>2]|0;Z=(c[H>>2]|0)+aa|0;do if((Y|0)>0){ba=c[p>>2]|0;if(!(ba&1)){wa=X>>1;xa=T+1>>1}else{wa=X;xa=T}if(ba&2){ya=wa;Aa=xa;Ba=aa;Ca=Z;break}ya=wa;Aa=xa;Ba=aa>>1;Ca=Z+1>>1}else{ya=X;Aa=T;Ba=aa;Ca=Z}while(0);U=U+(c[b+72+(Y<<5)+12>>2]<<2)|0;if(G>>>0<U>>>0){Z=b+72+(Y<<5)|0;aa=(ya|0)<(Aa|0);T=(Ba|0)<(Ca|0);X=G;ba=0;while(1){ca=c[Z>>2]|0;ia=X+(ca<<2)|0;if((ca|0)>0){ca=ba+8|0;da=(ca|0)>(Ba|0);R=(Ca|0)>(ba|0);fa=(ba|0)<(Ba|0)&da;ea=R&(Ca|0)<(ca|0);ga=X+4|0;ja=(ia>>>0>ga>>>0?ia:ga)+~X|0;ga=T&(aa&(R&da))^1;da=X;R=0;do{oa=R;R=R+8|0;do if((Aa|0)<=(oa|0)|(R|0)<=(ya|0)|ga)c[da>>2]=c[da>>2]|2;else{pa=(oa|0)<(ya|0);if(!(ea|(fa|(pa|(Aa|0)<(R|0))))){c[da>>2]=c[da>>2]|63488;break}ma=oa|1;Da=oa|2;Ea=oa|3;Fa=oa|4;Ga=oa|5;Ha=oa|6;Ia=oa|7;Ja=(ma|0)>=(Aa|0)|(ma|0)<(ya|0);ma=(Da|0)>=(Aa|0)|(Da|0)<(ya|0);Da=(Ea|0)>=(Aa|0)|(Ea|0)<(ya|0);Ea=(Fa|0)>=(Aa|0)|(Fa|0)<(ya|0);Fa=(Ga|0)>=(Aa|0)|(Ga|0)<(ya|0);Ga=(Ha|0)>=(Aa|0)|(Ha|0)<(ya|0);Ha=(Ia|0)>=(Aa|0)|(Ia|0)<(ya|0);Ia=0;Ka=0;La=0;Ma=0;while(1){Na=La+ba|0;Oa=La<<3;Pa=(Na|0)>=(Ca|0)|(Na|0)<(Ba|0);if(pa|Pa){Qa=Ia;Ra=Ka;Sa=Ma}else{Na=Vb(1,0,Oa|0)|0;Qa=Na|Ia;Ra=C|Ka;Sa=Ma+1|0}if(Ja|Pa){Ta=Qa;Ua=Ra;Va=Sa}else{Na=Vb(1,0,Oa|1|0)|0;Ta=Qa|Na;Ua=Ra|C;Va=Sa+1|0}if(ma|Pa){Wa=Ta;Xa=Ua;Ya=Va}else{Na=Vb(1,0,Oa|2|0)|0;Wa=Ta|Na;Xa=Ua|C;Ya=Va+1|0}if(Da|Pa){Za=Wa;_a=Xa;$a=Ya}else{Na=Vb(1,0,Oa|3|0)|0;Za=Wa|Na;_a=Xa|C;$a=Ya+1|0}if(Ea|Pa){ab=Za;bb=_a;cb=$a}else{Na=Vb(1,0,Oa|4|0)|0;ab=Za|Na;bb=_a|C;cb=$a+1|0}if(Fa|Pa){db=ab;eb=bb;fb=cb}else{Na=Vb(1,0,Oa|5|0)|0;db=ab|Na;eb=bb|C;fb=cb+1|0}if(Ga|Pa){gb=db;hb=eb;lb=fb}else{Na=Vb(1,0,Oa|6|0)|0;gb=db|Na;hb=eb|C;lb=fb+1|0}if(Ha|Pa){mb=gb;nb=hb;ob=lb}else{Pa=Vb(1,0,Oa|7|0)|0;mb=gb|Pa;nb=hb|C;ob=lb+1|0}La=La+1|0;if((La|0)==8){pb=mb;qb=nb;rb=ob;break}else{Ia=mb;Ka=nb;Ma=ob}}Ma=c[V>>2]|0;a:do if((Ma|0)>0){Ka=0;while(1){Ia=b+592+(Ka<<4)|0;if((c[Ia>>2]|0)==(pb|0)?(c[Ia+4>>2]|0)==(qb|0):0){sb=Ka;break a}Ia=Ka+1|0;if((Ia|0)<(Ma|0))Ka=Ia;else{tb=Ia;qa=65;break}}}else{tb=0;qa=65}while(0);if((qa|0)==65){qa=0;c[V>>2]=Ma+1;Ka=b+592+(tb<<4)|0;c[Ka>>2]=pb;c[Ka+4>>2]=qb;c[b+592+(tb<<4)+8>>2]=rb;sb=tb}c[da>>2]=c[da>>2]&-63489|sb<<11&63488}while(0);da=da+4|0}while(da>>>0<ia>>>0);ub=ca;vb=X+((ja>>>2)+1<<2)|0}else{ub=ba+8|0;vb=X}if(vb>>>0<U>>>0){X=vb;ba=ub}else{wb=vb;break}}}else wb=G;Y=Y+1|0;if((Y|0)==3)break;else G=wb}if((f+-3|0)>>>0<=3){G=c[p>>2]|0;Y=G&1^1;U=G>>>1&1^1;G=c[h>>2]|0;V=G+32|0;H=(c[i>>2]|0)+32|0;$=(V>>Y)+15&-16;W=_(H,V)|0;S=_($,H>>U)|0;ba=(V<<4)+16|0;X=(_($,16>>>U)|0)+(16>>>Y)|0;aa=0-X&15;T=S<<1;Z=W+16+T|0;ia=_(Z,f)|0;if(!(Z>>>0<W>>>0|((T|16)>>>0<S>>>0?1:((W>>>0)/(V>>>0)|0|0)!=(H|0)))?((ia>>>0)/(f>>>0)|0|0)==(Z|0):0){Z=ib(ia,16)|0;ia=Ob(c[Q>>2]<<2)|0;c[b+172>>2]=ia;if((Z|0)==0|(ia|0)==0){Pb(ia);jb(Z);xb=-1;break}H=c[h>>2]|0;T=b+236|0;c[T>>2]=H;da=c[i>>2]|0;c[b+240>>2]=da;R=b+244|0;c[R>>2]=V;V=H>>>Y;c[b+268>>2]=V;c[b+252>>2]=V;V=da>>>U;c[b+272>>2]=V;c[b+256>>2]=V;V=b+276|0;c[V>>2]=$;U=b+260|0;c[U>>2]=$;if((f|0)>1){da=1;do{n=b+236+(da*48|0)|0;l=T;j=n+48|0;do{c[n>>2]=c[l>>2];n=n+4|0;l=l+4|0}while((n|0)<(j|0));da=da+1|0}while((da|0)!=(f|0))}c[b+572>>2]=Z;if((f|0)>0){da=aa+W|0;T=da+X|0;Q=da+S|0;da=Q+X|0;Y=S+16-aa+Q|0;Q=Z;H=0;while(1){fa=b+236+(H*48|0)|0;c[b+236+(H*48|0)+12>>2]=Q+ba;c[b+236+(H*48|0)+28>>2]=Q+T;c[b+236+(H*48|0)+44>>2]=Q+da;kb(fa,fa);H=H+1|0;if((H|0)==(f|0))break;else Q=Q+Y|0}}c[b+576>>2]=-32-G;Y=0-$|0;c[b+584>>2]=Y;c[b+580>>2]=Y;Y=c[b+248>>2]|0;Q=Y;H=(c[J>>2]|0)+(c[I>>2]|0)|0;da=c[b+72>>2]|0;if((H|0)>0){T=c[R>>2]<<3;ba=(da|0)>0;Z=0;aa=Y;while(1){Y=Z+da|0;if(ba){S=Z+1|0;X=Z;W=aa;while(1){c[ia+(X<<2)>>2]=W-Q;X=X+1|0;if((X|0)>=(Y|0))break;else W=W+8|0}yb=(Y|0)>(S|0)?Y:S}else yb=Z;if((yb|0)<(H|0)){Z=yb;aa=aa+T|0}else{zb=yb;break}}}else zb=0;T=(c[P>>2]|0)+(c[M>>2]|0)|0;aa=c[L>>2]|0;if((zb|0)<(T|0)){Z=c[U>>2]<<3;H=(aa|0)>0;ba=zb;da=c[b+264>>2]|0;while(1){R=ba+aa|0;if(H){I=ba+1|0;J=ba;$=da;while(1){c[ia+(J<<2)>>2]=$-Q;J=J+1|0;if((J|0)>=(R|0))break;else $=$+8|0}Ab=(R|0)>(I|0)?R:I}else Ab=ba;if((Ab|0)<(T|0)){ba=Ab;da=da+Z|0}else{Bb=Ab;break}}}else Bb=zb;Z=(c[O>>2]|0)+(c[N>>2]|0)|0;da=c[K>>2]|0;if((Bb|0)<(Z|0)){ba=c[V>>2]<<3;T=(da|0)>0;H=Bb;aa=c[b+280>>2]|0;while(1){U=H+da|0;if(T){L=H+1|0;M=H;P=aa;while(1){c[ia+(M<<2)>>2]=P-Q;M=M+1|0;if((M|0)>=(U|0))break;else P=P+8|0}Cb=(U|0)>(L|0)?U:L}else Cb=H;if((Cb|0)<(Z|0)){H=Cb;aa=aa+ba|0}else break}}ba=b+524|0;c[ba>>2]=-1;c[ba+4>>2]=-1;c[ba+8>>2]=-1;c[ba+12>>2]=-1;c[ba+16>>2]=-1;c[ba+20>>2]=-1;ba=b+548|0;c[ba>>2]=0;c[ba+4>>2]=0;c[ba+8>>2]=0;c[ba+12>>2]=0;c[ba+16>>2]=0;c[ba+20>>2]=0;if((c[e+60>>2]|0)>>>0>31)c[b+60>>2]=31;ba=b+848|0;c[ba>>2]=0;c[ba+4>>2]=0;ba=b+856|0;c[ba>>2]=-1;c[ba+4>>2]=-1;ba=a[e>>0]|0;do if((ba&255)>3)Db=1;else{if(ba<<24>>24!=3){Db=0;break}aa=a[e+1>>0]|0;if((aa&255)>2){Db=1;break}if(aa<<24>>24!=2){Db=0;break}Db=(a[e+2>>0]|0)!=0&1}while(0);a[b+873>>0]=Db;g=0;return g|0}else xb=-23}else xb=-10}else xb=-1}else xb=-23;while(0);Pb(c[b+216>>2]|0);Pb(c[b+200>>2]|0);Pb(c[b+196>>2]|0);Pb(c[b+188>>2]|0);Pb(c[b+184>>2]|0);Pb(c[b+176>>2]|0);Pb(c[b+168>>2]|0);g=xb;return g|0}function nb(a){a=a|0;Pb(c[a+172>>2]|0);jb(c[a+572>>2]|0);Pb(c[a+216>>2]|0);Pb(c[a+200>>2]|0);Pb(c[a+196>>2]|0);Pb(c[a+188>>2]|0);Pb(c[a+184>>2]|0);Pb(c[a+176>>2]|0);Pb(c[a+168>>2]|0);return}function ob(b,d,e,f,g){b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0;if(!e)h=0;else h=(c[b+48>>2]&1|0)==0;i=16>>>(h&1);h=c[b+236+(d*48|0)+(e<<4)+8>>2]|0;j=c[b+236+(d*48|0)+(e<<4)+12>>2]|0;k=_(h,f)|0;f=_(h,g)|0;g=j+f|0;if((k|0)==(f|0))return;f=0-i|0;l=j+k|0;m=j+(k+-1+(c[b+236+(d*48|0)+(e<<4)>>2]|0))|0;while(1){Ub(l+f|0,a[l>>0]|0,i|0)|0;Ub(m+1|0,a[m>>0]|0,i|0)|0;l=l+h|0;if((l|0)==(g|0))break;else m=m+h|0}return}function pb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;if(!d){e=16;f=0}else{g=c[a+48>>2]|0;e=16>>>(g&1^1);f=(g&2|0)==0}g=c[a+236+(b*48|0)+(d<<4)+8>>2]|0;h=(c[a+236+(b*48|0)+(d<<4)>>2]|0)+(e<<1)|0;i=c[a+236+(b*48|0)+(d<<4)+12>>2]|0;j=0-e|0;k=0-(e+(_(16>>>(f&1),g)|0))|0;f=i+k|0;if((j|0)==(k|0))return;k=0-g|0;l=i+j|0;j=i+((_((c[a+236+(b*48|0)+(d<<4)+4>>2]|0)+-1|0,g)|0)-e)|0;do{e=l;l=l+k|0;Xb(l|0,e|0,h|0)|0;e=j;j=j+g|0;Xb(j|0,e|0,h|0)|0}while((l|0)!=(f|0));return}function qb(d,e,f,g,h,i){d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0;j=_(b[g>>1]|0,i&65535)|0;if((h|0)<2){i=(j+15|0)>>>5&65535;k=0;do{b[g+(k+64<<1)>>1]=i;k=k+1|0}while((k|0)!=64)}else{b[g>>1]=j;cb(g+128|0,g,h)}h=c[(c[d+172>>2]|0)+(e<<2)>>2]|0;j=(c[(c[d+168>>2]|0)+(e<<2)>>2]|0)>>>6&3;k=c[d+576+(f<<2)>>2]|0;i=(c[d+556>>2]|0)+h|0;if((j|0)==2){Wa(i,k,g+128|0);return}l=c[d+548+(j<<2)>>2]|0;j=b[(c[d+176>>2]|0)+(e<<1)>>1]|0;e=(f|0)!=0;if(e)m=(c[d+48>>2]&2|0)==0;else m=0;f=m&1;m=(j<<16>>16>>8)+31|0;n=a[1624+(f<<6)+m>>0]|0;if(e)o=(c[d+48>>2]&1|0)==0;else o=0;d=o&1;o=((j&65535)<<24>>24)+31|0;j=a[1624+(d<<6)+o>>0]|0;e=(a[1496+(d<<6)+o>>0]|0)+(_(a[1496+(f<<6)+m>>0]|0,k)|0)|0;if(!((j|n)<<24>>24)){Xa(i,l+(e+h)|0,k,g+128|0);return}else{Ya(i,l+(e+h)|0,l+((_(n<<24>>24,k)|0)+h+e+(j<<24>>24))|0,k,g+128|0);return}}function rb(b,c){b=b|0;c=c|0;var d=0,e=0,f=0;Ub(b|0,0,256)|0;if((c|0)>0)d=0;else return;do{e=127-d|0;f=e-c|0;if((f|0)>-1)a[b+f>>0]=d-c;a[b+e>>0]=0-d;e=d+127|0;a[b+e>>0]=d;f=e+c|0;if((f|0)<256)a[b+f>>0]=c-d;d=d+1|0}while((d|0)!=(c|0));return}function sb(b,e,f,g,h,i){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0;j=c[b+72+(g<<5)>>2]|0;k=c[b+72+(g<<5)+8>>2]|0;l=(c[b+72+(g<<5)+12>>2]|0)+k|0;m=k+(_(j,h)|0)|0;h=k+(_(j,i)|0)|0;i=c[b+576+(g<<2)>>2]|0;g=c[b+168>>2]|0;n=c[b+172>>2]|0;o=c[b+548+(f<<2)>>2]|0;if((m|0)>=(h|0))return;f=i<<1;b=i<<3;p=(j|0)>0;q=m;do{m=q;q=q+j|0;if(p){r=(m|0)>(k|0);s=m;while(1){if(c[g+(s<<2)>>2]&1){t=c[n+(s<<2)>>2]|0;if((s|0)>(m|0)){u=o+(t+-2)|0;v=0;while(1){w=u+2|0;x=d[w>>0]|0;y=u+1|0;z=d[y>>0]|0;A=a[e+(((d[u>>0]|0)+4-(d[u+3>>0]|0)+((x-z|0)*3|0)>>3)+127)>>0]|0;B=A+z|0;a[y>>0]=(B>>>31)+255&((B|0)>255?255:B);B=x-A|0;a[w>>0]=(B>>>31)+255&((B|0)>255?255:B);v=v+1|0;if((v|0)==8)break;else u=u+i|0}}if(r){u=t-f|0;v=t+i|0;B=t-i|0;w=0;do{A=o+(w+t)|0;x=o+(B+w)|0;y=d[x>>0]|0;z=a[e+(((d[o+(u+w)>>0]|0)+4-(d[o+(v+w)>>0]|0)+(((d[A>>0]|0)-y|0)*3|0)>>3)+127)>>0]|0;C=z+y|0;a[x>>0]=(C>>>31)+255&((C|0)>255?255:C);C=(d[A>>0]|0)-z|0;a[A>>0]=(C>>>31)+255&((C|0)>255?255:C);w=w+1|0}while((w|0)!=8)}w=s+1|0;if((w|0)<(q|0)?(c[g+(w<<2)>>2]&1|0)==0:0){v=o+(t+6)|0;u=0;while(1){B=v+2|0;C=d[B>>0]|0;A=v+1|0;z=d[A>>0]|0;x=a[e+(((d[v>>0]|0)+4-(d[v+3>>0]|0)+((C-z|0)*3|0)>>3)+127)>>0]|0;y=x+z|0;a[A>>0]=(y>>>31)+255&((y|0)>255?255:y);y=C-x|0;a[B>>0]=(y>>>31)+255&((y|0)>255?255:y);u=u+1|0;if((u|0)==8)break;else v=v+i|0}}v=s+j|0;if((v|0)<(l|0)?(c[g+(v<<2)>>2]&1|0)==0:0){v=t+b|0;u=v-f|0;y=v+i|0;B=v-i|0;x=0;do{C=o+(x+v)|0;A=o+(B+x)|0;z=d[A>>0]|0;D=a[e+(((d[o+(u+x)>>0]|0)+4-(d[o+(y+x)>>0]|0)+(((d[C>>0]|0)-z|0)*3|0)>>3)+127)>>0]|0;E=D+z|0;a[A>>0]=(E>>>31)+255&((E|0)>255?255:E);E=(d[C>>0]|0)-D|0;a[C>>0]=(E>>>31)+255&((E|0)>255?255:E);x=x+1|0}while((x|0)!=8);F=w}else F=w}else F=s+1|0;if((F|0)<(q|0))s=F;else break}}}while((q|0)<(h|0));return}function tb(b,e,f,g,h,j,k,l){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;k=k|0;l=l|0;var m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0;m=i;i=i+48|0;n=m;o=n+20|0;p=n+16|0;q=n+4|0;r=n+8|0;s=n+12|0;t=e<<1;u=n+24|0;v=n+28|0;w=n+32|0;x=n+36|0;y=g<<1;z=g*3|0;A=g<<2;B=g*5|0;C=g*6|0;D=g*7|0;E=g<<3;F=g*9|0;G=e*3|0;H=e<<2;I=e*5|0;J=e<<1;K=e*3|0;L=e<<2;M=e*5|0;N=e*6|0;O=e*7|0;P=0;Q=b+(e*6|0)|0;R=b+(e*5|0)|0;S=b;b=f;while(1){f=d[b>>0]|0;c[n>>2]=f;T=a[b+g>>0]|0;U=T&255;c[q>>2]=U;V=d[b+y>>0]|0;c[r>>2]=V;W=d[b+z>>0]|0;c[s>>2]=W;X=d[b+A>>0]|0;c[p>>2]=X;Y=d[b+B>>0]|0;c[o>>2]=Y;Z=d[b+C>>0]|0;c[u>>2]=Z;_=d[b+D>>0]|0;c[v>>2]=_;$=d[b+E>>0]|0;c[w>>2]=$;aa=d[b+F>>0]|0;c[x>>2]=aa;ba=U-f|0;ca=Y-Z|0;da=V-U|0;ea=Z-_|0;Z=W-V|0;fa=_-$|0;_=X-W|0;ga=((_|0)>-1?_:0-_|0)+(((Z|0)>-1?Z:0-Z|0)+(((da|0)>-1?da:0-da|0)+((ba|0)>-1?ba:0-ba|0)))|0;ba=$-aa|0;aa=((ba|0)>-1?ba:0-ba|0)+(((fa|0)>-1?fa:0-fa|0)+(((ea|0)>-1?ea:0-ea|0)+((ca|0)>-1?ca:0-ca|0)))|0;c[k>>2]=(c[k>>2]|0)+((ga|0)<255?ga:255);c[l>>2]=(c[l>>2]|0)+((aa|0)<255?aa:255);if((ga|0)<(j|0)&(aa|0)<(j|0)?(Y-X|0)<(h|0)&(X-Y|0)<(h|0):0){a[S>>0]=(X+4+(f*3|0)+(U<<1)+V+W|0)>>>3;a[S+e>>0]=((c[q>>2]|0)+4+(c[s>>2]|0)+(c[p>>2]|0)+(c[o>>2]|0)+((c[r>>2]|0)+(c[n>>2]|0)<<1)|0)>>>3;a[S+t>>0]=((c[n>>2]|0)+4+(c[q>>2]|0)+(c[r>>2]|0)+(c[s>>2]<<1)+(c[p>>2]|0)+(c[o>>2]|0)+(c[u>>2]|0)|0)>>>3;a[S+G>>0]=((c[q>>2]|0)+4+(c[r>>2]|0)+(c[s>>2]|0)+(c[p>>2]<<1)+(c[o>>2]|0)+(c[u>>2]|0)+(c[v>>2]|0)|0)>>>3;a[S+H>>0]=((c[r>>2]|0)+4+(c[s>>2]|0)+(c[p>>2]|0)+(c[o>>2]<<1)+(c[u>>2]|0)+(c[v>>2]|0)+(c[w>>2]|0)|0)>>>3;a[S+I>>0]=((c[s>>2]|0)+4+(c[p>>2]|0)+(c[o>>2]|0)+(c[u>>2]<<1)+(c[v>>2]|0)+(c[w>>2]|0)+(c[x>>2]|0)|0)>>>3;a[Q>>0]=((c[p>>2]|0)+4+(c[o>>2]|0)+(c[u>>2]|0)+(c[w>>2]|0)+((c[x>>2]|0)+(c[v>>2]|0)<<1)|0)>>>3;a[R+t>>0]=((c[o>>2]|0)+4+(c[u>>2]|0)+(c[v>>2]|0)+(c[w>>2]<<1)+((c[x>>2]|0)*3|0)|0)>>>3}else{a[S>>0]=T;a[S+e>>0]=c[r>>2];a[S+J>>0]=c[s>>2];a[S+K>>0]=c[p>>2];a[S+L>>0]=c[o>>2];a[S+M>>0]=c[u>>2];a[S+N>>0]=c[v>>2];a[S+O>>0]=c[w>>2]}P=P+1|0;if((P|0)==8)break;else{Q=Q+1|0;R=R+1|0;S=S+1|0;b=b+1|0}}i=m;return}function ub(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0;j=i;i=i+48|0;k=j;l=h+4|0;m=k+20|0;n=k+16|0;o=k+4|0;p=k+8|0;q=k+12|0;r=k+24|0;s=k+28|0;t=k+32|0;u=k+36|0;v=0;w=b;x=b+6|0;y=b+5|0;while(1){b=d[w+-1>>0]|0;c[k>>2]=b;z=d[w>>0]|0;c[o>>2]=z;A=d[w+1>>0]|0;c[p>>2]=A;B=d[w+2>>0]|0;c[q>>2]=B;C=d[w+3>>0]|0;c[n>>2]=C;D=d[w+4>>0]|0;c[m>>2]=D;E=d[w+5>>0]|0;c[r>>2]=E;F=d[w+6>>0]|0;c[s>>2]=F;G=d[w+7>>0]|0;c[t>>2]=G;H=d[w+8>>0]|0;c[u>>2]=H;I=z-b|0;J=D-E|0;K=A-z|0;L=E-F|0;E=B-A|0;M=F-G|0;F=C-B|0;N=((F|0)>-1?F:0-F|0)+(((E|0)>-1?E:0-E|0)+(((K|0)>-1?K:0-K|0)+((I|0)>-1?I:0-I|0)))|0;I=G-H|0;H=((I|0)>-1?I:0-I|0)+(((M|0)>-1?M:0-M|0)+(((L|0)>-1?L:0-L|0)+((J|0)>-1?J:0-J|0)))|0;c[h>>2]=(c[h>>2]|0)+((N|0)<255?N:255);c[l>>2]=(c[l>>2]|0)+((H|0)<255?H:255);if((N|0)<(g|0)&(H|0)<(g|0)?(D-C|0)<(f|0)&(C-D|0)<(f|0):0){a[w>>0]=(C+4+(b*3|0)+(z<<1)+A+B|0)>>>3;a[w+1>>0]=((c[o>>2]|0)+4+(c[q>>2]|0)+(c[n>>2]|0)+(c[m>>2]|0)+((c[p>>2]|0)+(c[k>>2]|0)<<1)|0)>>>3;a[w+2>>0]=((c[k>>2]|0)+4+(c[o>>2]|0)+(c[p>>2]|0)+(c[q>>2]<<1)+(c[n>>2]|0)+(c[m>>2]|0)+(c[r>>2]|0)|0)>>>3;a[w+3>>0]=((c[o>>2]|0)+4+(c[p>>2]|0)+(c[q>>2]|0)+(c[n>>2]<<1)+(c[m>>2]|0)+(c[r>>2]|0)+(c[s>>2]|0)|0)>>>3;a[w+4>>0]=((c[p>>2]|0)+4+(c[q>>2]|0)+(c[n>>2]|0)+(c[m>>2]<<1)+(c[r>>2]|0)+(c[s>>2]|0)+(c[t>>2]|0)|0)>>>3;a[w+5>>0]=((c[q>>2]|0)+4+(c[n>>2]|0)+(c[m>>2]|0)+(c[r>>2]<<1)+(c[s>>2]|0)+(c[t>>2]|0)+(c[u>>2]|0)|0)>>>3;a[x>>0]=((c[n>>2]|0)+4+(c[m>>2]|0)+(c[r>>2]|0)+(c[t>>2]|0)+((c[u>>2]|0)+(c[s>>2]|0)<<1)|0)>>>3;a[y+2>>0]=((c[m>>2]|0)+4+(c[r>>2]|0)+(c[s>>2]|0)+(c[t>>2]<<1)+((c[u>>2]|0)*3|0)|0)>>>3}v=v+1|0;if((v|0)==8)break;else{w=w+e|0;x=x+e|0;y=y+e|0}}i=j;return}function vb(b,e,f,g,h,j){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;k=i;i=i+576|0;l=k+288|0;m=k;n=g*3|0;o=d[1752+j>>0]|0;p=(o|0)<(n|0)?o:n;n=b+(0-(0-(f>>>2&1^1)&e))|0;o=g+32|0;g=d[1760+j>>0]|0;j=f>>>3&1^1;q=0;r=n;s=b;while(1){t=q<<3;u=0;do{v=(d[s+u>>0]|0)-(d[r+u>>0]|0)|0;w=o-(((v|0)>-1?v:0-v|0)<<g)|0;if((w|0)<-64)x=h;else{v=(p|0)<(w|0)?p:w;x=(v|0)>0?v:0}c[l+(u+t<<2)>>2]=x;u=u+1|0}while((u|0)!=8);u=s+(0-((q|0)<7|j)&e)|0;q=q+1|0;if((q|0)==9)break;else{t=s;s=u;r=t}}r=0-(f&1^1)|0;s=f>>>1&1;f=s^1;q=0;x=b;t=b+r|0;while(1){u=q<<3;v=0;w=t;y=x;while(1){z=(d[y>>0]|0)-(d[w>>0]|0)|0;A=o-(((z|0)>-1?z:0-z|0)<<g)|0;if((A|0)<-64)B=h;else{z=(p|0)<(A|0)?p:A;B=(z|0)>0?z:0}c[m+(v+u<<2)>>2]=B;v=v+1|0;if((v|0)==8)break;else{w=w+e|0;y=y+e|0}}y=x+((q|0)<7|f)|0;q=q+1|0;if((q|0)==9)break;else{w=x;x=y;t=w}}t=8-s|0;s=0;x=b;q=b+e|0;f=n;n=b;while(1){b=c[m+(s<<2)>>2]|0;B=(_(d[n+r>>0]|0,b)|0)+64|0;p=s<<3;h=c[l+(p<<2)>>2]|0;g=B+(_(d[f>>0]|0,h)|0)|0;B=s;s=s+1|0;o=s<<3;w=c[l+(o<<2)>>2]|0;y=g+(_(d[q>>0]|0,w)|0)|0;g=c[m+(B+8<<2)>>2]|0;v=y+(_(d[n+1>>0]|0,g)|0)|0;y=v+(_(d[n>>0]|0,128-b-h-w-g|0)|0)>>7;a[x>>0]=(y>>>31)+255&((y|0)>255?255:y);y=1;do{g=c[m+((y<<3)+B<<2)>>2]|0;w=(_(d[n+(y+-1)>>0]|0,g)|0)+64|0;h=c[l+(y+p<<2)>>2]|0;b=w+(_(d[f+y>>0]|0,h)|0)|0;w=c[l+(y+o<<2)>>2]|0;v=b+(_(d[q+y>>0]|0,w)|0)|0;b=y;y=y+1|0;u=c[m+((y<<3)+B<<2)>>2]|0;z=v+(_(d[n+y>>0]|0,u)|0)|0;v=z+(_(d[n+b>>0]|0,128-g-h-w-u|0)|0)>>7;a[x+b>>0]=(v>>>31)+255&((v|0)>255?255:v)}while((y|0)!=7);y=c[m+(B+56<<2)>>2]|0;v=(_(d[n+6>>0]|0,y)|0)+64|0;b=c[l+((p|7)<<2)>>2]|0;u=v+(_(d[f+7>>0]|0,b)|0)|0;v=c[l+((o|7)<<2)>>2]|0;w=u+(_(d[q+7>>0]|0,v)|0)|0;u=c[m+(B+64<<2)>>2]|0;h=w+(_(d[n+t>>0]|0,u)|0)|0;w=h+(_(d[n+7>>0]|0,128-y-b-v-u|0)|0)>>7;a[x+7>>0]=(w>>>31)+255&((w|0)>255?255:w);w=q+(0-((B|0)<6|j)&e)|0;if((s|0)==8)break;else{u=q;v=n;x=x+e|0;q=w;n=u;f=v}}i=k;return}function wb(c,e,f){c=c|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,$=0;g=i;i=i+144|0;h=g;j=g+102|0;k=g+68|0;a[j>>0]=0;l=f+255&255;a[k>>0]=l;f=(c|0)!=0;m=l;l=0;n=0;o=0;p=0;while(1){q=1-p+(m&255)|0;r=l&255;s=l<<24>>24!=0?2:7;a:do if((q|0)>0){t=0;u=1;v=1;w=2;while(1){x=(u|0)==0;y=v+1|0;z=y+r|0;A=0;B=0;C=0;while(1){D=C+p|0;E=e+(D<<1)|0;F=d[e+(D<<1)+1>>0]|0;do if((F|0)>=(z|0))if((F|0)==(z|0)){G=1;H=C+1|0;break}else{G=A;H=(Hb(E,z)|0)+C|0;break}else{G=A;H=C+1|0}while(0);E=B+1|0;if((H|0)<(q|0)){A=G;B=E;C=H}else{I=E;J=G;K=B;break}}B=x?t:v;if((K|0)<(w|0)){L=B;break a}if((_(I,s)|0)<(1<<y|0)){L=B;break}else{t=B;u=J;v=y;w=I}}}else L=1;while(0);s=o&65535;q=h+(n<<1)|0;b[q>>1]=s;r=o+1+(1<<L)|0;if(f){b[q>>1]=s+1<<16>>16;b[c+(o<<16>>16<<1)>>1]=L;M=m;N=l;O=n;P=L;Q=p}else{M=m;N=l;O=n;P=L;Q=p}while(1){s=M&255;b:do if((Q|0)>(s|0))R=Q;else{q=N&255;w=q+P|0;v=h+(O<<1)|0;if(f)S=Q;else{u=Q;while(1){if((w|0)<(d[e+(u<<1)+1>>0]|0|0)){R=u;break b}t=u+1|0;if((u|0)<(s|0))u=t;else{R=t;break b}}}while(1){u=d[e+(S<<1)+1>>0]|0;if((w|0)<(u|0)){R=S;break b}y=w-u|0;x=0-(d[e+(S<<1)>>0]|0|u-q<<8)&65535;if((y|0)!=31){u=1<<y;y=b[v>>1]|0;t=u+1+((u|0)<1?u^65535:65534)&65535;B=y;C=u;while(1){b[c+(B<<16>>16<<1)>>1]=x;if((C|0)>1){B=B+1<<16>>16;C=C+-1|0}else break}b[v>>1]=(y+1<<16>>16)+t<<16>>16}C=S+1|0;if((S|0)<(s|0))S=C;else{R=C;break}}}while(0);if((R|0)<=(s|0)){T=N;U=O;V=P;W=R;X=25;break}v=O+-1|0;if((O|0)<=0){Y=v;Z=R;break}q=a[j+v>>0]|0;w=(N&255)-(q&255)|0;M=a[k+v>>0]|0;N=q;O=v;P=w;Q=R}if((X|0)==25){X=0;w=(T&255)+V|0;v=U+1|0;a[j+v>>0]=w;if(f){q=h+(U<<1)|0;C=b[q>>1]|0;b[q>>1]=C+1<<16>>16;b[c+(C<<16>>16<<1)>>1]=r}a[k+v>>0]=W+255+(Hb(e+(W<<1)|0,w&255)|0);Y=v;Z=W}if((Y|0)<=-1){$=r;break}m=a[k+Y>>0]|0;l=a[j+Y>>0]|0;n=Y;o=r;p=Z}i=g;return $|0}function xb(a,c){a=a|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;d=b[a+(c<<1)>>1]|0;e=1<<d;f=c+1|0;c=0;g=e+1|0;while(1){h=b[a+(f+c<<1)>>1]|0;i=h<<16>>16;if(h<<16>>16<1){j=1<<d-(0-i>>8);k=g}else{j=1;k=(xb(a,i)|0)+g|0}c=j+c|0;if((c|0)>=(e|0)){l=k;break}else g=k}return l|0}function yb(a,c){a=a|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;d=b[c>>1]|0;e=b[c+8>>1]|0;f=(e+d<<16>>16)*46341>>16;g=(d-e<<16>>16)*46341>>16;e=b[c+4>>1]|0;d=b[c+12>>1]|0;h=(e*25080>>16)-(d*60547>>16)|0;i=(d*25080>>16)+(e*60547>>16)|0;e=b[c+2>>1]|0;d=b[c+14>>1]|0;j=(e*12785>>16)-(d*64277>>16)|0;k=b[c+10>>1]|0;l=b[c+6>>1]|0;c=(k*54491>>16)-(l*36410>>16)|0;m=(l*54491>>16)+(k*36410>>16)|0;k=(d*12785>>16)+(e*64277>>16)|0;e=c+j|0;d=(j-c<<16>>16)*46341>>16;c=m+k|0;j=(k-m<<16>>16)*46341>>16;m=f+i|0;k=f-i|0;i=g+h|0;f=g-h|0;h=j+d|0;g=j-d|0;b[a>>1]=c+m;b[a+16>>1]=h+i;b[a+32>>1]=g+f;b[a+48>>1]=e+k;b[a+64>>1]=k-e;b[a+80>>1]=f-g;b[a+96>>1]=i-h;b[a+112>>1]=m-c;return}function zb(a,c){a=a|0;c=c|0;var d=0,e=0,f=0,g=0,h=0;d=b[c>>1]|0;e=b[c+2>>1]|0;f=b[c+4>>1]|0;g=b[c+6>>1]|0;c=((e&65535)<<24>>24)+((d&65535)<<24>>24)+((f&65535)<<24>>24)+((g&65535)<<24>>24)|0;h=(e<<16>>16>>8)+(d<<16>>16>>8)+(f<<16>>16>>8)+(g<<16>>16>>8)|0;b[a>>1]=(c+2+(c>>31)|0)>>>2&255|(h+2+(h>>31)|0)>>>2<<8;return}function Ab(a,c){a=a|0;c=c|0;var d=0,e=0,f=0,g=0;d=b[c>>1]|0;e=b[c+4>>1]|0;f=((e&65535)<<24>>24)+((d&65535)<<24>>24)|0;g=(e<<16>>16>>8)+(d<<16>>16>>8)|0;b[a>>1]=(f+1+(f>>31)|0)>>>1&255|(g+1+(g>>31)|0)>>>1<<8;g=b[c+2>>1]|0;f=b[c+6>>1]|0;c=((f&65535)<<24>>24)+((g&65535)<<24>>24)|0;d=(f<<16>>16>>8)+(g<<16>>16>>8)|0;b[a+2>>1]=(c+1+(c>>31)|0)>>>1&255|(d+1+(d>>31)|0)>>>1<<8;return}function Bb(a,c){a=a|0;c=c|0;var d=0,e=0,f=0,g=0;d=b[c>>1]|0;e=b[c+2>>1]|0;f=((e&65535)<<24>>24)+((d&65535)<<24>>24)|0;g=(e<<16>>16>>8)+(d<<16>>16>>8)|0;b[a>>1]=(f+1+(f>>31)|0)>>>1&255|(g+1+(g>>31)|0)>>>1<<8;g=b[c+4>>1]|0;f=b[c+6>>1]|0;c=((f&65535)<<24>>24)+((g&65535)<<24>>24)|0;d=(f<<16>>16>>8)+(g<<16>>16>>8)|0;b[a+4>>1]=(c+1+(c>>31)|0)>>>1&255|(d+1+(d>>31)|0)>>>1<<8;return}function Cb(a,c){a=a|0;c=c|0;b[a>>1]=b[c>>1]|0;b[a+2>>1]=b[c+2>>1]|0;b[a+4>>1]=b[c+4>>1]|0;b[a+6>>1]=b[c+6>>1]|0;return}function Db(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=(_(c[b+32>>2]|0,e>>1)|0)+(d>>1)|0;c[a+16>>2]=f+(c[b+40>>2]|0);c[a+32>>2]=f+(c[b+72>>2]|0);return}function Eb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0;f=(_(c[b+32>>2]|0,e>>1)|0)+d|0;d=b+40|0;e=b+72|0;c[a+16>>2]=(c[d>>2]|0)+f;c[a+32>>2]=(c[e>>2]|0)+f;b=f+1|0;c[a+20>>2]=(c[d>>2]|0)+b;c[a+36>>2]=(c[e>>2]|0)+b;return}function Fb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=b+32|0;g=(_(c[f>>2]|0,e)|0)+(d>>1)|0;d=b+40|0;e=b+72|0;c[a+16>>2]=(c[d>>2]|0)+g;c[a+32>>2]=(c[e>>2]|0)+g;b=(c[f>>2]|0)+g|0;c[a+24>>2]=(c[d>>2]|0)+b;c[a+40>>2]=(c[e>>2]|0)+b;return}function Gb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;e=b+40|0;d=b+72|0;b=c[a>>2]|0;c[a+16>>2]=(c[e>>2]|0)+b;c[a+32>>2]=(c[d>>2]|0)+b;b=c[a+4>>2]|0;c[a+20>>2]=(c[e>>2]|0)+b;c[a+36>>2]=(c[d>>2]|0)+b;b=c[a+8>>2]|0;c[a+24>>2]=(c[e>>2]|0)+b;c[a+40>>2]=(c[d>>2]|0)+b;b=c[a+12>>2]|0;c[a+28>>2]=(c[e>>2]|0)+b;c[a+44>>2]=(c[d>>2]|0)+b;return}function Hb(a,b){a=a|0;b=b|0;var c=0,e=0,f=0,g=0,h=0,i=0,j=0;c=b+31|0;e=0;f=0;while(1){g=(d[a+(f<<1)+1>>0]|0)-b|0;if((g|0)<32){h=-2147483648>>>g;i=f+1|0}else{h=1;i=(Hb(a+(f<<1)|0,c)|0)+f|0}e=h+e|0;if((e|0)<=-1){j=i;break}else f=i}return j|0}function Ib(){fb(1776);db(1792);return}function Jb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;d=i;i=i+48|0;e=d+32|0;f=d;Mb(f,a,b);g=c[442]|0;if(!g)c[f+8>>2]=256;c[442]=g+1;g=Na(1792,1776,1856,f)|0;if(!g){c[466]=Pa(1792,c[464]|0)|0;f=c[460]|0;h=c[451]|0;j=c[452]|0;k=c[457]|0;l=c[458]|0;if((k|0)!=0&(l|0)!=0)m=((_(k,h)|0)>>>0)/(l>>>0)|0;else m=h;fa(c[449]|0,c[450]|0,f&1^1|0,f>>>1&1^1|0,+(+((c[455]|0)>>>0)/+((c[456]|0)>>>0)),h|0,j|0,c[453]|0,c[454]|0,m|0,j|0);n=Kb(a,b)|0;i=d;return n|0}else{if((g|0)>0){n=1;i=d;return n|0}c[e>>2]=g;oa(1872,e|0)|0;n=0;i=d;return n|0}return 0}function Kb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+96|0;e=d+32|0;f=d;g=d+40|0;Mb(f,a,b);b=Ra(c[466]|0,f,0)|0;if(b>>>0<2){Sa(c[466]|0,g)|0;f=c[460]|0;ha(c[g+12>>2]|0,c[g+8>>2]|0,c[g+28>>2]|0,c[g+24>>2]|0,c[g+44>>2]|0,c[g+40>>2]|0,c[449]|0,c[450]|0,f&1^1|0,f>>>1&1^1|0);h=1;i=d;return h|0}else{c[e>>2]=b;oa(1912,e|0)|0;h=0;i=d;return h|0}return 0}function Lb(){var a=0;a=c[466]|0;if(a){Qa(a);c[466]=0}gb(1776);eb(1792);return}function Mb(a,b,d){a=a|0;b=b|0;d=d|0;c[a>>2]=b;c[a+4>>2]=d;d=a+8|0;c[d>>2]=0;c[d+4>>2]=0;c[d+8>>2]=0;c[d+12>>2]=0;c[d+16>>2]=0;c[d+20>>2]=0;return}function Nb(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;if(!d){e=0;return e|0}else{f=d;g=b;h=c}while(1){c=a[g>>0]|0;b=a[h>>0]|0;if(c<<24>>24!=b<<24>>24){i=c;j=b;break}f=f+-1|0;if(!f){e=0;k=5;break}else{g=g+1|0;h=h+1|0}}if((k|0)==5)return e|0;e=(i&255)-(j&255)|0;return e|0}function Ob(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,la=0,ma=0,oa=0,pa=0,qa=0,ra=0,sa=0,ta=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Da=0,Ea=0,Fa=0,Ga=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0;do if(a>>>0<245){b=a>>>0<11?16:a+11&-8;d=b>>>3;e=c[488]|0;f=e>>>d;if(f&3){g=(f&1^1)+d|0;h=g<<1;i=1992+(h<<2)|0;j=1992+(h+2<<2)|0;h=c[j>>2]|0;k=h+8|0;l=c[k>>2]|0;do if((i|0)!=(l|0)){if(l>>>0<(c[492]|0)>>>0)ka();m=l+12|0;if((c[m>>2]|0)==(h|0)){c[m>>2]=i;c[j>>2]=l;break}else ka()}else c[488]=e&~(1<<g);while(0);l=g<<3;c[h+4>>2]=l|3;j=h+(l|4)|0;c[j>>2]=c[j>>2]|1;n=k;return n|0}j=c[490]|0;if(b>>>0>j>>>0){if(f){l=2<<d;i=f<<d&(l|0-l);l=(i&0-i)+-1|0;i=l>>>12&16;m=l>>>i;l=m>>>5&8;o=m>>>l;m=o>>>2&4;p=o>>>m;o=p>>>1&2;q=p>>>o;p=q>>>1&1;r=(l|i|m|o|p)+(q>>>p)|0;p=r<<1;q=1992+(p<<2)|0;o=1992+(p+2<<2)|0;p=c[o>>2]|0;m=p+8|0;i=c[m>>2]|0;do if((q|0)!=(i|0)){if(i>>>0<(c[492]|0)>>>0)ka();l=i+12|0;if((c[l>>2]|0)==(p|0)){c[l>>2]=q;c[o>>2]=i;s=c[490]|0;break}else ka()}else{c[488]=e&~(1<<r);s=j}while(0);j=r<<3;e=j-b|0;c[p+4>>2]=b|3;i=p+b|0;c[p+(b|4)>>2]=e|1;c[p+j>>2]=e;if(s){j=c[493]|0;o=s>>>3;q=o<<1;d=1992+(q<<2)|0;f=c[488]|0;k=1<<o;if(f&k){o=1992+(q+2<<2)|0;h=c[o>>2]|0;if(h>>>0<(c[492]|0)>>>0)ka();else{t=o;u=h}}else{c[488]=f|k;t=1992+(q+2<<2)|0;u=d}c[t>>2]=j;c[u+12>>2]=j;c[j+8>>2]=u;c[j+12>>2]=d}c[490]=e;c[493]=i;n=m;return n|0}i=c[489]|0;if(i){e=(i&0-i)+-1|0;i=e>>>12&16;d=e>>>i;e=d>>>5&8;j=d>>>e;d=j>>>2&4;q=j>>>d;j=q>>>1&2;k=q>>>j;q=k>>>1&1;f=c[2256+((e|i|d|j|q)+(k>>>q)<<2)>>2]|0;q=(c[f+4>>2]&-8)-b|0;k=f;j=f;while(1){f=c[k+16>>2]|0;if(!f){d=c[k+20>>2]|0;if(!d){v=q;w=j;break}else x=d}else x=f;f=(c[x+4>>2]&-8)-b|0;d=f>>>0<q>>>0;q=d?f:q;k=x;j=d?x:j}j=c[492]|0;if(w>>>0<j>>>0)ka();k=w+b|0;if(w>>>0>=k>>>0)ka();q=c[w+24>>2]|0;m=c[w+12>>2]|0;do if((m|0)==(w|0)){p=w+20|0;r=c[p>>2]|0;if(!r){d=w+16|0;f=c[d>>2]|0;if(!f){y=0;break}else{z=f;A=d}}else{z=r;A=p}while(1){p=z+20|0;r=c[p>>2]|0;if(r){z=r;A=p;continue}p=z+16|0;r=c[p>>2]|0;if(!r){B=z;C=A;break}else{z=r;A=p}}if(C>>>0<j>>>0)ka();else{c[C>>2]=0;y=B;break}}else{p=c[w+8>>2]|0;if(p>>>0<j>>>0)ka();r=p+12|0;if((c[r>>2]|0)!=(w|0))ka();d=m+8|0;if((c[d>>2]|0)==(w|0)){c[r>>2]=m;c[d>>2]=p;y=m;break}else ka()}while(0);do if(q){m=c[w+28>>2]|0;j=2256+(m<<2)|0;if((w|0)==(c[j>>2]|0)){c[j>>2]=y;if(!y){c[489]=c[489]&~(1<<m);break}}else{if(q>>>0<(c[492]|0)>>>0)ka();m=q+16|0;if((c[m>>2]|0)==(w|0))c[m>>2]=y;else c[q+20>>2]=y;if(!y)break}m=c[492]|0;if(y>>>0<m>>>0)ka();c[y+24>>2]=q;j=c[w+16>>2]|0;do if(j)if(j>>>0<m>>>0)ka();else{c[y+16>>2]=j;c[j+24>>2]=y;break}while(0);j=c[w+20>>2]|0;if(j)if(j>>>0<(c[492]|0)>>>0)ka();else{c[y+20>>2]=j;c[j+24>>2]=y;break}}while(0);if(v>>>0<16){q=v+b|0;c[w+4>>2]=q|3;j=w+(q+4)|0;c[j>>2]=c[j>>2]|1}else{c[w+4>>2]=b|3;c[w+(b|4)>>2]=v|1;c[w+(v+b)>>2]=v;j=c[490]|0;if(j){q=c[493]|0;m=j>>>3;j=m<<1;p=1992+(j<<2)|0;d=c[488]|0;r=1<<m;if(d&r){m=1992+(j+2<<2)|0;f=c[m>>2]|0;if(f>>>0<(c[492]|0)>>>0)ka();else{D=m;E=f}}else{c[488]=d|r;D=1992+(j+2<<2)|0;E=p}c[D>>2]=q;c[E+12>>2]=q;c[q+8>>2]=E;c[q+12>>2]=p}c[490]=v;c[493]=k}n=w+8|0;return n|0}else F=b}else F=b}else if(a>>>0<=4294967231){p=a+11|0;q=p&-8;j=c[489]|0;if(j){r=0-q|0;d=p>>>8;if(d)if(q>>>0>16777215)G=31;else{p=(d+1048320|0)>>>16&8;f=d<<p;d=(f+520192|0)>>>16&4;m=f<<d;f=(m+245760|0)>>>16&2;i=14-(d|p|f)+(m<<f>>>15)|0;G=q>>>(i+7|0)&1|i<<1}else G=0;i=c[2256+(G<<2)>>2]|0;a:do if(!i){H=r;I=0;J=0;K=86}else{f=r;m=0;p=q<<((G|0)==31?0:25-(G>>>1)|0);d=i;e=0;while(1){h=c[d+4>>2]&-8;o=h-q|0;if(o>>>0<f>>>0)if((h|0)==(q|0)){L=o;M=d;N=d;K=90;break a}else{O=o;P=d}else{O=f;P=e}o=c[d+20>>2]|0;d=c[d+16+(p>>>31<<2)>>2]|0;h=(o|0)==0|(o|0)==(d|0)?m:o;if(!d){H=O;I=h;J=P;K=86;break}else{f=O;m=h;p=p<<1;e=P}}}while(0);if((K|0)==86){if((I|0)==0&(J|0)==0){i=2<<G;r=j&(i|0-i);if(!r){F=q;break}i=(r&0-r)+-1|0;r=i>>>12&16;b=i>>>r;i=b>>>5&8;k=b>>>i;b=k>>>2&4;e=k>>>b;k=e>>>1&2;p=e>>>k;e=p>>>1&1;Q=c[2256+((i|r|b|k|e)+(p>>>e)<<2)>>2]|0;R=0}else{Q=I;R=J}if(!Q){S=H;T=R}else{L=H;M=Q;N=R;K=90}}if((K|0)==90)while(1){K=0;e=(c[M+4>>2]&-8)-q|0;p=e>>>0<L>>>0;k=p?e:L;e=p?M:N;p=c[M+16>>2]|0;if(p){L=k;M=p;N=e;K=90;continue}M=c[M+20>>2]|0;if(!M){S=k;T=e;break}else{L=k;N=e;K=90}}if((T|0)!=0?S>>>0<((c[490]|0)-q|0)>>>0:0){j=c[492]|0;if(T>>>0<j>>>0)ka();e=T+q|0;if(T>>>0>=e>>>0)ka();k=c[T+24>>2]|0;p=c[T+12>>2]|0;do if((p|0)==(T|0)){b=T+20|0;r=c[b>>2]|0;if(!r){i=T+16|0;m=c[i>>2]|0;if(!m){U=0;break}else{V=m;W=i}}else{V=r;W=b}while(1){b=V+20|0;r=c[b>>2]|0;if(r){V=r;W=b;continue}b=V+16|0;r=c[b>>2]|0;if(!r){X=V;Y=W;break}else{V=r;W=b}}if(Y>>>0<j>>>0)ka();else{c[Y>>2]=0;U=X;break}}else{b=c[T+8>>2]|0;if(b>>>0<j>>>0)ka();r=b+12|0;if((c[r>>2]|0)!=(T|0))ka();i=p+8|0;if((c[i>>2]|0)==(T|0)){c[r>>2]=p;c[i>>2]=b;U=p;break}else ka()}while(0);do if(k){p=c[T+28>>2]|0;j=2256+(p<<2)|0;if((T|0)==(c[j>>2]|0)){c[j>>2]=U;if(!U){c[489]=c[489]&~(1<<p);break}}else{if(k>>>0<(c[492]|0)>>>0)ka();p=k+16|0;if((c[p>>2]|0)==(T|0))c[p>>2]=U;else c[k+20>>2]=U;if(!U)break}p=c[492]|0;if(U>>>0<p>>>0)ka();c[U+24>>2]=k;j=c[T+16>>2]|0;do if(j)if(j>>>0<p>>>0)ka();else{c[U+16>>2]=j;c[j+24>>2]=U;break}while(0);j=c[T+20>>2]|0;if(j)if(j>>>0<(c[492]|0)>>>0)ka();else{c[U+20>>2]=j;c[j+24>>2]=U;break}}while(0);b:do if(S>>>0>=16){c[T+4>>2]=q|3;c[T+(q|4)>>2]=S|1;c[T+(S+q)>>2]=S;k=S>>>3;if(S>>>0<256){j=k<<1;p=1992+(j<<2)|0;b=c[488]|0;i=1<<k;if(b&i){k=1992+(j+2<<2)|0;r=c[k>>2]|0;if(r>>>0<(c[492]|0)>>>0)ka();else{Z=k;_=r}}else{c[488]=b|i;Z=1992+(j+2<<2)|0;_=p}c[Z>>2]=e;c[_+12>>2]=e;c[T+(q+8)>>2]=_;c[T+(q+12)>>2]=p;break}p=S>>>8;if(p)if(S>>>0>16777215)$=31;else{j=(p+1048320|0)>>>16&8;i=p<<j;p=(i+520192|0)>>>16&4;b=i<<p;i=(b+245760|0)>>>16&2;r=14-(p|j|i)+(b<<i>>>15)|0;$=S>>>(r+7|0)&1|r<<1}else $=0;r=2256+($<<2)|0;c[T+(q+28)>>2]=$;c[T+(q+20)>>2]=0;c[T+(q+16)>>2]=0;i=c[489]|0;b=1<<$;if(!(i&b)){c[489]=i|b;c[r>>2]=e;c[T+(q+24)>>2]=r;c[T+(q+12)>>2]=e;c[T+(q+8)>>2]=e;break}b=c[r>>2]|0;c:do if((c[b+4>>2]&-8|0)!=(S|0)){r=S<<(($|0)==31?0:25-($>>>1)|0);i=b;while(1){j=i+16+(r>>>31<<2)|0;p=c[j>>2]|0;if(!p){aa=j;ba=i;break}if((c[p+4>>2]&-8|0)==(S|0)){ca=p;break c}else{r=r<<1;i=p}}if(aa>>>0<(c[492]|0)>>>0)ka();else{c[aa>>2]=e;c[T+(q+24)>>2]=ba;c[T+(q+12)>>2]=e;c[T+(q+8)>>2]=e;break b}}else ca=b;while(0);b=ca+8|0;i=c[b>>2]|0;r=c[492]|0;if(i>>>0>=r>>>0&ca>>>0>=r>>>0){c[i+12>>2]=e;c[b>>2]=e;c[T+(q+8)>>2]=i;c[T+(q+12)>>2]=ca;c[T+(q+24)>>2]=0;break}else ka()}else{i=S+q|0;c[T+4>>2]=i|3;b=T+(i+4)|0;c[b>>2]=c[b>>2]|1}while(0);n=T+8|0;return n|0}else F=q}else F=q}else F=-1;while(0);T=c[490]|0;if(T>>>0>=F>>>0){S=T-F|0;ca=c[493]|0;if(S>>>0>15){c[493]=ca+F;c[490]=S;c[ca+(F+4)>>2]=S|1;c[ca+T>>2]=S;c[ca+4>>2]=F|3}else{c[490]=0;c[493]=0;c[ca+4>>2]=T|3;S=ca+(T+4)|0;c[S>>2]=c[S>>2]|1}n=ca+8|0;return n|0}ca=c[491]|0;if(ca>>>0>F>>>0){S=ca-F|0;c[491]=S;ca=c[494]|0;c[494]=ca+F;c[ca+(F+4)>>2]=S|1;c[ca+4>>2]=F|3;n=ca+8|0;return n|0}do if(!(c[606]|0)){ca=va(30)|0;if(!(ca+-1&ca)){c[608]=ca;c[607]=ca;c[609]=-1;c[610]=-1;c[611]=0;c[599]=0;c[606]=(ua(0)|0)&-16^1431655768;break}else ka()}while(0);ca=F+48|0;S=c[608]|0;T=F+47|0;ba=S+T|0;aa=0-S|0;S=ba&aa;if(S>>>0<=F>>>0){n=0;return n|0}$=c[598]|0;if(($|0)!=0?(_=c[596]|0,Z=_+S|0,Z>>>0<=_>>>0|Z>>>0>$>>>0):0){n=0;return n|0}d:do if(!(c[599]&4)){$=c[494]|0;e:do if($){Z=2400;while(1){_=c[Z>>2]|0;if(_>>>0<=$>>>0?(U=Z+4|0,(_+(c[U>>2]|0)|0)>>>0>$>>>0):0){da=Z;ea=U;break}Z=c[Z+8>>2]|0;if(!Z){K=174;break e}}Z=ba-(c[491]|0)&aa;if(Z>>>0<2147483647){U=na(Z|0)|0;_=(U|0)==((c[da>>2]|0)+(c[ea>>2]|0)|0);X=_?Z:0;if(_)if((U|0)==(-1|0))fa=X;else{ga=U;ha=X;K=194;break d}else{ia=U;ja=Z;la=X;K=184}}else fa=0}else K=174;while(0);do if((K|0)==174){$=na(0)|0;if(($|0)!=(-1|0)){q=$;X=c[607]|0;Z=X+-1|0;if(!(Z&q))ma=S;else ma=S-q+(Z+q&0-X)|0;X=c[596]|0;q=X+ma|0;if(ma>>>0>F>>>0&ma>>>0<2147483647){Z=c[598]|0;if((Z|0)!=0?q>>>0<=X>>>0|q>>>0>Z>>>0:0){fa=0;break}Z=na(ma|0)|0;q=(Z|0)==($|0);X=q?ma:0;if(q){ga=$;ha=X;K=194;break d}else{ia=Z;ja=ma;la=X;K=184}}else fa=0}else fa=0}while(0);f:do if((K|0)==184){X=0-ja|0;do if(ca>>>0>ja>>>0&(ja>>>0<2147483647&(ia|0)!=(-1|0))?(Z=c[608]|0,$=T-ja+Z&0-Z,$>>>0<2147483647):0)if((na($|0)|0)==(-1|0)){na(X|0)|0;fa=la;break f}else{oa=$+ja|0;break}else oa=ja;while(0);if((ia|0)==(-1|0))fa=la;else{ga=ia;ha=oa;K=194;break d}}while(0);c[599]=c[599]|4;pa=fa;K=191}else{pa=0;K=191}while(0);if((((K|0)==191?S>>>0<2147483647:0)?(fa=na(S|0)|0,S=na(0)|0,fa>>>0<S>>>0&((fa|0)!=(-1|0)&(S|0)!=(-1|0))):0)?(oa=S-fa|0,S=oa>>>0>(F+40|0)>>>0,S):0){ga=fa;ha=S?oa:pa;K=194}if((K|0)==194){pa=(c[596]|0)+ha|0;c[596]=pa;if(pa>>>0>(c[597]|0)>>>0)c[597]=pa;pa=c[494]|0;g:do if(pa){oa=2400;do{S=c[oa>>2]|0;fa=oa+4|0;ia=c[fa>>2]|0;if((ga|0)==(S+ia|0)){qa=S;ra=fa;sa=ia;ta=oa;K=204;break}oa=c[oa+8>>2]|0}while((oa|0)!=0);if(((K|0)==204?(c[ta+12>>2]&8|0)==0:0)?pa>>>0<ga>>>0&pa>>>0>=qa>>>0:0){c[ra>>2]=sa+ha;oa=(c[491]|0)+ha|0;ia=pa+8|0;fa=(ia&7|0)==0?0:0-ia&7;ia=oa-fa|0;c[494]=pa+fa;c[491]=ia;c[pa+(fa+4)>>2]=ia|1;c[pa+(oa+4)>>2]=40;c[495]=c[610];break}oa=c[492]|0;if(ga>>>0<oa>>>0){c[492]=ga;xa=ga}else xa=oa;oa=ga+ha|0;ia=2400;while(1){if((c[ia>>2]|0)==(oa|0)){ya=ia;za=ia;K=212;break}ia=c[ia+8>>2]|0;if(!ia){Aa=2400;break}}if((K|0)==212)if(!(c[za+12>>2]&8)){c[ya>>2]=ga;ia=za+4|0;c[ia>>2]=(c[ia>>2]|0)+ha;ia=ga+8|0;oa=(ia&7|0)==0?0:0-ia&7;ia=ga+(ha+8)|0;fa=(ia&7|0)==0?0:0-ia&7;ia=ga+(fa+ha)|0;S=oa+F|0;la=ga+S|0;ja=ia-(ga+oa)-F|0;c[ga+(oa+4)>>2]=F|3;h:do if((ia|0)!=(pa|0)){if((ia|0)==(c[493]|0)){T=(c[490]|0)+ja|0;c[490]=T;c[493]=la;c[ga+(S+4)>>2]=T|1;c[ga+(T+S)>>2]=T;break}T=ha+4|0;ca=c[ga+(T+fa)>>2]|0;if((ca&3|0)==1){ma=ca&-8;ea=ca>>>3;i:do if(ca>>>0>=256){da=c[ga+((fa|24)+ha)>>2]|0;aa=c[ga+(ha+12+fa)>>2]|0;do if((aa|0)==(ia|0)){ba=fa|16;X=ga+(T+ba)|0;$=c[X>>2]|0;if(!$){Z=ga+(ba+ha)|0;ba=c[Z>>2]|0;if(!ba){Ba=0;break}else{Ca=ba;Da=Z}}else{Ca=$;Da=X}while(1){X=Ca+20|0;$=c[X>>2]|0;if($){Ca=$;Da=X;continue}X=Ca+16|0;$=c[X>>2]|0;if(!$){Ea=Ca;Fa=Da;break}else{Ca=$;Da=X}}if(Fa>>>0<xa>>>0)ka();else{c[Fa>>2]=0;Ba=Ea;break}}else{X=c[ga+((fa|8)+ha)>>2]|0;if(X>>>0<xa>>>0)ka();$=X+12|0;if((c[$>>2]|0)!=(ia|0))ka();Z=aa+8|0;if((c[Z>>2]|0)==(ia|0)){c[$>>2]=aa;c[Z>>2]=X;Ba=aa;break}else ka()}while(0);if(!da)break;aa=c[ga+(ha+28+fa)>>2]|0;X=2256+(aa<<2)|0;do if((ia|0)!=(c[X>>2]|0)){if(da>>>0<(c[492]|0)>>>0)ka();Z=da+16|0;if((c[Z>>2]|0)==(ia|0))c[Z>>2]=Ba;else c[da+20>>2]=Ba;if(!Ba)break i}else{c[X>>2]=Ba;if(Ba)break;c[489]=c[489]&~(1<<aa);break i}while(0);aa=c[492]|0;if(Ba>>>0<aa>>>0)ka();c[Ba+24>>2]=da;X=fa|16;Z=c[ga+(X+ha)>>2]|0;do if(Z)if(Z>>>0<aa>>>0)ka();else{c[Ba+16>>2]=Z;c[Z+24>>2]=Ba;break}while(0);Z=c[ga+(T+X)>>2]|0;if(!Z)break;if(Z>>>0<(c[492]|0)>>>0)ka();else{c[Ba+20>>2]=Z;c[Z+24>>2]=Ba;break}}else{Z=c[ga+((fa|8)+ha)>>2]|0;aa=c[ga+(ha+12+fa)>>2]|0;da=1992+(ea<<1<<2)|0;do if((Z|0)!=(da|0)){if(Z>>>0<xa>>>0)ka();if((c[Z+12>>2]|0)==(ia|0))break;ka()}while(0);if((aa|0)==(Z|0)){c[488]=c[488]&~(1<<ea);break}do if((aa|0)==(da|0))Ga=aa+8|0;else{if(aa>>>0<xa>>>0)ka();X=aa+8|0;if((c[X>>2]|0)==(ia|0)){Ga=X;break}ka()}while(0);c[Z+12>>2]=aa;c[Ga>>2]=Z}while(0);Ha=ga+((ma|fa)+ha)|0;Ia=ma+ja|0}else{Ha=ia;Ia=ja}ea=Ha+4|0;c[ea>>2]=c[ea>>2]&-2;c[ga+(S+4)>>2]=Ia|1;c[ga+(Ia+S)>>2]=Ia;ea=Ia>>>3;if(Ia>>>0<256){T=ea<<1;ca=1992+(T<<2)|0;da=c[488]|0;X=1<<ea;do if(!(da&X)){c[488]=da|X;Ja=1992+(T+2<<2)|0;Ka=ca}else{ea=1992+(T+2<<2)|0;$=c[ea>>2]|0;if($>>>0>=(c[492]|0)>>>0){Ja=ea;Ka=$;break}ka()}while(0);c[Ja>>2]=la;c[Ka+12>>2]=la;c[ga+(S+8)>>2]=Ka;c[ga+(S+12)>>2]=ca;break}T=Ia>>>8;do if(!T)La=0;else{if(Ia>>>0>16777215){La=31;break}X=(T+1048320|0)>>>16&8;da=T<<X;ma=(da+520192|0)>>>16&4;$=da<<ma;da=($+245760|0)>>>16&2;ea=14-(ma|X|da)+($<<da>>>15)|0;La=Ia>>>(ea+7|0)&1|ea<<1}while(0);T=2256+(La<<2)|0;c[ga+(S+28)>>2]=La;c[ga+(S+20)>>2]=0;c[ga+(S+16)>>2]=0;ca=c[489]|0;ea=1<<La;if(!(ca&ea)){c[489]=ca|ea;c[T>>2]=la;c[ga+(S+24)>>2]=T;c[ga+(S+12)>>2]=la;c[ga+(S+8)>>2]=la;break}ea=c[T>>2]|0;j:do if((c[ea+4>>2]&-8|0)!=(Ia|0)){T=Ia<<((La|0)==31?0:25-(La>>>1)|0);ca=ea;while(1){da=ca+16+(T>>>31<<2)|0;$=c[da>>2]|0;if(!$){Ma=da;Na=ca;break}if((c[$+4>>2]&-8|0)==(Ia|0)){Oa=$;break j}else{T=T<<1;ca=$}}if(Ma>>>0<(c[492]|0)>>>0)ka();else{c[Ma>>2]=la;c[ga+(S+24)>>2]=Na;c[ga+(S+12)>>2]=la;c[ga+(S+8)>>2]=la;break h}}else Oa=ea;while(0);ea=Oa+8|0;ca=c[ea>>2]|0;T=c[492]|0;if(ca>>>0>=T>>>0&Oa>>>0>=T>>>0){c[ca+12>>2]=la;c[ea>>2]=la;c[ga+(S+8)>>2]=ca;c[ga+(S+12)>>2]=Oa;c[ga+(S+24)>>2]=0;break}else ka()}else{ca=(c[491]|0)+ja|0;c[491]=ca;c[494]=la;c[ga+(S+4)>>2]=ca|1}while(0);n=ga+(oa|8)|0;return n|0}else Aa=2400;while(1){S=c[Aa>>2]|0;if(S>>>0<=pa>>>0?(la=c[Aa+4>>2]|0,ja=S+la|0,ja>>>0>pa>>>0):0){Pa=S;Qa=la;Ra=ja;break}Aa=c[Aa+8>>2]|0}oa=Pa+(Qa+-39)|0;ja=Pa+(Qa+-47+((oa&7|0)==0?0:0-oa&7))|0;oa=pa+16|0;la=ja>>>0<oa>>>0?pa:ja;ja=la+8|0;S=ga+8|0;ia=(S&7|0)==0?0:0-S&7;S=ha+-40-ia|0;c[494]=ga+ia;c[491]=S;c[ga+(ia+4)>>2]=S|1;c[ga+(ha+-36)>>2]=40;c[495]=c[610];S=la+4|0;c[S>>2]=27;c[ja>>2]=c[600];c[ja+4>>2]=c[601];c[ja+8>>2]=c[602];c[ja+12>>2]=c[603];c[600]=ga;c[601]=ha;c[603]=0;c[602]=ja;ja=la+28|0;c[ja>>2]=7;if((la+32|0)>>>0<Ra>>>0){ia=ja;do{ja=ia;ia=ia+4|0;c[ia>>2]=7}while((ja+8|0)>>>0<Ra>>>0)}if((la|0)!=(pa|0)){ia=la-pa|0;c[S>>2]=c[S>>2]&-2;c[pa+4>>2]=ia|1;c[la>>2]=ia;ja=ia>>>3;if(ia>>>0<256){fa=ja<<1;ca=1992+(fa<<2)|0;ea=c[488]|0;T=1<<ja;if(ea&T){ja=1992+(fa+2<<2)|0;Z=c[ja>>2]|0;if(Z>>>0<(c[492]|0)>>>0)ka();else{Sa=ja;Ta=Z}}else{c[488]=ea|T;Sa=1992+(fa+2<<2)|0;Ta=ca}c[Sa>>2]=pa;c[Ta+12>>2]=pa;c[pa+8>>2]=Ta;c[pa+12>>2]=ca;break}ca=ia>>>8;if(ca)if(ia>>>0>16777215)Ua=31;else{fa=(ca+1048320|0)>>>16&8;T=ca<<fa;ca=(T+520192|0)>>>16&4;ea=T<<ca;T=(ea+245760|0)>>>16&2;Z=14-(ca|fa|T)+(ea<<T>>>15)|0;Ua=ia>>>(Z+7|0)&1|Z<<1}else Ua=0;Z=2256+(Ua<<2)|0;c[pa+28>>2]=Ua;c[pa+20>>2]=0;c[oa>>2]=0;T=c[489]|0;ea=1<<Ua;if(!(T&ea)){c[489]=T|ea;c[Z>>2]=pa;c[pa+24>>2]=Z;c[pa+12>>2]=pa;c[pa+8>>2]=pa;break}ea=c[Z>>2]|0;k:do if((c[ea+4>>2]&-8|0)!=(ia|0)){Z=ia<<((Ua|0)==31?0:25-(Ua>>>1)|0);T=ea;while(1){fa=T+16+(Z>>>31<<2)|0;ca=c[fa>>2]|0;if(!ca){Va=fa;Wa=T;break}if((c[ca+4>>2]&-8|0)==(ia|0)){Xa=ca;break k}else{Z=Z<<1;T=ca}}if(Va>>>0<(c[492]|0)>>>0)ka();else{c[Va>>2]=pa;c[pa+24>>2]=Wa;c[pa+12>>2]=pa;c[pa+8>>2]=pa;break g}}else Xa=ea;while(0);ea=Xa+8|0;ia=c[ea>>2]|0;oa=c[492]|0;if(ia>>>0>=oa>>>0&Xa>>>0>=oa>>>0){c[ia+12>>2]=pa;c[ea>>2]=pa;c[pa+8>>2]=ia;c[pa+12>>2]=Xa;c[pa+24>>2]=0;break}else ka()}}else{ia=c[492]|0;if((ia|0)==0|ga>>>0<ia>>>0)c[492]=ga;c[600]=ga;c[601]=ha;c[603]=0;c[497]=c[606];c[496]=-1;ia=0;do{ea=ia<<1;oa=1992+(ea<<2)|0;c[1992+(ea+3<<2)>>2]=oa;c[1992+(ea+2<<2)>>2]=oa;ia=ia+1|0}while((ia|0)!=32);ia=ga+8|0;oa=(ia&7|0)==0?0:0-ia&7;ia=ha+-40-oa|0;c[494]=ga+oa;c[491]=ia;c[ga+(oa+4)>>2]=ia|1;c[ga+(ha+-36)>>2]=40;c[495]=c[610]}while(0);ha=c[491]|0;if(ha>>>0>F>>>0){ga=ha-F|0;c[491]=ga;ha=c[494]|0;c[494]=ha+F;c[ha+(F+4)>>2]=ga|1;c[ha+4>>2]=F|3;n=ha+8|0;return n|0}}c[(wa()|0)>>2]=12;n=0;return n|0}function Pb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;if(!a)return;b=a+-8|0;d=c[492]|0;if(b>>>0<d>>>0)ka();e=c[a+-4>>2]|0;f=e&3;if((f|0)==1)ka();g=e&-8;h=a+(g+-8)|0;do if(!(e&1)){i=c[b>>2]|0;if(!f)return;j=-8-i|0;k=a+j|0;l=i+g|0;if(k>>>0<d>>>0)ka();if((k|0)==(c[493]|0)){m=a+(g+-4)|0;n=c[m>>2]|0;if((n&3|0)!=3){o=k;p=l;break}c[490]=l;c[m>>2]=n&-2;c[a+(j+4)>>2]=l|1;c[h>>2]=l;return}n=i>>>3;if(i>>>0<256){i=c[a+(j+8)>>2]|0;m=c[a+(j+12)>>2]|0;q=1992+(n<<1<<2)|0;if((i|0)!=(q|0)){if(i>>>0<d>>>0)ka();if((c[i+12>>2]|0)!=(k|0))ka()}if((m|0)==(i|0)){c[488]=c[488]&~(1<<n);o=k;p=l;break}if((m|0)!=(q|0)){if(m>>>0<d>>>0)ka();q=m+8|0;if((c[q>>2]|0)==(k|0))r=q;else ka()}else r=m+8|0;c[i+12>>2]=m;c[r>>2]=i;o=k;p=l;break}i=c[a+(j+24)>>2]|0;m=c[a+(j+12)>>2]|0;do if((m|0)==(k|0)){q=a+(j+20)|0;n=c[q>>2]|0;if(!n){s=a+(j+16)|0;t=c[s>>2]|0;if(!t){u=0;break}else{v=t;w=s}}else{v=n;w=q}while(1){q=v+20|0;n=c[q>>2]|0;if(n){v=n;w=q;continue}q=v+16|0;n=c[q>>2]|0;if(!n){x=v;y=w;break}else{v=n;w=q}}if(y>>>0<d>>>0)ka();else{c[y>>2]=0;u=x;break}}else{q=c[a+(j+8)>>2]|0;if(q>>>0<d>>>0)ka();n=q+12|0;if((c[n>>2]|0)!=(k|0))ka();s=m+8|0;if((c[s>>2]|0)==(k|0)){c[n>>2]=m;c[s>>2]=q;u=m;break}else ka()}while(0);if(i){m=c[a+(j+28)>>2]|0;q=2256+(m<<2)|0;if((k|0)==(c[q>>2]|0)){c[q>>2]=u;if(!u){c[489]=c[489]&~(1<<m);o=k;p=l;break}}else{if(i>>>0<(c[492]|0)>>>0)ka();m=i+16|0;if((c[m>>2]|0)==(k|0))c[m>>2]=u;else c[i+20>>2]=u;if(!u){o=k;p=l;break}}m=c[492]|0;if(u>>>0<m>>>0)ka();c[u+24>>2]=i;q=c[a+(j+16)>>2]|0;do if(q)if(q>>>0<m>>>0)ka();else{c[u+16>>2]=q;c[q+24>>2]=u;break}while(0);q=c[a+(j+20)>>2]|0;if(q)if(q>>>0<(c[492]|0)>>>0)ka();else{c[u+20>>2]=q;c[q+24>>2]=u;o=k;p=l;break}else{o=k;p=l}}else{o=k;p=l}}else{o=b;p=g}while(0);if(o>>>0>=h>>>0)ka();b=a+(g+-4)|0;u=c[b>>2]|0;if(!(u&1))ka();if(!(u&2)){if((h|0)==(c[494]|0)){d=(c[491]|0)+p|0;c[491]=d;c[494]=o;c[o+4>>2]=d|1;if((o|0)!=(c[493]|0))return;c[493]=0;c[490]=0;return}if((h|0)==(c[493]|0)){d=(c[490]|0)+p|0;c[490]=d;c[493]=o;c[o+4>>2]=d|1;c[o+d>>2]=d;return}d=(u&-8)+p|0;x=u>>>3;do if(u>>>0>=256){y=c[a+(g+16)>>2]|0;w=c[a+(g|4)>>2]|0;do if((w|0)==(h|0)){v=a+(g+12)|0;r=c[v>>2]|0;if(!r){f=a+(g+8)|0;e=c[f>>2]|0;if(!e){z=0;break}else{A=e;B=f}}else{A=r;B=v}while(1){v=A+20|0;r=c[v>>2]|0;if(r){A=r;B=v;continue}v=A+16|0;r=c[v>>2]|0;if(!r){C=A;D=B;break}else{A=r;B=v}}if(D>>>0<(c[492]|0)>>>0)ka();else{c[D>>2]=0;z=C;break}}else{v=c[a+g>>2]|0;if(v>>>0<(c[492]|0)>>>0)ka();r=v+12|0;if((c[r>>2]|0)!=(h|0))ka();f=w+8|0;if((c[f>>2]|0)==(h|0)){c[r>>2]=w;c[f>>2]=v;z=w;break}else ka()}while(0);if(y){w=c[a+(g+20)>>2]|0;l=2256+(w<<2)|0;if((h|0)==(c[l>>2]|0)){c[l>>2]=z;if(!z){c[489]=c[489]&~(1<<w);break}}else{if(y>>>0<(c[492]|0)>>>0)ka();w=y+16|0;if((c[w>>2]|0)==(h|0))c[w>>2]=z;else c[y+20>>2]=z;if(!z)break}w=c[492]|0;if(z>>>0<w>>>0)ka();c[z+24>>2]=y;l=c[a+(g+8)>>2]|0;do if(l)if(l>>>0<w>>>0)ka();else{c[z+16>>2]=l;c[l+24>>2]=z;break}while(0);l=c[a+(g+12)>>2]|0;if(l)if(l>>>0<(c[492]|0)>>>0)ka();else{c[z+20>>2]=l;c[l+24>>2]=z;break}}}else{l=c[a+g>>2]|0;w=c[a+(g|4)>>2]|0;y=1992+(x<<1<<2)|0;if((l|0)!=(y|0)){if(l>>>0<(c[492]|0)>>>0)ka();if((c[l+12>>2]|0)!=(h|0))ka()}if((w|0)==(l|0)){c[488]=c[488]&~(1<<x);break}if((w|0)!=(y|0)){if(w>>>0<(c[492]|0)>>>0)ka();y=w+8|0;if((c[y>>2]|0)==(h|0))E=y;else ka()}else E=w+8|0;c[l+12>>2]=w;c[E>>2]=l}while(0);c[o+4>>2]=d|1;c[o+d>>2]=d;if((o|0)==(c[493]|0)){c[490]=d;return}else F=d}else{c[b>>2]=u&-2;c[o+4>>2]=p|1;c[o+p>>2]=p;F=p}p=F>>>3;if(F>>>0<256){u=p<<1;b=1992+(u<<2)|0;d=c[488]|0;E=1<<p;if(d&E){p=1992+(u+2<<2)|0;h=c[p>>2]|0;if(h>>>0<(c[492]|0)>>>0)ka();else{G=p;H=h}}else{c[488]=d|E;G=1992+(u+2<<2)|0;H=b}c[G>>2]=o;c[H+12>>2]=o;c[o+8>>2]=H;c[o+12>>2]=b;return}b=F>>>8;if(b)if(F>>>0>16777215)I=31;else{H=(b+1048320|0)>>>16&8;G=b<<H;b=(G+520192|0)>>>16&4;u=G<<b;G=(u+245760|0)>>>16&2;E=14-(b|H|G)+(u<<G>>>15)|0;I=F>>>(E+7|0)&1|E<<1}else I=0;E=2256+(I<<2)|0;c[o+28>>2]=I;c[o+20>>2]=0;c[o+16>>2]=0;G=c[489]|0;u=1<<I;a:do if(G&u){H=c[E>>2]|0;b:do if((c[H+4>>2]&-8|0)!=(F|0)){b=F<<((I|0)==31?0:25-(I>>>1)|0);d=H;while(1){h=d+16+(b>>>31<<2)|0;p=c[h>>2]|0;if(!p){J=h;K=d;break}if((c[p+4>>2]&-8|0)==(F|0)){L=p;break b}else{b=b<<1;d=p}}if(J>>>0<(c[492]|0)>>>0)ka();else{c[J>>2]=o;c[o+24>>2]=K;c[o+12>>2]=o;c[o+8>>2]=o;break a}}else L=H;while(0);H=L+8|0;d=c[H>>2]|0;b=c[492]|0;if(d>>>0>=b>>>0&L>>>0>=b>>>0){c[d+12>>2]=o;c[H>>2]=o;c[o+8>>2]=d;c[o+12>>2]=L;c[o+24>>2]=0;break}else ka()}else{c[489]=G|u;c[E>>2]=o;c[o+24>>2]=E;c[o+12>>2]=o;c[o+8>>2]=o}while(0);o=(c[496]|0)+-1|0;c[496]=o;if(!o)M=2408;else return;while(1){o=c[M>>2]|0;if(!o)break;else M=o+8|0}c[496]=-1;return}function Qb(a,b){a=a|0;b=b|0;var d=0,e=0;if(a){d=_(b,a)|0;if((b|a)>>>0>65535)e=((d>>>0)/(a>>>0)|0|0)==(b|0)?d:-1;else e=d}else e=0;d=Ob(e)|0;if(!d)return d|0;if(!(c[d+-4>>2]&3))return d|0;Ub(d|0,0,e|0)|0;return d|0}function Rb(){}function Sb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=b-d>>>0;e=b-d-(c>>>0>a>>>0|0)>>>0;return (C=e,a-c>>>0|0)|0}function Tb(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=a+c>>>0;return (C=b+d+(e>>>0<a>>>0|0)>>>0,e|0)|0}function Ub(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;g=b&3;h=d|d<<8|d<<16|d<<24;i=f&~3;if(g){g=b+4-g|0;while((b|0)<(g|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(i|0)){c[b>>2]=h;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function Vb(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b<<c|(a&(1<<c)-1<<32-c)>>>32-c;return a<<c}C=a<<c-32;return 0}function Wb(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function Xb(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return ra(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function Yb(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>>c;return a>>>c|(b&(1<<c)-1)<<32-c}C=0;return b>>>c-32|0}function Zb(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>c;return a>>>c|(b&(1<<c)-1)<<32-c}C=(b|0)<0?-1:0;return b>>c-32|0}function _b(b){b=b|0;var c=0;c=a[m+(b&255)>>0]|0;if((c|0)<8)return c|0;c=a[m+(b>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[m+(b>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return (a[m+(b>>>24)>>0]|0)+24|0}function $b(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;c=a&65535;d=b&65535;e=_(d,c)|0;f=a>>>16;a=(e>>>16)+(_(d,f)|0)|0;d=b>>>16;b=_(d,c)|0;return (C=(a>>>16)+(_(d,f)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|e&65535|0)|0}function ac(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;e=b>>31|((b|0)<0?-1:0)<<1;f=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;g=d>>31|((d|0)<0?-1:0)<<1;h=((d|0)<0?-1:0)>>31|((d|0)<0?-1:0)<<1;i=Sb(e^a,f^b,e,f)|0;b=C;a=g^e;e=h^f;return Sb((fc(i,b,Sb(g^c,h^d,g,h)|0,C,0)|0)^a,C^e,a,e)|0}function bc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+8|0;g=f|0;h=b>>31|((b|0)<0?-1:0)<<1;j=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;k=e>>31|((e|0)<0?-1:0)<<1;l=((e|0)<0?-1:0)>>31|((e|0)<0?-1:0)<<1;m=Sb(h^a,j^b,h,j)|0;b=C;fc(m,b,Sb(k^d,l^e,k,l)|0,C,g)|0;l=Sb(c[g>>2]^h,c[g+4>>2]^j,h,j)|0;j=C;i=f;return (C=j,l)|0}function cc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;a=c;c=$b(e,a)|0;f=C;return (C=(_(b,a)|0)+(_(d,e)|0)+f|f&0,c|0|0)|0}function dc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return fc(a,b,c,d,0)|0}function ec(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=i;i=i+8|0;g=f|0;fc(a,b,d,e,g)|0;i=f;return (C=c[g+4>>2]|0,c[g>>2]|0)|0}function fc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0;g=a;h=b;i=h;j=d;k=e;l=k;if(!i){m=(f|0)!=0;if(!l){if(m){c[f>>2]=(g>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(g>>>0)/(j>>>0)>>>0;return (C=n,o)|0}else{if(!m){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;o=0;return (C=n,o)|0}}m=(l|0)==0;do if(j){if(!m){p=(aa(l|0)|0)-(aa(i|0)|0)|0;if(p>>>0<=31){q=p+1|0;r=31-p|0;s=p-31>>31;t=q;u=g>>>(q>>>0)&s|i<<r;v=i>>>(q>>>0)&s;w=0;x=g<<r;break}if(!f){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return (C=n,o)|0}r=j-1|0;if(r&j){s=(aa(j|0)|0)+33-(aa(i|0)|0)|0;q=64-s|0;p=32-s|0;y=p>>31;z=s-32|0;A=z>>31;t=s;u=p-1>>31&i>>>(z>>>0)|(i<<p|g>>>(s>>>0))&A;v=A&i>>>(s>>>0);w=g<<q&y;x=(i<<q|g>>>(z>>>0))&y|g<<p&s-33>>31;break}if(f){c[f>>2]=r&g;c[f+4>>2]=0}if((j|0)==1){n=h|b&0;o=a|0|0;return (C=n,o)|0}else{r=_b(j|0)|0;n=i>>>(r>>>0)|0;o=i<<32-r|g>>>(r>>>0)|0;return (C=n,o)|0}}else{if(m){if(f){c[f>>2]=(i>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(i>>>0)/(j>>>0)>>>0;return (C=n,o)|0}if(!g){if(f){c[f>>2]=0;c[f+4>>2]=(i>>>0)%(l>>>0)}n=0;o=(i>>>0)/(l>>>0)>>>0;return (C=n,o)|0}r=l-1|0;if(!(r&l)){if(f){c[f>>2]=a|0;c[f+4>>2]=r&i|b&0}n=0;o=i>>>((_b(l|0)|0)>>>0);return (C=n,o)|0}r=(aa(l|0)|0)-(aa(i|0)|0)|0;if(r>>>0<=30){s=r+1|0;p=31-r|0;t=s;u=i<<p|g>>>(s>>>0);v=i>>>(s>>>0);w=0;x=g<<p;break}if(!f){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return (C=n,o)|0}while(0);if(!t){B=x;D=w;E=v;F=u;G=0;H=0}else{b=d|0|0;d=k|e&0;e=Tb(b|0,d|0,-1,-1)|0;k=C;h=x;x=w;w=v;v=u;u=t;t=0;do{a=h;h=x>>>31|h<<1;x=t|x<<1;g=v<<1|a>>>31|0;a=v>>>31|w<<1|0;Sb(e,k,g,a)|0;i=C;l=i>>31|((i|0)<0?-1:0)<<1;t=l&1;v=Sb(g,a,l&b,(((i|0)<0?-1:0)>>31|((i|0)<0?-1:0)<<1)&d)|0;w=C;u=u-1|0}while((u|0)!=0);B=h;D=x;E=w;F=v;G=0;H=t}t=D;D=0;if(f){c[f>>2]=F;c[f+4>>2]=E}n=(t|0)>>>31|(B|D)<<1|(D<<1|t>>>31)&0|G;o=(t<<1|0>>>31)&-2|H;return (C=n,o)|0}function gc(a,b,c){a=a|0;b=b|0;c=c|0;ya[a&7](b|0,c|0)}function hc(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;za[a&7](b|0,c|0,d|0,e|0)}function ic(a,b){a=a|0;b=b|0;ba(0)}function jc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;ba(1)} + +// EMSCRIPTEN_END_FUNCS +var ya=[ic,zb,Ab,Bb,Cb,ic,ic,ic];var za=[jc,Db,Eb,Fb,Gb,jc,jc,jc];return{_ogv_video_decoder_init:Ib,_free:Pb,_ogv_video_decoder_process_header:Jb,_i64Add:Tb,_ogv_video_decoder_destroy:Lb,_i64Subtract:Sb,_memset:Ub,_malloc:Ob,_memcpy:Xb,_strlen:Wb,_ogv_video_decoder_process_frame:Kb,_bitshift64Shl:Vb,runPostSets:Rb,stackAlloc:Aa,stackSave:Ba,stackRestore:Ca,establishStackSpace:Da,setThrew:Ea,setTempRet0:Ha,getTempRet0:Ia,dynCall_vii:gc,dynCall_viiii:hc}}) + + +// EMSCRIPTEN_END_ASM +(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var _ogv_video_decoder_init=Module["_ogv_video_decoder_init"]=asm["_ogv_video_decoder_init"];var _free=Module["_free"]=asm["_free"];var runPostSets=Module["runPostSets"]=asm["runPostSets"];var _ogv_video_decoder_process_header=Module["_ogv_video_decoder_process_header"]=asm["_ogv_video_decoder_process_header"];var _i64Add=Module["_i64Add"]=asm["_i64Add"];var _ogv_video_decoder_destroy=Module["_ogv_video_decoder_destroy"]=asm["_ogv_video_decoder_destroy"];var _i64Subtract=Module["_i64Subtract"]=asm["_i64Subtract"];var _memset=Module["_memset"]=asm["_memset"];var _malloc=Module["_malloc"]=asm["_malloc"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var _strlen=Module["_strlen"]=asm["_strlen"];var _ogv_video_decoder_process_frame=Module["_ogv_video_decoder_process_frame"]=asm["_ogv_video_decoder_process_frame"];var _bitshift64Shl=Module["_bitshift64Shl"]=asm["_bitshift64Shl"];var dynCall_vii=Module["dynCall_vii"]=asm["dynCall_vii"];var dynCall_viiii=Module["dynCall_viiii"]=asm["dynCall_viiii"];Runtime.stackAlloc=asm["stackAlloc"];Runtime.stackSave=asm["stackSave"];Runtime.stackRestore=asm["stackRestore"];Runtime.establishStackSpace=asm["establishStackSpace"];Runtime.setTempRet0=asm["setTempRet0"];Runtime.getTempRet0=asm["getTempRet0"];var i64Math=(function(){var goog={math:{}};goog.math.Long=(function(low,high){this.low_=low|0;this.high_=high|0});goog.math.Long.IntCache_={};goog.math.Long.fromInt=(function(value){if(-128<=value&&value<128){var cachedObj=goog.math.Long.IntCache_[value];if(cachedObj){return cachedObj}}var obj=new goog.math.Long(value|0,value<0?-1:0);if(-128<=value&&value<128){goog.math.Long.IntCache_[value]=obj}return obj});goog.math.Long.fromNumber=(function(value){if(isNaN(value)||!isFinite(value)){return goog.math.Long.ZERO}else if(value<=-goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MIN_VALUE}else if(value+1>=goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MAX_VALUE}else if(value<0){return goog.math.Long.fromNumber(-value).negate()}else{return new goog.math.Long(value%goog.math.Long.TWO_PWR_32_DBL_|0,value/goog.math.Long.TWO_PWR_32_DBL_|0)}});goog.math.Long.fromBits=(function(lowBits,highBits){return new goog.math.Long(lowBits,highBits)});goog.math.Long.fromString=(function(str,opt_radix){if(str.length==0){throw Error("number format error: empty string")}var radix=opt_radix||10;if(radix<2||36<radix){throw Error("radix out of range: "+radix)}if(str.charAt(0)=="-"){return goog.math.Long.fromString(str.substring(1),radix).negate()}else if(str.indexOf("-")>=0){throw Error('number format error: interior "-" character: '+str)}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,8));var result=goog.math.Long.ZERO;for(var i=0;i<str.length;i+=8){var size=Math.min(8,str.length-i);var value=parseInt(str.substring(i,i+size),radix);if(size<8){var power=goog.math.Long.fromNumber(Math.pow(radix,size));result=result.multiply(power).add(goog.math.Long.fromNumber(value))}else{result=result.multiply(radixToPower);result=result.add(goog.math.Long.fromNumber(value))}}return result});goog.math.Long.TWO_PWR_16_DBL_=1<<16;goog.math.Long.TWO_PWR_24_DBL_=1<<24;goog.math.Long.TWO_PWR_32_DBL_=goog.math.Long.TWO_PWR_16_DBL_*goog.math.Long.TWO_PWR_16_DBL_;goog.math.Long.TWO_PWR_31_DBL_=goog.math.Long.TWO_PWR_32_DBL_/2;goog.math.Long.TWO_PWR_48_DBL_=goog.math.Long.TWO_PWR_32_DBL_*goog.math.Long.TWO_PWR_16_DBL_;goog.math.Long.TWO_PWR_64_DBL_=goog.math.Long.TWO_PWR_32_DBL_*goog.math.Long.TWO_PWR_32_DBL_;goog.math.Long.TWO_PWR_63_DBL_=goog.math.Long.TWO_PWR_64_DBL_/2;goog.math.Long.ZERO=goog.math.Long.fromInt(0);goog.math.Long.ONE=goog.math.Long.fromInt(1);goog.math.Long.NEG_ONE=goog.math.Long.fromInt(-1);goog.math.Long.MAX_VALUE=goog.math.Long.fromBits(4294967295|0,2147483647|0);goog.math.Long.MIN_VALUE=goog.math.Long.fromBits(0,2147483648|0);goog.math.Long.TWO_PWR_24_=goog.math.Long.fromInt(1<<24);goog.math.Long.prototype.toInt=(function(){return this.low_});goog.math.Long.prototype.toNumber=(function(){return this.high_*goog.math.Long.TWO_PWR_32_DBL_+this.getLowBitsUnsigned()});goog.math.Long.prototype.toString=(function(opt_radix){var radix=opt_radix||10;if(radix<2||36<radix){throw Error("radix out of range: "+radix)}if(this.isZero()){return"0"}if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){var radixLong=goog.math.Long.fromNumber(radix);var div=this.div(radixLong);var rem=div.multiply(radixLong).subtract(this);return div.toString(radix)+rem.toInt().toString(radix)}else{return"-"+this.negate().toString(radix)}}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,6));var rem=this;var result="";while(true){var remDiv=rem.div(radixToPower);var intval=rem.subtract(remDiv.multiply(radixToPower)).toInt();var digits=intval.toString(radix);rem=remDiv;if(rem.isZero()){return digits+result}else{while(digits.length<6){digits="0"+digits}result=""+digits+result}}});goog.math.Long.prototype.getHighBits=(function(){return this.high_});goog.math.Long.prototype.getLowBits=(function(){return this.low_});goog.math.Long.prototype.getLowBitsUnsigned=(function(){return this.low_>=0?this.low_:goog.math.Long.TWO_PWR_32_DBL_+this.low_});goog.math.Long.prototype.getNumBitsAbs=(function(){if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){return 64}else{return this.negate().getNumBitsAbs()}}else{var val=this.high_!=0?this.high_:this.low_;for(var bit=31;bit>0;bit--){if((val&1<<bit)!=0){break}}return this.high_!=0?bit+33:bit+1}});goog.math.Long.prototype.isZero=(function(){return this.high_==0&&this.low_==0});goog.math.Long.prototype.isNegative=(function(){return this.high_<0});goog.math.Long.prototype.isOdd=(function(){return(this.low_&1)==1});goog.math.Long.prototype.equals=(function(other){return this.high_==other.high_&&this.low_==other.low_});goog.math.Long.prototype.notEquals=(function(other){return this.high_!=other.high_||this.low_!=other.low_});goog.math.Long.prototype.lessThan=(function(other){return this.compare(other)<0});goog.math.Long.prototype.lessThanOrEqual=(function(other){return this.compare(other)<=0});goog.math.Long.prototype.greaterThan=(function(other){return this.compare(other)>0});goog.math.Long.prototype.greaterThanOrEqual=(function(other){return this.compare(other)>=0});goog.math.Long.prototype.compare=(function(other){if(this.equals(other)){return 0}var thisNeg=this.isNegative();var otherNeg=other.isNegative();if(thisNeg&&!otherNeg){return-1}if(!thisNeg&&otherNeg){return 1}if(this.subtract(other).isNegative()){return-1}else{return 1}});goog.math.Long.prototype.negate=(function(){if(this.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.MIN_VALUE}else{return this.not().add(goog.math.Long.ONE)}});goog.math.Long.prototype.add=(function(other){var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.subtract=(function(other){return this.add(other.negate())});goog.math.Long.prototype.multiply=(function(other){if(this.isZero()){return goog.math.Long.ZERO}else if(other.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){return other.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}else if(other.equals(goog.math.Long.MIN_VALUE)){return this.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().multiply(other.negate())}else{return this.negate().multiply(other).negate()}}else if(other.isNegative()){return this.multiply(other.negate()).negate()}if(this.lessThan(goog.math.Long.TWO_PWR_24_)&&other.lessThan(goog.math.Long.TWO_PWR_24_)){return goog.math.Long.fromNumber(this.toNumber()*other.toNumber())}var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.div=(function(other){if(other.isZero()){throw Error("division by zero")}else if(this.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){if(other.equals(goog.math.Long.ONE)||other.equals(goog.math.Long.NEG_ONE)){return goog.math.Long.MIN_VALUE}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ONE}else{var halfThis=this.shiftRight(1);var approx=halfThis.div(other).shiftLeft(1);if(approx.equals(goog.math.Long.ZERO)){return other.isNegative()?goog.math.Long.ONE:goog.math.Long.NEG_ONE}else{var rem=this.subtract(other.multiply(approx));var result=approx.add(rem.div(other));return result}}}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().div(other.negate())}else{return this.negate().div(other).negate()}}else if(other.isNegative()){return this.div(other.negate()).negate()}var res=goog.math.Long.ZERO;var rem=this;while(rem.greaterThanOrEqual(other)){var approx=Math.max(1,Math.floor(rem.toNumber()/other.toNumber()));var log2=Math.ceil(Math.log(approx)/Math.LN2);var delta=log2<=48?1:Math.pow(2,log2-48);var approxRes=goog.math.Long.fromNumber(approx);var approxRem=approxRes.multiply(other);while(approxRem.isNegative()||approxRem.greaterThan(rem)){approx-=delta;approxRes=goog.math.Long.fromNumber(approx);approxRem=approxRes.multiply(other)}if(approxRes.isZero()){approxRes=goog.math.Long.ONE}res=res.add(approxRes);rem=rem.subtract(approxRem)}return res});goog.math.Long.prototype.modulo=(function(other){return this.subtract(this.div(other).multiply(other))});goog.math.Long.prototype.not=(function(){return goog.math.Long.fromBits(~this.low_,~this.high_)});goog.math.Long.prototype.and=(function(other){return goog.math.Long.fromBits(this.low_&other.low_,this.high_&other.high_)});goog.math.Long.prototype.or=(function(other){return goog.math.Long.fromBits(this.low_|other.low_,this.high_|other.high_)});goog.math.Long.prototype.xor=(function(other){return goog.math.Long.fromBits(this.low_^other.low_,this.high_^other.high_)});goog.math.Long.prototype.shiftLeft=(function(numBits){numBits&=63;if(numBits==0){return this}else{var low=this.low_;if(numBits<32){var high=this.high_;return goog.math.Long.fromBits(low<<numBits,high<<numBits|low>>>32-numBits)}else{return goog.math.Long.fromBits(0,low<<numBits-32)}}});goog.math.Long.prototype.shiftRight=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>numBits)}else{return goog.math.Long.fromBits(high>>numBits-32,high>=0?0:-1)}}});goog.math.Long.prototype.shiftRightUnsigned=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>>numBits)}else if(numBits==32){return goog.math.Long.fromBits(high,0)}else{return goog.math.Long.fromBits(high>>>numBits-32,0)}}});var navigator={appName:"Modern Browser"};var dbits;var canary=0xdeadbeefcafe;var j_lm=(canary&16777215)==15715070;function BigInteger(a,b,c){if(a!=null)if("number"==typeof a)this.fromNumber(a,b,c);else if(b==null&&"string"!=typeof a)this.fromString(a,256);else this.fromString(a,b)}function nbi(){return new BigInteger(null)}function am1(i,x,w,j,c,n){while(--n>=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}if(j_lm&&navigator.appName=="Microsoft Internet Explorer"){BigInteger.prototype.am=am2;dbits=30}else if(j_lm&&navigator.appName!="Netscape"){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz";var BI_RC=new Array;var rr,vv;rr="0".charCodeAt(0);for(vv=0;vv<=9;++vv)BI_RC[rr++]=vv;rr="a".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;rr="A".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;function int2char(n){return BI_RM.charAt(n)}function intAt(s,i){var c=BI_RC[s.charCodeAt(i)];return c==null?-1:c}function bnpCopyTo(r){for(var i=this.t-1;i>=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{this.fromRadix(s,b);return}this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)this[this.t++]=x;else if(sh+k>this.DB){this[this.t-1]|=(x&(1<<this.DB-sh)-1)<<sh;this[this.t++]=x>>this.DB-sh}else this[this.t-1]|=x<<sh;sh+=k;if(sh>=this.DB)sh-=this.DB}if(k==8&&(s[0]&128)!=0){this.s=-1;if(sh>0)this[this.t-1]|=(1<<this.DB-sh)-1<<sh}this.clamp();if(mi)BigInteger.ZERO.subTo(this,this)}function bnpClamp(){var c=this.s&this.DM;while(this.t>0&&this[this.t-1]==c)--this.t}function bnToString(b){if(this.s<0)return"-"+this.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return this.toRadix(b);var km=(1<<k)-1,d,m=false,r="",i=this.t;var p=this.DB-i*this.DB%k;if(i-->0){if(p<this.DB&&(d=this[i]>>p)>0){m=true;r=int2char(d)}while(i>=0){if(p<k){d=(this[i]&(1<<p)-1)<<k-p;d|=this[--i]>>(p+=this.DB-k)}else{d=this[i]>>(p-=k)&km;if(p<=0){p+=this.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i<this.t;++i)r[i-n]=this[i];r.t=Math.max(this.t-n,0);r.s=this.s}function bnpLShiftTo(n,r){var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<cbs)-1;var ds=Math.floor(n/this.DB),c=this.s<<bs&this.DM,i;for(i=this.t-1;i>=0;--i){r[i+ds+1]=this[i]>>cbs|c;c=(this[i]&bm)<<bs}for(i=ds-1;i>=0;--i)r[i]=0;r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp()}function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return}var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<bs)-1;r[0]=this[ds]>>bs;for(var i=ds+1;i<this.t;++i){r[i-ds-1]|=(this[i]&bm)<<cbs;r[i-ds]=this[i]>>bs}if(bs>0)r[this.t-ds-1]|=(this.s&bm)<<cbs;r.t=this.t-ds;r.clamp()}function bnpSubTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]-a[i];r[i++]=c&this.DM;c>>=this.DB}if(a.t<this.t){c-=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB}c+=this.s}else{c+=this.s;while(i<a.t){c-=a[i];r[i++]=c&this.DM;c>>=this.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=this.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i<y.t;++i)r[i+x.t]=x.am(0,y[i],r,i,0,x.t);r.s=0;r.clamp();if(this.s!=a.s)BigInteger.ZERO.subTo(r,r)}function bnpSquareTo(r){var x=this.abs();var i=r.t=2*x.t;while(--i>=0)r[i]=0;for(i=0;i<x.t-1;++i){var c=x.am(i,x[i],r,2*i,0,1);if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1))>=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0)return;var pt=this.abs();if(pt.t<pm.t){if(q!=null)q.fromInt(0);if(r!=null)this.copyTo(r);return}if(r==null)r=nbi();var y=nbi(),ts=this.s,ms=m.s;var nsh=this.DB-nbits(pm[pm.t-1]);if(nsh>0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<<this.F1)+(ys>1?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<<this.F1)/yt,e=1<<this.F2;var i=r.t,j=i-ys,t=q==null?nbi():q;y.dlShiftTo(j,t);if(r.compareTo(t)>=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t<ys)y[y.t++]=0;while(--j>=0){var qd=r[--i]==y0?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))<qd){y.dlShiftTo(j,t);r.subTo(t,r);while(r[i]<--qd)r.subTo(t,r)}}if(q!=null){r.drShiftTo(ys,q);if(ts!=ms)BigInteger.ZERO.subTo(q,q)}r.t=ys;r.clamp();if(nsh>0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<m.DB-15)-1;this.mt2=2*m.t}function montConvert(x){var r=nbi();x.abs().dlShiftTo(this.m.t,r);r.divRemTo(this.m,null,r);if(x.s<0&&r.compareTo(BigInteger.ZERO)>0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i<this.m.t;++i){var j=x[i]&32767;var u0=j*this.mpl+((j*this.mph+(x[i]>>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<<i)>0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnpFromRadix(s,b){this.fromInt(0);if(b==null)b=10;var cs=this.chunkSize(b);var d=Math.pow(b,cs),mi=false,j=0,w=0;for(var i=0;i<s.length;++i){var x=intAt(s,i);if(x<0){if(s.charAt(i)=="-"&&this.signum()==0)mi=true;continue}w=b*w+x;if(++j>=cs){this.dMultiply(d);this.dAddOffset(w,0);j=0;w=0}}if(j>0){this.dMultiply(Math.pow(b,j));this.dAddOffset(w,0)}if(mi)BigInteger.ZERO.subTo(this,this)}function bnpChunkSize(r){return Math.floor(Math.LN2*this.DB/Math.log(r))}function bnSigNum(){if(this.s<0)return-1;else if(this.t<=0||this.t==1&&this[0]<=0)return 0;else return 1}function bnpDMultiply(n){this[this.t]=this.am(0,n-1,this,0,0,this.t);++this.t;this.clamp()}function bnpDAddOffset(n,w){if(n==0)return;while(this.t<=w)this[this.t++]=0;this[w]+=n;while(this[w]>=this.DV){this[w]-=this.DV;if(++w>=this.t)this[this.t++]=0;++this[w]}}function bnpToRadix(b){if(b==null)b=10;if(this.signum()==0||b<2||b>36)return"0";var cs=this.chunkSize(b);var a=Math.pow(b,cs);var d=nbv(a),y=nbi(),z=nbi(),r="";this.divRemTo(d,y,z);while(y.signum()>0){r=(a+z.intValue()).toString(b).substr(1)+r;y.divRemTo(d,y,z)}return z.intValue().toString(b)+r}function bnIntValue(){if(this.s<0){if(this.t==1)return this[0]-this.DV;else if(this.t==0)return-1}else if(this.t==1)return this[0];else if(this.t==0)return 0;return(this[1]&(1<<32-this.DB)-1)<<this.DB|this[0]}function bnpAddTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]+a[i];r[i++]=c&this.DM;c>>=this.DB}if(a.t<this.t){c+=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB}c+=this.s}else{c+=this.s;while(i<a.t){c+=a[i];r[i++]=c&this.DM;c>>=this.DB}c+=a.s}r.s=c<0?-1:0;if(c>0)r[i++]=c;else if(c<-1)r[i++]=this.DV+c;r.t=i;r.clamp()}BigInteger.prototype.fromRadix=bnpFromRadix;BigInteger.prototype.chunkSize=bnpChunkSize;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.dMultiply=bnpDMultiply;BigInteger.prototype.dAddOffset=bnpDAddOffset;BigInteger.prototype.toRadix=bnpToRadix;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.addTo=bnpAddTo;var Wrapper={abs:(function(l,h){var x=new goog.math.Long(l,h);var ret;if(x.isNegative()){ret=x.negate()}else{ret=x}HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_}),ensureTemps:(function(){if(Wrapper.ensuredTemps)return;Wrapper.ensuredTemps=true;Wrapper.two32=new BigInteger;Wrapper.two32.fromString("4294967296",10);Wrapper.two64=new BigInteger;Wrapper.two64.fromString("18446744073709551616",10);Wrapper.temp1=new BigInteger;Wrapper.temp2=new BigInteger}),lh2bignum:(function(l,h){var a=new BigInteger;a.fromString(h.toString(),10);var b=new BigInteger;a.multiplyTo(Wrapper.two32,b);var c=new BigInteger;c.fromString(l.toString(),10);var d=new BigInteger;c.addTo(b,d);return d}),stringify:(function(l,h,unsigned){var ret=(new goog.math.Long(l,h)).toString();if(unsigned&&ret[0]=="-"){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(ret,10);ret=new BigInteger;Wrapper.two64.addTo(bignum,ret);ret=ret.toString(10)}return ret}),fromString:(function(str,base,min,max,unsigned){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(str,base);var bigmin=new BigInteger;bigmin.fromString(min,10);var bigmax=new BigInteger;bigmax.fromString(max,10);if(unsigned&&bignum.compareTo(BigInteger.ZERO)<0){var temp=new BigInteger;bignum.addTo(Wrapper.two64,temp);bignum=temp}var error=false;if(bignum.compareTo(bigmin)<0){bignum=bigmin;error=true}else if(bignum.compareTo(bigmax)>0){bignum=bigmax;error=true}var ret=goog.math.Long.fromString(bignum.toString());HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_;if(error)throw"range error"})};return Wrapper})();function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){assert(runDependencies==0,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");assert(__ATPRERUN__.length==0,"cannot call main when preRun functions remain to be called");args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]),"i8",ALLOC_NORMAL)];pad();for(var i=0;i<argc-1;i=i+1){argv.push(allocate(intArrayFromString(args[i]),"i8",ALLOC_NORMAL));pad()}argv.push(0);argv=allocate(argv,"i32",ALLOC_NORMAL);initialStackTop=STACKTOP;try{var ret=Module["_main"](argc,argv,0);exit(ret,true)}catch(e){if(e instanceof ExitStatus){return}else if(e=="SimulateInfiniteLoop"){Module["noExitRuntime"]=true;return}else{if(e&&typeof e==="object"&&e.stack)Module.printErr("exception thrown: "+[e,e.stack]);throw e}}finally{calledMain=true}};function run(args){args=args||Module["arguments"];if(preloadStartTime===null)preloadStartTime=Date.now();if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(ENVIRONMENT_IS_WEB&&preloadStartTime!==null){Module.printErr("pre-main prep time: "+(Date.now()-preloadStartTime)+" ms")}if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(Module["_main"]&&shouldRunNow)Module["callMain"](args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["stdout"]["once"]("drain",(function(){process["exit"](status)}));console.log(" ");setTimeout((function(){process["exit"](status)}),500)}else if(ENVIRONMENT_IS_SHELL&&typeof quit==="function"){quit(status)}throw new ExitStatus(status)}Module["exit"]=Module.exit=exit;var abortDecorators=[];function abort(what){if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=false;if(Module["noInitialRun"]){shouldRunNow=false}Module["noExitRuntime"]=true;run();var inputBuffer,inputBufferSize;function reallocInputBuffer(size){if(inputBuffer&&inputBufferSize>=size){return inputBuffer}if(inputBuffer){Module._free(inputBuffer)}inputBufferSize=size;inputBuffer=Module._malloc(inputBufferSize);return inputBuffer}Module.loadedMetadata=!!options.videoFormat;Module.videoFormat=options.videoFormat||null;Module.frameBuffer=null;Object.defineProperty(Module,"processing",{get:function getProcessing(){return false}});Module.init=(function(callback){Module._ogv_video_decoder_init();callback()});Module.processHeader=(function(data,callback){var len=data.byteLength;var buffer=reallocInputBuffer(len);Module.HEAPU8.set(new Uint8Array(data),buffer);var ret=Module._ogv_video_decoder_process_header(buffer,len);callback(ret)});Module.processFrame=(function(data,callback){var len=data.byteLength;var buffer=reallocInputBuffer(len);Module.HEAPU8.set(new Uint8Array(data),buffer);var ret=Module._ogv_video_decoder_process_frame(buffer,len);callback(ret)}) + + + + + + return Module; +}; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-demuxer-ogg.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-demuxer-ogg.js new file mode 100644 index 00000000..13c6c731 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-demuxer-ogg.js @@ -0,0 +1,23 @@ +var OGVDemuxerOgg = function(Module) { + Module = Module || {}; + +var options=Module;Module={print:(function(str){console.log(str)})};var Module;if(!Module)Module=(typeof OGVDemuxerOgg!=="undefined"?OGVDemuxerOgg:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB;var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath["normalize"](filename);var ret=nodeFS["readFileSync"](filename);if(!ret&&filename!=nodePath["resolve"](filename)){filename=path.join(__dirname,"..","src",filename);ret=nodeFS["readFileSync"](filename)}if(ret&&!binary)ret=ret.toString();return ret};Module["readBinary"]=function readBinary(filename){return Module["read"](filename,true)};Module["load"]=function load(f){globalEval(read(f))};if(!Module["thisProgram"]){if(process["argv"].length>1){Module["thisProgram"]=process["argv"][1].replace(/\\/g,"/")}else{Module["thisProgram"]="unknown-program"}}Module["arguments"]=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",(function(ex){if(!(ex instanceof ExitStatus)){throw ex}}));Module["inspect"]=(function(){return"[Emscripten Module object]"})}else if(ENVIRONMENT_IS_SHELL){if(!Module["print"])Module["print"]=print;if(typeof printErr!="undefined")Module["printErr"]=printErr;if(typeof read!="undefined"){Module["read"]=read}else{Module["read"]=function read(){throw"no read() available (jsc?)"}}Module["readBinary"]=function readBinary(f){if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}var data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){Module["arguments"]=scriptArgs}else if(typeof arguments!="undefined"){Module["arguments"]=arguments}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){Module["read"]=function read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(typeof arguments!="undefined"){Module["arguments"]=arguments}if(typeof console!=="undefined"){if(!Module["print"])Module["print"]=function print(x){console.log(x)};if(!Module["printErr"])Module["printErr"]=function printErr(x){console.log(x)}}else{var TRY_USE_DUMP=false;if(!Module["print"])Module["print"]=TRY_USE_DUMP&&typeof dump!=="undefined"?(function(x){dump(x)}):(function(x){})}if(ENVIRONMENT_IS_WORKER){Module["load"]=importScripts}if(typeof Module["setWindowTitle"]==="undefined"){Module["setWindowTitle"]=(function(title){document.title=title})}}else{throw"Unknown runtime environment. Where are we?"}function globalEval(x){eval.call(null,x)}if(!Module["load"]&&Module["read"]){Module["load"]=function load(f){globalEval(Module["read"](f))}}if(!Module["print"]){Module["print"]=(function(){})}if(!Module["printErr"]){Module["printErr"]=Module["print"]}if(!Module["arguments"]){Module["arguments"]=[]}if(!Module["thisProgram"]){Module["thisProgram"]="./this.program"}Module.print=Module["print"];Module.printErr=Module["printErr"];Module["preRun"]=[];Module["postRun"]=[];for(var key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}var Runtime={setTempRet0:(function(value){tempRet0=value}),getTempRet0:(function(){return tempRet0}),stackSave:(function(){return STACKTOP}),stackRestore:(function(stackTop){STACKTOP=stackTop}),getNativeTypeSize:(function(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return Runtime.QUANTUM_SIZE}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0);return bits/8}else{return 0}}}}),getNativeFieldSize:(function(type){return Math.max(Runtime.getNativeTypeSize(type),Runtime.QUANTUM_SIZE)}),STACK_ALIGN:16,prepVararg:(function(ptr,type){if(type==="double"||type==="i64"){if(ptr&7){assert((ptr&7)===4);ptr+=4}}else{assert((ptr&3)===0)}return ptr}),getAlignSize:(function(type,size,vararg){if(!vararg&&(type=="i64"||type=="double"))return 8;if(!type)return Math.min(size,8);return Math.min(size||(type?Runtime.getNativeFieldSize(type):0),Runtime.QUANTUM_SIZE)}),dynCall:(function(sig,ptr,args){if(args&&args.length){if(!args.splice)args=Array.prototype.slice.call(args);args.splice(0,0,ptr);return Module["dynCall_"+sig].apply(null,args)}else{return Module["dynCall_"+sig].call(null,ptr)}}),functionPointers:[],addFunction:(function(func){for(var i=0;i<Runtime.functionPointers.length;i++){if(!Runtime.functionPointers[i]){Runtime.functionPointers[i]=func;return 2*(1+i)}}throw"Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS."}),removeFunction:(function(index){Runtime.functionPointers[(index-2)/2]=null}),warnOnce:(function(text){if(!Runtime.warnOnce.shown)Runtime.warnOnce.shown={};if(!Runtime.warnOnce.shown[text]){Runtime.warnOnce.shown[text]=1;Module.printErr(text)}}),funcWrappers:{},getFuncWrapper:(function(func,sig){assert(sig);if(!Runtime.funcWrappers[sig]){Runtime.funcWrappers[sig]={}}var sigCache=Runtime.funcWrappers[sig];if(!sigCache[func]){sigCache[func]=function dynCall_wrapper(){return Runtime.dynCall(sig,func,arguments)}}return sigCache[func]}),getCompilerSetting:(function(name){throw"You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work"}),stackAlloc:(function(size){var ret=STACKTOP;STACKTOP=STACKTOP+size|0;STACKTOP=STACKTOP+15&-16;return ret}),staticAlloc:(function(size){var ret=STATICTOP;STATICTOP=STATICTOP+size|0;STATICTOP=STATICTOP+15&-16;return ret}),dynamicAlloc:(function(size){var ret=DYNAMICTOP;DYNAMICTOP=DYNAMICTOP+size|0;DYNAMICTOP=DYNAMICTOP+15&-16;if(DYNAMICTOP>=TOTAL_MEMORY){var success=enlargeMemory();if(!success){DYNAMICTOP=ret;return 0}}return ret}),alignMemory:(function(size,quantum){var ret=size=Math.ceil(size/(quantum?quantum:16))*(quantum?quantum:16);return ret}),makeBigInt:(function(low,high,unsigned){var ret=unsigned?+(low>>>0)+ +(high>>>0)*+4294967296:+(low>>>0)+ +(high|0)*+4294967296;return ret}),GLOBAL_BASE:8,QUANTUM_SIZE:4,__dummy__:0};Module["Runtime"]=Runtime;var __THREW__=0;var ABORT=false;var EXITSTATUS=0;var undef=0;var tempValue,tempInt,tempBigInt,tempInt2,tempBigInt2,tempPair,tempBigIntI,tempBigIntR,tempBigIntS,tempBigIntP,tempBigIntD,tempDouble,tempFloat;var tempI64,tempI64b;var tempRet0,tempRet1,tempRet2,tempRet3,tempRet4,tempRet5,tempRet6,tempRet7,tempRet8,tempRet9;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var globalScope=this;function getCFunc(ident){var func=Module["_"+ident];if(!func){try{func=eval("_"+ident)}catch(e){}}assert(func,"Cannot call unknown function "+ident+" (perhaps LLVM optimizations or closure removed it?)");return func}var cwrap,ccall;((function(){var JSfuncs={"stackSave":(function(){Runtime.stackSave()}),"stackRestore":(function(){Runtime.stackRestore()}),"arrayToC":(function(arr){var ret=Runtime.stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}),"stringToC":(function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=Runtime.stackAlloc((str.length<<2)+1);writeStringToMemory(str,ret)}return ret})};var toC={"string":JSfuncs["stringToC"],"array":JSfuncs["arrayToC"]};ccall=function ccallFunc(ident,returnType,argTypes,args,opts){var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=Runtime.stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);if(returnType==="string")ret=Pointer_stringify(ret);if(stack!==0){if(opts&&opts.async){EmterpreterAsync.asyncFinalizers.push((function(){Runtime.stackRestore(stack)}));return}Runtime.stackRestore(stack)}return ret};var sourceRegex=/^function\s*\(([^)]*)\)\s*{\s*([^*]*?)[\s;]*(?:return\s*(.*?)[;\s]*)?}$/;function parseJSFunc(jsfunc){var parsed=jsfunc.toString().match(sourceRegex).slice(1);return{arguments:parsed[0],body:parsed[1],returnValue:parsed[2]}}var JSsource={};for(var fun in JSfuncs){if(JSfuncs.hasOwnProperty(fun)){JSsource[fun]=parseJSFunc(JSfuncs[fun])}}cwrap=function cwrap(ident,returnType,argTypes){argTypes=argTypes||[];var cfunc=getCFunc(ident);var numericArgs=argTypes.every((function(type){return type==="number"}));var numericRet=returnType!=="string";if(numericRet&&numericArgs){return cfunc}var argNames=argTypes.map((function(x,i){return"$"+i}));var funcstr="(function("+argNames.join(",")+") {";var nargs=argTypes.length;if(!numericArgs){funcstr+="var stack = "+JSsource["stackSave"].body+";";for(var i=0;i<nargs;i++){var arg=argNames[i],type=argTypes[i];if(type==="number")continue;var convertCode=JSsource[type+"ToC"];funcstr+="var "+convertCode.arguments+" = "+arg+";";funcstr+=convertCode.body+";";funcstr+=arg+"="+convertCode.returnValue+";"}}var cfuncname=parseJSFunc((function(){return cfunc})).returnValue;funcstr+="var ret = "+cfuncname+"("+argNames.join(",")+");";if(!numericRet){var strgfy=parseJSFunc((function(){return Pointer_stringify})).returnValue;funcstr+="ret = "+strgfy+"(ret);"}if(!numericArgs){funcstr+=JSsource["stackRestore"].body.replace("()","(stack)")+";"}funcstr+="return ret})";return eval(funcstr)}}))();Module["cwrap"]=cwrap;Module["ccall"]=ccall;function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=+1?tempDouble>+0?(Math_min(+Math_floor(tempDouble/+4294967296),+4294967295)|0)>>>0:~~+Math_ceil((tempDouble- +(~~tempDouble>>>0))/+4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}Module["setValue"]=setValue;function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for setValue: "+type)}return null}Module["getValue"]=getValue;var ALLOC_NORMAL=0;var ALLOC_STACK=1;var ALLOC_STATIC=2;var ALLOC_DYNAMIC=3;var ALLOC_NONE=4;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;Module["ALLOC_STACK"]=ALLOC_STACK;Module["ALLOC_STATIC"]=ALLOC_STATIC;Module["ALLOC_DYNAMIC"]=ALLOC_DYNAMIC;Module["ALLOC_NONE"]=ALLOC_NONE;function allocate(slab,types,allocator,ptr){var zeroinit,size;if(typeof slab==="number"){zeroinit=true;size=slab}else{zeroinit=false;size=slab.length}var singleType=typeof types==="string"?types:null;var ret;if(allocator==ALLOC_NONE){ret=ptr}else{ret=[_malloc,Runtime.stackAlloc,Runtime.staticAlloc,Runtime.dynamicAlloc][allocator===undefined?ALLOC_STATIC:allocator](Math.max(size,singleType?1:types.length))}if(zeroinit){var ptr=ret,stop;assert((ret&3)==0);stop=ret+(size&~3);for(;ptr<stop;ptr+=4){HEAP32[ptr>>2]=0}stop=ret+size;while(ptr<stop){HEAP8[ptr++>>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i<size){var curr=slab[i];if(typeof curr==="function"){curr=Runtime.getFunctionIndex(curr)}type=singleType||types[i];if(type===0){i++;continue}if(type=="i64")type="i32";setValue(ret+i,curr,type);if(previousType!==type){typeSize=Runtime.getNativeTypeSize(type);previousType=type}i+=typeSize}return ret}Module["allocate"]=allocate;function getMemory(size){if(!staticSealed)return Runtime.staticAlloc(size);if(typeof _sbrk!=="undefined"&&!_sbrk.called||!runtimeInitialized)return Runtime.dynamicAlloc(size);return _malloc(size)}Module["getMemory"]=getMemory;function Pointer_stringify(ptr,length){if(length===0||!ptr)return"";var hasUtf=0;var t;var i=0;while(1){t=HEAPU8[ptr+i>>0];hasUtf|=t;if(t==0&&!length)break;i++;if(length&&i==length)break}if(!length)length=i;var ret="";if(hasUtf<128){var MAX_CHUNK=1024;var curr;while(length>0){curr=String.fromCharCode.apply(String,HEAPU8.subarray(ptr,ptr+Math.min(length,MAX_CHUNK)));ret=ret?ret+curr:curr;ptr+=MAX_CHUNK;length-=MAX_CHUNK}return ret}return Module["UTF8ToString"](ptr)}Module["Pointer_stringify"]=Pointer_stringify;function AsciiToString(ptr){var str="";while(1){var ch=HEAP8[ptr++>>0];if(!ch)return str;str+=String.fromCharCode(ch)}}Module["AsciiToString"]=AsciiToString;function stringToAscii(str,outPtr){return writeAsciiToMemory(str,outPtr,false)}Module["stringToAscii"]=stringToAscii;function UTF8ArrayToString(u8Array,idx){var u0,u1,u2,u3,u4,u5;var str="";while(1){u0=u8Array[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}u1=u8Array[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}u2=u8Array[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u3=u8Array[idx++]&63;if((u0&248)==240){u0=(u0&7)<<18|u1<<12|u2<<6|u3}else{u4=u8Array[idx++]&63;if((u0&252)==248){u0=(u0&3)<<24|u1<<18|u2<<12|u3<<6|u4}else{u5=u8Array[idx++]&63;u0=(u0&1)<<30|u1<<24|u2<<18|u3<<12|u4<<6|u5}}}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}Module["UTF8ArrayToString"]=UTF8ArrayToString;function UTF8ToString(ptr){return UTF8ArrayToString(HEAPU8,ptr)}Module["UTF8ToString"]=UTF8ToString;function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=2097151){if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else if(u<=67108863){if(outIdx+4>=endIdx)break;outU8Array[outIdx++]=248|u>>24;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+5>=endIdx)break;outU8Array[outIdx++]=252|u>>30;outU8Array[outIdx++]=128|u>>24&63;outU8Array[outIdx++]=128|u>>18&63;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}Module["stringToUTF8Array"]=stringToUTF8Array;function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}Module["stringToUTF8"]=stringToUTF8;function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127){++len}else if(u<=2047){len+=2}else if(u<=65535){len+=3}else if(u<=2097151){len+=4}else if(u<=67108863){len+=5}else{len+=6}}return len}Module["lengthBytesUTF8"]=lengthBytesUTF8;function UTF16ToString(ptr){var i=0;var str="";while(1){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)return str;++i;str+=String.fromCharCode(codeUnit)}}Module["UTF16ToString"]=UTF16ToString;function stringToUTF16(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}Module["stringToUTF16"]=stringToUTF16;function lengthBytesUTF16(str){return str.length*2}Module["lengthBytesUTF16"]=lengthBytesUTF16;function UTF32ToString(ptr){var i=0;var str="";while(1){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)return str;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}}Module["UTF32ToString"]=UTF32ToString;function stringToUTF32(str,outPtr,maxBytesToWrite){if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}Module["stringToUTF32"]=stringToUTF32;function lengthBytesUTF32(str){var len=0;for(var i=0;i<str.length;++i){var codeUnit=str.charCodeAt(i);if(codeUnit>=55296&&codeUnit<=57343)++i;len+=4}return len}Module["lengthBytesUTF32"]=lengthBytesUTF32;function demangle(func){var hasLibcxxabi=!!Module["___cxa_demangle"];if(hasLibcxxabi){try{var buf=_malloc(func.length);writeStringToMemory(func.substr(1),buf);var status=_malloc(4);var ret=Module["___cxa_demangle"](buf,0,0,status);if(getValue(status,"i32")===0&&ret){return Pointer_stringify(ret)}}catch(e){}finally{if(buf)_free(buf);if(status)_free(status);if(ret)_free(ret)}}var i=3;var basicTypes={"v":"void","b":"bool","c":"char","s":"short","i":"int","l":"long","f":"float","d":"double","w":"wchar_t","a":"signed char","h":"unsigned char","t":"unsigned short","j":"unsigned int","m":"unsigned long","x":"long long","y":"unsigned long long","z":"..."};var subs=[];var first=true;function dump(x){if(x)Module.print(x);Module.print(func);var pre="";for(var a=0;a<i;a++)pre+=" ";Module.print(pre+"^")}function parseNested(){i++;if(func[i]==="K")i++;var parts=[];while(func[i]!=="E"){if(func[i]==="S"){i++;var next=func.indexOf("_",i);var num=func.substring(i,next)||0;parts.push(subs[num]||"?");i=next+1;continue}if(func[i]==="C"){parts.push(parts[parts.length-1]);i+=2;continue}var size=parseInt(func.substr(i));var pre=size.toString().length;if(!size||!pre){i--;break}var curr=func.substr(i+pre,size);parts.push(curr);subs.push(curr);i+=pre+size}i++;return parts}function parse(rawList,limit,allowVoid){limit=limit||Infinity;var ret="",list=[];function flushList(){return"("+list.join(", ")+")"}var name;if(func[i]==="N"){name=parseNested().join("::");limit--;if(limit===0)return rawList?[name]:name}else{if(func[i]==="K"||first&&func[i]==="L")i++;var size=parseInt(func.substr(i));if(size){var pre=size.toString().length;name=func.substr(i+pre,size);i+=pre+size}}first=false;if(func[i]==="I"){i++;var iList=parse(true);var iRet=parse(true,1,true);ret+=iRet[0]+" "+name+"<"+iList.join(", ")+">"}else{ret=name}paramLoop:while(i<func.length&&limit-->0){var c=func[i++];if(c in basicTypes){list.push(basicTypes[c])}else{switch(c){case"P":list.push(parse(true,1,true)[0]+"*");break;case"R":list.push(parse(true,1,true)[0]+"&");break;case"L":{i++;var end=func.indexOf("E",i);var size=end-i;list.push(func.substr(i,size));i+=size+2;break};case"A":{var size=parseInt(func.substr(i));i+=size.toString().length;if(func[i]!=="_")throw"?";i++;list.push(parse(true,1,true)[0]+" ["+size+"]");break};case"E":break paramLoop;default:ret+="?"+c;break paramLoop}}}if(!allowVoid&&list.length===1&&list[0]==="void")list=[];if(rawList){if(ret){list.push(ret+"?")}return list}else{return ret+flushList()}}var parsed=func;try{if(func=="Object._main"||func=="_main"){return"main()"}if(typeof func==="number")func=Pointer_stringify(func);if(func[0]!=="_")return func;if(func[1]!=="_")return func;if(func[2]!=="Z")return func;switch(func[3]){case"n":return"operator new()";case"d":return"operator delete()"}parsed=parse()}catch(e){parsed+="?"}if(parsed.indexOf("?")>=0&&!hasLibcxxabi){Runtime.warnOnce("warning: a problem occurred in builtin C++ name demangling; build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling")}return parsed}function demangleAll(text){return text.replace(/__Z[\w\d_]+/g,(function(x){var y=demangle(x);return x===y?x:x+" ["+y+"]"}))}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){return demangleAll(jsStackTrace())}Module["stackTrace"]=stackTrace;var PAGE_SIZE=4096;function alignMemoryPage(x){if(x%4096>0){x+=4096-x%4096}return x}var HEAP;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var STATIC_BASE=0,STATICTOP=0,staticSealed=false;var STACK_BASE=0,STACKTOP=0,STACK_MAX=0;var DYNAMIC_BASE=0,DYNAMICTOP=0;function enlargeMemory(){abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value "+TOTAL_MEMORY+", (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.")}var TOTAL_STACK=Module["TOTAL_STACK"]||5242880;var TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;var totalMemory=64*1024;while(totalMemory<TOTAL_MEMORY||totalMemory<2*TOTAL_STACK){if(totalMemory<16*1024*1024){totalMemory*=2}else{totalMemory+=16*1024*1024}}if(totalMemory!==TOTAL_MEMORY){Module.printErr("increasing TOTAL_MEMORY to "+totalMemory+" to be compliant with the asm.js spec (and given that TOTAL_STACK="+TOTAL_STACK+")");TOTAL_MEMORY=totalMemory}assert(typeof Int32Array!=="undefined"&&typeof Float64Array!=="undefined"&&!!(new Int32Array(1))["subarray"]&&!!(new Int32Array(1))["set"],"JS engine does not provide full typed array support");var buffer;buffer=new ArrayBuffer(TOTAL_MEMORY);HEAP8=new Int8Array(buffer);HEAP16=new Int16Array(buffer);HEAP32=new Int32Array(buffer);HEAPU8=new Uint8Array(buffer);HEAPU16=new Uint16Array(buffer);HEAPU32=new Uint32Array(buffer);HEAPF32=new Float32Array(buffer);HEAPF64=new Float64Array(buffer);HEAP32[0]=255;assert(HEAPU8[0]===255&&HEAPU8[3]===0,"Typed arrays 2 must be run on a little-endian system");Module["HEAP"]=HEAP;Module["buffer"]=buffer;Module["HEAP8"]=HEAP8;Module["HEAP16"]=HEAP16;Module["HEAP32"]=HEAP32;Module["HEAPU8"]=HEAPU8;Module["HEAPU16"]=HEAPU16;Module["HEAPU32"]=HEAPU32;Module["HEAPF32"]=HEAPF32;Module["HEAPF64"]=HEAPF64;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Runtime.dynCall("v",func)}else{Runtime.dynCall("vi",func,[callback.arg])}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function ensureInitRuntime(){if(runtimeInitialized)return;runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){callRuntimeCallbacks(__ATEXIT__);runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}Module["addOnPreRun"]=Module.addOnPreRun=addOnPreRun;function addOnInit(cb){__ATINIT__.unshift(cb)}Module["addOnInit"]=Module.addOnInit=addOnInit;function addOnPreMain(cb){__ATMAIN__.unshift(cb)}Module["addOnPreMain"]=Module.addOnPreMain=addOnPreMain;function addOnExit(cb){__ATEXIT__.unshift(cb)}Module["addOnExit"]=Module.addOnExit=addOnExit;function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}Module["addOnPostRun"]=Module.addOnPostRun=addOnPostRun;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}Module["intArrayFromString"]=intArrayFromString;function intArrayToString(array){var ret=[];for(var i=0;i<array.length;i++){var chr=array[i];if(chr>255){chr&=255}ret.push(String.fromCharCode(chr))}return ret.join("")}Module["intArrayToString"]=intArrayToString;function writeStringToMemory(string,buffer,dontAddNull){var array=intArrayFromString(string,dontAddNull);var i=0;while(i<array.length){var chr=array[i];HEAP8[buffer+i>>0]=chr;i=i+1}}Module["writeStringToMemory"]=writeStringToMemory;function writeArrayToMemory(array,buffer){for(var i=0;i<array.length;i++){HEAP8[buffer++>>0]=array[i]}}Module["writeArrayToMemory"]=writeArrayToMemory;function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i<str.length;++i){HEAP8[buffer++>>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}Module["writeAsciiToMemory"]=writeAsciiToMemory;function unSign(value,bits,ignore){if(value>=0){return value}return bits<=32?2*Math.abs(1<<bits-1)+value:Math.pow(2,bits)+value}function reSign(value,bits,ignore){if(value<=0){return value}var half=bits<=32?Math.abs(1<<bits-1):Math.pow(2,bits-1);if(value>=half&&(bits<=32||value>half)){value=-2*half+value}return value}if(!Math["imul"]||Math["imul"](4294967295,5)!==-5)Math["imul"]=function imul(a,b){var ah=a>>>16;var al=a&65535;var bh=b>>>16;var bl=b&65535;return al*bl+(ah*bl+al*bh<<16)|0};Math.imul=Math["imul"];if(!Math["clz32"])Math["clz32"]=(function(x){x=x>>>0;for(var i=0;i<32;i++){if(x&1<<31-i)return i}return 32});Math.clz32=Math["clz32"];var Math_abs=Math.abs;var Math_cos=Math.cos;var Math_sin=Math.sin;var Math_tan=Math.tan;var Math_acos=Math.acos;var Math_asin=Math.asin;var Math_atan=Math.atan;var Math_atan2=Math.atan2;var Math_exp=Math.exp;var Math_log=Math.log;var Math_sqrt=Math.sqrt;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_pow=Math.pow;var Math_imul=Math.imul;var Math_fround=Math.fround;var Math_min=Math.min;var Math_clz32=Math.clz32;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}Module["addRunDependency"]=addRunDependency;function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["removeRunDependency"]=removeRunDependency;Module["preloadedImages"]={};Module["preloadedAudios"]={};var memoryInitializer=null;var ASM_CONSTS=[];STATIC_BASE=8;STATICTOP=STATIC_BASE+3392;__ATINIT__.push();allocate([0,0,0,0,183,29,193,4,110,59,130,9,217,38,67,13,220,118,4,19,107,107,197,23,178,77,134,26,5,80,71,30,184,237,8,38,15,240,201,34,214,214,138,47,97,203,75,43,100,155,12,53,211,134,205,49,10,160,142,60,189,189,79,56,112,219,17,76,199,198,208,72,30,224,147,69,169,253,82,65,172,173,21,95,27,176,212,91,194,150,151,86,117,139,86,82,200,54,25,106,127,43,216,110,166,13,155,99,17,16,90,103,20,64,29,121,163,93,220,125,122,123,159,112,205,102,94,116,224,182,35,152,87,171,226,156,142,141,161,145,57,144,96,149,60,192,39,139,139,221,230,143,82,251,165,130,229,230,100,134,88,91,43,190,239,70,234,186,54,96,169,183,129,125,104,179,132,45,47,173,51,48,238,169,234,22,173,164,93,11,108,160,144,109,50,212,39,112,243,208,254,86,176,221,73,75,113,217,76,27,54,199,251,6,247,195,34,32,180,206,149,61,117,202,40,128,58,242,159,157,251,246,70,187,184,251,241,166,121,255,244,246,62,225,67,235,255,229,154,205,188,232,45,208,125,236,119,112,134,52,192,109,71,48,25,75,4,61,174,86,197,57,171,6,130,39,28,27,67,35,197,61,0,46,114,32,193,42,207,157,142,18,120,128,79,22,161,166,12,27,22,187,205,31,19,235,138,1,164,246,75,5,125,208,8,8,202,205,201,12,7,171,151,120,176,182,86,124,105,144,21,113,222,141,212,117,219,221,147,107,108,192,82,111,181,230,17,98,2,251,208,102,191,70,159,94,8,91,94,90,209,125,29,87,102,96,220,83,99,48,155,77,212,45,90,73,13,11,25,68,186,22,216,64,151,198,165,172,32,219,100,168,249,253,39,165,78,224,230,161,75,176,161,191,252,173,96,187,37,139,35,182,146,150,226,178,47,43,173,138,152,54,108,142,65,16,47,131,246,13,238,135,243,93,169,153,68,64,104,157,157,102,43,144,42,123,234,148,231,29,180,224,80,0,117,228,137,38,54,233,62,59,247,237,59,107,176,243,140,118,113,247,85,80,50,250,226,77,243,254,95,240,188,198,232,237,125,194,49,203,62,207,134,214,255,203,131,134,184,213,52,155,121,209,237,189,58,220,90,160,251,216,238,224,12,105,89,253,205,109,128,219,142,96,55,198,79,100,50,150,8,122,133,139,201,126,92,173,138,115,235,176,75,119,86,13,4,79,225,16,197,75,56,54,134,70,143,43,71,66,138,123,0,92,61,102,193,88,228,64,130,85,83,93,67,81,158,59,29,37,41,38,220,33,240,0,159,44,71,29,94,40,66,77,25,54,245,80,216,50,44,118,155,63,155,107,90,59,38,214,21,3,145,203,212,7,72,237,151,10,255,240,86,14,250,160,17,16,77,189,208,20,148,155,147,25,35,134,82,29,14,86,47,241,185,75,238,245,96,109,173,248,215,112,108,252,210,32,43,226,101,61,234,230,188,27,169,235,11,6,104,239,182,187,39,215,1,166,230,211,216,128,165,222,111,157,100,218,106,205,35,196,221,208,226,192,4,246,161,205,179,235,96,201,126,141,62,189,201,144,255,185,16,182,188,180,167,171,125,176,162,251,58,174,21,230,251,170,204,192,184,167,123,221,121,163,198,96,54,155,113,125,247,159,168,91,180,146,31,70,117,150,26,22,50,136,173,11,243,140,116,45,176,129,195,48,113,133,153,144,138,93,46,141,75,89,247,171,8,84,64,182,201,80,69,230,142,78,242,251,79,74,43,221,12,71,156,192,205,67,33,125,130,123,150,96,67,127,79,70,0,114,248,91,193,118,253,11,134,104,74,22,71,108,147,48,4,97,36,45,197,101,233,75,155,17,94,86,90,21,135,112,25,24,48,109,216,28,53,61,159,2,130,32,94,6,91,6,29,11,236,27,220,15,81,166,147,55,230,187,82,51,63,157,17,62,136,128,208,58,141,208,151,36,58,205,86,32,227,235,21,45,84,246,212,41,121,38,169,197,206,59,104,193,23,29,43,204,160,0,234,200,165,80,173,214,18,77,108,210,203,107,47,223,124,118,238,219,193,203,161,227,118,214,96,231,175,240,35,234,24,237,226,238,29,189,165,240,170,160,100,244,115,134,39,249,196,155,230,253,9,253,184,137,190,224,121,141,103,198,58,128,208,219,251,132,213,139,188,154,98,150,125,158,187,176,62,147,12,173,255,151,177,16,176,175,6,13,113,171,223,43,50,166,104,54,243,162,109,102,180,188,218,123,117,184,3,93,54,181,180,64,247,177,79,103,103,83,0,0,0,0,184,8,0,0,7,0,0,0,192,8,0,0,1,0,0,0,1,0,0,0,2,0,0,0,200,8,0,0,7,0,0,0,208,8,0,0,3,0,0,0,2,0,0,0,4,0,0,0,216,8,0,0,5,0,0,0,216,8,0,0,5,0,0,0,3,0,0,0,0,0,0,0,224,8,0,0,8,0,0,0,240,8,0,0,6,0,0,0,0,0,0,0,0,0,0,0,248,8,0,0,8,0,0,0,8,9,0,0,7,0,0,0,0,0,0,0,0,0,0,0,16,9,0,0,7,0,0,0,16,9,0,0,8,0,0,0,0,0,0,0,0,0,0,0,24,9,0,0,7,0,0,0,32,9,0,0,9,0,0,0,0,0,0,0,0,0,0,0,48,9,0,0,4,0,0,0,56,9,0,0,10,0,0,0,4,0,0,0,0,0,0,0,64,9,0,0,5,0,0,0,72,9,0,0,11,0,0,0,4,0,0,0,0,0,0,0,80,9,0,0,7,0,0,0,80,9,0,0,12,0,0,0,0,0,0,0,0,0,0,0,88,9,0,0,8,0,0,0,104,9,0,0,13,0,0,0,5,0,0,0,0,0,0,0,112,9,0,0,8,0,0,0,128,9,0,0,14,0,0,0,0,0,0,0,0,0,0,0,136,9,0,0,5,0,0,0,144,9,0,0,15,0,0,0,0,0,0,0,0,0,0,0,152,9,0,0,8,0,0,0,168,9,0,0,16,0,0,0,6,0,0,0,17,0,0,0,176,9,0,0,5,0,0,0,184,9,0,0,18,0,0,0,7,0,0,0,0,0,0,0,192,9,0,0,0,0,0,0,200,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,118,111,114,98,105,115,0,129,116,104,101,111,114,97,0,129,107,97,116,101,0,0,0,0,0,0,0,0,0,0,0,79,112,117,115,84,97,103,115,0,0,0,0,0,0,0,0,79,86,80,56,48,2,32,0,128,2,0,0,204,1,0,0,24,0,0,0,1,0,0,0,176,0,0,0,120,0,0,0,96,1,0,0,240,0,0,0,96,1,0,0,32,1,0,0,192,2,0,0,224,1,0,0,192,2,0,0,64,2,0,0,208,2,0,0,224,1,0,0,208,2,0,0,64,2,0,0,0,5,0,0,208,2,0,0,0,5,0,0,208,2,0,0,128,7,0,0,56,4,0,0,128,7,0,0,56,4,0,0,128,7,0,0,56,4,0,0,128,7,0,0,56,4,0,0,0,8,0,0,56,4,0,0,0,16,0,0,112,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,9,0,0,0,10,0,0,0,9,0,0,0,10,0,0,0,9,0,0,0,10,0,0,0,4,0,0,0,3,0,0,0,7,0,0,0,6,0,0,0,4,0,0,0,3,0,0,0,7,0,0,0,6,0,0,0,2,0,0,0,2,0,0,0,7,0,0,0,6,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,192,93,0,0,233,3,0,0,24,0,0,0,1,0,0,0,25,0,0,0,1,0,0,0,48,117,0,0,233,3,0,0,30,0,0,0,1,0,0,0,50,0,0,0,1,0,0,0,96,234,0,0,233,3,0,0,60,0,0,0,1,0,0,0,152,58,0,0,233,3,0,0,25,0,0,0,2,0,0,0,224,1,0,0,192,3,0,0,128,7,0,0,64,11,0,0,224,1,0,0,192,3,0,0,128,7,0,0,64,11,0,0,224,1,0,0,192,3,0,0,128,7,0,0,64,11,0,0,224,1,0,0,192,3,0,0,224,1,0,0,192,3,0,0,120,0,0,0,240,0,0,0,224,1,0,0,192,3,0,0,120,0,0,0,240,0,0,0,224,1,0,0,192,3,0,0,120,0,0,0,240,0,0,0,224,1,0,0,192,3,0,0,120,0,0,0,240,0,0,0,224,1,0,0,192,3,0,0,0,0,0,0,1,0,0,0,3,0,0,0,7,0,0,0,15,0,0,0,31,0,0,0,63,0,0,0,127,0,0,0,255,0,0,0,255,1,0,0,255,3,0,0,255,7,0,0,255,15,0,0,255,31,0,0,255,63,0,0,255,127,0,0,255,255,0,0,255,255,1,0,255,255,3,0,255,255,7,0,255,255,15,0,255,255,31,0,255,255,63,0,255,255,127,0,255,255,255,0,255,255,255,1,255,255,255,3,255,255,255,7,255,255,255,15,255,255,255,31,255,255,255,63,255,255,255,127,255,255,255,255,0,0,0,0,128,116,104,101,111,114,97,0,84,104,101,111,114,97,0,0,1,118,111,114,98,105,115,0,86,111,114,98,105,115,0,0,83,112,101,101,120,0,0,0,80,67,77,32,32,32,32,32,0,0,0,0,0,0,0,0,80,67,77,0,0,0,0,0,67,77,77,76,0,0,0,0,0,0,0,0,0,0,0,0,67,77,77,76,0,0,0,0,65,110,110,111,100,101,120,0,102,105,115,104,101,97,100,0,83,107,101,108,101,116,111,110,0,0,0,0,0,0,0,0,102,76,97,67,0,0,0,0,70,108,97,99,48,0,0,0,127,70,76,65,67,0,0,0,70,108,97,99,0,0,0,0,65,110,120,68,97,116,97,0,67,69,76,84,32,32,32,32,0,0,0,0,0,0,0,0,67,69,76,84,0,0,0,0,128,107,97,116,101,0,0,0,0,0,0,0,0,0,0,0,75,97,116,101,0,0,0,0,66,66,67,68,0,0,0,0,68,105,114,97,99,0,0,0,79,112,117,115,72,101,97,100,0,0,0,0,0,0,0,0,79,112,117,115,0,0,0,0,79,86,80,56,48,0,0,0,86,80,56,0,0,0,0,0,0,0,0,0,0,0,0,0,85,110,107,110,111,119,110,0,86,80,56,48,0,0,0,0,102,105,115,104,101,97,100,0,0,0,0,0,0,0,0,0,102,105,115,98,111,110,101,0,0,0,0,0,0,0,0,0,105,110,100,101,120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,69,114,114,111,114,32,37,100,32,102,114,111,109,32,111,103,103,122,95,114,101,97,100,95,105,110,112,117,116,10,0,0,69,120,112,101,99,116,101,100,32,116,111,32,114,101,97,100,32,37,100,32,102,114,111,109,32,111,103,103,122,95,114,101,97,100,95,105,110,112,117,116,32,98,117,116,32,103,97,118,101,32,37,100,10,0,0,0,116,104,101,111,114,97,0,0,118,111,114,98,105,115,0,0,111,112,117,115,0,0,0,0,73,110,118,97,108,105,100,32,111,103,103,32,115,107,101,108,101,116,111,110,32,116,114,97,99,107,32,100,97,116,97,63,32,37,100,10,0,0,0,0,73,110,118,97,108,105,100,32,115,116,97,116,101,32,105,110,32,79,103,103,32,114,101,97,100,80,97,99,107,101,116,67,97,108,108,98,97,99,107,0,69,114,114,111,114,32,112,114,111,99,101,115,115,105,110,103,32,115,107,101,108,101,116,111,110,32,112,97,99,107,101,116,58,32,37,100,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"i8",ALLOC_NONE,Runtime.GLOBAL_BASE);var tempDoublePtr=Runtime.alignMemory(allocate(12,"i8",ALLOC_STATIC),8);assert(tempDoublePtr%8==0);function copyTempFloat(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3]}function copyTempDouble(ptr){HEAP8[tempDoublePtr]=HEAP8[ptr];HEAP8[tempDoublePtr+1]=HEAP8[ptr+1];HEAP8[tempDoublePtr+2]=HEAP8[ptr+2];HEAP8[tempDoublePtr+3]=HEAP8[ptr+3];HEAP8[tempDoublePtr+4]=HEAP8[ptr+4];HEAP8[tempDoublePtr+5]=HEAP8[ptr+5];HEAP8[tempDoublePtr+6]=HEAP8[ptr+6];HEAP8[tempDoublePtr+7]=HEAP8[ptr+7]}function _ogvjs_callback_loaded_metadata(videoCodecStr,audioCodecStr){if(videoCodecStr){Module.videoCodec=Module.Pointer_stringify(videoCodecStr)}if(audioCodecStr){Module.audioCodec=Module.Pointer_stringify(audioCodecStr)}var len=Module._ogv_demuxer_media_duration();if(len>=0){Module.duration=len}else{Module.duration=NaN}Module.loadedMetadata=true}Module["_bitshift64Ashr"]=_bitshift64Ashr;function _ogvjs_callback_video_packet(buffer,len,frameTimestamp,keyframeTimestamp){Module.videoPackets.push({data:Module.HEAPU8.buffer.slice?Module.HEAPU8.buffer.slice(buffer,buffer+len):(new Uint8Array(new Uint8Array(Module.HEAPU8.buffer,buffer,len))).buffer,timestamp:frameTimestamp,keyframeTimestamp:keyframeTimestamp})}Module["_i64Subtract"]=_i64Subtract;var ___errno_state=0;function ___setErrNo(value){HEAP32[___errno_state>>2]=value;return value}var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 85:return totalMemory/PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 79:return 0;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(ERRNO_CODES.EINVAL);return-1}var _SItoD=true;var _SItoF=true;Module["_memset"]=_memset;var FS=undefined;function _close(fildes){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{FS.close(stream);return 0}catch(e){FS.handleFSError(e);return-1}}function _fileno(stream){stream=FS.getStreamFromPtr(stream);if(!stream)return-1;return stream.fd}function _fclose(stream){var fd=_fileno(stream);return _close(fd)}Module["_bitshift64Shl"]=_bitshift64Shl;function _abort(){Module["abort"]()}var SOCKFS=undefined;function _send(fd,buf,len,flags){var sock=SOCKFS.getSocket(fd);if(!sock){___setErrNo(ERRNO_CODES.EBADF);return-1}return _write(fd,buf,len)}function _pwrite(fildes,buf,nbyte,offset){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte,offset)}catch(e){FS.handleFSError(e);return-1}}function _write(fildes,buf,nbyte){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{var slab=HEAP8;return FS.write(stream,slab,buf,nbyte)}catch(e){FS.handleFSError(e);return-1}}function _fwrite(ptr,size,nitems,stream){var bytesToWrite=nitems*size;if(bytesToWrite==0)return 0;var fd=_fileno(stream);var bytesWritten=_write(fd,ptr,bytesToWrite);if(bytesWritten==-1){var streamObj=FS.getStreamFromPtr(stream);if(streamObj)streamObj.error=true;return 0}else{return bytesWritten/size|0}}Module["_strlen"]=_strlen;function __reallyNegative(x){return x<0||x===0&&1/x===-Infinity}function __formatString(format,varargs){assert((varargs&3)===0);var textIndex=format;var argIndex=0;function getNextArg(type){var ret;argIndex=Runtime.prepVararg(argIndex,type);if(type==="double"){ret=(HEAP32[tempDoublePtr>>2]=HEAP32[varargs+argIndex>>2],HEAP32[tempDoublePtr+4>>2]=HEAP32[varargs+(argIndex+4)>>2],+HEAPF64[tempDoublePtr>>3]);argIndex+=8}else if(type=="i64"){ret=[HEAP32[varargs+argIndex>>2],HEAP32[varargs+(argIndex+4)>>2]];argIndex+=8}else{assert((argIndex&3)===0);type="i32";ret=HEAP32[varargs+argIndex>>2];argIndex+=4}return ret}var ret=[];var curr,next,currArg;while(1){var startTextIndex=textIndex;curr=HEAP8[textIndex>>0];if(curr===0)break;next=HEAP8[textIndex+1>>0];if(curr==37){var flagAlwaysSigned=false;var flagLeftAlign=false;var flagAlternative=false;var flagZeroPad=false;var flagPadSign=false;flagsLoop:while(1){switch(next){case 43:flagAlwaysSigned=true;break;case 45:flagLeftAlign=true;break;case 35:flagAlternative=true;break;case 48:if(flagZeroPad){break flagsLoop}else{flagZeroPad=true;break};case 32:flagPadSign=true;break;default:break flagsLoop}textIndex++;next=HEAP8[textIndex+1>>0]}var width=0;if(next==42){width=getNextArg("i32");textIndex++;next=HEAP8[textIndex+1>>0]}else{while(next>=48&&next<=57){width=width*10+(next-48);textIndex++;next=HEAP8[textIndex+1>>0]}}var precisionSet=false,precision=-1;if(next==46){precision=0;precisionSet=true;textIndex++;next=HEAP8[textIndex+1>>0];if(next==42){precision=getNextArg("i32");textIndex++}else{while(1){var precisionChr=HEAP8[textIndex+1>>0];if(precisionChr<48||precisionChr>57)break;precision=precision*10+(precisionChr-48);textIndex++}}next=HEAP8[textIndex+1>>0]}if(precision<0){precision=6;precisionSet=false}var argSize;switch(String.fromCharCode(next)){case"h":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==104){textIndex++;argSize=1}else{argSize=2}break;case"l":var nextNext=HEAP8[textIndex+2>>0];if(nextNext==108){textIndex++;argSize=8}else{argSize=4}break;case"L":case"q":case"j":argSize=8;break;case"z":case"t":case"I":argSize=4;break;default:argSize=null}if(argSize)textIndex++;next=HEAP8[textIndex+1>>0];switch(String.fromCharCode(next)){case"d":case"i":case"u":case"o":case"x":case"X":case"p":{var signed=next==100||next==105;argSize=argSize||4;var currArg=getNextArg("i"+argSize*8);var origArg=currArg;var argText;if(argSize==8){currArg=Runtime.makeBigInt(currArg[0],currArg[1],next==117)}if(argSize<=4){var limit=Math.pow(256,argSize)-1;currArg=(signed?reSign:unSign)(currArg&limit,argSize*8)}var currAbsArg=Math.abs(currArg);var prefix="";if(next==100||next==105){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],null);else argText=reSign(currArg,8*argSize,1).toString(10)}else if(next==117){if(argSize==8&&i64Math)argText=i64Math.stringify(origArg[0],origArg[1],true);else argText=unSign(currArg,8*argSize,1).toString(10);currArg=Math.abs(currArg)}else if(next==111){argText=(flagAlternative?"0":"")+currAbsArg.toString(8)}else if(next==120||next==88){prefix=flagAlternative&&currArg!=0?"0x":"";if(argSize==8&&i64Math){if(origArg[1]){argText=(origArg[1]>>>0).toString(16);var lower=(origArg[0]>>>0).toString(16);while(lower.length<8)lower="0"+lower;argText+=lower}else{argText=(origArg[0]>>>0).toString(16)}}else if(currArg<0){currArg=-currArg;argText=(currAbsArg-1).toString(16);var buffer=[];for(var i=0;i<argText.length;i++){buffer.push((15-parseInt(argText[i],16)).toString(16))}argText=buffer.join("");while(argText.length<argSize*2)argText="f"+argText}else{argText=currAbsArg.toString(16)}if(next==88){prefix=prefix.toUpperCase();argText=argText.toUpperCase()}}else if(next==112){if(currAbsArg===0){argText="(nil)"}else{prefix="0x";argText=currAbsArg.toString(16)}}if(precisionSet){while(argText.length<precision){argText="0"+argText}}if(currArg>=0){if(flagAlwaysSigned){prefix="+"+prefix}else if(flagPadSign){prefix=" "+prefix}}if(argText.charAt(0)=="-"){prefix="-"+prefix;argText=argText.substr(1)}while(prefix.length+argText.length<width){if(flagLeftAlign){argText+=" "}else{if(flagZeroPad){argText="0"+argText}else{prefix=" "+prefix}}}argText=prefix+argText;argText.split("").forEach((function(chr){ret.push(chr.charCodeAt(0))}));break};case"f":case"F":case"e":case"E":case"g":case"G":{var currArg=getNextArg("double");var argText;if(isNaN(currArg)){argText="nan";flagZeroPad=false}else if(!isFinite(currArg)){argText=(currArg<0?"-":"")+"inf";flagZeroPad=false}else{var isGeneral=false;var effectivePrecision=Math.min(precision,20);if(next==103||next==71){isGeneral=true;precision=precision||1;var exponent=parseInt(currArg.toExponential(effectivePrecision).split("e")[1],10);if(precision>exponent&&exponent>=-4){next=(next==103?"f":"F").charCodeAt(0);precision-=exponent+1}else{next=(next==103?"e":"E").charCodeAt(0);precision--}effectivePrecision=Math.min(precision,20)}if(next==101||next==69){argText=currArg.toExponential(effectivePrecision);if(/[eE][-+]\d$/.test(argText)){argText=argText.slice(0,-1)+"0"+argText.slice(-1)}}else if(next==102||next==70){argText=currArg.toFixed(effectivePrecision);if(currArg===0&&__reallyNegative(currArg)){argText="-"+argText}}var parts=argText.split("e");if(isGeneral&&!flagAlternative){while(parts[0].length>1&&parts[0].indexOf(".")!=-1&&(parts[0].slice(-1)=="0"||parts[0].slice(-1)==".")){parts[0]=parts[0].slice(0,-1)}}else{if(flagAlternative&&argText.indexOf(".")==-1)parts[0]+=".";while(precision>effectivePrecision++)parts[0]+="0"}argText=parts[0]+(parts.length>1?"e"+parts[1]:"");if(next==69)argText=argText.toUpperCase();if(currArg>=0){if(flagAlwaysSigned){argText="+"+argText}else if(flagPadSign){argText=" "+argText}}}while(argText.length<width){if(flagLeftAlign){argText+=" "}else{if(flagZeroPad&&(argText[0]=="-"||argText[0]=="+")){argText=argText[0]+"0"+argText.slice(1)}else{argText=(flagZeroPad?"0":" ")+argText}}}if(next<97)argText=argText.toUpperCase();argText.split("").forEach((function(chr){ret.push(chr.charCodeAt(0))}));break};case"s":{var arg=getNextArg("i8*");var argLength=arg?_strlen(arg):"(null)".length;if(precisionSet)argLength=Math.min(argLength,precision);if(!flagLeftAlign){while(argLength<width--){ret.push(32)}}if(arg){for(var i=0;i<argLength;i++){ret.push(HEAPU8[arg++>>0])}}else{ret=ret.concat(intArrayFromString("(null)".substr(0,argLength),true))}if(flagLeftAlign){while(argLength<width--){ret.push(32)}}break};case"c":{if(flagLeftAlign)ret.push(getNextArg("i8"));while(--width>0){ret.push(32)}if(!flagLeftAlign)ret.push(getNextArg("i8"));break};case"n":{var ptr=getNextArg("i32*");HEAP32[ptr>>2]=ret.length;break};case"%":{ret.push(curr);break};default:{for(var i=startTextIndex;i<textIndex+2;i++){ret.push(HEAP8[i>>0])}}}textIndex+=2}else{ret.push(curr);textIndex+=1}}return ret}function _fprintf(stream,format,varargs){var result=__formatString(format,varargs);var stack=Runtime.stackSave();var ret=_fwrite(allocate(result,"i8",ALLOC_STACK),1,result.length,stream);Runtime.stackRestore(stack);return ret}function _printf(format,varargs){var result=__formatString(format,varargs);var string=intArrayToString(result);if(string[string.length-1]==="\n")string=string.substr(0,string.length-1);Module.print(string);return result.length}function _ogvjs_callback_frame_ready(){return Module.videoPackets.length>0?1:0}function _fflush(stream){}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest);return dest}Module["_memcpy"]=_memcpy;Module["_strncpy"]=_strncpy;Module["_i64Add"]=_i64Add;function _ogvjs_callback_audio_packet(buffer,len,audioTimestamp){Module.audioPackets.push({data:Module.HEAPU8.buffer.slice?Module.HEAPU8.buffer.slice(buffer,buffer+len):(new Uint8Array(new Uint8Array(Module.HEAPU8.buffer,buffer,len))).buffer,timestamp:audioTimestamp})}Module["_memmove"]=_memmove;function _ogvjs_callback_audio_ready(){return Module.audioPackets.length>0?1:0}function _lseek(fildes,offset,whence){var stream=FS.getStream(fildes);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}try{return FS.llseek(stream,offset,whence)}catch(e){FS.handleFSError(e);return-1}}function _fseek(stream,offset,whence){var fd=_fileno(stream);var ret=_lseek(fd,offset,whence);if(ret==-1){return-1}stream=FS.getStreamFromPtr(stream);stream.eof=false;return 0}function ___errno_location(){return ___errno_state}function _ftell(stream){stream=FS.getStreamFromPtr(stream);if(!stream){___setErrNo(ERRNO_CODES.EBADF);return-1}if(FS.isChrdev(stream.node.mode)){___setErrNo(ERRNO_CODES.ESPIPE);return-1}else{return stream.position}}Module["_strcpy"]=_strcpy;function _sbrk(bytes){var self=_sbrk;if(!self.called){DYNAMICTOP=alignMemoryPage(DYNAMICTOP);self.called=true;assert(Runtime.dynamicAlloc);self.alloc=Runtime.dynamicAlloc;Runtime.dynamicAlloc=(function(){abort("cannot dynamically allocate, sbrk now has control")})}var ret=DYNAMICTOP;if(bytes!=0){var success=self.alloc(bytes);if(!success)return-1>>>0}return ret}function _time(ptr){var ret=Date.now()/1e3|0;if(ptr){HEAP32[ptr>>2]=ret}return ret}___errno_state=Runtime.staticAlloc(4);HEAP32[___errno_state>>2]=0;STACK_BASE=STACKTOP=Runtime.alignMemory(STATICTOP);staticSealed=true;STACK_MAX=STACK_BASE+TOTAL_STACK;DYNAMIC_BASE=DYNAMICTOP=Runtime.alignMemory(STACK_MAX);assert(DYNAMIC_BASE<TOTAL_MEMORY,"TOTAL_MEMORY not big enough for stack");var cttz_i8=allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0],"i8",ALLOC_DYNAMIC);function invoke_iiii(index,a1,a2,a3){try{return Module["dynCall_iiii"](index,a1,a2,a3)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_vi(index,a1){try{Module["dynCall_vi"](index,a1)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_ii(index,a1){try{return Module["dynCall_ii"](index,a1)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_iiiii(index,a1,a2,a3,a4){try{return Module["dynCall_iiiii"](index,a1,a2,a3,a4)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_iii(index,a1,a2){try{return Module["dynCall_iii"](index,a1,a2)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}function invoke_iiiiii(index,a1,a2,a3,a4,a5){try{return Module["dynCall_iiiiii"](index,a1,a2,a3,a4,a5)}catch(e){if(typeof e!=="number"&&e!=="longjmp")throw e;asm["setThrew"](1,0)}}Module.asmGlobalArg={"Math":Math,"Int8Array":Int8Array,"Int16Array":Int16Array,"Int32Array":Int32Array,"Uint8Array":Uint8Array,"Uint16Array":Uint16Array,"Uint32Array":Uint32Array,"Float32Array":Float32Array,"Float64Array":Float64Array,"NaN":NaN,"Infinity":Infinity};Module.asmLibraryArg={"abort":abort,"assert":assert,"invoke_iiii":invoke_iiii,"invoke_vi":invoke_vi,"invoke_ii":invoke_ii,"invoke_iiiii":invoke_iiiii,"invoke_iii":invoke_iii,"invoke_iiiiii":invoke_iiiiii,"_send":_send,"_lseek":_lseek,"___setErrNo":___setErrNo,"_ogvjs_callback_audio_packet":_ogvjs_callback_audio_packet,"_ogvjs_callback_loaded_metadata":_ogvjs_callback_loaded_metadata,"_fflush":_fflush,"_pwrite":_pwrite,"__reallyNegative":__reallyNegative,"_sbrk":_sbrk,"_emscripten_memcpy_big":_emscripten_memcpy_big,"_fileno":_fileno,"_ogvjs_callback_frame_ready":_ogvjs_callback_frame_ready,"_sysconf":_sysconf,"_close":_close,"_ogvjs_callback_video_packet":_ogvjs_callback_video_packet,"_fseek":_fseek,"_printf":_printf,"_fclose":_fclose,"_write":_write,"_ftell":_ftell,"___errno_location":___errno_location,"_abort":_abort,"_fwrite":_fwrite,"_time":_time,"_fprintf":_fprintf,"__formatString":__formatString,"_ogvjs_callback_audio_ready":_ogvjs_callback_audio_ready,"STACKTOP":STACKTOP,"STACK_MAX":STACK_MAX,"tempDoublePtr":tempDoublePtr,"ABORT":ABORT,"cttz_i8":cttz_i8};// EMSCRIPTEN_START_ASM +var asm=(function(global,env,buffer) { +"use asm";var a=new global.Int8Array(buffer);var b=new global.Int16Array(buffer);var c=new global.Int32Array(buffer);var d=new global.Uint8Array(buffer);var e=new global.Uint16Array(buffer);var f=new global.Uint32Array(buffer);var g=new global.Float32Array(buffer);var h=new global.Float64Array(buffer);var i=env.STACKTOP|0;var j=env.STACK_MAX|0;var k=env.tempDoublePtr|0;var l=env.ABORT|0;var m=env.cttz_i8|0;var n=0;var o=0;var p=0;var q=0;var r=global.NaN,s=global.Infinity;var t=0,u=0,v=0,w=0,x=0.0,y=0,z=0,A=0,B=0.0;var C=0;var D=0;var E=0;var F=0;var G=0;var H=0;var I=0;var J=0;var K=0;var L=0;var M=global.Math.floor;var N=global.Math.abs;var O=global.Math.sqrt;var P=global.Math.pow;var Q=global.Math.cos;var R=global.Math.sin;var S=global.Math.tan;var T=global.Math.acos;var U=global.Math.asin;var V=global.Math.atan;var W=global.Math.atan2;var X=global.Math.exp;var Y=global.Math.log;var Z=global.Math.ceil;var _=global.Math.imul;var $=global.Math.min;var aa=global.Math.clz32;var ba=env.abort;var ca=env.assert;var da=env.invoke_iiii;var ea=env.invoke_vi;var fa=env.invoke_ii;var ga=env.invoke_iiiii;var ha=env.invoke_iii;var ia=env.invoke_iiiiii;var ja=env._send;var ka=env._lseek;var la=env.___setErrNo;var ma=env._ogvjs_callback_audio_packet;var na=env._ogvjs_callback_loaded_metadata;var oa=env._fflush;var pa=env._pwrite;var qa=env.__reallyNegative;var ra=env._sbrk;var sa=env._emscripten_memcpy_big;var ta=env._fileno;var ua=env._ogvjs_callback_frame_ready;var va=env._sysconf;var wa=env._close;var xa=env._ogvjs_callback_video_packet;var ya=env._fseek;var za=env._printf;var Aa=env._fclose;var Ba=env._write;var Ca=env._ftell;var Da=env.___errno_location;var Ea=env._abort;var Fa=env._fwrite;var Ga=env._time;var Ha=env._fprintf;var Ia=env.__formatString;var Ja=env._ogvjs_callback_audio_ready;var Ka=0.0; +// EMSCRIPTEN_START_FUNCS +function Ra(a){a=a|0;var b=0;b=i;i=i+a|0;i=i+15&-16;return b|0}function Sa(){return i|0}function Ta(a){a=a|0;i=a}function Ua(a,b){a=a|0;b=b|0;i=a;j=b}function Va(a,b){a=a|0;b=b|0;if(!n){n=a;o=b}}function Wa(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0]}function Xa(b){b=b|0;a[k>>0]=a[b>>0];a[k+1>>0]=a[b+1>>0];a[k+2>>0]=a[b+2>>0];a[k+3>>0]=a[b+3>>0];a[k+4>>0]=a[b+4>>0];a[k+5>>0]=a[b+5>>0];a[k+6>>0]=a[b+6>>0];a[k+7>>0]=a[b+7>>0]}function Ya(a){a=a|0;C=a}function Za(){return C|0}function _a(a){a=a|0;return (d[(c[a>>2]|0)+5>>0]|0)&1|0}function $a(a){a=a|0;return (d[(c[a>>2]|0)+5>>0]|0)&2|0}function ab(a){a=a|0;var b=0,e=0;b=c[a>>2]|0;a=Ie(d[b+13>>0]|0|0,0,8)|0;e=Ie(a|(d[b+12>>0]|0)|0,C|0,8)|0;a=Ie(e|(d[b+11>>0]|0)|0,C|0,8)|0;e=Ie(a|(d[b+10>>0]|0)|0,C|0,8)|0;a=Ie(e|(d[b+9>>0]|0)|0,C|0,8)|0;e=Ie(a|(d[b+8>>0]|0)|0,C|0,8)|0;a=Ie(e|(d[b+7>>0]|0)|0,C|0,8)|0;return a|(d[b+6>>0]|0)|0}function bb(a){a=a|0;var b=0;b=c[a>>2]|0;return (d[b+15>>0]|0)<<8|(d[b+14>>0]|0)|(d[b+16>>0]|0)<<16|(d[b+17>>0]|0)<<24|0}function cb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0;if(!a){d=-1;return d|0}He(a|0,0,360)|0;c[a+4>>2]=16384;c[a+24>>2]=1024;e=ye(16384)|0;c[a>>2]=e;f=ye(4096)|0;g=a+16|0;c[g>>2]=f;h=ye(8192)|0;i=a+20|0;c[i>>2]=h;do if(!e)j=f;else{if((h|0)==0|(f|0)==0){ze(e);j=c[g>>2]|0;break}c[a+336>>2]=b;d=0;return d|0}while(0);if(j)ze(j);j=c[i>>2]|0;if(j)ze(j);He(a|0,0,360)|0;d=-1;return d|0}function db(a){a=a|0;var b=0;if(!a)return 0;b=c[a>>2]|0;if(b)ze(b);b=c[a+16>>2]|0;if(b)ze(b);b=c[a+20>>2]|0;if(b)ze(b);He(a|0,0,360)|0;return 0}function eb(a){a=a|0;if(!a)return 0;c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;c[a+20>>2]=0;c[a+24>>2]=0;return 0}function fb(a){a=a|0;var b=0;if(!a)return 0;b=c[a>>2]|0;if(b)ze(b);c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;c[a+20>>2]=0;c[a+24>>2]=0;return 0}function gb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;d=a+4|0;e=c[d>>2]|0;if((e|0)<=-1){f=0;return f|0}g=a+12|0;h=c[g>>2]|0;i=a+8|0;if(!h)j=e;else{k=(c[i>>2]|0)-h|0;c[i>>2]=k;if((k|0)>0){l=c[a>>2]|0;Ne(l|0,l+h|0,k|0)|0;m=c[d>>2]|0}else m=e;c[g>>2]=0;j=m}m=c[i>>2]|0;do if((j-m|0)<(b|0)){g=b+4096+m|0;e=c[a>>2]|0;if(!e)n=ye(g)|0;else n=Be(e,g)|0;if(n){c[a>>2]=n;c[d>>2]=g;o=n;p=c[i>>2]|0;break}g=c[a>>2]|0;if(g)ze(g);c[a>>2]=0;c[a+4>>2]=0;c[a+8>>2]=0;c[a+12>>2]=0;c[a+16>>2]=0;c[a+20>>2]=0;c[a+24>>2]=0;f=0;return f|0}else{o=c[a>>2]|0;p=m}while(0);f=o+p|0;return f|0}function hb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=c[a+4>>2]|0;if((d|0)<=-1){e=-1;return e|0}f=a+8|0;a=(c[f>>2]|0)+b|0;if((a|0)>(d|0)){e=-1;return e|0}c[f>>2]=a;e=0;return e|0}function ib(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0;f=i;i=i+16|0;g=f;h=c[b>>2]|0;j=b+12|0;k=c[j>>2]|0;l=h+k|0;m=b+8|0;n=(c[m>>2]|0)-k|0;if((c[b+4>>2]|0)<=-1){o=0;i=f;return o|0}p=b+20|0;q=c[p>>2]|0;do if(!q){if((n|0)<27){o=0;i=f;return o|0}if(ve(l,1032,4)|0){r=b+24|0;break}s=h+(k+26)|0;t=a[s>>0]|0;u=(t&255)+27|0;if((n|0)<(u|0)){o=0;i=f;return o|0}if(t<<24>>24){t=k+27|0;v=b+24|0;w=c[v>>2]|0;x=0;do{w=w+(d[h+(t+x)>>0]|0)|0;c[v>>2]=w;x=x+1|0}while((x|0)<(d[s>>0]|0|0))}c[p>>2]=u;y=u;z=11}else{y=q;z=11}while(0);do if((z|0)==11){q=b+24|0;if((y+(c[q>>2]|0)|0)>(n|0)){o=0;i=f;return o|0}s=h+(k+22)|0;x=d[s>>0]|d[s+1>>0]<<8|d[s+2>>0]<<16|d[s+3>>0]<<24;c[g>>2]=x;a[s>>0]=0;a[s+1>>0]=0;a[s+2>>0]=0;a[s+3>>0]=0;w=c[p>>2]|0;v=w+k|0;t=c[q>>2]|0;a[s>>0]=0;A=h+(k+23)|0;a[A>>0]=0;B=h+(k+24)|0;a[B>>0]=0;C=h+(k+25)|0;a[C>>0]=0;if((w|0)>0){D=0;E=0;while(1){F=c[8+(((d[h+(E+k)>>0]|0)^D>>>24)<<2)>>2]^D<<8;E=E+1|0;if((E|0)==(w|0)){G=F;break}else D=F}}else G=0;if((t|0)>0){D=G;w=0;while(1){E=c[8+(((d[h+(v+w)>>0]|0)^D>>>24)<<2)>>2]^D<<8;w=w+1|0;if((w|0)==(t|0)){H=E;break}else D=E}}else H=G;a[s>>0]=H;a[A>>0]=H>>>8;a[B>>0]=H>>>16;a[C>>0]=H>>>24;if(ve(g,s,4)|0){a[s>>0]=x;a[s+1>>0]=x>>8;a[s+2>>0]=x>>16;a[s+3>>0]=x>>24;r=q;break}D=c[b>>2]|0;t=c[j>>2]|0;if(!e){I=c[q>>2]|0;J=c[p>>2]|0}else{c[e>>2]=D+t;w=c[p>>2]|0;c[e+4>>2]=w;c[e+8>>2]=D+(w+t);D=c[q>>2]|0;c[e+12>>2]=D;I=D;J=w}c[b+16>>2]=0;w=I+J|0;c[j>>2]=t+w;c[p>>2]=0;c[q>>2]=0;o=w;i=f;return o|0}while(0);c[p>>2]=0;c[r>>2]=0;r=ue(h+(k+1)|0,79,n+-1|0)|0;n=c[b>>2]|0;if(!r)K=n+(c[m>>2]|0)|0;else K=r;r=K;c[j>>2]=r-n;o=l-r|0;i=f;return o|0}function jb(b,e){b=b|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0;f=c[e>>2]|0;g=c[e+8>>2]|0;h=c[e+12>>2]|0;e=a[f+4>>0]|0;i=d[f+5>>0]|0;j=i&1;k=i&2;l=i&4;i=Ie(d[f+13>>0]|0|0,0,8)|0;m=Ie(i|(d[f+12>>0]|0)|0,C|0,8)|0;i=Ie(m|(d[f+11>>0]|0)|0,C|0,8)|0;m=Ie(i|(d[f+10>>0]|0)|0,C|0,8)|0;i=Ie(m|(d[f+9>>0]|0)|0,C|0,8)|0;m=Ie(i|(d[f+8>>0]|0)|0,C|0,8)|0;i=Ie(m|(d[f+7>>0]|0)|0,C|0,8)|0;m=C;n=i|(d[f+6>>0]|0);i=(d[f+15>>0]|0)<<8|(d[f+14>>0]|0)|(d[f+16>>0]|0)<<16|(d[f+17>>0]|0)<<24;o=(d[f+19>>0]|0)<<8|(d[f+18>>0]|0)|(d[f+20>>0]|0)<<16|(d[f+21>>0]|0)<<24;p=d[f+26>>0]|0;if(!b){q=-1;return q|0}r=c[b>>2]|0;if(!r){q=-1;return q|0}s=b+36|0;t=c[s>>2]|0;u=b+12|0;v=c[u>>2]|0;if(v){w=b+8|0;x=c[w>>2]|0;y=x-v|0;c[w>>2]=y;if((x|0)!=(v|0))Ne(r|0,r+v|0,y|0)|0;c[u>>2]=0}if(t){u=b+28|0;y=c[u>>2]|0;if((y|0)==(t|0))z=t;else{v=c[b+16>>2]|0;Ne(v|0,v+(t<<2)|0,y-t<<2|0)|0;y=c[b+20>>2]|0;Ne(y|0,y+(t<<3)|0,(c[u>>2]|0)-t<<3|0)|0;z=c[u>>2]|0}c[u>>2]=z-t;z=b+32|0;c[z>>2]=(c[z>>2]|0)-t;c[s>>2]=0}if(e<<24>>24!=0?1:(i|0)!=(c[b+336>>2]|0)){q=-1;return q|0}if(nb(b,p+1|0)|0){q=-1;return q|0}i=b+340|0;e=c[i>>2]|0;if((o|0)!=(e|0)){s=b+32|0;t=c[s>>2]|0;z=b+28|0;u=c[z>>2]|0;if((t|0)<(u|0)){y=c[b+16>>2]|0;v=b+8|0;r=c[v>>2]|0;x=t;while(1){w=r-(c[y+(x<<2)>>2]&255)|0;x=x+1|0;if((x|0)>=(u|0)){A=w;break}else r=w}c[v>>2]=A}c[z>>2]=t;if((e|0)!=-1){e=t+1|0;c[z>>2]=e;c[(c[b+16>>2]|0)+(t<<2)>>2]=1024;c[s>>2]=e}}a:do if(!j){B=g;D=h;E=k;F=0}else{e=c[b+28>>2]|0;if((e|0)>=1?(c[(c[b+16>>2]|0)+(e+-1<<2)>>2]|0)!=1024:0){B=g;D=h;E=k;F=0;break}else{G=g;H=h;I=0}while(1){if((I|0)>=(p|0)){B=G;D=H;E=0;F=I;break a}e=a[f+(I+27)>>0]|0;s=e&255;t=G+s|0;z=H-s|0;s=I+1|0;if(e<<24>>24==-1){G=t;H=z;I=s}else{B=t;D=z;E=0;F=s;break}}}while(0);if(D){I=b+4|0;H=c[I>>2]|0;G=b+8|0;h=c[G>>2]|0;do if((H-D|0)>(h|0)){J=c[b>>2]|0;K=h}else{if((H|0)>(2147483647-D|0)){g=c[b>>2]|0;if(g)ze(g);g=c[b+16>>2]|0;if(g)ze(g);g=c[b+20>>2]|0;if(g)ze(g);He(b|0,0,360)|0;q=-1;return q|0}g=H+D|0;k=(g|0)<2147482623?g+1024|0:g;g=Be(c[b>>2]|0,k)|0;if(g){c[I>>2]=k;c[b>>2]=g;J=g;K=c[G>>2]|0;break}g=c[b>>2]|0;if(g)ze(g);g=c[b+16>>2]|0;if(g)ze(g);g=c[b+20>>2]|0;if(g)ze(g);He(b|0,0,360)|0;q=-1;return q|0}while(0);Ke(J+K|0,B|0,D|0)|0;c[G>>2]=(c[G>>2]|0)+D}if((F|0)<(p|0)){D=b+28|0;G=b+32|0;B=c[b+16>>2]|0;K=c[b+20>>2]|0;J=c[D>>2]|0;I=E;E=-1;H=F;b:while(1){F=J;h=I;g=H;while(1){k=a[f+(g+27)>>0]|0;j=k&255;s=B+(F<<2)|0;c[s>>2]=j;z=K+(F<<3)|0;c[z>>2]=-1;c[z+4>>2]=-1;if(h)c[s>>2]=j|256;j=F;F=F+1|0;c[D>>2]=F;g=g+1|0;if(k<<24>>24!=-1){L=j;M=F;N=g;break}if((g|0)>=(p|0)){O=E;break b}else h=0}c[G>>2]=M;if((N|0)<(p|0)){J=M;I=0;E=L;H=N}else{O=L;break}}if((O|0)!=-1){L=(c[b+20>>2]|0)+(O<<3)|0;c[L>>2]=n;c[L+4>>2]=m}}if((l|0)!=0?(c[b+328>>2]=1,l=c[b+28>>2]|0,(l|0)>0):0){m=(c[b+16>>2]|0)+(l+-1<<2)|0;c[m>>2]=c[m>>2]|512}c[i>>2]=o+1;q=0;return q|0}function kb(a){a=a|0;var b=0,d=0;if((c[a+4>>2]|0)<=-1){b=-1;return b|0}d=a+8|0;c[d>>2]=0;c[d+4>>2]=0;c[d+8>>2]=0;c[d+12>>2]=0;c[d+16>>2]=0;b=0;return b|0}function lb(a){a=a|0;var b=0,d=0;if(!a){b=-1;return b|0}if(!(c[a>>2]|0)){b=-1;return b|0}c[a+8>>2]=0;c[a+12>>2]=0;c[a+28>>2]=0;c[a+32>>2]=0;c[a+36>>2]=0;c[a+324>>2]=0;c[a+328>>2]=0;c[a+332>>2]=0;c[a+340>>2]=-1;d=a+344|0;c[d>>2]=0;c[d+4>>2]=0;c[d+8>>2]=0;c[d+12>>2]=0;b=0;return b|0}function mb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;if(!a){d=0;return d|0}e=c[a>>2]|0;if(!e){d=0;return d|0}f=a+36|0;g=c[f>>2]|0;if((c[a+32>>2]|0)<=(g|0)){d=0;return d|0}h=c[a+16>>2]|0;i=c[h+(g<<2)>>2]|0;if(i&1024){c[f>>2]=g+1;j=a+344|0;k=j;l=Me(c[k>>2]|0,c[k+4>>2]|0,1,0)|0;k=j;c[k>>2]=l;c[k+4>>2]=C;d=-1;return d|0}k=(b|0)==0;l=i&255;j=i&512;m=i&256;if((l|0)==255){i=255;n=j;o=g;while(1){p=o+1|0;q=c[h+(p<<2)>>2]|0;r=q&255;s=(q&512|0)==0?n:512;q=r+i|0;if((r|0)==255){i=q;n=s;o=p}else{t=q;u=s;v=p;break}}}else{t=l;u=j;v=g}if(k){k=a+12|0;g=a+344|0;j=g;w=g;x=k;y=c[k>>2]|0;z=c[j>>2]|0;A=c[j+4>>2]|0}else{c[b+12>>2]=u;c[b+8>>2]=m;m=a+12|0;u=c[m>>2]|0;c[b>>2]=e+u;e=a+344|0;j=e;k=c[j>>2]|0;g=c[j+4>>2]|0;j=b+24|0;c[j>>2]=k;c[j+4>>2]=g;j=(c[a+20>>2]|0)+(v<<3)|0;a=c[j+4>>2]|0;l=b+16|0;c[l>>2]=c[j>>2];c[l+4>>2]=a;c[b+4>>2]=t;w=e;x=m;y=u;z=k;A=g}c[x>>2]=y+t;c[f>>2]=v+1;v=Me(z|0,A|0,1,0)|0;A=w;c[A>>2]=v;c[A+4>>2]=C;d=1;return d|0}function nb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=a+24|0;e=c[d>>2]|0;if((e-b|0)>(c[a+28>>2]|0)){f=0;return f|0}if((e|0)>(2147483647-b|0)){g=c[a>>2]|0;if(g)ze(g);g=c[a+16>>2]|0;if(g)ze(g);g=c[a+20>>2]|0;if(g)ze(g);He(a|0,0,360)|0;f=-1;return f|0}g=e+b|0;b=(g|0)<2147483615?g+32|0:g;g=a+16|0;e=Be(c[g>>2]|0,b<<2)|0;if(!e){h=c[a>>2]|0;if(h)ze(h);h=c[g>>2]|0;if(h)ze(h);h=c[a+20>>2]|0;if(h)ze(h);He(a|0,0,360)|0;f=-1;return f|0}c[g>>2]=e;e=a+20|0;h=Be(c[e>>2]|0,b<<3)|0;if(h){c[e>>2]=h;c[d>>2]=b;f=0;return f|0}b=c[a>>2]|0;if(b)ze(b);b=c[g>>2]|0;if(b)ze(b);b=c[e>>2]|0;if(b)ze(b);He(a|0,0,360)|0;f=-1;return f|0}function ob(a){a=a|0;var b=0,d=0,e=0,f=0,g=0;b=i;i=i+16|0;d=b+8|0;e=b+4|0;f=b;c[e>>2]=a;if(sc(c[e>>2]|0)|0){c[d>>2]=0;g=c[d>>2]|0;i=b;return g|0}c[f>>2]=ye(568)|0;if(!(c[f>>2]|0)){c[d>>2]=0;g=c[d>>2]|0;i=b;return g|0}c[c[f>>2]>>2]=c[e>>2];c[(c[f>>2]|0)+4>>2]=0;c[(c[f>>2]|0)+8>>2]=0;c[(c[f>>2]|0)+64>>2]=0;c[(c[f>>2]|0)+68>>2]=0;c[(c[f>>2]|0)+72>>2]=1024;c[(c[f>>2]|0)+76>>2]=0;e=_b()|0;c[(c[f>>2]|0)+80>>2]=e;do if(c[(c[f>>2]|0)+80>>2]|0){c[(c[f>>2]|0)+84>>2]=0;c[(c[f>>2]|0)+88>>2]=0;c[(c[f>>2]|0)+92>>2]=0;c[(c[f>>2]|0)+96>>2]=0;c[(c[f>>2]|0)+100>>2]=0;c[(c[f>>2]|0)+104>>2]=0;e=gc()|0;c[(c[f>>2]|0)+560>>2]=e;e=c[f>>2]|0;if(!(c[(c[f>>2]|0)+560>>2]|0)){ze(c[e+80>>2]|0);break}Eb(e)|0;c[d>>2]=c[f>>2];g=c[d>>2]|0;i=b;return g|0}while(0);ze(c[f>>2]|0);c[d>>2]=0;g=c[d>>2]|0;i=b;return g|0}function pb(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;i=i+16|0;d=b+4|0;e=b;c[e>>2]=a;if(!(c[e>>2]|0)){c[d>>2]=-2;f=c[d>>2]|0;i=b;return f|0}Fb(c[e>>2]|0)|0;dc(c[(c[e>>2]|0)+80>>2]|0,1)|0;$b(c[(c[e>>2]|0)+80>>2]|0);lc(c[(c[e>>2]|0)+560>>2]|0,2)|0;hc(c[(c[e>>2]|0)+560>>2]|0);if(c[(c[e>>2]|0)+96>>2]|0)ze(c[(c[e>>2]|0)+92>>2]|0);if((c[(c[e>>2]|0)+4>>2]|0)!=0?(Aa(c[(c[e>>2]|0)+4>>2]|0)|0)==-1:0){c[d>>2]=-10;f=c[d>>2]|0;i=b;return f|0}if(c[(c[e>>2]|0)+8>>2]|0){Db(c[e>>2]|0)|0;ze(c[(c[e>>2]|0)+8>>2]|0)}ze(c[e>>2]|0);c[d>>2]=0;f=c[d>>2]|0;i=b;return f|0}function qb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;b=i;i=i+16|0;d=b;e=b+12|0;f=b+8|0;c[e>>2]=a;do if(c[e>>2]|0)if(c[c[e>>2]>>2]&1){a=d;c[a>>2]=-3;c[a+4>>2]=-1;break}else{c[f>>2]=(c[e>>2]|0)+112;a=(c[f>>2]|0)+416|0;g=c[a+4>>2]|0;h=d;c[h>>2]=c[a>>2];c[h+4>>2]=g;break}else{g=d;c[g>>2]=-2;c[g+4>>2]=-1}while(0);f=d;C=c[f+4>>2]|0;i=b;return c[f>>2]|0}function rb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0;b=i;i=i+16|0;d=b;e=b+8|0;c[e>>2]=a;do if(c[e>>2]|0)if(c[c[e>>2]>>2]&1){a=d;c[a>>2]=-3;c[a+4>>2]=-1;break}else{a=(c[e>>2]|0)+112+424|0;f=c[a+4>>2]|0;g=d;c[g>>2]=c[a>>2];c[g+4>>2]=f;break}else{f=d;c[f>>2]=-2;c[f+4>>2]=-1}while(0);e=d;C=c[e+4>>2]|0;i=b;return c[e>>2]|0}function sb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[f>>2]=a;c[g>>2]=b;if((c[g>>2]|0)==-1){c[e>>2]=0;h=c[e>>2]|0;i=d;return h|0}else{c[e>>2]=cc(c[(c[f>>2]|0)+80>>2]|0,1,c[g>>2]|0)|0;h=c[e>>2]|0;i=d;return h|0}return 0}function tb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;c[h>>2]=ye(512)|0;if(!(c[h>>2]|0)){c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}cb(c[h>>2]|0,c[g>>2]|0)|0;g=(yb(c[h>>2]|0)|0)==-1;b=c[h>>2]|0;if(g){ze(b);c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}else{c[b+360>>2]=15;c[(c[h>>2]|0)+364>>2]=3;c[(c[h>>2]|0)+368>>2]=0;b=(c[h>>2]|0)+376|0;c[b>>2]=1;c[b+4>>2]=0;b=(c[h>>2]|0)+384|0;c[b>>2]=1;c[b+4>>2]=0;b=(c[h>>2]|0)+392|0;c[b>>2]=0;c[b+4>>2]=0;b=(c[h>>2]|0)+400|0;c[b>>2]=0;c[b+4>>2]=0;c[(c[h>>2]|0)+408>>2]=0;c[(c[h>>2]|0)+420>>2]=0;c[(c[h>>2]|0)+424>>2]=1;c[(c[h>>2]|0)+428>>2]=0;b=(c[h>>2]|0)+432|0;c[b>>2]=0;c[b+4>>2]=0;b=(c[h>>2]|0)+440|0;c[b>>2]=-1;c[b+4>>2]=-1;c[(c[h>>2]|0)+448>>2]=0;c[(c[h>>2]|0)+452>>2]=0;c[(c[h>>2]|0)+456>>2]=0;c[(c[h>>2]|0)+460>>2]=0;c[(c[h>>2]|0)+464>>2]=0;c[(c[h>>2]|0)+468>>2]=0;c[(c[h>>2]|0)+472>>2]=0;c[(c[h>>2]|0)+476>>2]=0;c[(c[h>>2]|0)+480>>2]=0;c[(c[h>>2]|0)+504>>2]=0;ec(c[(c[f>>2]|0)+80>>2]|0,c[h>>2]|0)|0;c[e>>2]=c[h>>2];j=c[e>>2]|0;i=d;return j|0}return 0}function ub(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=i;i=i+32|0;h=g+8|0;j=g+16|0;k=g+20|0;l=g+24|0;m=g+4|0;n=g;o=g+12|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;if(!(c[j>>2]|0)){c[h>>2]=-2;p=c[h>>2]|0;i=g;return p|0}f=c[j>>2]|0;if((c[k>>2]|0)==-1){if((c[f+96>>2]|0)!=0?(c[(c[j>>2]|0)+92>>2]|0)!=0:0)ze(c[(c[j>>2]|0)+92>>2]|0);c[(c[j>>2]|0)+88>>2]=c[l>>2];c[(c[j>>2]|0)+92>>2]=c[m>>2];c[(c[j>>2]|0)+96>>2]=c[n>>2]}else{c[o>>2]=sb(f,c[k>>2]|0)|0;if(!(c[o>>2]|0)){c[h>>2]=-20;p=c[h>>2]|0;i=g;return p|0}if((c[(c[o>>2]|0)+456>>2]|0)!=0?(c[(c[o>>2]|0)+452>>2]|0)!=0:0)ze(c[(c[o>>2]|0)+452>>2]|0);c[(c[o>>2]|0)+448>>2]=c[l>>2];c[(c[o>>2]|0)+452>>2]=c[m>>2];c[(c[o>>2]|0)+456>>2]=c[n>>2]}c[h>>2]=0;p=c[h>>2]|0;i=g;return p|0}function vb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;do if(!(c[(c[f>>2]|0)+88>>2]|0)){c[h>>2]=sb(c[f>>2]|0,c[g>>2]|0)|0;if(!(c[h>>2]|0)){c[e>>2]=-20;break}if(c[(c[h>>2]|0)+448>>2]|0){c[e>>2]=1;break}else{c[e>>2]=0;break}}else c[e>>2]=1;while(0);i=d;return c[e>>2]|0}function wb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;f=i;i=i+32|0;g=f+8|0;h=f+24|0;j=f+20|0;k=f;l=f+16|0;c[h>>2]=a;c[j>>2]=b;b=k;c[b>>2]=d;c[b+4>>2]=e;do if(!(c[h>>2]|0)){e=g;c[e>>2]=-2;c[e+4>>2]=-1}else{e=k;if((c[e>>2]|0)==-1?(c[e+4>>2]|0)==-1:0){e=g;c[e>>2]=-1;c[e+4>>2]=-1;break}e=c[h>>2]|0;if((c[j>>2]|0)==-1){if(c[e+88>>2]|0){b=k;d=Qa[c[(c[h>>2]|0)+88>>2]&31](c[h>>2]|0,c[j>>2]|0,c[b>>2]|0,c[b+4>>2]|0,c[(c[h>>2]|0)+92>>2]|0)|0;b=g;c[b>>2]=d;c[b+4>>2]=C;break}}else{c[l>>2]=sb(e,c[j>>2]|0)|0;if(!(c[l>>2]|0)){e=g;c[e>>2]=-1;c[e+4>>2]=-1;break}if(c[(c[l>>2]|0)+448>>2]|0){e=k;b=Qa[c[(c[l>>2]|0)+448>>2]&31](c[h>>2]|0,c[j>>2]|0,c[e>>2]|0,c[e+4>>2]|0,c[(c[l>>2]|0)+452>>2]|0)|0;e=g;c[e>>2]=b;c[e+4>>2]=C;break}if(c[(c[h>>2]|0)+88>>2]|0){e=k;b=Qa[c[(c[h>>2]|0)+88>>2]&31](c[h>>2]|0,c[j>>2]|0,c[e>>2]|0,c[e+4>>2]|0,c[(c[h>>2]|0)+92>>2]|0)|0;e=g;c[e>>2]=b;c[e+4>>2]=C;break}}e=g;c[e>>2]=-1;c[e+4>>2]=-1}while(0);h=g;C=c[h+4>>2]|0;i=f;return c[h>>2]|0}function xb(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[e>>2]=a;a=c[e>>2]|0;if((a|0)==1)c[d>>2]=-14;else if((a|0)==-1)c[d>>2]=-15;else if(!a)c[d>>2]=0;else c[d>>2]=c[e>>2];i=b;return c[d>>2]|0}function yb(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;i=i+16|0;d=b+4|0;e=b;c[e>>2]=a;c[(c[e>>2]|0)+412>>2]=0;a=_b()|0;c[(c[e>>2]|0)+416>>2]=a;if(!(c[(c[e>>2]|0)+416>>2]|0)){c[d>>2]=-1;f=c[d>>2]|0;i=b;return f|0}else{fc(c[(c[e>>2]|0)+416>>2]|0,1,0)|0;c[d>>2]=0;f=c[d>>2]|0;i=b;return f|0}return 0}function zb(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;i=i+16|0;d=b;c[d>>2]=a;dc(c[(c[d>>2]|0)+416>>2]|0,1)|0;$b(c[(c[d>>2]|0)+416>>2]|0);c[(c[d>>2]|0)+416>>2]=0;if(!(c[(c[d>>2]|0)+412>>2]|0)){e=c[d>>2]|0;f=e+412|0;c[f>>2]=0;i=b;return 0}ze(c[(c[d>>2]|0)+412>>2]|0);e=c[d>>2]|0;f=e+412|0;c[f>>2]=0;i=b;return 0}function Ab(b,d,e,f){b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;g=i;i=i+64|0;h=g+52|0;j=g+44|0;k=g+24|0;l=g+20|0;m=g+12|0;n=g+40|0;o=g+48|0;p=g+56|0;q=g+28|0;r=g+8|0;s=g+4|0;t=g+32|0;u=g;v=g+16|0;w=g+36|0;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=f;c[o>>2]=c[l>>2];c[w>>2]=0;if((c[m>>2]|0)<8){c[h>>2]=-1;x=c[h>>2]|0;i=g;return x|0}c[t>>2]=(c[o>>2]|0)+(c[m>>2]|0);c[s>>2]=a[(c[o>>2]|0)+3>>0]<<24&-16777216|a[(c[o>>2]|0)+2>>0]<<16&16711680|a[(c[o>>2]|0)+1>>0]<<8&65280|a[c[o>>2]>>0]&255;c[o>>2]=(c[o>>2]|0)+4;if((c[s>>2]|0)>>>0>((c[t>>2]|0)-(c[o>>2]|0)|0)>>>0){c[h>>2]=-1;x=c[h>>2]|0;i=g;return x|0}c[n>>2]=sb(c[j>>2]|0,c[k>>2]|0)|0;if(!(c[n>>2]|0)){c[h>>2]=-20;x=c[h>>2]|0;i=g;return x|0}if((c[s>>2]|0)>>>0>0){m=yc(c[o>>2]|0,c[s>>2]|0)|0;c[w>>2]=m;if(!m){c[h>>2]=-18;x=c[h>>2]|0;i=g;return x|0}m=(zc(c[j>>2]|0,c[k>>2]|0,c[w>>2]|0)|0)==-18;ze(c[w>>2]|0);if(m){c[h>>2]=-18;x=c[h>>2]|0;i=g;return x|0}}c[o>>2]=(c[o>>2]|0)+(c[s>>2]|0);if(((c[o>>2]|0)+4|0)>>>0>(c[t>>2]|0)>>>0){c[h>>2]=-1;x=c[h>>2]|0;i=g;return x|0}c[q>>2]=a[(c[o>>2]|0)+3>>0]<<24&-16777216|a[(c[o>>2]|0)+2>>0]<<16&16711680|a[(c[o>>2]|0)+1>>0]<<8&65280|a[c[o>>2]>>0]&255;c[o>>2]=(c[o>>2]|0)+4;c[p>>2]=0;while(1){if((c[p>>2]|0)>=(c[q>>2]|0)){y=34;break}if(((c[o>>2]|0)+4|0)>>>0>(c[t>>2]|0)>>>0){y=17;break}c[s>>2]=a[(c[o>>2]|0)+3>>0]<<24&-16777216|a[(c[o>>2]|0)+2>>0]<<16&16711680|a[(c[o>>2]|0)+1>>0]<<8&65280|a[c[o>>2]>>0]&255;c[o>>2]=(c[o>>2]|0)+4;if((c[s>>2]|0)>>>0>((c[t>>2]|0)-(c[o>>2]|0)|0)>>>0){y=19;break}c[r>>2]=0;c[u>>2]=c[o>>2];c[v>>2]=Ac(c[o>>2]|0,61,c[s>>2]|0)|0;if(c[v>>2]|0){a[c[v>>2]>>0]=0;c[v>>2]=(c[v>>2]|0)+1;c[r>>2]=(c[o>>2]|0)+(c[s>>2]|0)-(c[v>>2]|0)}if(c[r>>2]|0){m=yc(c[v>>2]|0,c[r>>2]|0)|0;c[w>>2]=m;if(!m){y=24;break}m=(Bc(c[n>>2]|0,c[u>>2]|0,c[w>>2]|0)|0)==0;ze(c[w>>2]|0);if(m){y=26;break}}else{m=yc(c[u>>2]|0,c[s>>2]|0)|0;c[w>>2]=m;if(!m){y=28;break}m=(Bc(c[n>>2]|0,c[w>>2]|0,0)|0)==0;ze(c[w>>2]|0);if(m){y=30;break}}if(c[v>>2]|0)a[(c[v>>2]|0)+-1>>0]=61;c[o>>2]=(c[o>>2]|0)+(c[s>>2]|0);c[p>>2]=(c[p>>2]|0)+1}if((y|0)==17){c[h>>2]=-1;x=c[h>>2]|0;i=g;return x|0}else if((y|0)==19){c[h>>2]=-1;x=c[h>>2]|0;i=g;return x|0}else if((y|0)==24){c[h>>2]=-18;x=c[h>>2]|0;i=g;return x|0}else if((y|0)==26){c[h>>2]=-18;x=c[h>>2]|0;i=g;return x|0}else if((y|0)==28){c[h>>2]=-18;x=c[h>>2]|0;i=g;return x|0}else if((y|0)==30){c[h>>2]=-18;x=c[h>>2]|0;i=g;return x|0}else if((y|0)==34){c[h>>2]=0;x=c[h>>2]|0;i=g;return x|0}return 0}function Bb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;d=c[g>>2]|0;do if(c[(c[g>>2]|0)+4>>2]|0)if((ya(c[d+4>>2]|0,c[h>>2]|0,c[j>>2]|0)|0)==-1)c[f>>2]=-10;else l=10;else{b=c[d+8>>2]|0;c[k>>2]=b;if(!b){c[f>>2]=-3;break}if(!(c[(c[k>>2]|0)+16>>2]|0)){c[f>>2]=-1;break}if((La[c[(c[k>>2]|0)+16>>2]&1](c[(c[k>>2]|0)+20>>2]|0,c[h>>2]|0,c[j>>2]|0)|0)==-1)c[f>>2]=-1;else l=10}while(0);if((l|0)==10)c[f>>2]=0;i=e;return c[f>>2]|0}function Cb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0;b=i;i=i+16|0;d=b+12|0;e=b+8|0;f=b+4|0;g=b;c[e>>2]=a;a=c[e>>2]|0;do if(c[(c[e>>2]|0)+4>>2]|0){h=Ca(c[a+4>>2]|0)|0;c[g>>2]=h;if((h|0)==-1)c[d>>2]=-1;else j=10}else{h=c[a+8>>2]|0;c[f>>2]=h;if(!h){c[d>>2]=-3;break}if(!(c[(c[f>>2]|0)+24>>2]|0)){c[d>>2]=-1;break}h=Na[c[(c[f>>2]|0)+24>>2]&7](c[(c[f>>2]|0)+28>>2]|0)|0;c[g>>2]=h;if((h|0)==-1)c[d>>2]=-1;else j=10}while(0);if((j|0)==10)c[d>>2]=c[g>>2];i=b;return c[d>>2]|0}function Db(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;b=i;i=i+16|0;d=b+8|0;e=b+4|0;f=b;c[e>>2]=a;a=c[e>>2]|0;do if(c[(c[e>>2]|0)+4>>2]|0)if((oa(c[a+4>>2]|0)|0)==-1)c[d>>2]=-10;else g=10;else{h=c[a+8>>2]|0;c[f>>2]=h;if(!h){c[d>>2]=-3;break}if(!(c[(c[f>>2]|0)+32>>2]|0)){c[d>>2]=-3;break}if((Na[c[(c[f>>2]|0)+32>>2]&7](c[(c[f>>2]|0)+36>>2]|0)|0)==-1)c[d>>2]=-1;else g=10}while(0);if((g|0)==10)c[d>>2]=0;i=b;return c[d>>2]|0}function Eb(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=(c[d>>2]|0)+112;eb(c[e>>2]|0)|0;cb((c[e>>2]|0)+32|0,-1)|0;c[(c[e>>2]|0)+392>>2]=-1;c[(c[e>>2]|0)+396>>2]=0;c[(c[e>>2]|0)+400>>2]=0;c[(c[e>>2]|0)+404>>2]=0;c[(c[e>>2]|0)+408>>2]=0;a=(c[e>>2]|0)+416|0;c[a>>2]=0;c[a+4>>2]=0;c[(c[e>>2]|0)+432>>2]=0;c[(c[e>>2]|0)+436>>2]=0;c[(c[e>>2]|0)+440>>2]=0;i=b;return c[d>>2]|0}function Fb(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=(c[d>>2]|0)+112;db((c[e>>2]|0)+32|0)|0;fb(c[e>>2]|0)|0;i=b;return c[d>>2]|0}function Gb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;f=i;i=i+32|0;g=f+8|0;h=f+16|0;j=f+20|0;k=f+24|0;l=f+4|0;m=f;n=f+12|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;if(!(c[h>>2]|0)){c[g>>2]=-2;o=c[g>>2]|0;i=f;return o|0}c[m>>2]=(c[h>>2]|0)+112;if(c[c[h>>2]>>2]&1){c[g>>2]=-3;o=c[g>>2]|0;i=f;return o|0}do if((c[j>>2]|0)==-1){c[(c[m>>2]|0)+396>>2]=c[k>>2];c[(c[m>>2]|0)+400>>2]=c[l>>2]}else{c[n>>2]=sb(c[h>>2]|0,c[j>>2]|0)|0;if(!(c[n>>2]|0))c[n>>2]=tb(c[h>>2]|0,c[j>>2]|0)|0;if(c[n>>2]|0){c[(c[n>>2]|0)+468>>2]=c[k>>2];c[(c[n>>2]|0)+472>>2]=c[l>>2];break}c[g>>2]=-18;o=c[g>>2]|0;i=f;return o|0}while(0);c[g>>2]=0;o=c[g>>2]|0;i=f;return o|0}function Hb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;g=i;i=i+32|0;h=g+4|0;j=g+16|0;k=g+8|0;l=g+20|0;m=g+28|0;n=g;o=g+12|0;p=g+24|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[n>>2]=f;c[p>>2]=c[k>>2];f=ye(72)|0;c[o>>2]=f;if(!f){c[h>>2]=0;q=c[h>>2]|0;i=g;return q|0}f=c[o>>2]|0;e=c[k>>2]|0;k=f+56|0;do{c[f>>2]=c[e>>2];f=f+4|0;e=e+4|0}while((f|0)<(k|0));e=ye(c[(c[p>>2]|0)+4>>2]|0)|0;c[c[o>>2]>>2]=e;f=c[o>>2]|0;if(!e){ze(f);c[h>>2]=0;q=c[h>>2]|0;i=g;return q|0}else{Ke(c[f>>2]|0,c[c[p>>2]>>2]|0,c[(c[p>>2]|0)+4>>2]|0)|0;c[(c[o>>2]|0)+56>>2]=c[m>>2];c[(c[o>>2]|0)+68>>2]=c[l>>2];c[(c[o>>2]|0)+60>>2]=c[n>>2];c[(c[o>>2]|0)+64>>2]=c[j>>2];c[h>>2]=c[o>>2];q=c[h>>2]|0;i=g;return q|0}return 0}function Ib(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;ze(c[c[d>>2]>>2]|0);ze(c[d>>2]|0);i=b;return}function Jb(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=c[d>>2];Ib(c[e>>2]|0);i=b;return 1}function Kb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;b=i;i=i+16|0;d=b+12|0;e=b+8|0;f=b+4|0;g=b;c[e>>2]=a;c[f>>2]=c[e>>2];e=(c[f>>2]|0)+32|0;do if(((c[e>>2]|0)==-1?(c[e+4>>2]|0)==-1:0)?(a=(c[(c[f>>2]|0)+56>>2]|0)+488|0,(c[a>>2]|0)!=-1?1:(c[a+4>>2]|0)!=-1):0){c[g>>2]=Xb(c[(c[f>>2]|0)+64>>2]|0,c[(c[f>>2]|0)+68>>2]|0)|0;if(!((c[g>>2]|0)<0|(c[g>>2]|0)>=15)){a=(c[(c[f>>2]|0)+56>>2]|0)+488|0;h=Ub(c[g>>2]|0,c[a>>2]|0,c[a+4>>2]|0,c[(c[f>>2]|0)+56>>2]|0,c[f>>2]|0,c[(c[(c[f>>2]|0)+56>>2]|0)+508>>2]|0)|0;a=(c[f>>2]|0)+32|0;c[a>>2]=h;c[a+4>>2]=C;a=(c[f>>2]|0)+32|0;h=c[a+4>>2]|0;j=(c[(c[f>>2]|0)+56>>2]|0)+488|0;c[j>>2]=c[a>>2];c[j+4>>2]=h;c[(c[(c[f>>2]|0)+56>>2]|0)+508>>2]=c[f>>2];break}c[d>>2]=0;k=c[d>>2]|0;i=b;return k|0}while(0);c[d>>2]=1;k=c[d>>2]|0;i=b;return k|0}function Lb(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;b=i;i=i+32|0;d=b+28|0;e=b+24|0;f=b+20|0;g=b+8|0;h=b;j=b+16|0;c[e>>2]=a;c[f>>2]=c[e>>2];e=(c[f>>2]|0)+32|0;if((c[e>>2]|0)==-1?(c[e+4>>2]|0)==-1:0){c[d>>2]=0;k=c[d>>2]|0;i=b;return k|0}e=(c[(c[f>>2]|0)+60>>2]|0)+424|0;a=c[e+4>>2]|0;l=g;c[l>>2]=c[e>>2];c[l+4>>2]=a;a=(c[(c[f>>2]|0)+60>>2]|0)+416|0;l=c[a+4>>2]|0;e=h;c[e>>2]=c[a>>2];c[e+4>>2]=l;l=(c[f>>2]|0)+32|0;e=c[l+4>>2]|0;a=(c[(c[f>>2]|0)+60>>2]|0)+424|0;c[a>>2]=c[l>>2];c[a+4>>2]=e;e=(c[f>>2]|0)+32|0;a=wb(c[(c[f>>2]|0)+64>>2]|0,c[(c[f>>2]|0)+68>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;e=(c[(c[f>>2]|0)+60>>2]|0)+416|0;c[e>>2]=a;c[e+4>>2]=C;e=c[f>>2]|0;if(c[(c[(c[f>>2]|0)+56>>2]|0)+468>>2]|0){a=Oa[c[(c[e+56>>2]|0)+468>>2]&15](c[(c[f>>2]|0)+64>>2]|0,c[f>>2]|0,c[(c[f>>2]|0)+68>>2]|0,c[(c[(c[f>>2]|0)+56>>2]|0)+472>>2]|0)|0;c[j>>2]=a;if((a|0)<0?(c[(c[(c[f>>2]|0)+64>>2]|0)+76>>2]=c[j>>2],(c[j>>2]|0)==-1):0){c[d>>2]=-1;k=c[d>>2]|0;i=b;return k|0}}else if(((c[(c[e+60>>2]|0)+396>>2]|0)!=0?(e=Oa[c[(c[(c[f>>2]|0)+60>>2]|0)+396>>2]&15](c[(c[f>>2]|0)+64>>2]|0,c[f>>2]|0,c[(c[f>>2]|0)+68>>2]|0,c[(c[(c[f>>2]|0)+60>>2]|0)+400>>2]|0)|0,c[j>>2]=e,(e|0)<0):0)?(c[(c[(c[f>>2]|0)+64>>2]|0)+76>>2]=c[j>>2],(c[j>>2]|0)==-1):0){c[d>>2]=-1;k=c[d>>2]|0;i=b;return k|0}j=g;g=c[j+4>>2]|0;e=(c[(c[f>>2]|0)+60>>2]|0)+424|0;c[e>>2]=c[j>>2];c[e+4>>2]=g;g=h;h=c[g+4>>2]|0;e=(c[(c[f>>2]|0)+60>>2]|0)+416|0;c[e>>2]=c[g>>2];c[e+4>>2]=h;Ib(c[f>>2]|0);c[d>>2]=1;k=c[d>>2]|0;i=b;return k|0}function Mb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;e=i;i=i+48|0;f=e;g=e+16|0;h=e+28|0;j=e+4|0;k=e+32|0;l=e+36|0;m=e+12|0;n=e+24|0;o=e+20|0;p=e+8|0;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[n>>2]=c[j>>2];c[o>>2]=0;c[p>>2]=0;if(!(c[g>>2]|0)){c[f>>2]=-2;q=c[f>>2]|0;i=e;return q|0}if(c[c[g>>2]>>2]&1){c[f>>2]=-3;q=c[f>>2]|0;i=e;return q|0}j=c[(c[g>>2]|0)+76>>2]|0;c[p>>2]=j;d=c[g>>2]|0;if(j){c[d+76>>2]=0;c[f>>2]=xb(c[p>>2]|0)|0;q=c[f>>2]|0;i=e;return q|0}c[k>>2]=d+112;c[p>>2]=Dc(c[g>>2]|0)|0;if((c[p>>2]|0)==-18){c[f>>2]=c[p>>2];q=c[f>>2]|0;i=e;return q|0}while(1){if(!((c[p>>2]|0)!=-1&(c[p>>2]|0)!=1&(c[n>>2]|0)>0))break;c[m>>2]=(c[n>>2]|0)<4096?c[n>>2]|0:4096;c[l>>2]=gb(c[k>>2]|0,c[m>>2]|0)|0;Ke(c[l>>2]|0,c[h>>2]|0,c[m>>2]|0)|0;hb(c[k>>2]|0,c[m>>2]|0)|0;c[h>>2]=(c[h>>2]|0)+(c[m>>2]|0);c[n>>2]=(c[n>>2]|0)-(c[m>>2]|0);c[o>>2]=(c[o>>2]|0)+(c[m>>2]|0);c[p>>2]=Dc(c[g>>2]|0)|0;if((c[p>>2]|0)==-18){r=11;break}}if((r|0)==11){c[f>>2]=c[p>>2];q=c[f>>2]|0;i=e;return q|0}if((c[p>>2]|0)==-1)Ob(c[g>>2]|0)|0;r=(c[p>>2]|0)==-404;if(c[o>>2]|0){if(r)c[p>>2]=0;c[(c[g>>2]|0)+76>>2]=c[p>>2];c[f>>2]=c[o>>2];q=c[f>>2]|0;i=e;return q|0}if(r){c[f>>2]=-14;q=c[f>>2]|0;i=e;return q|0}else{c[f>>2]=xb(c[p>>2]|0)|0;q=c[f>>2]|0;i=e;return q|0}return 0}function Nb(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=(c[d>>2]|0)+488|0;c[a>>2]=-1;c[a+4>>2]=-1;i=b;return 0}function Ob(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[e>>2]=a;do if(!(c[e>>2]|0))c[d>>2]=-2;else{if(c[c[e>>2]>>2]&1){c[d>>2]=-3;break}Ec(c[e>>2]|0);if((c[(c[e>>2]|0)+4>>2]|0)!=0?(Fc(c[e>>2]|0,c[(c[e>>2]|0)+64>>2]|0,-1,-1,0)|0)<0:0){c[d>>2]=-10;break}c[d>>2]=0}while(0);i=b;return c[d>>2]|0}function Pb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;e=i;i=i+32|0;f=e+24|0;g=e+20|0;h=e+16|0;j=e+12|0;k=e+8|0;l=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;d=l;c[d>>2]=-1;c[d+4>>2]=-1;if(!(c[g>>2]|0)){c[f>>2]=-1;m=c[f>>2]|0;i=e;return m|0}if(c[c[g>>2]>>2]&1){c[f>>2]=-1;m=c[f>>2]|0;i=e;return m|0}if((c[h>>2]|0)==0&(c[j>>2]|0)==0){d=l;c[d>>2]=0;c[d+4>>2]=0}c[k>>2]=(c[g>>2]|0)+112;if(!((c[h>>2]|0)==0&(c[j>>2]|0)==1)){d=(c[k>>2]|0)+416|0;c[d>>2]=-1;c[d+4>>2]=-1}d=l;c[f>>2]=Fc(c[g>>2]|0,c[h>>2]|0,c[d>>2]|0,c[d+4>>2]|0,c[j>>2]|0)|0;m=c[f>>2]|0;i=e;return m|0}function Qb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;d=Hc(c[f>>2]|0,c[h>>2]|0,c[(c[g>>2]|0)+8>>2]|0,c[(c[g>>2]|0)+12>>2]|0)|0;i=e;return d|0}function Rb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f+8|0;l=f+4|0;m=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=0;c[m>>2]=Xb(c[h>>2]|0,c[k>>2]|0)|0;if((c[m>>2]|0)<0|(c[m>>2]|0)>=15){c[g>>2]=0;n=c[g>>2]|0;i=f;return n|0}if((c[m>>2]|0)==6?($a(c[j>>2]|0)|0)==0:0){c[g>>2]=Ic(c[h>>2]|0,c[k>>2]|0,c[(c[j>>2]|0)+8>>2]|0,c[(c[j>>2]|0)+12>>2]|0,c[l>>2]|0)|0;n=c[g>>2]|0;i=f;return n|0}c[g>>2]=Qa[c[1040+((c[m>>2]|0)*24|0)+12>>2]&31](c[h>>2]|0,c[k>>2]|0,c[(c[j>>2]|0)+8>>2]|0,c[(c[j>>2]|0)+12>>2]|0,c[l>>2]|0)|0;n=c[g>>2]|0;i=f;return n|0}function Sb(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f+8|0;l=f+4|0;m=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=0;c[m>>2]=Xb(c[h>>2]|0,c[k>>2]|0)|0;if((c[m>>2]|0)<0|(c[m>>2]|0)>=15){c[g>>2]=0;n=c[g>>2]|0;i=f;return n|0}if((c[m>>2]|0)==6?(c[(c[j>>2]|0)+8>>2]|0)==0:0){c[g>>2]=Ic(c[h>>2]|0,c[k>>2]|0,c[c[j>>2]>>2]|0,c[(c[j>>2]|0)+4>>2]|0,c[l>>2]|0)|0;n=c[g>>2]|0;i=f;return n|0}c[g>>2]=Qa[c[1040+((c[m>>2]|0)*24|0)+12>>2]&31](c[h>>2]|0,c[k>>2]|0,c[c[j>>2]>>2]|0,c[(c[j>>2]|0)+4>>2]|0,c[l>>2]|0)|0;n=c[g>>2]|0;i=f;return n|0}function Tb(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;g=i;i=i+48|0;h=g+16|0;j=g+32|0;k=g+8|0;l=g+28|0;m=g+24|0;n=g;c[j>>2]=a;a=k;c[a>>2]=b;c[a+4>>2]=d;c[l>>2]=e;c[m>>2]=f;if(c[1040+((c[j>>2]|0)*24|0)+16>>2]|0){f=k;e=Oa[c[1040+((c[j>>2]|0)*24|0)+16>>2]&15](c[f>>2]|0,c[f+4>>2]|0,c[l>>2]|0,c[m>>2]|0)|0;m=n;c[m>>2]=e;c[m+4>>2]=C;m=n;n=c[m+4>>2]|0;e=h;c[e>>2]=c[m>>2];c[e+4>>2]=n;o=h;p=o;q=c[p>>2]|0;r=o+4|0;s=r;t=c[s>>2]|0;C=t;i=g;return q|0}else{n=k;k=c[n+4>>2]|0;e=h;c[e>>2]=c[n>>2];c[e+4>>2]=k;o=h;p=o;q=c[p>>2]|0;r=o+4|0;s=r;t=c[s>>2]|0;C=t;i=g;return q|0}return 0}function Ub(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+32|0;j=h+8|0;k=h+28|0;l=h;m=h+24|0;n=h+20|0;o=h+16|0;c[k>>2]=a;a=l;c[a>>2]=b;c[a+4>>2]=d;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;if(c[1040+((c[k>>2]|0)*24|0)+20>>2]|0){g=l;l=Qa[c[1040+((c[k>>2]|0)*24|0)+20>>2]&31](c[g>>2]|0,c[g+4>>2]|0,c[m>>2]|0,c[n>>2]|0,c[o>>2]|0)|0;o=j;c[o>>2]=l;c[o+4>>2]=C;p=j;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=h;return r|0}else{o=j;c[o>>2]=0;c[o+4>>2]=0;p=j;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=h;return r|0}return 0}function Vb(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0;g=i;i=i+32|0;h=g+20|0;j=g+16|0;k=g+12|0;l=g+8|0;m=g+4|0;n=g;c[h>>2]=a;c[j>>2]=b;c[k>>2]=e;c[l>>2]=f;c[m>>2]=-1;c[n>>2]=-1;switch(c[(c[j>>2]|0)+360>>2]|0){case 3:case 2:{c[m>>2]=0;break}case 14:{if((c[(c[l>>2]|0)+4>>2]|0)>7?(ve(c[c[l>>2]>>2]|0,1472,7)|0)==0:0)c[m>>2]=7;break}case 8:{if((c[(c[l>>2]|0)+4>>2]|0)>4?((d[c[c[l>>2]>>2]>>0]|0)&7|0)==4:0){c[n>>2]=((d[(c[c[l>>2]>>2]|0)+1>>0]|0)<<16)+((d[(c[c[l>>2]>>2]|0)+2>>0]|0)<<8)+(d[(c[c[l>>2]>>2]|0)+3>>0]|0);c[m>>2]=4}break}case 11:{if((c[(c[l>>2]|0)+4>>2]|0)>9?(ve(c[c[l>>2]>>2]|0,1440,8)|0)==0:0)c[m>>2]=9;break}case 0:{if((c[(c[l>>2]|0)+4>>2]|0)>7?(ve(c[c[l>>2]>>2]|0,1432,7)|0)==0:0)c[m>>2]=7;break}case 13:{if((c[(c[l>>2]|0)+4>>2]|0)>8?(ve(c[c[l>>2]>>2]|0,1456,8)|0)==0:0)c[m>>2]=8;break}case 1:{if((c[(c[l>>2]|0)+4>>2]|0)>7?(ve(c[c[l>>2]>>2]|0,1424,7)|0)==0:0)c[m>>2]=7;break}default:{}}if((c[n>>2]|0)==-1)c[n>>2]=(c[(c[l>>2]|0)+4>>2]|0)-(c[m>>2]|0);if((c[m>>2]|0)<0){i=g;return 0}Ab(c[h>>2]|0,c[k>>2]|0,(c[c[l>>2]>>2]|0)+(c[m>>2]|0)|0,c[n>>2]|0)|0;i=g;return 0}function Wb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=sb(c[g>>2]|0,c[h>>2]|0)|0;if(!(c[k>>2]|0)){c[f>>2]=-20;l=c[f>>2]|0;i=e;return l|0}else{c[(c[k>>2]|0)+360>>2]=c[j>>2];c[f>>2]=0;l=c[f>>2]|0;i=e;return l|0}return 0}function Xb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;do if(c[f>>2]|0){c[h>>2]=sb(c[f>>2]|0,c[g>>2]|0)|0;if(!(c[h>>2]|0)){c[e>>2]=-20;break}else{c[e>>2]=c[(c[h>>2]|0)+360>>2];break}}else c[e>>2]=-2;while(0);i=d;return c[e>>2]|0}function Yb(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;do if(c[f>>2]|0){c[h>>2]=sb(c[f>>2]|0,c[g>>2]|0)|0;if(!(c[h>>2]|0)){c[e>>2]=-20;break}else{c[e>>2]=c[(c[h>>2]|0)+364>>2];break}}else c[e>>2]=-2;while(0);i=d;return c[e>>2]|0}function Zb(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;if(!(c[g>>2]|0)){c[f>>2]=-2;l=c[f>>2]|0;i=e;return l|0}c[k>>2]=sb(c[g>>2]|0,c[h>>2]|0)|0;if(!(c[k>>2]|0)){c[f>>2]=-20;l=c[f>>2]|0;i=e;return l|0}else{c[(c[k>>2]|0)+368>>2]=c[j>>2];c[f>>2]=0;l=c[f>>2]|0;i=e;return l|0}return 0}function _b(){var a=0,b=0,d=0,e=0;a=i;i=i+16|0;b=a+4|0;d=a;c[d>>2]=ye(20)|0;if(!(c[d>>2]|0)){c[b>>2]=0;e=c[b>>2]|0;i=a;return e|0}else{c[c[d>>2]>>2]=0;c[(c[d>>2]|0)+4>>2]=0;c[(c[d>>2]|0)+8>>2]=0;c[(c[d>>2]|0)+12>>2]=0;c[(c[d>>2]|0)+16>>2]=0;c[b>>2]=c[d>>2];e=c[b>>2]|0;i=a;return e|0}return 0}function $b(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;Jc(c[d>>2]|0);ze(c[d>>2]|0);i=b;return}function ac(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[e>>2]=a;if(!(c[e>>2]|0))c[d>>2]=0;else c[d>>2]=c[(c[e>>2]|0)+4>>2];i=b;return c[d>>2]|0}function bc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[f>>2]=a;c[g>>2]=b;do if(c[f>>2]|0)if((c[g>>2]|0)>=(c[(c[f>>2]|0)+4>>2]|0)){c[e>>2]=0;break}else{c[e>>2]=c[(c[(c[f>>2]|0)+8>>2]|0)+(c[g>>2]<<2)>>2];break}else c[e>>2]=0;while(0);i=d;return c[e>>2]|0}function cc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[l>>2]=0;while(1){if((c[l>>2]|0)>=(c[(c[g>>2]|0)+4>>2]|0)){m=6;break}c[k>>2]=c[(c[(c[g>>2]|0)+8>>2]|0)+(c[l>>2]<<2)>>2];if(Pa[c[h>>2]&1](c[k>>2]|0,c[j>>2]|0)|0){m=4;break}c[l>>2]=(c[l>>2]|0)+1}if((m|0)==4){c[f>>2]=c[k>>2];n=c[f>>2]|0;i=e;return n|0}else if((m|0)==6){c[f>>2]=0;n=c[f>>2]|0;i=e;return n|0}return 0}function dc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[e>>2]=a;c[f>>2]=b;c[g>>2]=0;while(1){if((c[g>>2]|0)>=(c[(c[e>>2]|0)+4>>2]|0))break;Na[c[f>>2]&7](c[(c[(c[e>>2]|0)+8>>2]|0)+(c[g>>2]<<2)>>2]|0)|0;c[g>>2]=(c[g>>2]|0)+1}i=d;return 0}function ec(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[f>>2]=a;c[g>>2]=b;if(!(Kc(c[f>>2]|0)|0)){c[e>>2]=0;h=c[e>>2]|0;i=d;return h|0}else{c[(c[(c[f>>2]|0)+8>>2]|0)+((c[(c[f>>2]|0)+4>>2]|0)-1<<2)>>2]=c[g>>2];Lc(c[f>>2]|0);c[e>>2]=c[g>>2];h=c[e>>2]|0;i=d;return h|0}return 0}function fc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[(c[f>>2]|0)+12>>2]=c[g>>2];c[(c[f>>2]|0)+16>>2]=c[h>>2];if(!(c[g>>2]|0)){i=e;return 0}Mc(c[f>>2]|0,0,(c[(c[f>>2]|0)+4>>2]|0)-1|0);i=e;return 0}function gc(){var a=0,b=0,d=0,e=0,f=0,g=0;a=i;i=i+16|0;b=a+12|0;d=a+8|0;e=a+4|0;f=a;c[d>>2]=ye(8)|0;if(!(c[d>>2]|0)){c[b>>2]=0;g=c[b>>2]|0;i=a;return g|0}c[e>>2]=ye(12)|0;if(!(c[e>>2]|0)){ze(c[d>>2]|0);c[b>>2]=0;g=c[b>>2]|0;i=a;return g|0}c[f>>2]=ye(12)|0;if(!(c[f>>2]|0)){ze(c[e>>2]|0);ze(c[d>>2]|0);c[b>>2]=0;g=c[b>>2]|0;i=a;return g|0}else{c[c[e>>2]>>2]=c[f>>2];c[(c[e>>2]|0)+4>>2]=0;c[(c[f>>2]|0)+4>>2]=c[e>>2];c[c[f>>2]>>2]=0;c[c[d>>2]>>2]=c[e>>2];c[(c[d>>2]|0)+4>>2]=c[f>>2];c[b>>2]=c[d>>2];g=c[b>>2]|0;i=a;return g|0}return 0}function hc(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=c[c[c[d>>2]>>2]>>2];while(1){if(!(c[e>>2]|0))break;ze(c[(c[e>>2]|0)+4>>2]|0);c[e>>2]=c[c[e>>2]>>2]}ze(c[(c[d>>2]|0)+4>>2]|0);ze(c[d>>2]|0);i=b;return}function ic(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;i=b;return (c[c[c[d>>2]>>2]>>2]|0)==(c[(c[d>>2]|0)+4>>2]|0)|0}function jc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;if(!(c[f>>2]|0)){c[e>>2]=-1;j=c[e>>2]|0;i=d;return j|0}c[h>>2]=ye(12)|0;if(!(c[h>>2]|0)){c[e>>2]=-1;j=c[e>>2]|0;i=d;return j|0}else{c[(c[h>>2]|0)+8>>2]=c[g>>2];c[c[h>>2]>>2]=c[(c[f>>2]|0)+4>>2];c[(c[h>>2]|0)+4>>2]=c[(c[(c[f>>2]|0)+4>>2]|0)+4>>2];c[c[(c[h>>2]|0)+4>>2]>>2]=c[h>>2];c[(c[c[h>>2]>>2]|0)+4>>2]=c[h>>2];c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}return 0}function kc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[e>>2]=a;c[f>>2]=b;c[g>>2]=c[(c[(c[e>>2]|0)+4>>2]|0)+4>>2];while(1){if((c[g>>2]|0)==(c[c[e>>2]>>2]|0)){h=5;break}if(!(Na[c[f>>2]&7](c[(c[g>>2]|0)+8>>2]|0)|0)){h=5;break}c[g>>2]=c[(c[g>>2]|0)+4>>2]}if((h|0)==5){i=d;return}}function lc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;d=i;i=i+32|0;e=d+20|0;f=d+16|0;g=d+12|0;h=d+8|0;j=d+4|0;k=d;c[e>>2]=a;c[f>>2]=b;c[j>>2]=0;c[g>>2]=c[c[c[e>>2]>>2]>>2];while(1){if((c[g>>2]|0)==(c[(c[e>>2]|0)+4>>2]|0)){l=7;break}c[k>>2]=Na[c[f>>2]&7](c[(c[g>>2]|0)+8>>2]|0)|0;if((c[k>>2]|0)==-1)c[j>>2]=-1;if(!(c[k>>2]|0)){l=7;break}c[h>>2]=c[c[g>>2]>>2];c[c[(c[g>>2]|0)+4>>2]>>2]=c[c[g>>2]>>2];c[(c[c[g>>2]>>2]|0)+4>>2]=c[(c[g>>2]|0)+4>>2];ze(c[g>>2]|0);c[g>>2]=c[h>>2]}if((l|0)==7){i=d;return c[j>>2]|0}return 0}function mc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;if(!(c[g>>2]|0)){c[f>>2]=-2;l=c[f>>2]|0;i=e;return l|0}c[k>>2]=sb(c[g>>2]|0,c[h>>2]|0)|0;if(!(c[k>>2]|0)){c[f>>2]=-20;l=c[f>>2]|0;i=e;return l|0}else{c[(c[k>>2]|0)+408>>2]=c[j>>2];c[f>>2]=Nc(c[g>>2]|0,c[h>>2]|0)|0;l=c[f>>2]|0;i=e;return l|0}return 0}function nc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;do if(c[f>>2]|0){c[h>>2]=sb(c[f>>2]|0,c[g>>2]|0)|0;if(!(c[h>>2]|0)){c[e>>2]=-20;break}else{c[e>>2]=c[(c[h>>2]|0)+408>>2];break}}else c[e>>2]=-2;while(0);i=d;return c[e>>2]|0}function oc(a,b,d,e,f,g){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;h=i;i=i+32|0;j=h+28|0;k=h+24|0;l=h+20|0;m=h+8|0;n=h;o=h+16|0;c[k>>2]=a;c[l>>2]=b;b=m;c[b>>2]=d;c[b+4>>2]=e;e=n;c[e>>2]=f;c[e+4>>2]=g;if(!(c[k>>2]|0)){c[j>>2]=-2;p=c[j>>2]|0;i=h;return p|0}c[o>>2]=sb(c[k>>2]|0,c[l>>2]|0)|0;if(!(c[o>>2]|0)){c[j>>2]=-20;p=c[j>>2]|0;i=h;return p|0}else{g=m;m=c[g+4>>2]|0;e=(c[o>>2]|0)+376|0;c[e>>2]=c[g>>2];c[e+4>>2]=m;m=n;n=c[m+4>>2]|0;e=(c[o>>2]|0)+384|0;c[e>>2]=c[m>>2];c[e+4>>2]=n;c[j>>2]=Nc(c[k>>2]|0,c[l>>2]|0)|0;p=c[j>>2]|0;i=h;return p|0}return 0}function pc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f+8|0;l=f+4|0;m=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;if(!(c[h>>2]|0)){c[g>>2]=-2;n=c[g>>2]|0;i=f;return n|0}c[m>>2]=sb(c[h>>2]|0,c[j>>2]|0)|0;if(!(c[m>>2]|0)){c[g>>2]=-20;n=c[g>>2]|0;i=f;return n|0}else{j=(c[m>>2]|0)+376|0;h=c[j+4>>2]|0;e=c[k>>2]|0;c[e>>2]=c[j>>2];c[e+4>>2]=h;h=(c[m>>2]|0)+384|0;m=Ve(c[h>>2]|0,c[h+4>>2]|0,1e3,0)|0;h=c[l>>2]|0;c[h>>2]=m;c[h+4>>2]=C;c[g>>2]=0;n=c[g>>2]|0;i=f;return n|0}return 0}function qc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f;l=f+8|0;c[h>>2]=a;c[j>>2]=b;b=k;c[b>>2]=d;c[b+4>>2]=e;if(!(c[h>>2]|0)){c[g>>2]=-2;m=c[g>>2]|0;i=f;return m|0}c[l>>2]=sb(c[h>>2]|0,c[j>>2]|0)|0;if(!(c[l>>2]|0)){c[g>>2]=-20;m=c[g>>2]|0;i=f;return m|0}else{e=k;k=c[e+4>>2]|0;b=(c[l>>2]|0)+392|0;c[b>>2]=c[e>>2];c[b+4>>2]=k;c[g>>2]=Nc(c[h>>2]|0,c[j>>2]|0)|0;m=c[g>>2]|0;i=f;return m|0}return 0}function rc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;e=i;i=i+48|0;f=e+4|0;g=e+16|0;h=e+8|0;j=e+20|0;k=e+32|0;l=e;m=e+12|0;n=e+24|0;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;Oc(k,c[h>>2]|0,c[j>>2]|0);Pc(k,104);j=Qc(k)|0;c[c[g>>2]>>2]=j;j=Qc(k)|0;c[(c[g>>2]|0)+4>>2]=j;j=Qc(k)|0;c[(c[g>>2]|0)+8>>2]=j;j=Qc(k)|0;c[(c[g>>2]|0)+12>>2]=j;j=Qc(k)|0;c[l>>2]=j;c[(c[g>>2]|0)+20>>2]=j;if((c[l>>2]|0)>>>0>=17){c[f>>2]=-1;o=c[f>>2]|0;i=e;return o|0}c[(c[g>>2]|0)+24>>2]=c[1480+(c[l>>2]<<3)>>2];c[(c[g>>2]|0)+28>>2]=c[1480+(c[l>>2]<<3)+4>>2];if(Rc(k)|0){j=Qc(k)|0;c[(c[g>>2]|0)+24>>2]=j;j=Qc(k)|0;c[(c[g>>2]|0)+28>>2]=j}if(Rc(k)|0){j=Qc(k)|0;c[(c[g>>2]|0)+16>>2]=j}do if(Rc(k)|0){c[m>>2]=Qc(k)|0;if((c[m>>2]|0)<2){c[(c[g>>2]|0)+40>>2]=c[m>>2];break}else{c[(c[g>>2]|0)+40>>2]=0;break}}else c[(c[g>>2]|0)+40>>2]=c[1616+(c[l>>2]<<2)>>2];while(0);c[(c[g>>2]|0)+44>>2]=c[1704+(c[l>>2]<<2)>>2];c[(c[g>>2]|0)+32>>2]=c[1880+(c[1792+(c[l>>2]<<2)>>2]<<3)>>2];c[(c[g>>2]|0)+36>>2]=c[1880+(c[1792+(c[l>>2]<<2)>>2]<<3)+4>>2];if((Rc(k)|0)!=0?(c[n>>2]=Qc(k)|0,c[(c[g>>2]|0)+32>>2]=c[1880+(c[n>>2]<<3)>>2],c[(c[g>>2]|0)+36>>2]=c[1880+(c[n>>2]<<3)+4>>2],(c[n>>2]|0)==0):0){n=Qc(k)|0;c[(c[g>>2]|0)+32>>2]=n;n=Qc(k)|0;c[(c[g>>2]|0)+36>>2]=n}c[f>>2]=0;o=c[f>>2]|0;i=e;return o|0}function sc(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[e>>2]=a;if(c[e>>2]&1)c[d>>2]=-11;else c[d>>2]=0;i=b;return c[d>>2]|0}function tc(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=c[d>>2];zb(c[e>>2]|0)|0;if((c[(c[e>>2]|0)+336>>2]|0)!=-1)db(c[e>>2]|0)|0;if(c[(c[e>>2]|0)+456>>2]|0)ze(c[(c[e>>2]|0)+452>>2]|0);if(!(c[(c[e>>2]|0)+504>>2]|0)){f=c[e>>2]|0;ze(f);i=b;return 0}ze(c[(c[e>>2]|0)+504>>2]|0);f=c[e>>2]|0;ze(f);i=b;return 0}function uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[e>>2]=a;c[f>>2]=b;c[g>>2]=c[e>>2];i=d;return (c[(c[g>>2]|0)+336>>2]|0)==(c[f>>2]|0)|0}function vc(b){b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;d=i;i=i+16|0;e=d+8|0;f=d+4|0;g=d;c[f>>2]=b;if(!(c[f>>2]|0)){c[e>>2]=0;h=c[e>>2]|0;i=d;return h|0}c[g>>2]=c[f>>2];while(1){if(!(a[c[g>>2]>>0]|0)){j=10;break}if((a[c[g>>2]>>0]|0)<32){j=8;break}if((a[c[g>>2]>>0]|0)>125){j=8;break}if((a[c[g>>2]>>0]|0)==61){j=8;break}c[g>>2]=(c[g>>2]|0)+1}if((j|0)==8){c[e>>2]=0;h=c[e>>2]|0;i=d;return h|0}else if((j|0)==10){c[e>>2]=1;h=c[e>>2]|0;i=d;return h|0}return 0}function wc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;c[g>>2]=a;c[h>>2]=b;c[e>>2]=d;do if((c[g>>2]|0)!=(c[h>>2]|0)){if(!((c[g>>2]|0)!=0&(c[h>>2]|0)!=0)){c[f>>2]=0;break}if(we(c[c[g>>2]>>2]|0,c[c[h>>2]>>2]|0)|0){c[f>>2]=0;break}if(xe(c[(c[g>>2]|0)+4>>2]|0,c[(c[h>>2]|0)+4>>2]|0)|0){c[f>>2]=0;break}else{c[f>>2]=1;break}}else c[f>>2]=1;while(0);i=e;return c[f>>2]|0}function xc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;if(!(c[d>>2]|0)){i=b;return}if(c[c[d>>2]>>2]|0)ze(c[c[d>>2]>>2]|0);if(c[(c[d>>2]|0)+4>>2]|0)ze(c[(c[d>>2]|0)+4>>2]|0);ze(c[d>>2]|0);i=b;return}function yc(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;j=e;c[g>>2]=b;c[h>>2]=d;do if(c[g>>2]|0){if(!(c[h>>2]|0)){c[f>>2]=0;break}c[h>>2]=(c[h>>2]|0)>>>0<4294967294?c[h>>2]|0:-2;c[j>>2]=ye((c[h>>2]|0)+1|0)|0;if(!(c[j>>2]|0)){c[f>>2]=0;break}if(!(Le(c[j>>2]|0,c[g>>2]|0,c[h>>2]|0)|0)){ze(c[j>>2]|0);c[f>>2]=0;break}else{a[(c[j>>2]|0)+(c[h>>2]|0)>>0]=0;c[f>>2]=c[j>>2];break}}else c[f>>2]=0;while(0);i=e;return c[f>>2]|0}function zc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;if(!(c[g>>2]|0)){c[f>>2]=-2;l=c[f>>2]|0;i=e;return l|0}c[k>>2]=sb(c[g>>2]|0,c[h>>2]|0)|0;if(!(c[k>>2]|0)){c[f>>2]=-20;l=c[f>>2]|0;i=e;return l|0}if(c[(c[k>>2]|0)+412>>2]|0)ze(c[(c[k>>2]|0)+412>>2]|0);h=Sc(c[j>>2]|0)|0;c[(c[k>>2]|0)+412>>2]=h;if(!h){c[f>>2]=-18;l=c[f>>2]|0;i=e;return l|0}else{c[f>>2]=0;l=c[f>>2]|0;i=e;return l|0}return 0}function Ac(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;i=i+32|0;g=f+12|0;h=f+8|0;j=f+16|0;k=f+4|0;l=f;c[h>>2]=b;a[j>>0]=d;c[k>>2]=e;c[l>>2]=0;while(1){if(!(a[c[h>>2]>>0]|0)){m=7;break}if((c[l>>2]|0)>=(c[k>>2]|0)){m=7;break}if((a[c[h>>2]>>0]|0)==(a[j>>0]|0)){m=5;break}c[l>>2]=(c[l>>2]|0)+1;c[h>>2]=(c[h>>2]|0)+1}if((m|0)==5){c[g>>2]=c[h>>2];n=c[g>>2]|0;i=f;return n|0}else if((m|0)==7){c[g>>2]=0;n=c[g>>2]|0;i=f;return n|0}return 0}function Bc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0;e=i;i=i+32|0;f=e+8|0;g=e+16|0;h=e+20|0;j=e+24|0;k=e+4|0;l=e;m=e+12|0;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[m>>2]=0;a:while(1){d=c[m>>2]|0;if((d|0)>=(ac(c[(c[g>>2]|0)+416>>2]|0)|0)){n=14;break}c[k>>2]=bc(c[(c[g>>2]|0)+416>>2]|0,c[m>>2]|0)|0;do if((c[c[k>>2]>>2]|0)!=0?(we(c[h>>2]|0,c[c[k>>2]>>2]|0)|0)==0:0){d=c[j>>2]|0;if(!(c[(c[k>>2]|0)+4>>2]|0))if(!d){n=7;break a}else break;if((d|0)!=0?(xe(c[j>>2]|0,c[(c[k>>2]|0)+4>>2]|0)|0)==0:0){n=12;break a}if((c[j>>2]|0)==0?(c[(c[k>>2]|0)+4>>2]|0)==0:0){n=12;break a}}while(0);c[m>>2]=(c[m>>2]|0)+1}if((n|0)==7){c[f>>2]=c[k>>2];o=c[f>>2]|0;i=e;return o|0}else if((n|0)==12){c[f>>2]=c[k>>2];o=c[f>>2]|0;i=e;return o|0}else if((n|0)==14){n=Tc(c[h>>2]|0,c[j>>2]|0)|0;c[l>>2]=n;if(!n){c[f>>2]=0;o=c[f>>2]|0;i=e;return o|0}else{c[f>>2]=ec(c[(c[g>>2]|0)+416>>2]|0,c[l>>2]|0)|0;o=c[f>>2]|0;i=e;return o|0}}return 0}function Cc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0;b=i;i=i+16|0;d=b+8|0;e=b+4|0;f=b;c[e>>2]=a;if(!(c[e>>2]|0)){c[d>>2]=0;g=c[d>>2]|0;i=b;return g|0}else{c[f>>2]=Je(c[e>>2]|0)|0;c[d>>2]=(c[f>>2]|0)>>>0<4294967294?c[f>>2]|0:-2;g=c[d>>2]|0;i=b;return g|0}return 0}function Dc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;b=i;i=i+160|0;d=b+120|0;e=b+124|0;f=b+112|0;g=b+88|0;h=b+108|0;j=b+116|0;k=b+100|0;l=b+96|0;m=b+16|0;n=b+136|0;o=b+128|0;p=b;q=b+84|0;r=b+104|0;s=b+92|0;t=b+8|0;u=b+80|0;v=b+72|0;c[e>>2]=a;c[f>>2]=(c[e>>2]|0)+112;c[o>>2]=0;c[j>>2]=m;c[k>>2]=m+32;a:while(1){if(c[o>>2]|0){w=75;break}b:do if((c[o>>2]|0)==0?(c[(c[f>>2]|0)+392>>2]|0)!=-1:0)do{c[l>>2]=c[(c[f>>2]|0)+392>>2];c[g>>2]=sb(c[e>>2]|0,c[l>>2]|0)|0;if((c[g>>2]|0)==0?(a=tb(c[e>>2]|0,c[l>>2]|0)|0,c[g>>2]=a,(a|0)==0):0){w=7;break a}c[h>>2]=c[g>>2];c[q>>2]=mb(c[h>>2]|0,c[j>>2]|0)|0;if((c[q>>2]|0)==-1){a=(c[g>>2]|0)+440|0;x=c[a+4>>2]|0;y=(c[(c[g>>2]|0)+364>>2]|0)-1|0;z=((y|0)<0)<<31>>31;if((x|0)<(z|0)|((x|0)==(z|0)?(c[a>>2]|0)>>>0<y>>>0:0)){w=10;break a}c[q>>2]=mb(c[h>>2]|0,c[j>>2]|0)|0;if((c[q>>2]|0)==-1){w=12;break a}c[(c[f>>2]|0)+440>>2]=1;c[(c[f>>2]|0)+436>>2]=c[(c[e>>2]|0)+64>>2];c[(c[f>>2]|0)+444>>2]=1}if((c[q>>2]|0)<=0)break b;y=(c[g>>2]|0)+440|0;a=y;z=Me(c[a>>2]|0,c[a+4>>2]|0,1,0)|0;a=y;c[a>>2]=z;c[a+4>>2]=C;a=(c[j>>2]|0)+16|0;z=c[a+4>>2]|0;y=p;c[y>>2]=c[a>>2];c[y+4>>2]=z;c[r>>2]=Xb(c[e>>2]|0,c[l>>2]|0)|0;do if(!((c[r>>2]|0)<0|(c[r>>2]|0)>=15)){if(((c[r>>2]|0)==6?1:(c[(c[g>>2]|0)+448>>2]|0)==0)?(c[c[e>>2]>>2]&32|0)!=0:0)Sb(c[e>>2]|0,c[j>>2]|0,c[l>>2]|0,0)|0;if(!(c[c[e>>2]>>2]&32)){z=p;y=c[z+4>>2]|0;a=(c[f>>2]|0)+424|0;c[a>>2]=c[z>>2];c[a+4>>2]=y;break}y=p;a=Tb(c[r>>2]|0,c[y>>2]|0,c[y+4>>2]|0,c[g>>2]|0,c[j>>2]|0)|0;y=(c[f>>2]|0)+424|0;c[y>>2]=a;c[y+4>>2]=C;y=p;if(((c[y>>2]|0)!=-1?1:(c[y+4>>2]|0)!=-1)?(y=(c[f>>2]|0)+424|0,a=c[y+4>>2]|0,z=p,x=c[z+4>>2]|0,(a|0)<(x|0)|((a|0)==(x|0)?(c[y>>2]|0)>>>0<(c[z>>2]|0)>>>0:0)):0){z=p;y=c[z+4>>2]|0;x=(c[f>>2]|0)+424|0;c[x>>2]=c[z>>2];c[x+4>>2]=y}}else{y=p;x=c[y+4>>2]|0;z=(c[f>>2]|0)+424|0;c[z>>2]=c[y>>2];c[z+4>>2]=x}while(0);x=(c[f>>2]|0)+424|0;z=c[x+4>>2]|0;y=(c[g>>2]|0)+488|0;c[y>>2]=c[x>>2];c[y+4>>2]=z;if(!((c[(c[e>>2]|0)+88>>2]|0)==0?(c[(c[g>>2]|0)+448>>2]|0)==0:0))w=27;if((w|0)==27?(w=0,z=(c[f>>2]|0)+424|0,(c[z>>2]|0)!=-1?1:(c[z+4>>2]|0)!=-1):0){z=(c[f>>2]|0)+424|0;y=wb(c[e>>2]|0,c[l>>2]|0,c[z>>2]|0,c[z+4>>2]|0)|0;z=(c[f>>2]|0)+416|0;c[z>>2]=y;c[z+4>>2]=C}z=(c[g>>2]|0)+440|0;if((c[z>>2]|0)==1&(c[z+4>>2]|0)==0)Vb(c[e>>2]|0,c[g>>2]|0,c[l>>2]|0,c[j>>2]|0)|0;z=(c[f>>2]|0)+424|0;y=c[z+4>>2]|0;x=c[k>>2]|0;c[x>>2]=c[z>>2];c[x+4>>2]=y;c[(c[k>>2]|0)+8>>2]=c[(c[f>>2]|0)+436>>2];c[(c[k>>2]|0)+12>>2]=c[(c[e>>2]|0)+64>>2];c[(c[k>>2]|0)+16>>2]=c[(c[f>>2]|0)+440>>2];c[(c[k>>2]|0)+20>>2]=c[(c[f>>2]|0)+444>>2];do if(c[c[e>>2]>>2]&32){y=(c[f>>2]|0)+424|0;x=c[e>>2]|0;if((c[y>>2]|0)==-1?(c[y+4>>2]|0)==-1:0){c[s>>2]=Hb(x,m,c[l>>2]|0,c[g>>2]|0,c[f>>2]|0)|0;jc(c[(c[e>>2]|0)+560>>2]|0,c[s>>2]|0)|0;w=45;break}if(!(ic(c[x+560>>2]|0)|0)){x=(c[g>>2]|0)+488|0;y=c[x+4>>2]|0;z=t;c[z>>2]=c[x>>2];c[z+4>>2]=y;c[(c[g>>2]|0)+508>>2]=c[j>>2];kc(c[(c[e>>2]|0)+560>>2]|0,3);c[(c[e>>2]|0)+76>>2]=0;if((lc(c[(c[e>>2]|0)+560>>2]|0,4)|0)==-1){w=36;break a}y=(c[e>>2]|0)+76|0;if((c[(c[e>>2]|0)+76>>2]|0)>0){c[o>>2]=c[y>>2];c[(c[e>>2]|0)+76>>2]=0;break}c[y>>2]=0;y=t;z=c[y+4>>2]|0;x=(c[g>>2]|0)+488|0;c[x>>2]=c[y>>2];c[x+4>>2]=z;if(!(ic(c[(c[e>>2]|0)+560>>2]|0)|0)){c[u>>2]=Hb(c[e>>2]|0,m,c[l>>2]|0,c[g>>2]|0,c[f>>2]|0)|0;jc(c[(c[e>>2]|0)+560>>2]|0,c[u>>2]|0)|0;w=45}else w=41}else w=41}else w=41;while(0);do if((w|0)==41){w=0;if(c[(c[g>>2]|0)+468>>2]|0){c[o>>2]=Oa[c[(c[g>>2]|0)+468>>2]&15](c[e>>2]|0,m,c[l>>2]|0,c[(c[g>>2]|0)+472>>2]|0)|0;w=45;break}if(c[(c[f>>2]|0)+396>>2]|0){c[o>>2]=Oa[c[(c[f>>2]|0)+396>>2]&15](c[e>>2]|0,m,c[l>>2]|0,c[(c[f>>2]|0)+400>>2]|0)|0;w=45}else w=45}while(0);if((w|0)==45){w=0;if((c[(c[f>>2]|0)+436>>2]|0)==(c[(c[e>>2]|0)+64>>2]|0)){z=(c[f>>2]|0)+444|0;c[z>>2]=(c[z>>2]|0)+1}else{c[(c[f>>2]|0)+436>>2]=c[(c[e>>2]|0)+64>>2];c[(c[f>>2]|0)+444>>2]=1}c[(c[f>>2]|0)+440>>2]=1;if(!(c[(c[j>>2]|0)+8>>2]|0))c[(c[g>>2]|0)+420>>2]=1}}while((c[o>>2]|0)==0);while(0);if((c[o>>2]|0)==1|(c[o>>2]|0)==-1|(c[o>>2]|0)==-17){w=51;break}if((Uc(c[e>>2]|0,n)|0)<0){w=53;break}c[l>>2]=bb(n)|0;c[(c[f>>2]|0)+392>>2]=c[l>>2];c[g>>2]=sb(c[e>>2]|0,c[l>>2]|0)|0;z=c[e>>2]|0;x=c[l>>2]|0;if(!(c[g>>2]|0)){y=tb(z,x)|0;c[g>>2]=y;if(!y){w=56;break}Qb(c[e>>2]|0,n,c[l>>2]|0)|0;if(c[c[e>>2]>>2]&32)Rb(c[e>>2]|0,n,c[l>>2]|0,0)|0}else if((Xb(z,x)|0)==9)Qb(c[e>>2]|0,n,c[l>>2]|0)|0;c[h>>2]=c[g>>2];x=ab(n)|0;z=v;c[z>>2]=x;c[z+4>>2]=C;z=v;x=c[z+4>>2]|0;y=(c[g>>2]|0)+496|0;c[y>>2]=c[z>>2];c[y+4>>2]=x;if(c[(c[e>>2]|0)+88>>2]|0){x=v;if((c[x>>2]|0)!=-1?1:(c[x+4>>2]|0)!=-1)w=64;else w=65}else{x=v;if((c[(c[g>>2]|0)+448>>2]|0)!=0&((c[x>>2]|0)!=-1?1:(c[x+4>>2]|0)!=-1))w=64;else w=65}if((w|0)==64){w=0;x=v;y=wb(c[e>>2]|0,c[l>>2]|0,c[x>>2]|0,c[x+4>>2]|0)|0;x=(c[f>>2]|0)+416|0;c[x>>2]=y;c[x+4>>2]=C}else if((w|0)==65?(w=0,x=v,(c[x>>2]|0)==0&(c[x+4>>2]|0)==0):0){x=(c[f>>2]|0)+416|0;c[x>>2]=0;c[x+4>>2]=0}if(!(c[(c[g>>2]|0)+476>>2]|0)){if(c[(c[f>>2]|0)+404>>2]|0)c[o>>2]=Oa[c[(c[f>>2]|0)+404>>2]&15](c[e>>2]|0,n,c[l>>2]|0,c[(c[f>>2]|0)+408>>2]|0)|0}else c[o>>2]=Oa[c[(c[g>>2]|0)+476>>2]&15](c[e>>2]|0,n,c[l>>2]|0,c[(c[g>>2]|0)+480>>2]|0)|0;jb(c[h>>2]|0,n)|0;x=(_a(n)|0)!=0;y=(c[f>>2]|0)+440|0;if(!x){c[y>>2]=1;c[(c[f>>2]|0)+436>>2]=c[(c[e>>2]|0)+64>>2];c[(c[f>>2]|0)+444>>2]=0;continue}if((c[y>>2]|0)==-1)continue;y=(c[f>>2]|0)+440|0;c[y>>2]=(c[y>>2]|0)+1}if((w|0)==7){c[d>>2]=-18;A=c[d>>2]|0;i=b;return A|0}else if((w|0)==10){c[d>>2]=-17;A=c[d>>2]|0;i=b;return A|0}else if((w|0)==12){c[d>>2]=-17;A=c[d>>2]|0;i=b;return A|0}else if((w|0)==36){c[d>>2]=-17;A=c[d>>2]|0;i=b;return A|0}else if((w|0)==51){c[d>>2]=c[o>>2];A=c[d>>2]|0;i=b;return A|0}else if((w|0)==53){c[d>>2]=-404;A=c[d>>2]|0;i=b;return A|0}else if((w|0)==56){c[d>>2]=-18;A=c[d>>2]|0;i=b;return A|0}else if((w|0)==75){c[d>>2]=c[o>>2];A=c[d>>2]|0;i=b;return A|0}return 0}function Ec(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;dc(c[(c[d>>2]|0)+80>>2]|0,5)|0;i=b;return}function Fc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0;g=i;i=i+32|0;h=g+16|0;j=g+12|0;k=g;l=g+8|0;c[h>>2]=a;c[j>>2]=b;b=k;c[b>>2]=d;c[b+4>>2]=e;c[l>>2]=f;Ec(c[h>>2]|0);f=k;k=Wc(c[h>>2]|0,c[j>>2]|0,c[f>>2]|0,c[f+4>>2]|0,c[l>>2]|0)|0;i=g;return k|0}function Gc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=(c[g>>2]|0)+112;if((Bb(c[g>>2]|0,c[h>>2]|0,c[j>>2]|0)|0)==-1){c[f>>2]=-1;m=c[f>>2]|0;i=e;return m|0}else{c[l>>2]=Cb(c[g>>2]|0)|0;c[(c[g>>2]|0)+64>>2]=c[l>>2];kb(c[k>>2]|0)|0;dc(c[(c[g>>2]|0)+80>>2]|0,6)|0;c[f>>2]=c[l>>2];m=c[f>>2]|0;i=e;return m|0}return 0}function Hc(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;f=i;i=i+32|0;g=f+8|0;h=f+16|0;j=f+20|0;k=f+24|0;l=f+4|0;m=f;n=f+12|0;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=e;c[m>>2]=0;while(1){if((c[m>>2]|0)>=15){o=7;break}c[n>>2]=1040+((c[m>>2]|0)*24|0);if((c[l>>2]|0)>=(c[(c[n>>2]|0)+4>>2]|0)?(ve(c[k>>2]|0,c[c[n>>2]>>2]|0,c[(c[n>>2]|0)+4>>2]|0)|0)==0:0){o=5;break}c[m>>2]=(c[m>>2]|0)+1}if((o|0)==5){Wb(c[h>>2]|0,c[j>>2]|0,c[m>>2]|0)|0;c[g>>2]=1;p=c[g>>2]|0;i=f;return p|0}else if((o|0)==7){Wb(c[h>>2]|0,c[j>>2]|0,15)|0;c[g>>2]=0;p=c[g>>2]|0;i=f;return p|0}return 0}function Ic(a,b,e,f,g){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;h=i;i=i+64|0;j=h+20|0;k=h+40|0;l=h+44|0;m=h+36|0;n=h+32|0;o=h+52|0;p=h+16|0;q=h;r=h+8|0;s=h+28|0;t=h+24|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=e;c[n>>2]=f;c[h+48>>2]=g;c[o>>2]=c[m>>2];m=q;c[m>>2]=0;c[m+4>>2]=0;m=r;c[m>>2]=0;c[m+4>>2]=0;if((c[n>>2]|0)<48){c[j>>2]=0;u=c[j>>2]|0;i=h;return u|0}c[p>>2]=bd((c[o>>2]|0)+12|0)|0;if(vb(c[k>>2]|0,c[p>>2]|0)|0){c[j>>2]=1;u=c[j>>2]|0;i=h;return u|0}else{n=id((c[o>>2]|0)+20|0)|0;m=q;c[m>>2]=n;c[m+4>>2]=C;m=id((c[o>>2]|0)+28|0)|0;n=r;c[n>>2]=m;c[n+4>>2]=C;c[s>>2]=d[(c[o>>2]|0)+48>>0];o=c[k>>2]|0;n=c[p>>2]|0;m=q;q=c[m>>2]|0;g=c[m+4>>2]|0;m=r;r=Ue(1e3,0,c[m>>2]|0,c[m+4>>2]|0)|0;oc(o,n,q,g,r,C)|0;mc(c[k>>2]|0,c[p>>2]|0,c[s>>2]|0)|0;c[t>>2]=Yb(c[k>>2]|0,c[l>>2]|0)|0;Zc(c[k>>2]|0,c[l>>2]|0,(c[t>>2]|0)+1|0)|0;c[j>>2]=1;u=c[j>>2]|0;i=h;return u|0}return 0}function Jc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;if(c[(c[d>>2]|0)+8>>2]|0){ze(c[(c[d>>2]|0)+8>>2]|0);c[(c[d>>2]|0)+8>>2]=0}c[(c[d>>2]|0)+4>>2]=0;c[c[d>>2]>>2]=0;i=b;return}function Kc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0;b=i;i=i+16|0;d=b+12|0;e=b+8|0;f=b+4|0;g=b;c[e>>2]=a;a=(c[e>>2]|0)+4|0;c[a>>2]=(c[a>>2]|0)+1;do if((c[(c[e>>2]|0)+4>>2]|0)>(c[c[e>>2]>>2]|0)){if(!(c[c[e>>2]>>2]|0))c[g>>2]=1;else c[g>>2]=c[c[e>>2]>>2]<<1;c[f>>2]=Be(c[(c[e>>2]|0)+8>>2]|0,c[g>>2]<<2)|0;if(c[f>>2]|0){c[c[e>>2]>>2]=c[g>>2];c[(c[e>>2]|0)+8>>2]=c[f>>2];break}a=(c[e>>2]|0)+4|0;c[a>>2]=(c[a>>2]|0)+-1;c[d>>2]=0;h=c[d>>2]|0;i=b;return h|0}while(0);c[d>>2]=c[e>>2];h=c[d>>2]|0;i=b;return h|0}function Lc(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;if(!(c[(c[d>>2]|0)+12>>2]|0)){i=b;return}c[e>>2]=(c[(c[d>>2]|0)+4>>2]|0)-1;while(1){if((c[e>>2]|0)<=0){f=6;break}if((La[c[(c[d>>2]|0)+12>>2]&1](c[(c[(c[d>>2]|0)+8>>2]|0)+((c[e>>2]|0)-1<<2)>>2]|0,c[(c[(c[d>>2]|0)+8>>2]|0)+(c[e>>2]<<2)>>2]|0,c[(c[d>>2]|0)+16>>2]|0)|0)<=0){f=6;break}Bd(c[(c[d>>2]|0)+8>>2]|0,c[e>>2]|0,(c[e>>2]|0)-1|0);c[e>>2]=(c[e>>2]|0)+-1}if((f|0)==6){i=b;return}}function Mc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[l>>2]=c[(c[f>>2]|0)+8>>2];if((c[g>>2]|0)>=(c[h>>2]|0)){i=e;return}Bd(c[l>>2]|0,c[g>>2]|0,((c[g>>2]|0)+(c[h>>2]|0)|0)/2|0);c[k>>2]=c[g>>2];c[j>>2]=(c[g>>2]|0)+1;while(1){if((c[j>>2]|0)>(c[h>>2]|0))break;if((La[c[(c[f>>2]|0)+12>>2]&1](c[(c[l>>2]|0)+(c[j>>2]<<2)>>2]|0,c[(c[l>>2]|0)+(c[g>>2]<<2)>>2]|0,c[(c[f>>2]|0)+16>>2]|0)|0)<0){d=c[l>>2]|0;b=(c[k>>2]|0)+1|0;c[k>>2]=b;Bd(d,b,c[j>>2]|0)}c[j>>2]=(c[j>>2]|0)+1}Bd(c[l>>2]|0,c[g>>2]|0,c[k>>2]|0);Mc(c[f>>2]|0,c[g>>2]|0,(c[k>>2]|0)-1|0);Mc(c[f>>2]|0,(c[k>>2]|0)+1|0,c[h>>2]|0);i=e;return}function Nc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;if(!(c[f>>2]|0)){c[e>>2]=-2;j=c[e>>2]|0;i=d;return j|0}c[h>>2]=sb(c[f>>2]|0,c[g>>2]|0)|0;if(!(c[h>>2]|0)){c[e>>2]=-20;j=c[e>>2]|0;i=d;return j|0}b=(c[h>>2]|0)+376|0;if((c[b>>2]|0)==0&(c[b+4>>2]|0)==0){b=(c[h>>2]|0)+376|0;c[b>>2]=1;c[b+4>>2]=0;b=(c[h>>2]|0)+384|0;c[b>>2]=0;c[b+4>>2]=0}b=c[f>>2]|0;a=c[g>>2]|0;if(!(c[(c[h>>2]|0)+408>>2]|0)){c[e>>2]=ub(b,a,19,0,1)|0;j=c[e>>2]|0;i=d;return j|0}h=(Xb(b,a)|0)==12;a=c[f>>2]|0;b=c[g>>2]|0;if(h){c[e>>2]=ub(a,b,20,0,1)|0;j=c[e>>2]|0;i=d;return j|0}h=(Xb(a,b)|0)==14;b=c[f>>2]|0;f=c[g>>2]|0;if(h){c[e>>2]=ub(b,f,21,0,1)|0;j=c[e>>2]|0;i=d;return j|0}else{c[e>>2]=ub(b,f,22,0,1)|0;j=c[e>>2]|0;i=d;return j|0}return 0}function Oc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[c[f>>2]>>2]=c[g>>2];c[(c[f>>2]|0)+4>>2]=c[g>>2];c[(c[f>>2]|0)+8>>2]=(c[(c[f>>2]|0)+4>>2]|0)+(c[h>>2]|0);c[(c[f>>2]|0)+12>>2]=8;i=e;return}function Pc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0;d=i;i=i+16|0;e=d+4|0;f=d;c[e>>2]=a;c[f>>2]=b;b=(c[e>>2]|0)+12|0;c[b>>2]=(c[b>>2]|0)-(c[f>>2]|0);while(1){if((c[(c[e>>2]|0)+12>>2]|0)>0)break;f=(c[e>>2]|0)+4|0;c[f>>2]=(c[f>>2]|0)+1;f=(c[e>>2]|0)+12|0;c[f>>2]=(c[f>>2]|0)+8}i=d;return}function Qc(a){a=a|0;var b=0,d=0,e=0,f=0,g=0;b=i;i=i+16|0;d=b+8|0;e=b+4|0;f=b;c[d>>2]=a;c[e>>2]=0;c[f>>2]=0;while(1){a=(Gd(c[d>>2]|0,1)|0)!=0^1;g=c[e>>2]|0;if(!a)break;c[e>>2]=g+1;c[f>>2]=c[f>>2]<<1;a=Gd(c[d>>2]|0,1)|0;c[f>>2]=c[f>>2]|a}i=b;return (1<<g)-1+(c[f>>2]|0)|0}function Rc(a){a=a|0;var b=0,d=0;b=i;i=i+16|0;d=b;c[d>>2]=a;a=Gd(c[d>>2]|0,1)|0;i=b;return a|0}function Sc(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;i=i+16|0;d=b+8|0;e=b+4|0;f=b;c[e>>2]=a;do if(c[e>>2]|0){c[f>>2]=ye((Cc(c[e>>2]|0)|0)+1|0)|0;if(!(c[f>>2]|0)){c[d>>2]=0;break}else{c[d>>2]=Oe(c[f>>2]|0,c[e>>2]|0)|0;break}}else c[d>>2]=0;while(0);i=b;return c[d>>2]|0}function Tc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;if(!(vc(c[f>>2]|0)|0)){c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}c[h>>2]=ye(8)|0;if(!(c[h>>2]|0)){c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}b=Sc(c[f>>2]|0)|0;c[c[h>>2]>>2]=b;if(!(c[c[h>>2]>>2]|0)){ze(c[h>>2]|0);c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}if(c[g>>2]|0){b=Sc(c[g>>2]|0)|0;c[(c[h>>2]|0)+4>>2]=b;if(!(c[(c[h>>2]|0)+4>>2]|0)){ze(c[c[h>>2]>>2]|0);ze(c[h>>2]|0);c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}}else c[(c[h>>2]|0)+4>>2]=0;c[e>>2]=c[h>>2];j=c[e>>2]|0;i=d;return j|0}function Uc(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;d=i;i=i+32|0;e=d+20|0;f=d+16|0;g=d+12|0;h=d+8|0;j=d+4|0;k=d;c[f>>2]=a;c[g>>2]=b;c[h>>2]=(c[f>>2]|0)+112;c[k>>2]=0;b=(c[f>>2]|0)+64|0;c[b>>2]=(c[b>>2]|0)+(c[(c[h>>2]|0)+432>>2]|0);while(1){c[j>>2]=ib(c[h>>2]|0,c[g>>2]|0)|0;if(!(c[j>>2]|0)){l=3;break}b=c[j>>2]|0;if((c[j>>2]|0)<0){a=(c[f>>2]|0)+64|0;c[a>>2]=(c[a>>2]|0)+(0-b)}else{c[(c[h>>2]|0)+432>>2]=b;c[k>>2]=1}if(!((c[k>>2]|0)!=0^1)){l=8;break}}if((l|0)==3){c[e>>2]=-2;m=c[e>>2]|0;i=d;return m|0}else if((l|0)==8){c[e>>2]=c[(c[f>>2]|0)+64>>2];m=c[e>>2]|0;i=d;return m|0}return 0}function Vc(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=c[d>>2];if((c[(c[e>>2]|0)+336>>2]|0)==-1){i=b;return 0}lb(c[e>>2]|0)|0;i=b;return 0}function Wc(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=i;i=i+32|0;h=g+28|0;j=g+20|0;k=g+24|0;l=g;m=g+16|0;n=g+12|0;o=g+8|0;c[j>>2]=a;c[k>>2]=b;b=l;c[b>>2]=d;c[b+4>>2]=e;c[m>>2]=f;c[n>>2]=(c[j>>2]|0)+112;c[o>>2]=Gc(c[j>>2]|0,c[k>>2]|0,c[m>>2]|0)|0;if((c[o>>2]|0)==-1){c[h>>2]=-1;p=c[h>>2]|0;i=g;return p|0}c[(c[j>>2]|0)+64>>2]=c[o>>2];j=l;if((c[j>>2]|0)!=-1?1:(c[j+4>>2]|0)!=-1){j=l;l=c[j+4>>2]|0;m=(c[n>>2]|0)+416|0;c[m>>2]=c[j>>2];c[m+4>>2]=l}c[h>>2]=c[o>>2];p=c[h>>2]|0;i=g;return p|0}function Xc(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;j=i;i=i+48|0;k=j+12|0;l=j+16|0;m=j+28|0;n=j+4|0;o=j+32|0;p=j+40|0;q=j+24|0;r=j+20|0;s=j+8|0;t=j+44|0;u=j;c[l>>2]=b;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[j+36>>2]=h;c[p>>2]=c[n>>2];a[t>>0]=0;if((c[o>>2]|0)<41){c[k>>2]=0;v=c[k>>2]|0;i=j;return v|0}c[q>>2]=(d[(c[p>>2]|0)+7>>0]<<16)+(d[(c[p>>2]|0)+8>>0]<<8)+(d[(c[p>>2]|0)+9>>0]|0);c[r>>2]=Yc((c[p>>2]|0)+22|0)|0;c[s>>2]=Yc((c[p>>2]|0)+26|0)|0;if(!(c[r>>2]|0))c[r>>2]=1;a[t>>0]=(d[(c[p>>2]|0)+40>>0]&3)<<3;a[t>>0]=a[t>>0]|(d[(c[p>>2]|0)+41>>0]&224)>>5;c[u>>2]=a[t>>0];t=c[l>>2]|0;p=c[m>>2]|0;o=c[r>>2]|0;r=c[s>>2]|0;s=Ue(1e3,0,r|0,((r|0)<0)<<31>>31|0)|0;oc(t,p,o,((o|0)<0)<<31>>31,s,C)|0;mc(c[l>>2]|0,c[m>>2]|0,c[u>>2]|0)|0;if((c[q>>2]|0)<197120)qc(c[l>>2]|0,c[m>>2]|0,-1,-1)|0;Zc(c[l>>2]|0,c[m>>2]|0,3)|0;c[k>>2]=1;v=c[k>>2]|0;i=j;return v|0}function Yc(a){a=a|0;var b=0,e=0;b=i;i=i+16|0;e=b;c[e>>2]=a;i=b;return (d[c[e>>2]>>0]|0)<<24|(d[(c[e>>2]|0)+1>>0]|0)<<16|(d[(c[e>>2]|0)+2>>0]|0)<<8|(d[(c[e>>2]|0)+3>>0]|0)|0}function Zc(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;if(!(c[g>>2]|0)){c[f>>2]=-2;l=c[f>>2]|0;i=e;return l|0}c[k>>2]=sb(c[g>>2]|0,c[h>>2]|0)|0;if(!(c[k>>2]|0)){c[f>>2]=-20;l=c[f>>2]|0;i=e;return l|0}else{c[(c[k>>2]|0)+364>>2]=c[j>>2];c[f>>2]=0;l=c[f>>2]|0;i=e;return l|0}return 0}function _c(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;h=i;i=i+48|0;j=h+8|0;k=h;l=h+28|0;m=h+24|0;n=h+20|0;o=h+16|0;p=h+36|0;q=h+32|0;r=k;c[r>>2]=b;c[r+4>>2]=e;c[l>>2]=f;c[m>>2]=g;if(!(c[(c[m>>2]|0)+4>>2]|0))s=64;else s=d[c[c[m>>2]>>2]>>0]|0;a[p>>0]=s;c[q>>2]=c[(c[l>>2]|0)+504>>2];a:do if(!((d[p>>0]|0)&128)){s=k;m=c[s+4>>2]|0;if((m|0)>-1|(m|0)==-1&(c[s>>2]|0)>>>0>4294967295){c[c[q>>2]>>2]=1;s=k;m=c[s+4>>2]|0;g=j;c[g>>2]=c[s>>2];c[g+4>>2]=m;break}m=(c[l>>2]|0)+488|0;g=c[q>>2]|0;if((c[m>>2]|0)==-1?(c[m+4>>2]|0)==-1:0){c[g>>2]=1;m=j;c[m>>2]=-1;c[m+4>>2]=-1;break}if(!(c[g>>2]|0)){c[c[q>>2]>>2]=1;g=j;c[g>>2]=-1;c[g+4>>2]=-1;break}g=c[l>>2]|0;if((d[p>>0]|0)&64){m=g+488|0;s=Me(c[m>>2]|0,c[m+4>>2]|0,1,0)|0;m=j;c[m>>2]=s;c[m+4>>2]=C;break}else{c[o>>2]=c[g+408>>2];g=(c[l>>2]|0)+488|0;m=Fe(c[g>>2]|0,c[g+4>>2]|0,c[o>>2]|0)|0;c[n>>2]=m;m=(c[l>>2]|0)+488|0;g=(1<<c[o>>2])-1|0;s=Me(c[m>>2]&g|0,c[m+4>>2]&((g|0)<0)<<31>>31|0,1,0)|0;g=c[n>>2]|0;m=Me(g|0,((g|0)<0)<<31>>31|0,s|0,C|0)|0;c[n>>2]=m;m=c[n>>2]|0;s=Ie(m|0,((m|0)<0)<<31>>31|0,c[o>>2]|0)|0;m=j;c[m>>2]=s;c[m+4>>2]=C;break}}else{do if(!(c[q>>2]|0)){m=ye(4)|0;c[(c[l>>2]|0)+504>>2]=m;if(!(c[(c[l>>2]|0)+504>>2]|0)){m=j;c[m>>2]=-1;c[m+4>>2]=-1;break a}else{c[q>>2]=c[(c[l>>2]|0)+504>>2];break}}while(0);c[c[q>>2]>>2]=0;m=j;c[m>>2]=0;c[m+4>>2]=0}while(0);q=j;C=c[q+4>>2]|0;i=h;return c[q>>2]|0}function $c(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;g=i;i=i+48|0;h=g;j=g+8|0;k=g+28|0;l=g+16|0;m=g+24|0;n=j;c[n>>2]=a;c[n+4>>2]=b;c[k>>2]=d;c[g+32>>2]=e;c[g+20>>2]=f;f=j;e=Fe(c[f>>2]|0,c[f+4>>2]|0,c[(c[k>>2]|0)+408>>2]|0)|0;c[l>>2]=e;e=j;j=c[l>>2]<<c[(c[k>>2]|0)+408>>2];f=Ge(c[e>>2]|0,c[e+4>>2]|0,j|0,((j|0)<0)<<31>>31|0)|0;c[m>>2]=f;f=c[l>>2]|0;if(!(c[m>>2]|0)){l=(f-60<<c[(c[k>>2]|0)+408>>2])+59|0;j=h;c[j>>2]=l;c[j+4>>2]=((l|0)<0)<<31>>31;o=h;p=o;q=c[p>>2]|0;r=o+4|0;s=r;t=c[s>>2]|0;C=t;i=g;return q|0}else{l=Ie(f|0,((f|0)<0)<<31>>31|0,c[(c[k>>2]|0)+408>>2]|0)|0;k=(c[m>>2]|0)-1|0;m=Me(l|0,C|0,k|0,((k|0)<0)<<31>>31|0)|0;k=h;c[k>>2]=m;c[k+4>>2]=C;o=h;p=o;q=c[p>>2]|0;r=o+4|0;s=r;t=c[s>>2]|0;C=t;i=g;return q|0}return 0}function ad(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=i;i=i+48|0;h=g+28|0;j=g+12|0;k=g+24|0;l=g+20|0;m=g+32|0;n=g+16|0;o=g;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[g+8>>2]=f;c[n>>2]=c[l>>2];l=o;c[l>>2]=0;c[l+4>>2]=0;if((c[m>>2]|0)<30){c[h>>2]=0;p=c[h>>2]|0;i=g;return p|0}else{m=bd((c[n>>2]|0)+12|0)|0;n=o;c[n>>2]=m;c[n+4>>2]=((m|0)<0)<<31>>31;m=o;oc(c[j>>2]|0,c[k>>2]|0,c[m>>2]|0,c[m+4>>2]|0,1e3,0)|0;Zb(c[j>>2]|0,c[k>>2]|0,2)|0;Zc(c[j>>2]|0,c[k>>2]|0,3)|0;c[h>>2]=1;p=c[h>>2]|0;i=g;return p|0}return 0}function bd(a){a=a|0;var b=0,e=0;b=i;i=i+16|0;e=b;c[e>>2]=a;i=b;return d[c[e>>2]>>0]|0|(d[(c[e>>2]|0)+1>>0]|0)<<8|(d[(c[e>>2]|0)+2>>0]|0)<<16|(d[(c[e>>2]|0)+3>>0]|0)<<24|0}function cd(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0;g=i;i=i+80|0;h=g+8|0;j=g+24|0;k=g+40|0;l=g+16|0;m=g+20|0;n=g+28|0;o=g+36|0;p=g+32|0;q=g+44|0;r=g+48|0;s=g+52|0;t=g+56|0;u=g+60|0;v=g+64|0;w=g;c[w>>2]=a;c[w+4>>2]=b;c[j>>2]=e;c[k>>2]=f;f=c[c[k>>2]>>2]|0;if(!(c[(c[j>>2]|0)+504>>2]|0)){c[o>>2]=1<<((d[f+28>>0]|0)>>4);c[n>>2]=1<<((d[(c[c[k>>2]>>2]|0)+28>>0]|0)&15);e=ye(44)|0;c[(c[j>>2]|0)+504>>2]=e;if(!(c[(c[j>>2]|0)+504>>2]|0)){e=h;c[e>>2]=-1;c[e+4>>2]=-1;x=h;y=x;z=c[y>>2]|0;A=x+4|0;B=A;D=c[B>>2]|0;C=D;i=g;return z|0}else{c[l>>2]=c[(c[j>>2]|0)+504>>2];c[(c[l>>2]|0)+12>>2]=c[o>>2]>>1;c[(c[l>>2]|0)+8>>2]=((c[o>>2]>>2)*3|0)-(c[n>>2]>>2);c[(c[l>>2]|0)+4>>2]=(c[o>>2]>>2)+(c[n>>2]>>2);c[c[l>>2]>>2]=c[(c[l>>2]|0)+12>>2];c[(c[l>>2]|0)+20>>2]=c[n>>2];c[(c[l>>2]|0)+24>>2]=c[o>>2];c[(c[l>>2]|0)+16>>2]=c[n>>2]>>1;c[(c[l>>2]|0)+28>>2]=0;n=h;c[n>>2]=0;c[n+4>>2]=0;x=h;y=x;z=c[y>>2]|0;A=x+4|0;B=A;D=c[B>>2]|0;C=D;i=g;return z|0}}if(!((d[f>>0]|0)&1)){c[l>>2]=c[(c[j>>2]|0)+504>>2];f=h;c[f>>2]=-1;c[f+4>>2]=-1;x=h;y=x;z=c[y>>2]|0;A=x+4|0;B=A;D=c[B>>2]|0;C=D;i=g;return z|0}a:do if((d[c[c[k>>2]>>2]>>0]|0|0)==5){c[p>>2]=(c[c[k>>2]>>2]|0)+((c[(c[k>>2]|0)+4>>2]|0)-1);c[r>>2]=0;c[q>>2]=8;while(1){f=(c[q>>2]|0)+-1|0;c[q>>2]=f;if(!((1<<f&(d[c[p>>2]>>0]|0)|0)!=0^1))break;if(c[q>>2]|0)continue;c[q>>2]=8;c[p>>2]=(c[p>>2]|0)+-1}while(1){c[q>>2]=((c[q>>2]|0)+7|0)%8|0;if((c[q>>2]|0)==7)c[p>>2]=(c[p>>2]|0)+-1;if((d[(c[p>>2]|0)+-5>>0]|0)&~((1<<(c[q>>2]|0)+1)-1))break;if(d[(c[p>>2]|0)+-4>>0]|0)break;if(d[(c[p>>2]|0)+-3>>0]|0)break;if(d[(c[p>>2]|0)+-2>>0]|0)break;if((d[(c[p>>2]|0)+-1>>0]|0)&(1<<(c[q>>2]|0)+1)-1)break;c[r>>2]=(c[r>>2]|0)+1;c[p>>2]=(c[p>>2]|0)+-5}c[m>>2]=0;while(1){if((c[m>>2]|0)>=2)break;f=d[c[p>>2]>>0]|0;n=c[q>>2]|0;if((c[q>>2]|0)>4)c[s>>2]=f>>n-5&63;else{c[s>>2]=f&(1<<n+1)-1;c[s>>2]=c[s>>2]<<5-(c[q>>2]|0);c[s>>2]=c[s>>2]|((d[(c[p>>2]|0)+-1>>0]|0)&~((1<<(c[q>>2]|0)+3)-1))>>(c[q>>2]|0)+3}c[s>>2]=(c[s>>2]|0)+1;if((c[s>>2]|0)==(c[r>>2]|0))break;c[q>>2]=((c[q>>2]|0)+1|0)%8|0;if(!(c[q>>2]|0))c[p>>2]=(c[p>>2]|0)+1;c[p>>2]=(c[p>>2]|0)+5;c[r>>2]=(c[r>>2]|0)-1;c[m>>2]=(c[m>>2]|0)+1}c[v>>2]=44+((c[r>>2]|0)-1<<2);if((c[v>>2]|0)>>>0<44){n=h;c[n>>2]=-1;c[n+4>>2]=-1;x=h;y=x;z=c[y>>2]|0;A=x+4|0;B=A;D=c[B>>2]|0;C=D;i=g;return z|0}c[l>>2]=Be(c[(c[j>>2]|0)+504>>2]|0,c[v>>2]|0)|0;if(!(c[l>>2]|0)){n=h;c[n>>2]=-1;c[n+4>>2]=-1;x=h;y=x;z=c[y>>2]|0;A=x+4|0;B=A;D=c[B>>2]|0;C=D;i=g;return z|0}c[(c[j>>2]|0)+504>>2]=c[l>>2];c[u>>2]=-1;do{n=(c[u>>2]|0)+1|0;c[u>>2]=n}while((1<<n|0)<(c[r>>2]|0));c[(c[l>>2]|0)+36>>2]=c[u>>2];c[t>>2]=(c[l>>2]|0)+40;c[u>>2]=0;while(1){if((c[u>>2]|0)>=(c[r>>2]|0))break a;c[q>>2]=((c[q>>2]|0)+1|0)%8|0;if(!(c[q>>2]|0))c[p>>2]=(c[p>>2]|0)+1;n=(d[c[p>>2]>>0]|0)>>c[q>>2]&1;f=c[t>>2]|0;c[t>>2]=f+4;c[f>>2]=n;c[p>>2]=(c[p>>2]|0)+5;c[u>>2]=(c[u>>2]|0)+1}}while(0);u=h;c[u>>2]=0;c[u+4>>2]=0;x=h;y=x;z=c[y>>2]|0;A=x+4|0;B=A;D=c[B>>2]|0;C=D;i=g;return z|0}function dd(a,b,e,f,g){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0;h=i;i=i+64|0;j=h+16|0;k=h;l=h+36|0;m=h+32|0;n=h+40|0;o=h+44|0;p=h+48|0;q=h+28|0;r=h+24|0;s=h+8|0;t=k;c[t>>2]=a;c[t+4>>2]=b;c[l>>2]=e;c[m>>2]=f;c[n>>2]=g;c[o>>2]=c[(c[l>>2]|0)+504>>2];c[p>>2]=(d[c[c[m>>2]>>2]>>0]|0)>>1&(1<<c[(c[o>>2]|0)+36>>2])-1;m=c[o>>2]|0;if(c[(c[o>>2]|0)+40+(c[p>>2]<<2)>>2]|0)u=c[m+24>>2]|0;else u=c[m+20>>2]|0;c[q>>2]=u;c[p>>2]=(d[c[c[n>>2]>>2]>>0]|0)>>1&(1<<c[(c[o>>2]|0)+36>>2])-1;n=c[o>>2]|0;if(c[(c[o>>2]|0)+40+(c[p>>2]<<2)>>2]|0)v=c[n+24>>2]|0;else v=c[n+20>>2]|0;c[r>>2]=v;v=k;k=((c[q>>2]|0)+(c[r>>2]|0)|0)/4|0;r=Ge(c[v>>2]|0,c[v+4>>2]|0,k|0,((k|0)<0)<<31>>31|0)|0;k=s;c[k>>2]=r;c[k+4>>2]=C;if((c[s+4>>2]|0)<0){k=j;c[k>>2]=0;c[k+4>>2]=0;w=j;x=w;y=c[x>>2]|0;z=w+4|0;A=z;B=c[A>>2]|0;C=B;i=h;return y|0}else{k=s;s=c[k+4>>2]|0;r=j;c[r>>2]=c[k>>2];c[r+4>>2]=s;w=j;x=w;y=c[x>>2]|0;z=w+4|0;A=z;B=c[A>>2]|0;C=B;i=h;return y|0}return 0}function ed(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;g=i;i=i+48|0;h=g+32|0;j=g+12|0;k=g+28|0;l=g+24|0;m=g+36|0;n=g+16|0;o=g;p=g+20|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[g+8>>2]=f;c[n>>2]=c[l>>2];l=o;c[l>>2]=0;c[l+4>>2]=0;if((c[m>>2]|0)<68){c[h>>2]=0;q=c[h>>2]|0;i=g;return q|0}else{m=bd((c[n>>2]|0)+36|0)|0;l=o;c[l>>2]=m;c[l+4>>2]=((m|0)<0)<<31>>31;m=o;oc(c[j>>2]|0,c[k>>2]|0,c[m>>2]|0,c[m+4>>2]|0,1e3,0)|0;Zb(c[j>>2]|0,c[k>>2]|0,3)|0;m=bd((c[n>>2]|0)+68|0)|0;n=Me(m|0,((m|0)<0)<<31>>31|0,2,0)|0;c[p>>2]=n;Zc(c[j>>2]|0,c[k>>2]|0,c[p>>2]|0)|0;c[h>>2]=1;q=c[h>>2]|0;i=g;return q|0}return 0}function fd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+32|0;g=f+8|0;h=f;j=f+24|0;k=f+20|0;l=f+16|0;m=h;c[m>>2]=a;c[m+4>>2]=b;c[j>>2]=d;c[k>>2]=e;c[l>>2]=c[(c[j>>2]|0)+504>>2];do if(!(c[(c[j>>2]|0)+504>>2]|0)){e=ye(12)|0;c[(c[j>>2]|0)+504>>2]=e;if(!(c[(c[j>>2]|0)+504>>2]|0)){e=g;c[e>>2]=-1;c[e+4>>2]=-1;break}else{c[l>>2]=c[(c[j>>2]|0)+504>>2];c[(c[l>>2]|0)+8>>2]=0;e=_(c[(c[c[k>>2]>>2]|0)+64>>2]|0,c[(c[c[k>>2]>>2]|0)+56>>2]|0)|0;c[(c[l>>2]|0)+4>>2]=e;c[c[l>>2]>>2]=1;e=g;c[e>>2]=0;c[e+4>>2]=0;break}}else{e=c[l>>2]|0;if((c[c[l>>2]>>2]|0)<2)c[e>>2]=(c[e>>2]|0)+1;else c[e+8>>2]=1;e=h;d=c[e+4>>2]|0;if((d|0)>-1|(d|0)==-1&(c[e>>2]|0)>>>0>4294967295){e=h;d=c[e+4>>2]|0;b=g;c[b>>2]=c[e>>2];c[b+4>>2]=d;break}if(!(c[(c[l>>2]|0)+8>>2]|0)){d=g;c[d>>2]=0;c[d+4>>2]=0;break}d=(c[j>>2]|0)+488|0;b=c[d+4>>2]|0;if((b|0)>0|(b|0)==0&(c[d>>2]|0)>>>0>0){d=(c[j>>2]|0)+488|0;b=c[(c[l>>2]|0)+4>>2]|0;e=Me(c[d>>2]|0,c[d+4>>2]|0,b|0,((b|0)<0)<<31>>31|0)|0;b=g;c[b>>2]=e;c[b+4>>2]=C;break}else{b=g;c[b>>2]=-1;c[b+4>>2]=-1;break}}while(0);l=g;C=c[l+4>>2]|0;i=f;return c[l>>2]|0}function gd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=i;i=i+48|0;h=g+28|0;j=g+12|0;k=g+24|0;l=g+20|0;m=g+32|0;n=g+16|0;o=g;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[g+8>>2]=f;c[n>>2]=c[l>>2];if((c[m>>2]|0)<28){c[h>>2]=0;p=c[h>>2]|0;i=g;return p|0}else{m=Yc((c[n>>2]|0)+16|0)|0;n=o;c[n>>2]=m;c[n+4>>2]=((m|0)<0)<<31>>31;m=o;oc(c[j>>2]|0,c[k>>2]|0,c[m>>2]|0,c[m+4>>2]|0,1e3,0)|0;Zc(c[j>>2]|0,c[k>>2]|0,3)|0;c[h>>2]=1;p=c[h>>2]|0;i=g;return p|0}return 0}function hd(a,b,e,f,g){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0;h=i;i=i+48|0;j=h+24|0;k=h+28|0;l=h+32|0;m=h+36|0;n=h+40|0;o=h+20|0;p=h;q=h+8|0;r=h+16|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=e;c[n>>2]=f;c[h+44>>2]=g;c[o>>2]=c[m>>2];m=p;c[m>>2]=0;c[m+4>>2]=0;m=q;c[m>>2]=0;c[m+4>>2]=0;if((c[n>>2]|0)<28){c[j>>2]=0;s=c[j>>2]|0;i=h;return s|0}m=id((c[o>>2]|0)+12|0)|0;g=p;c[g>>2]=m;c[g+4>>2]=C;g=id((c[o>>2]|0)+20|0)|0;m=q;c[m>>2]=g;c[m+4>>2]=C;if((c[n>>2]|0)>28)c[r>>2]=d[(c[o>>2]|0)+28>>0];else c[r>>2]=0;o=c[k>>2]|0;n=c[l>>2]|0;m=p;p=c[m>>2]|0;g=c[m+4>>2]|0;m=q;q=Ue(1e3,0,c[m>>2]|0,c[m+4>>2]|0)|0;oc(o,n,p,g,q,C)|0;mc(c[k>>2]|0,c[l>>2]|0,c[r>>2]|0)|0;Zc(c[k>>2]|0,c[l>>2]|0,3)|0;c[j>>2]=1;s=c[j>>2]|0;i=h;return s|0}function id(a){a=a|0;var b=0,e=0,f=0,g=0;b=i;i=i+16|0;e=b+8|0;f=b+4|0;g=b;c[e>>2]=a;c[f>>2]=d[c[e>>2]>>0]|0|(d[(c[e>>2]|0)+1>>0]|0)<<8|(d[(c[e>>2]|0)+2>>0]|0)<<16|(d[(c[e>>2]|0)+3>>0]|0)<<24;c[g>>2]=d[(c[e>>2]|0)+4>>0]|0|(d[(c[e>>2]|0)+5>>0]|0)<<8|(d[(c[e>>2]|0)+6>>0]|0)<<16|(d[(c[e>>2]|0)+7>>0]|0)<<24;C=c[g>>2]|0;i=b;return c[f>>2]|0}function jd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0;g=i;i=i+32|0;h=g+16|0;j=g+12|0;c[h>>2]=a;c[j>>2]=b;c[g+8>>2]=d;c[g+4>>2]=e;c[g>>2]=f;oc(c[h>>2]|0,c[j>>2]|0,0,0,1,0)|0;i=g;return 1}function kd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0;g=i;i=i+32|0;h=g+16|0;j=g+12|0;c[h>>2]=a;c[j>>2]=b;c[g+8>>2]=d;c[g+4>>2]=e;c[g>>2]=f;oc(c[h>>2]|0,c[j>>2]|0,0,0,1,0)|0;Zc(c[h>>2]|0,c[j>>2]|0,1)|0;i=g;return 1}function ld(a,b,e,f,g){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0;h=i;i=i+32|0;j=h+24|0;k=h+16|0;l=h+20|0;m=h+8|0;n=h;c[j>>2]=a;c[k>>2]=b;c[l>>2]=e;c[h+28>>2]=f;c[h+12>>2]=g;c[m>>2]=c[l>>2];l=n;c[l>>2]=0;c[l+4>>2]=0;l=(d[(c[m>>2]|0)+14>>0]|0)<<12;g=(d[(c[m>>2]|0)+15>>0]|0)<<4;f=(d[(c[m>>2]|0)+16>>0]|0)>>4&15;m=n;c[m>>2]=l|g|f;c[m+4>>2]=((l|0)<0)<<31>>31|((g|0)<0)<<31>>31|((f|0)<0)<<31>>31;f=n;oc(c[j>>2]|0,c[k>>2]|0,c[f>>2]|0,c[f+4>>2]|0,1e3,0)|0;Zc(c[j>>2]|0,c[k>>2]|0,3)|0;i=h;return 1}function md(b,e,f,g){b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;h=i;i=i+48|0;j=h;k=h+8|0;l=h+20|0;m=h+28|0;n=h+16|0;o=h+32|0;p=h+24|0;q=k;c[q>>2]=b;c[q+4>>2]=e;c[l>>2]=f;c[m>>2]=g;do if(c[(c[l>>2]|0)+504>>2]|0){c[n>>2]=c[(c[l>>2]|0)+504>>2];if((d[c[c[m>>2]>>2]>>0]|0|0)==255)c[(c[n>>2]|0)+8>>2]=1;g=k;if((((c[g>>2]|0)==-1?(c[g+4>>2]|0)==-1:0)?(d[c[c[m>>2]>>2]>>0]|0|0)==255:0)?(c[(c[m>>2]|0)+4>>2]|0)>2:0){a[o>>0]=((d[(c[c[m>>2]>>2]|0)+2>>0]|0)&240)>>4;do switch(d[o>>0]|0|0){case 0:{c[p>>2]=-1;break}case 1:{c[p>>2]=192;break}case 2:{c[p>>2]=576;break}case 3:{c[p>>2]=1152;break}case 4:{c[p>>2]=2304;break}case 5:{c[p>>2]=4608;break}case 6:{c[p>>2]=-1;break}case 7:{c[p>>2]=-1;break}case 8:{c[p>>2]=256;break}case 9:{c[p>>2]=512;break}case 10:{c[p>>2]=1024;break}case 11:{c[p>>2]=2048;break}case 12:{c[p>>2]=4096;break}case 13:{c[p>>2]=8192;break}case 14:{c[p>>2]=16384;break}case 15:{c[p>>2]=32768;break}default:c[p>>2]=-1}while(0);if((c[p>>2]|0)==-1)break;g=c[n>>2]|0;f=c[p>>2]|0;e=Me(c[g>>2]|0,c[g+4>>2]|0,f|0,((f|0)<0)<<31>>31|0)|0;f=k;c[f>>2]=e;c[f+4>>2]=C;break}f=k;if(((c[f>>2]|0)==-1?(c[f+4>>2]|0)==-1:0)?(c[(c[n>>2]|0)+8>>2]|0)==0:0){f=k;c[f>>2]=0;c[f+4>>2]=0}}else{f=ye(16)|0;c[(c[l>>2]|0)+504>>2]=f;if(c[(c[l>>2]|0)+504>>2]|0){c[n>>2]=c[(c[l>>2]|0)+504>>2];f=c[n>>2]|0;c[f>>2]=0;c[f+4>>2]=0;c[(c[n>>2]|0)+8>>2]=0;break}f=j;c[f>>2]=-1;c[f+4>>2]=-1;r=j;s=r;t=c[s>>2]|0;u=r+4|0;v=u;w=c[v>>2]|0;C=w;i=h;return t|0}while(0);l=k;p=c[l+4>>2]|0;o=c[n>>2]|0;c[o>>2]=c[l>>2];c[o+4>>2]=p;p=k;k=c[p+4>>2]|0;o=j;c[o>>2]=c[p>>2];c[o+4>>2]=k;r=j;s=r;t=c[s>>2]|0;u=r+4|0;v=u;w=c[v>>2]|0;C=w;i=h;return t|0}function nd(a,b,e,f,g){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;h=i;i=i+48|0;j=h+32|0;k=h+12|0;l=h+28|0;m=h+24|0;n=h+36|0;o=h+16|0;p=h;q=h+20|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=e;c[n>>2]=f;c[h+8>>2]=g;c[o>>2]=c[m>>2];m=p;c[m>>2]=0;c[m+4>>2]=0;if((c[n>>2]|0)<51){c[j>>2]=0;r=c[j>>2]|0;i=h;return r|0}else{n=(d[(c[o>>2]|0)+27>>0]|0)<<12;m=(d[(c[o>>2]|0)+28>>0]|0)<<4;g=(d[(c[o>>2]|0)+29>>0]|0)>>4&15;f=p;c[f>>2]=n|m|g;c[f+4>>2]=((n|0)<0)<<31>>31|((m|0)<0)<<31>>31|((g|0)<0)<<31>>31;g=p;oc(c[k>>2]|0,c[l>>2]|0,c[g>>2]|0,c[g+4>>2]|0,1e3,0)|0;c[q>>2]=(od((c[o>>2]|0)+7|0)|0)&65535;Zc(c[k>>2]|0,c[l>>2]|0,c[q>>2]|0)|0;c[j>>2]=1;r=c[j>>2]|0;i=h;return r|0}return 0}function od(a){a=a|0;var b=0,e=0;b=i;i=i+16|0;e=b;c[e>>2]=a;i=b;return ((d[c[e>>2]>>0]|0)<<8|(d[(c[e>>2]|0)+1>>0]|0))&65535|0}function pd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;g=i;i=i+48|0;h=g+32|0;j=g+28|0;k=g+36|0;l=g+16|0;m=g+40|0;n=g+20|0;o=g;p=g+8|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[g+24>>2]=f;c[n>>2]=c[l>>2];l=o;c[l>>2]=0;c[l+4>>2]=0;l=p;c[l>>2]=0;c[l+4>>2]=0;if((c[m>>2]|0)<28){c[h>>2]=0;q=c[h>>2]|0;i=g;return q|0}else{m=id((c[n>>2]|0)+8|0)|0;l=o;c[l>>2]=m;c[l+4>>2]=C;l=id((c[n>>2]|0)+16|0)|0;n=p;c[n>>2]=l;c[n+4>>2]=C;n=c[j>>2]|0;j=c[k>>2]|0;k=o;o=c[k>>2]|0;l=c[k+4>>2]|0;k=p;p=Ue(1e3,0,c[k>>2]|0,c[k+4>>2]|0)|0;oc(n,j,o,l,p,C)|0;c[h>>2]=1;q=c[h>>2]|0;i=g;return q|0}return 0}function qd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;g=i;i=i+48|0;h=g+32|0;j=g+12|0;k=g+28|0;l=g+24|0;m=g+36|0;n=g+16|0;o=g;p=g+20|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[g+8>>2]=f;c[n>>2]=c[l>>2];l=o;c[l>>2]=0;c[l+4>>2]=0;if((c[m>>2]|0)<56){c[h>>2]=0;q=c[h>>2]|0;i=g;return q|0}else{m=bd((c[n>>2]|0)+40|0)|0;l=o;c[l>>2]=m;c[l+4>>2]=((m|0)<0)<<31>>31;m=o;oc(c[j>>2]|0,c[k>>2]|0,c[m>>2]|0,c[m+4>>2]|0,1e3,0)|0;m=bd((c[n>>2]|0)+52|0)|0;n=Me(m|0,((m|0)<0)<<31>>31|0,2,0)|0;c[p>>2]=n;Zc(c[j>>2]|0,c[k>>2]|0,c[p>>2]|0)|0;c[h>>2]=1;q=c[h>>2]|0;i=g;return q|0}return 0}function rd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0;f=i;i=i+32|0;g=f+8|0;h=f;j=f+24|0;k=f+16|0;l=h;c[l>>2]=a;c[l+4>>2]=b;c[j>>2]=d;c[f+20>>2]=e;c[k>>2]=c[(c[j>>2]|0)+504>>2];do if(!(c[(c[j>>2]|0)+504>>2]|0)){e=ye(12)|0;c[(c[j>>2]|0)+504>>2]=e;if(!(c[(c[j>>2]|0)+504>>2]|0)){e=g;c[e>>2]=-1;c[e+4>>2]=-1;break}else{c[k>>2]=c[(c[j>>2]|0)+504>>2];c[(c[k>>2]|0)+8>>2]=0;c[(c[k>>2]|0)+4>>2]=256;c[c[k>>2]>>2]=1;e=g;c[e>>2]=0;c[e+4>>2]=0;break}}else{e=c[k>>2]|0;if((c[c[k>>2]>>2]|0)<2)c[e>>2]=(c[e>>2]|0)+1;else c[e+8>>2]=1;e=h;d=c[e+4>>2]|0;if((d|0)>-1|(d|0)==-1&(c[e>>2]|0)>>>0>4294967295){e=h;d=c[e+4>>2]|0;b=g;c[b>>2]=c[e>>2];c[b+4>>2]=d;break}if(!(c[(c[k>>2]|0)+8>>2]|0)){d=g;c[d>>2]=0;c[d+4>>2]=0;break}d=(c[j>>2]|0)+488|0;b=c[d+4>>2]|0;if((b|0)>0|(b|0)==0&(c[d>>2]|0)>>>0>0){d=(c[j>>2]|0)+488|0;b=c[(c[k>>2]|0)+4>>2]|0;e=Me(c[d>>2]|0,c[d+4>>2]|0,b|0,((b|0)<0)<<31>>31|0)|0;b=g;c[b>>2]=e;c[b+4>>2]=C;break}else{b=g;c[b>>2]=-1;c[b+4>>2]=-1;break}}while(0);k=g;C=c[k+4>>2]|0;i=f;return c[k>>2]|0}function sd(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;j=i;i=i+48|0;k=j;l=j+16|0;m=j+4|0;n=j+8|0;o=j+32|0;p=j+12|0;q=j+24|0;r=j+20|0;s=j+40|0;t=j+28|0;c[l>>2]=b;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[j+36>>2]=h;c[p>>2]=c[n>>2];a[s>>0]=0;if((c[o>>2]|0)<64){c[k>>2]=0;u=c[k>>2]|0;i=j;return u|0}else{c[q>>2]=bd((c[p>>2]|0)+24|0)|0;c[r>>2]=bd((c[p>>2]|0)+28|0)|0;a[s>>0]=a[(c[p>>2]|0)+15>>0]|0;c[t>>2]=d[(c[p>>2]|0)+11>>0];p=c[l>>2]|0;o=c[m>>2]|0;n=c[q>>2]|0;q=c[r>>2]|0;r=Ue(1e3,0,q|0,((q|0)<0)<<31>>31|0)|0;oc(p,o,n,((n|0)<0)<<31>>31,r,C)|0;mc(c[l>>2]|0,c[m>>2]|0,d[s>>0]|0)|0;Zc(c[l>>2]|0,c[m>>2]|0,c[t>>2]|0)|0;c[k>>2]=1;u=c[k>>2]|0;i=j;return u|0}return 0}function td(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0;g=i;i=i+32|0;h=g+4|0;j=g+16|0;k=g+8|0;l=g+20|0;m=g+28|0;n=g+12|0;o=g+24|0;c[j>>2]=a;c[k>>2]=b;c[l>>2]=d;c[m>>2]=e;c[g>>2]=f;c[n>>2]=22;c[o>>2]=ye(48)|0;if(!(c[o>>2]|0)){c[h>>2]=-1;p=c[h>>2]|0;i=g;return p|0}if((rc(c[o>>2]|0,c[l>>2]|0,c[m>>2]|0)|0)==-1){ze(c[o>>2]|0);c[h>>2]=-1;p=c[h>>2]|0;i=g;return p|0}else{m=c[j>>2]|0;l=c[k>>2]|0;f=Ue(2,0,c[(c[o>>2]|0)+32>>2]|0,0)|0;e=C;d=Ue(1e3,0,c[(c[o>>2]|0)+36>>2]|0,0)|0;oc(m,l,f,e,d,C)|0;mc(c[j>>2]|0,c[k>>2]|0,c[n>>2]|0)|0;Zc(c[j>>2]|0,c[k>>2]|0,0)|0;ze(c[o>>2]|0);c[h>>2]=1;p=c[h>>2]|0;i=g;return p|0}return 0}function ud(b,e,f,g,h){b=b|0;e=e|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0;j=i;i=i+32|0;k=j+24|0;l=j+16|0;m=j+20|0;n=j+12|0;o=j+4|0;p=j+28|0;c[l>>2]=b;c[m>>2]=e;c[n>>2]=f;c[o>>2]=g;c[j>>2]=h;c[j+8>>2]=c[n>>2];if((c[o>>2]|0)<19){c[k>>2]=0;q=c[k>>2]|0;i=j;return q|0}a[p>>0]=a[(c[n>>2]|0)+9>>0]|0;if((d[p>>0]|0|0)<1){c[k>>2]=0;q=c[k>>2]|0;i=j;return q|0}else{oc(c[l>>2]|0,c[m>>2]|0,48e3,0,1e3,0)|0;mc(c[l>>2]|0,c[m>>2]|0,0)|0;p=c[l>>2]|0;o=c[m>>2]|0;qc(p,o,(vd((c[n>>2]|0)+10|0)|0)&65535,0)|0;Zc(c[l>>2]|0,c[m>>2]|0,2)|0;c[k>>2]=1;q=c[k>>2]|0;i=j;return q|0}return 0}function vd(a){a=a|0;var b=0,e=0;b=i;i=i+16|0;e=b;c[e>>2]=a;i=b;return (d[c[e>>2]>>0]|0|(d[(c[e>>2]|0)+1>>0]|0)<<8)&65535|0}function wd(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;f=i;i=i+48|0;g=f+16|0;h=f+24|0;j=f+36|0;k=f+40|0;l=f+32|0;m=f;n=f+8|0;o=h;c[o>>2]=a;c[o+4>>2]=b;c[j>>2]=d;c[k>>2]=e;c[l>>2]=c[(c[j>>2]|0)+504>>2];if(!(c[(c[j>>2]|0)+504>>2]|0)){e=ye(16)|0;c[(c[j>>2]|0)+504>>2]=e;if(!(c[(c[j>>2]|0)+504>>2]|0)){e=g;c[e>>2]=-1;c[e+4>>2]=-1;p=g;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=f;return r|0}else{c[l>>2]=c[(c[j>>2]|0)+504>>2];c[(c[l>>2]|0)+4>>2]=0;c[c[l>>2]>>2]=1;e=(c[l>>2]|0)+8|0;c[e>>2]=0;c[e+4>>2]=0;e=g;c[e>>2]=0;c[e+4>>2]=0;p=g;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=f;return r|0}}e=c[l>>2]|0;if((c[c[l>>2]>>2]|0)<2)c[e>>2]=(c[e>>2]|0)+1;else c[e+4>>2]=1;e=h;d=c[e+4>>2]|0;if((d|0)>-1|(d|0)==-1&(c[e>>2]|0)>>>0>4294967295){e=h;h=c[e+4>>2]|0;d=g;c[d>>2]=c[e>>2];c[d+4>>2]=h;p=g;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=f;return r|0}if(!(c[(c[l>>2]|0)+4>>2]|0)){h=g;c[h>>2]=0;c[h+4>>2]=0;p=g;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=f;return r|0}h=xd(c[k>>2]|0)|0;k=m;c[k>>2]=h;c[k+4>>2]=C;k=(c[j>>2]|0)+488|0;h=c[k+4>>2]|0;if(!((h|0)>0|(h|0)==0&(c[k>>2]|0)>>>0>0)){k=m;h=(c[l>>2]|0)+8|0;l=h;d=Me(c[l>>2]|0,c[l+4>>2]|0,c[k>>2]|0,c[k+4>>2]|0)|0;k=h;c[k>>2]=d;c[k+4>>2]=C;k=g;c[k>>2]=-1;c[k+4>>2]=-1;p=g;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=f;return r|0}k=(c[j>>2]|0)+488|0;d=m;m=Me(c[k>>2]|0,c[k+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=n;c[d>>2]=m;c[d+4>>2]=C;d=n;m=c[d+4>>2]|0;k=(c[j>>2]|0)+496|0;h=c[k+4>>2]|0;if((m|0)>(h|0)|((m|0)==(h|0)?(c[d>>2]|0)>>>0>(c[k>>2]|0)>>>0:0)?(k=(c[j>>2]|0)+496|0,d=c[k+4>>2]|0,h=(c[j>>2]|0)+488|0,m=c[h+4>>2]|0,(d|0)>(m|0)|((d|0)==(m|0)?(c[k>>2]|0)>>>0>=(c[h>>2]|0)>>>0:0)):0){h=(c[j>>2]|0)+496|0;v=c[h>>2]|0;w=c[h+4>>2]|0}else{h=n;v=c[h>>2]|0;w=c[h+4>>2]|0}h=g;c[h>>2]=v;c[h+4>>2]=w;p=g;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=f;return r|0}function xd(b){b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;e=i;i=i+32|0;f=e;g=e+16|0;h=e+21|0;j=e+22|0;k=e+20|0;l=e+8|0;m=e+12|0;c[g>>2]=b;do if((c[(c[g>>2]|0)+4>>2]|0)>=1){a[h>>0]=a[c[c[g>>2]>>2]>>0]|0;a[j>>0]=(d[h>>0]|0)&3;c[l>>2]=c[1968+((d[h>>0]|0)>>3<<2)>>2];if((d[j>>0]|0|0)==3?(c[(c[g>>2]|0)+4>>2]|0)<2:0){b=f;c[b>>2]=0;c[b+4>>2]=0;break}b=d[j>>0]|0;if((b|0)==3)a[k>>0]=(d[(c[c[g>>2]>>2]|0)+1>>0]|0)&63;else if(!b)a[k>>0]=1;else if((b|0)==2|(b|0)==1)a[k>>0]=2;c[m>>2]=_(c[l>>2]|0,d[k>>0]|0)|0;if((c[m>>2]|0)>5760){b=f;c[b>>2]=0;c[b+4>>2]=0;break}else{b=c[m>>2]|0;n=f;c[n>>2]=b;c[n+4>>2]=((b|0)<0)<<31>>31;break}}else{b=f;c[b>>2]=0;c[b+4>>2]=0}while(0);m=f;C=c[m+4>>2]|0;i=e;return c[m>>2]|0}function yd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;g=i;i=i+32|0;h=g+8|0;j=g+28|0;k=g+24|0;l=g+20|0;m=g+16|0;n=g;o=h;c[o>>2]=a;c[o+4>>2]=b;c[j>>2]=d;c[k>>2]=e;c[l>>2]=f;c[m>>2]=c[(c[j>>2]|0)+504>>2];j=h;f=c[j+4>>2]|0;e=(c[m>>2]|0)+8|0;d=c[e+4>>2]|0;b=h;h=c[b>>2]|0;o=c[b+4>>2]|0;if(!((f|0)>(d|0)|((f|0)==(d|0)?(c[j>>2]|0)>>>0>=(c[e>>2]|0)>>>0:0))){e=n;c[e>>2]=h;c[e+4>>2]=o;e=xd(c[k>>2]|0)|0;k=(c[m>>2]|0)+8|0;j=k;d=Ge(c[j>>2]|0,c[j+4>>2]|0,e|0,C|0)|0;e=k;c[e>>2]=d;c[e+4>>2]=C;p=n;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=g;return r|0}e=xd(c[l>>2]|0)|0;l=Ge(h|0,o|0,e|0,C|0)|0;e=n;c[e>>2]=l;c[e+4>>2]=C;e=n;l=c[e+4>>2]|0;o=(c[m>>2]|0)+8|0;h=c[o+4>>2]|0;if((l|0)<(h|0)|((l|0)==(h|0)?(c[e>>2]|0)>>>0<(c[o>>2]|0)>>>0:0)){o=(c[m>>2]|0)+8|0;e=c[o+4>>2]|0;h=n;c[h>>2]=c[o>>2];c[h+4>>2]=e}e=(c[m>>2]|0)+8|0;c[e>>2]=0;c[e+4>>2]=0;p=n;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=g;return r|0}function zd(a,b,e,f,g){a=a|0;b=b|0;e=e|0;f=f|0;g=g|0;var h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0;h=i;i=i+48|0;j=h+28|0;k=h+16|0;l=h+4|0;m=h+8|0;n=h+32|0;o=h+12|0;p=h+24|0;q=h+20|0;c[k>>2]=a;c[l>>2]=b;c[m>>2]=e;c[n>>2]=f;c[h>>2]=g;c[o>>2]=c[m>>2];if((c[n>>2]|0)<26){c[j>>2]=0;r=c[j>>2]|0;i=h;return r|0}if((d[c[m>>2]>>0]|0|0)!=79){c[j>>2]=0;r=c[j>>2]|0;i=h;return r|0}if(ve((c[m>>2]|0)+1|0,2512,4)|0){c[j>>2]=0;r=c[j>>2]|0;i=h;return r|0}if((d[(c[m>>2]|0)+5>>0]|0|0)!=1){c[j>>2]=0;r=c[j>>2]|0;i=h;return r|0}if((d[(c[m>>2]|0)+6>>0]|0|0)!=1){c[j>>2]=0;r=c[j>>2]|0;i=h;return r|0}else{c[p>>2]=Yc((c[o>>2]|0)+18|0)|0;c[q>>2]=Yc((c[o>>2]|0)+22|0)|0;o=c[k>>2]|0;m=c[l>>2]|0;n=c[p>>2]|0;p=c[q>>2]|0;q=Ue(1e3,0,p|0,((p|0)<0)<<31>>31|0)|0;oc(o,m,n,((n|0)<0)<<31>>31,q,C)|0;mc(c[k>>2]|0,c[l>>2]|0,32)|0;Zc(c[k>>2]|0,c[l>>2]|0,1)|0;c[j>>2]=1;r=c[j>>2]|0;i=h;return r|0}return 0}function Ad(a,b,e,f){a=a|0;b=b|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0;g=i;i=i+80|0;h=g+40|0;j=g+24|0;k=g+48|0;l=g+52|0;m=g+56|0;n=g+60|0;o=g+68|0;p=g+64|0;q=g+32|0;r=g;s=g+8|0;t=g+16|0;u=j;c[u>>2]=a;c[u+4>>2]=b;c[k>>2]=e;c[l>>2]=f;c[p>>2]=c[(c[k>>2]|0)+504>>2];if(!(c[(c[k>>2]|0)+504>>2]|0)){f=ye(8)|0;c[(c[k>>2]|0)+504>>2]=f;if(!(c[(c[k>>2]|0)+504>>2]|0)){f=h;c[f>>2]=-1;c[f+4>>2]=-1;v=h;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=g;return x|0}else{c[p>>2]=c[(c[k>>2]|0)+504>>2];c[(c[p>>2]|0)+4>>2]=0;c[c[p>>2]>>2]=1;f=h;c[f>>2]=0;c[f+4>>2]=0;v=h;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=g;return x|0}}if(!(c[(c[l>>2]|0)+4>>2]|0))B=1;else B=(d[c[c[l>>2]>>2]>>0]|0|0)==79;c[m>>2]=B&1;if((c[m>>2]|0)==0?(c[(c[l>>2]|0)+4>>2]|0)>0:0)D=((d[c[c[l>>2]>>2]>>0]|0)&1|0)==0;else D=0;c[n>>2]=D&1;if((c[m>>2]|0)==0?(c[(c[l>>2]|0)+4>>2]|0)>0:0)E=((d[c[c[l>>2]>>2]>>0]|0)>>4&1|0)!=0;else E=0;c[o>>2]=E&1;E=c[p>>2]|0;if(c[m>>2]|0)c[E>>2]=(c[E>>2]|0)+1;else c[E+4>>2]=1;E=j;l=c[E+4>>2]|0;if((l|0)>-1|(l|0)==-1&(c[E>>2]|0)>>>0>4294967295){E=j;j=c[E+4>>2]|0;l=h;c[l>>2]=c[E>>2];c[l+4>>2]=j;v=h;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=g;return x|0}if(!(c[(c[p>>2]|0)+4>>2]|0)){p=h;c[p>>2]=0;c[p+4>>2]=0;v=h;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=g;return x|0}p=(c[k>>2]|0)+488|0;j=c[p+4>>2]|0;if(!((j|0)>0|(j|0)==0&(c[p>>2]|0)>>>0>0)){p=h;c[p>>2]=-1;c[p+4>>2]=-1;v=h;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=g;return x|0}p=(c[k>>2]|0)+488|0;j=c[p>>2]|0;l=c[p+4>>2]|0;if(c[m>>2]|0){m=h;c[m>>2]=j;c[m+4>>2]=l;v=h;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=g;return x|0}m=Fe(j|0,l|0,32)|0;l=q;c[l>>2]=m;c[l+4>>2]=C;l=(c[k>>2]|0)+488|0;m=Fe(c[l>>2]|0,c[l+4>>2]|0,30)|0;l=r;c[l>>2]=m&3;c[l+4>>2]=0;l=(c[k>>2]|0)+488|0;k=Fe(c[l>>2]|0,c[l+4>>2]|0,3)|0;l=s;c[l>>2]=k&134217727;c[l+4>>2]=0;if(c[n>>2]|0){n=s;c[n>>2]=0;c[n+4>>2]=0}else{n=s;l=Me(c[n>>2]|0,c[n+4>>2]|0,1,0)|0;n=s;c[n>>2]=l;c[n+4>>2]=C}do if(!(c[o>>2]|0)){n=r;if((c[n>>2]|0)==3&(c[n+4>>2]|0)==0){n=r;c[n>>2]=0;c[n+4>>2]=0;break}else{n=r;l=Me(c[n>>2]|0,c[n+4>>2]|0,1,0)|0;n=r;c[n>>2]=l;c[n+4>>2]=C;break}}else{n=q;l=Me(c[n>>2]|0,c[n+4>>2]|0,1,0)|0;n=q;c[n>>2]=l;c[n+4>>2]=C;n=r;c[n>>2]=3;c[n+4>>2]=0}while(0);o=c[q>>2]|0;q=r;r=Ie(c[q>>2]|0,c[q+4>>2]|0,30)|0;q=o|C;o=s;s=Ie(c[o>>2]|0,c[o+4>>2]|0,3)|0;o=t;c[o>>2]=r|s;c[o+4>>2]=q|C;q=t;t=c[q+4>>2]|0;o=h;c[o>>2]=c[q>>2];c[o+4>>2]=t;v=h;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=g;return x|0}function Bd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;j=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=d;c[j>>2]=c[(c[f>>2]|0)+(c[g>>2]<<2)>>2];c[(c[f>>2]|0)+(c[g>>2]<<2)>>2]=c[(c[f>>2]|0)+(c[h>>2]<<2)>>2];c[(c[f>>2]|0)+(c[h>>2]<<2)>>2]=c[j>>2];i=e;return}function Cd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;g=i;i=i+32|0;h=g+8|0;j=g+28|0;k=g+24|0;l=g;m=g+16|0;c[j>>2]=a;c[k>>2]=b;b=l;c[b>>2]=d;c[b+4>>2]=e;c[g+20>>2]=f;c[m>>2]=sb(c[j>>2]|0,c[k>>2]|0)|0;if(!(c[m>>2]|0)){k=h;c[k>>2]=-1;c[k+4>>2]=-1;n=h;o=n;p=c[o>>2]|0;q=n+4|0;r=q;s=c[r>>2]|0;C=s;i=g;return p|0}k=l;j=c[k+4>>2]|0;f=(c[m>>2]|0)+392|0;e=c[f+4>>2]|0;if((j|0)<(e|0)|((j|0)==(e|0)?(c[k>>2]|0)>>>0<=(c[f>>2]|0)>>>0:0)){t=0;u=0}else{f=l;k=(c[m>>2]|0)+392|0;e=Ge(c[f>>2]|0,c[f+4>>2]|0,c[k>>2]|0,c[k+4>>2]|0)|0;t=e;u=C}e=l;c[e>>2]=t;c[e+4>>2]=u;u=(c[m>>2]|0)+384|0;e=l;l=Ue(c[u>>2]|0,c[u+4>>2]|0,c[e>>2]|0,c[e+4>>2]|0)|0;e=(c[m>>2]|0)+376|0;m=Se(l|0,C|0,c[e>>2]|0,c[e+4>>2]|0)|0;e=h;c[e>>2]=m;c[e+4>>2]=C;n=h;o=n;p=c[o>>2]|0;q=n+4|0;r=q;s=c[r>>2]|0;C=s;i=g;return p|0}function Dd(a,d,f,g,h){a=a|0;d=d|0;f=f|0;g=g|0;h=h|0;var j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;j=i;i=i+80|0;k=j+32|0;l=j+48|0;m=j+52|0;n=j+8|0;o=j+64|0;p=j+40|0;q=j;r=j+56|0;s=j+68|0;t=j+16|0;u=j+24|0;c[l>>2]=a;c[m>>2]=d;d=n;c[d>>2]=f;c[d+4>>2]=g;c[j+60>>2]=h;c[o>>2]=sb(c[l>>2]|0,c[m>>2]|0)|0;if(!(c[o>>2]|0)){m=k;c[m>>2]=-1;c[m+4>>2]=-1;v=k;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=j;return x|0}else{m=n;l=Fe(c[m>>2]|0,c[m+4>>2]|0,c[(c[o>>2]|0)+408>>2]|0)|0;m=p;c[m>>2]=l;c[m+4>>2]=C;m=n;n=c[m>>2]|0;l=c[m+4>>2]|0;m=p;h=Ie(c[m>>2]|0,c[m+4>>2]|0,c[(c[o>>2]|0)+408>>2]|0)|0;m=Ge(n|0,l|0,h|0,C|0)|0;h=q;c[h>>2]=m;c[h+4>>2]=C;h=p;p=q;m=Me(c[h>>2]|0,c[h+4>>2]|0,c[p>>2]|0,c[p+4>>2]|0)|0;p=Fe(m|0,C|0,9)|0;c[r>>2]=p;p=q;q=Fe(c[p>>2]|0,c[p+4>>2]|0,9)|0;b[s>>1]=q;q=Ge(c[r>>2]|0,0,e[s>>1]|0|0,0)|0;s=t;c[s>>2]=q;c[s+4>>2]=C;s=t;t=(c[o>>2]|0)+384|0;q=Ue(c[s>>2]|0,c[s+4>>2]|0,c[t>>2]|0,c[t+4>>2]|0)|0;t=(c[o>>2]|0)+376|0;o=Se(q|0,C|0,c[t>>2]|0,c[t+4>>2]|0)|0;t=u;c[t>>2]=o;c[t+4>>2]=C;t=u;u=c[t+4>>2]|0;o=k;c[o>>2]=c[t>>2];c[o+4>>2]=u;v=k;w=v;x=c[w>>2]|0;y=v+4|0;z=y;A=c[z>>2]|0;C=A;i=j;return x|0}return 0}function Ed(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0;g=i;i=i+48|0;h=g+24|0;j=g+32|0;k=g+36|0;l=g+16|0;m=g+40|0;n=g;o=g+8|0;c[j>>2]=a;c[k>>2]=b;b=l;c[b>>2]=d;c[b+4>>2]=e;c[g+44>>2]=f;c[m>>2]=sb(c[j>>2]|0,c[k>>2]|0)|0;if(!(c[m>>2]|0)){k=h;c[k>>2]=-1;c[k+4>>2]=-1;p=h;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=g;return r|0}else{k=l;l=Fe(c[k>>2]|0,c[k+4>>2]|0,c[(c[m>>2]|0)+408>>2]|0)|0;k=n;c[k>>2]=l;c[k+4>>2]=C;k=n;n=(c[m>>2]|0)+384|0;l=Ue(c[k>>2]|0,c[k+4>>2]|0,c[n>>2]|0,c[n+4>>2]|0)|0;n=(c[m>>2]|0)+376|0;m=Se(l|0,C|0,c[n>>2]|0,c[n+4>>2]|0)|0;n=o;c[n>>2]=m;c[n+4>>2]=C;n=o;o=c[n+4>>2]|0;m=h;c[m>>2]=c[n>>2];c[m+4>>2]=o;p=h;q=p;r=c[q>>2]|0;s=p+4|0;t=s;u=c[t>>2]|0;C=u;i=g;return r|0}return 0}function Fd(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0;g=i;i=i+64|0;h=g+32|0;j=g+40|0;k=g+44|0;l=g;m=g+52|0;n=g+24|0;o=g+8|0;p=g+16|0;c[j>>2]=a;c[k>>2]=b;b=l;c[b>>2]=d;c[b+4>>2]=e;c[g+48>>2]=f;c[m>>2]=sb(c[j>>2]|0,c[k>>2]|0)|0;if(!(c[m>>2]|0)){k=h;c[k>>2]=-1;c[k+4>>2]=-1;q=h;r=q;s=c[r>>2]|0;t=q+4|0;u=t;v=c[u>>2]|0;C=v;i=g;return s|0}k=l;j=Fe(c[k>>2]|0,c[k+4>>2]|0,c[(c[m>>2]|0)+408>>2]|0)|0;k=n;c[k>>2]=j;c[k+4>>2]=C;k=l;j=c[k>>2]|0;f=c[k+4>>2]|0;k=n;e=Ie(c[k>>2]|0,c[k+4>>2]|0,c[(c[m>>2]|0)+408>>2]|0)|0;k=Ge(j|0,f|0,e|0,C|0)|0;e=o;c[e>>2]=k;c[e+4>>2]=C;e=n;n=o;o=Me(c[e>>2]|0,c[e+4>>2]|0,c[n>>2]|0,c[n+4>>2]|0)|0;n=l;c[n>>2]=o;c[n+4>>2]=C;n=l;o=c[n+4>>2]|0;if((o|0)>0|(o|0)==0&(c[n>>2]|0)>>>0>0){n=(c[m>>2]|0)+392|0;o=l;e=Ge(c[o>>2]|0,c[o+4>>2]|0,c[n>>2]|0,c[n+4>>2]|0)|0;n=l;c[n>>2]=e;c[n+4>>2]=C}n=l;l=(c[m>>2]|0)+384|0;e=Ue(c[n>>2]|0,c[n+4>>2]|0,c[l>>2]|0,c[l+4>>2]|0)|0;l=(c[m>>2]|0)+376|0;m=Se(e|0,C|0,c[l>>2]|0,c[l+4>>2]|0)|0;l=p;c[l>>2]=m;c[l+4>>2]=C;l=p;p=c[l+4>>2]|0;m=h;c[m>>2]=c[l>>2];c[m+4>>2]=p;q=h;r=q;s=c[r>>2]|0;t=q+4|0;u=t;v=c[u>>2]|0;C=v;i=g;return s|0}function Gd(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[k>>2]=0;while(1){if((c[h>>2]|0)<=0){l=9;break}if((c[(c[g>>2]|0)+4>>2]|0)>>>0>=(c[(c[g>>2]|0)+8>>2]|0)>>>0){l=9;break}b=(c[(c[g>>2]|0)+12>>2]|0)-(c[h>>2]|0)|0;c[j>>2]=b;m=d[c[(c[g>>2]|0)+4>>2]>>0]|0;if((b|0)>=0)break;c[k>>2]=c[k>>2]|(m&c[2096+(c[(c[g>>2]|0)+12>>2]<<2)>>2])<<0-(c[j>>2]|0);c[h>>2]=(c[h>>2]|0)-(c[(c[g>>2]|0)+12>>2]|0);b=(c[g>>2]|0)+4|0;c[b>>2]=(c[b>>2]|0)+1;c[(c[g>>2]|0)+12>>2]=8}if((l|0)==9){c[f>>2]=c[k>>2];n=c[f>>2]|0;i=e;return n|0}c[k>>2]=c[k>>2]|m>>c[j>>2]&c[2096+(c[h>>2]<<2)>>2];j=(c[g>>2]|0)+12|0;c[j>>2]=(c[j>>2]|0)-(c[h>>2]|0);if(!(c[(c[g>>2]|0)+12>>2]|0)){h=(c[g>>2]|0)+4|0;c[h>>2]=(c[h>>2]|0)+1;c[(c[g>>2]|0)+12>>2]=8}c[f>>2]=c[k>>2];n=c[f>>2]|0;i=e;return n|0}function Hd(){var a=0,d=0,e=0,f=0,g=0;a=i;i=i+16|0;d=a+4|0;e=a;c[e>>2]=0;c[e>>2]=Ae(1,136)|0;if(!(c[e>>2]|0)){c[d>>2]=0;f=c[d>>2]|0;i=a;return f|0}g=Sd()|0;c[(c[e>>2]|0)+112>>2]=g;g=c[e>>2]|0;if(!(c[(c[e>>2]|0)+112>>2]|0)){ze(g);c[d>>2]=0;f=c[d>>2]|0;i=a;return f|0}else{b[g+116>>1]=0;b[(c[e>>2]|0)+118>>1]=0;c[(c[e>>2]|0)+120>>2]=0;g=(c[e>>2]|0)+128|0;c[g>>2]=0;c[g+4>>2]=0;c[d>>2]=c[e>>2];f=c[d>>2]|0;i=a;return f|0}return 0}function Id(a){a=a|0;var b=0,d=0,e=0,f=0;b=i;i=i+16|0;d=b+4|0;e=b;c[e>>2]=a;if(!(c[e>>2]|0)){c[d>>2]=-2;f=c[d>>2]|0;i=b;return f|0}else{Td(c[(c[e>>2]|0)+112>>2]|0);ze(c[e>>2]|0);c[d>>2]=0;f=c[d>>2]|0;i=b;return f|0}return 0}function Jd(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;j=e;c[g>>2]=a;c[h>>2]=d;c[j>>2]=-1;if(!(c[g>>2]|0)){c[f>>2]=-2;k=c[f>>2]|0;i=e;return k|0}if(!(c[h>>2]|0)){c[f>>2]=-13;k=c[f>>2]|0;i=e;return k|0}if(c[(c[h>>2]|0)+12>>2]|0){if((c[(c[g>>2]|0)+120>>2]|0)!=1){c[f>>2]=-1;k=c[f>>2]|0;i=e;return k|0}b[(c[g>>2]|0)+118>>1]=1;c[(c[g>>2]|0)+120>>2]=2;if(c[(c[h>>2]|0)+4>>2]|0){c[f>>2]=-6;k=c[f>>2]|0;i=e;return k|0}else{c[f>>2]=0;k=c[f>>2]|0;i=e;return k|0}}do if(!(ve(c[c[h>>2]>>2]|0,2520,8)|0)){c[j>>2]=Xd(c[g>>2]|0,c[h>>2]|0)|0;if(c[j>>2]|0){if(c[(c[h>>2]|0)+8>>2]|0){if(c[(c[g>>2]|0)+120>>2]|0)c[j>>2]=-14}else c[j>>2]=-12;c[(c[g>>2]|0)+120>>2]=1}}else{if(!(ve(c[c[h>>2]>>2]|0,2536,8)|0)){c[j>>2]=Yd(c[g>>2]|0,c[h>>2]|0)|0;if(!(c[j>>2]|0))break;if((c[(c[g>>2]|0)+120>>2]|0)==1)break;c[j>>2]=-14;break}if(ve(c[c[h>>2]>>2]|0,2552,6)|0){c[j>>2]=-1;break}b[(c[g>>2]|0)+116>>1]=1;c[j>>2]=Zd(c[g>>2]|0,c[h>>2]|0)|0;if((c[j>>2]|0)!=0?(c[(c[g>>2]|0)+120>>2]|0)!=1:0)c[j>>2]=-14}while(0);c[f>>2]=c[j>>2];k=c[f>>2]|0;i=e;return k|0}function Kd(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;j=e;c[g>>2]=a;c[h>>2]=d;c[j>>2]=-1;d=_d(c[g>>2]|0,c[h>>2]|0)|0;c[j>>2]=d;if((d|0)<0){c[f>>2]=c[j>>2];k=c[f>>2]|0;i=e;return k|0}else{b[c[h>>2]>>1]=b[c[g>>2]>>1]|0;c[f>>2]=0;k=c[f>>2]|0;i=e;return k|0}return 0}function Ld(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+16|0;f=e+12|0;g=e+8|0;h=e+4|0;j=e;c[g>>2]=a;c[h>>2]=d;c[j>>2]=-1;d=_d(c[g>>2]|0,c[h>>2]|0)|0;c[j>>2]=d;if((d|0)<0){c[f>>2]=c[j>>2];k=c[f>>2]|0;i=e;return k|0}else{b[c[h>>2]>>1]=b[(c[g>>2]|0)+2>>1]|0;c[f>>2]=0;k=c[f>>2]|0;i=e;return k|0}return 0}function Md(a,b){a=a|0;b=b|0;var d=0,f=0,g=0,h=0,j=0,k=0,l=0;d=i;i=i+32|0;f=d+16|0;g=d+12|0;h=d+8|0;j=d+4|0;k=d;c[g>>2]=a;c[h>>2]=b;c[j>>2]=-1;c[k>>2]=0;b=_d(c[g>>2]|0,c[h>>2]|0)|0;c[j>>2]=b;if((b|0)<0){c[f>>2]=c[j>>2];l=c[f>>2]|0;i=d;return l|0}c[k>>2]=(e[c[g>>2]>>1]|0)<<16|(e[(c[g>>2]|0)+2>>1]|0);if((c[k>>2]|0)>>>0<196610){c[f>>2]=-1;l=c[f>>2]|0;i=d;return l|0}else{k=(c[g>>2]|0)+96|0;g=c[k+4>>2]|0;j=c[h>>2]|0;c[j>>2]=c[k>>2];c[j+4>>2]=g;c[f>>2]=0;l=c[f>>2]|0;i=d;return l|0}return 0}function Nd(a,d,f,g,h,j){a=a|0;d=d|0;f=f|0;g=g|0;h=h|0;j=j|0;var k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0;k=i;i=i+64|0;l=k+44|0;m=k+28|0;n=k+16|0;o=k+20|0;p=k+8|0;q=k+48|0;r=k+24|0;s=k+36|0;t=k+40|0;u=k;v=k+32|0;c[m>>2]=a;c[n>>2]=d;c[o>>2]=f;f=p;c[f>>2]=g;c[f+4>>2]=h;c[q>>2]=j;c[r>>2]=0;c[s>>2]=-1;c[t>>2]=0;j=u;c[j>>2]=-1;c[j+4>>2]=2147483647;j=_d(c[m>>2]|0,c[q>>2]|0)|0;c[s>>2]=j;if((j|0)<0){c[l>>2]=c[s>>2];w=c[l>>2]|0;i=k;return w|0}if(!(b[(c[m>>2]|0)+116>>1]|0)){c[l>>2]=-19;w=c[l>>2]|0;i=k;return w|0}if((c[n>>2]|0)==0|(c[o>>2]|0)==0){c[l>>2]=-1;w=c[l>>2]|0;i=k;return w|0}do if((e[c[m>>2]>>1]|0)==3){s=(c[m>>2]|0)+80|0;j=c[s+4>>2]|0;h=p;f=c[h+4>>2]|0;if(!((j|0)<(f|0)|((j|0)==(f|0)?(c[s>>2]|0)>>>0<(c[h>>2]|0)>>>0:0))?(h=p,s=c[h+4>>2]|0,f=(c[m>>2]|0)+64|0,j=c[f+4>>2]|0,!((s|0)<(j|0)|((s|0)==(j|0)?(c[h>>2]|0)>>>0<(c[f>>2]|0)>>>0:0))):0)break;c[l>>2]=-17;w=c[l>>2]|0;i=k;return w|0}while(0);c[t>>2]=0;while(1){if((c[t>>2]|0)>>>0>=(c[o>>2]|0)>>>0){x=23;break}c[v>>2]=0;f=Wd(c[(c[m>>2]|0)+112>>2]|0,c[(c[n>>2]|0)+(c[t>>2]<<2)>>2]|0)|0;c[r>>2]=f;if(!f){x=14;break}if((e[c[m>>2]>>1]|0)==4){f=(c[r>>2]|0)+32|0;h=c[f+4>>2]|0;j=p;s=c[j+4>>2]|0;if((h|0)<(s|0)|((h|0)==(s|0)?(c[f>>2]|0)>>>0<(c[j>>2]|0)>>>0:0)){x=18;break}j=p;f=c[j+4>>2]|0;s=(c[r>>2]|0)+24|0;h=c[s+4>>2]|0;if((f|0)<(h|0)|((f|0)==(h|0)?(c[j>>2]|0)>>>0<(c[s>>2]|0)>>>0:0)){x=18;break}}s=p;c[v>>2]=$d(c[r>>2]|0,c[s>>2]|0,c[s+4>>2]|0)|0;if((c[v>>2]|0)!=0?(s=c[v>>2]|0,j=c[s+4>>2]|0,h=u,f=c[h+4>>2]|0,!((j|0)>(f|0)|((j|0)==(f|0)?(c[s>>2]|0)>>>0>(c[h>>2]|0)>>>0:0))):0){h=c[v>>2]|0;s=c[h+4>>2]|0;f=u;c[f>>2]=c[h>>2];c[f+4>>2]=s}c[t>>2]=(c[t>>2]|0)+1}if((x|0)==14){c[l>>2]=-8;w=c[l>>2]|0;i=k;return w|0}else if((x|0)==18){c[l>>2]=-17;w=c[l>>2]|0;i=k;return w|0}else if((x|0)==23){x=u;if((c[x>>2]|0)==-1?(c[x+4>>2]|0)==2147483647:0){c[l>>2]=-1;w=c[l>>2]|0;i=k;return w|0}else{x=u;u=c[x+4>>2]|0;t=c[q>>2]|0;c[t>>2]=c[x>>2];c[t+4>>2]=u;c[l>>2]=0;w=c[l>>2]|0;i=k;return w|0}}return 0}function Od(a,b,d){a=a|0;b=b|0;d=d|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f+8|0;l=f+4|0;m=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=-1;d=_d(c[h>>2]|0,c[k>>2]|0)|0;c[l>>2]=d;if((d|0)<0){c[g>>2]=c[l>>2];n=c[g>>2]|0;i=f;return n|0}do if((e[c[h>>2]>>1]|0|0)<4){l=(c[h>>2]|0)+64|0;d=c[l+4>>2]|0;b=c[k>>2]|0;c[b>>2]=c[l>>2];c[b+4>>2]=d}else{c[m>>2]=0;d=Wd(c[(c[h>>2]|0)+112>>2]|0,c[j>>2]|0)|0;c[m>>2]=d;if(d){d=(c[m>>2]|0)+24|0;b=c[d+4>>2]|0;l=c[k>>2]|0;c[l>>2]=c[d>>2];c[l+4>>2]=b;break}c[g>>2]=-8;n=c[g>>2]|0;i=f;return n|0}while(0);c[g>>2]=0;n=c[g>>2]|0;i=f;return n|0}function Pd(a,b,d){a=a|0;b=b|0;d=d|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f+8|0;l=f+4|0;m=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=-1;d=_d(c[h>>2]|0,c[k>>2]|0)|0;c[l>>2]=d;if((d|0)<0){c[g>>2]=c[l>>2];n=c[g>>2]|0;i=f;return n|0}do if((e[c[h>>2]>>1]|0|0)<4){l=(c[h>>2]|0)+72|0;d=c[l+4>>2]|0;b=c[k>>2]|0;c[b>>2]=c[l>>2];c[b+4>>2]=d}else{c[m>>2]=0;d=Wd(c[(c[h>>2]|0)+112>>2]|0,c[j>>2]|0)|0;c[m>>2]=d;if(d){d=(c[m>>2]|0)+16|0;b=c[d+4>>2]|0;l=c[k>>2]|0;c[l>>2]=c[d>>2];c[l+4>>2]=b;break}c[g>>2]=-8;n=c[g>>2]|0;i=f;return n|0}while(0);c[g>>2]=0;n=c[g>>2]|0;i=f;return n|0}function Qd(a,b,d){a=a|0;b=b|0;d=d|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f+8|0;l=f+4|0;m=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=-1;d=_d(c[h>>2]|0,c[k>>2]|0)|0;c[l>>2]=d;if((d|0)<0){c[g>>2]=c[l>>2];n=c[g>>2]|0;i=f;return n|0}do if((e[c[h>>2]>>1]|0|0)<4){l=(c[h>>2]|0)+80|0;d=c[l+4>>2]|0;b=c[k>>2]|0;c[b>>2]=c[l>>2];c[b+4>>2]=d}else{c[m>>2]=0;d=Wd(c[(c[h>>2]|0)+112>>2]|0,c[j>>2]|0)|0;c[m>>2]=d;if(d){d=(c[m>>2]|0)+32|0;b=c[d+4>>2]|0;l=c[k>>2]|0;c[l>>2]=c[d>>2];c[l+4>>2]=b;break}c[g>>2]=-8;n=c[g>>2]|0;i=f;return n|0}while(0);c[g>>2]=0;n=c[g>>2]|0;i=f;return n|0}function Rd(a,b,d){a=a|0;b=b|0;d=d|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0;f=i;i=i+32|0;g=f+20|0;h=f+16|0;j=f+12|0;k=f+8|0;l=f+4|0;m=f;c[h>>2]=a;c[j>>2]=b;c[k>>2]=d;c[l>>2]=-1;d=_d(c[h>>2]|0,c[k>>2]|0)|0;c[l>>2]=d;if((d|0)<0){c[g>>2]=c[l>>2];n=c[g>>2]|0;i=f;return n|0}do if((e[c[h>>2]>>1]|0|0)<4){l=(c[h>>2]|0)+88|0;d=c[l+4>>2]|0;b=c[k>>2]|0;c[b>>2]=c[l>>2];c[b+4>>2]=d}else{c[m>>2]=0;d=Wd(c[(c[h>>2]|0)+112>>2]|0,c[j>>2]|0)|0;c[m>>2]=d;if(d){d=(c[m>>2]|0)+16|0;b=c[d+4>>2]|0;l=c[k>>2]|0;c[l>>2]=c[d>>2];c[l+4>>2]=b;break}c[g>>2]=-8;n=c[g>>2]|0;i=f;return n|0}while(0);c[g>>2]=0;n=c[g>>2]|0;i=f;return n|0}function Sd(){var a=0,b=0,d=0;a=i;i=i+16|0;b=a+4|0;d=a;c[d>>2]=Ae(1,8)|0;if(!(c[d>>2]|0))c[b>>2]=0;else c[b>>2]=c[d>>2];i=a;return c[b>>2]|0}function Td(a){a=a|0;var b=0,d=0,e=0;b=i;i=i+16|0;d=b+4|0;e=b;c[d>>2]=a;c[e>>2]=0;if(!(c[d>>2]|0)){i=b;return}if(c[(c[d>>2]|0)+4>>2]|0){c[e>>2]=0;while(1){if((c[e>>2]|0)>>>0>=(c[c[d>>2]>>2]|0)>>>0)break;if(c[(c[(c[d>>2]|0)+4>>2]|0)+((c[e>>2]|0)*12|0)+4>>2]|0){if(c[(c[(c[(c[d>>2]|0)+4>>2]|0)+((c[e>>2]|0)*12|0)+4>>2]|0)+48>>2]|0)ze(c[(c[(c[(c[d>>2]|0)+4>>2]|0)+((c[e>>2]|0)*12|0)+4>>2]|0)+48>>2]|0);ze(c[(c[(c[d>>2]|0)+4>>2]|0)+((c[e>>2]|0)*12|0)+4>>2]|0)}if(c[(c[(c[d>>2]|0)+4>>2]|0)+((c[e>>2]|0)*12|0)+8>>2]|0){if(c[(c[(c[(c[d>>2]|0)+4>>2]|0)+((c[e>>2]|0)*12|0)+8>>2]|0)+40>>2]|0)ze(c[(c[(c[(c[d>>2]|0)+4>>2]|0)+((c[e>>2]|0)*12|0)+8>>2]|0)+40>>2]|0);ze(c[(c[(c[d>>2]|0)+4>>2]|0)+((c[e>>2]|0)*12|0)+8>>2]|0)}c[e>>2]=(c[e>>2]|0)+1}ze(c[(c[d>>2]|0)+4>>2]|0)}ze(c[d>>2]|0);i=b;return}function Ud(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=0;do if(c[g>>2]|0){if(!(c[h>>2]|0)){c[f>>2]=-1;break}c[k>>2]=be(c[g>>2]|0,c[j>>2]|0)|0;if(!(c[k>>2]|0)){c[f>>2]=-4;break}if(c[(c[k>>2]|0)+4>>2]|0){c[f>>2]=-1;break}else{c[(c[k>>2]|0)+4>>2]=c[h>>2];c[f>>2]=1;break}}else c[f>>2]=-1;while(0);i=e;return c[f>>2]|0}function Vd(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e+4|0;k=e;c[g>>2]=a;c[h>>2]=b;c[j>>2]=d;c[k>>2]=0;do if(c[g>>2]|0){if(!(c[h>>2]|0)){c[f>>2]=-1;break}c[k>>2]=be(c[g>>2]|0,c[j>>2]|0)|0;if(!(c[k>>2]|0)){c[f>>2]=-4;break}if(c[(c[k>>2]|0)+8>>2]|0){c[f>>2]=-1;break}else{c[(c[k>>2]|0)+8>>2]=c[h>>2];c[f>>2]=1;break}}else c[f>>2]=-1;while(0);i=e;return c[f>>2]|0}function Wd(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;c[h>>2]=0;if(!(c[f>>2]|0)){c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}c[h>>2]=ae(c[f>>2]|0,c[g>>2]|0)|0;if(!(c[h>>2]|0))k=0;else k=c[(c[h>>2]|0)+8>>2]|0;c[e>>2]=k;j=c[e>>2]|0;i=d;return j|0}function Xd(b,d){b=b|0;d=d|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+32|0;g=f+16|0;h=f+12|0;j=f+8|0;k=f+4|0;l=f;c[h>>2]=b;c[j>>2]=d;c[l>>2]=0;if(!(c[h>>2]|0)){c[g>>2]=-2;m=c[g>>2]|0;i=f;return m|0}if((c[j>>2]|0)!=0?(c[c[j>>2]>>2]|0)!=0:0){c[l>>2]=(c[c[j>>2]>>2]|0)+8;c[l>>2]=ce(c[l>>2]|0,c[h>>2]|0)|0;c[l>>2]=ce(c[l>>2]|0,(c[h>>2]|0)+2|0)|0;c[k>>2]=(e[c[h>>2]>>1]|0)<<16|(e[(c[h>>2]|0)+2>>1]|0);if((c[k>>2]|0)>>>0>262144){c[g>>2]=-11;m=c[g>>2]|0;i=f;return m|0}if((c[k>>2]|0)==262144?(c[(c[j>>2]|0)+4>>2]|0)!=80:0){c[g>>2]=-18;m=c[g>>2]|0;i=f;return m|0}if((e[c[h>>2]>>1]|0|0)==3){if((e[(c[h>>2]|0)+2>>1]|0|0)>=2?(c[(c[j>>2]|0)+4>>2]|0)!=112:0){c[g>>2]=-18;m=c[g>>2]|0;i=f;return m|0}if((e[(c[h>>2]|0)+2>>1]|0|0)==0?(c[(c[j>>2]|0)+4>>2]|0)!=64:0){c[g>>2]=-18;m=c[g>>2]|0;i=f;return m|0}}c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+8|0)|0;c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+16|0)|0;c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+24|0)|0;c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+32|0)|0;j=(c[h>>2]|0)+40|0;d=c[l>>2]|0;b=j+20|0;do{a[j>>0]=a[d>>0]|0;j=j+1|0;d=d+1|0}while((j|0)<(b|0));if((c[k>>2]|0)>>>0>=196610){c[l>>2]=(c[l>>2]|0)+20;if((e[c[h>>2]>>1]|0|0)==3){c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+64|0)|0;c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+72|0)|0;c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+80|0)|0;c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+88|0)|0}c[l>>2]=de(c[l>>2]|0,(c[h>>2]|0)+96|0)|0;de(c[l>>2]|0,(c[h>>2]|0)+104|0)|0}c[g>>2]=1;m=c[g>>2]|0;i=f;return m|0}c[g>>2]=-13;m=c[g>>2]|0;i=f;return m|0}function Yd(b,d){b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;e=i;i=i+32|0;f=e+20|0;g=e+16|0;h=e+12|0;j=e+8|0;k=e+4|0;l=e;c[g>>2]=b;c[h>>2]=d;c[j>>2]=0;c[k>>2]=-1;c[l>>2]=0;if(!(c[g>>2]|0)){c[f>>2]=-2;m=c[f>>2]|0;i=e;return m|0}if((c[h>>2]|0)!=0?(c[c[h>>2]>>2]|0)!=0:0){if((c[(c[h>>2]|0)+4>>2]|0)<52){c[f>>2]=-7;m=c[f>>2]|0;i=e;return m|0}c[j>>2]=Ae(1,56)|0;if(!(c[j>>2]|0)){c[f>>2]=-4;m=c[f>>2]|0;i=e;return m|0}c[l>>2]=(c[c[h>>2]>>2]|0)+8;c[l>>2]=ee(c[l>>2]|0,c[j>>2]|0)|0;c[l>>2]=fe(c[l>>2]|0,(c[j>>2]|0)+4|0)|0;c[l>>2]=ee(c[l>>2]|0,(c[j>>2]|0)+8|0)|0;c[l>>2]=de(c[l>>2]|0,(c[j>>2]|0)+16|0)|0;c[l>>2]=de(c[l>>2]|0,(c[j>>2]|0)+24|0)|0;c[l>>2]=de(c[l>>2]|0,(c[j>>2]|0)+32|0)|0;c[l>>2]=ee(c[l>>2]|0,(c[j>>2]|0)+40|0)|0;a[(c[j>>2]|0)+44>>0]=a[c[l>>2]>>0]|0;l=Ae((c[(c[h>>2]|0)+4>>2]|0)-52|0,1)|0;c[(c[j>>2]|0)+48>>2]=l;l=c[j>>2]|0;if(!(c[(c[j>>2]|0)+48>>2]|0)){ze(l);c[f>>2]=-4;m=c[f>>2]|0;i=e;return m|0}Ke(c[l+48>>2]|0,(c[c[h>>2]>>2]|0)+52|0,(c[(c[h>>2]|0)+4>>2]|0)-52|0)|0;c[k>>2]=Ud(c[(c[g>>2]|0)+112>>2]|0,c[j>>2]|0,c[(c[j>>2]|0)+4>>2]|0)|0;if((c[k>>2]|0)<0)ze(c[j>>2]|0);c[f>>2]=c[k>>2];m=c[f>>2]|0;i=e;return m|0}c[f>>2]=-13;m=c[f>>2]|0;i=e;return m|0}function Zd(a,b){a=a|0;b=b|0;var d=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;d=i;i=i+80|0;f=d+72|0;g=d+56|0;h=d+60|0;j=d+16|0;k=d+8|0;l=d;m=d+48|0;n=d+76|0;o=d+40|0;p=d+68|0;q=d+64|0;r=d+24|0;s=d+32|0;c[g>>2]=a;c[h>>2]=b;b=j;c[b>>2]=0;c[b+4>>2]=0;b=k;c[b>>2]=0;c[b+4>>2]=0;b=l;c[b>>2]=0;c[b+4>>2]=0;b=m;c[b>>2]=1e3;c[b+4>>2]=0;c[n>>2]=0;b=o;c[b>>2]=-1;c[b+4>>2]=-1;c[p>>2]=0;c[q>>2]=-1;if(!(c[g>>2]|0)){c[f>>2]=-2;t=c[f>>2]|0;i=d;return t|0}if((c[h>>2]|0)!=0?(c[c[h>>2]>>2]|0)!=0:0){c[n>>2]=Ae(1,48)|0;if(!(c[n>>2]|0)){c[f>>2]=-4;t=c[f>>2]|0;i=d;return t|0}c[p>>2]=(c[c[h>>2]>>2]|0)+6;c[p>>2]=fe(c[p>>2]|0,c[n>>2]|0)|0;c[p>>2]=de(c[p>>2]|0,(c[n>>2]|0)+8|0)|0;c[p>>2]=de(c[p>>2]|0,(c[n>>2]|0)+16|0)|0;if(((e[c[g>>2]>>1]|0)<<16|(e[(c[g>>2]|0)+2>>1]|0)|0)==262144){c[p>>2]=de(c[p>>2]|0,(c[n>>2]|0)+24|0)|0;c[p>>2]=de(c[p>>2]|0,(c[n>>2]|0)+32|0)|0}b=(c[n>>2]|0)+16|0;do if((c[b>>2]|0)==0&(c[b+4>>2]|0)==0)c[q>>2]=-9;else{a=(c[n>>2]|0)+8|0;u=Ue(c[a>>2]|0,c[a+4>>2]|0,2,0)|0;a=Me(26,0,u|0,C|0)|0;u=o;c[u>>2]=a;c[u+4>>2]=C;u=o;a=c[u+4>>2]|0;v=c[(c[h>>2]|0)+4>>2]|0;w=((v|0)<0)<<31>>31;if((a|0)>(w|0)|((a|0)==(w|0)?(c[u>>2]|0)>>>0>v>>>0:0)){c[q>>2]=-10;break}v=Ae(c[(c[n>>2]|0)+8>>2]|0,16)|0;c[(c[n>>2]|0)+40>>2]=v;if(!(c[(c[n>>2]|0)+40>>2]|0)){c[q>>2]=-4;break}v=j;c[v>>2]=0;c[v+4>>2]=0;while(1){v=j;u=c[v+4>>2]|0;w=(c[n>>2]|0)+8|0;a=c[w+4>>2]|0;if(!((u|0)<(a|0)|((u|0)==(a|0)?(c[v>>2]|0)>>>0<(c[w>>2]|0)>>>0:0)))break;w=r;c[w>>2]=0;c[w+4>>2]=0;w=s;c[w>>2]=0;c[w+4>>2]=0;c[p>>2]=ge(c[p>>2]|0,r)|0;w=r;v=k;a=Me(c[v>>2]|0,c[v+4>>2]|0,c[w>>2]|0,c[w+4>>2]|0)|0;w=k;c[w>>2]=a;c[w+4>>2]=C;c[p>>2]=ge(c[p>>2]|0,s)|0;w=s;a=l;v=Me(c[a>>2]|0,c[a+4>>2]|0,c[w>>2]|0,c[w+4>>2]|0)|0;w=l;c[w>>2]=v;c[w+4>>2]=C;w=k;v=c[w+4>>2]|0;a=(c[(c[n>>2]|0)+40>>2]|0)+(c[j>>2]<<4)|0;c[a>>2]=c[w>>2];c[a+4>>2]=v;v=l;a=m;w=Ue(c[v>>2]|0,c[v+4>>2]|0,c[a>>2]|0,c[a+4>>2]|0)|0;a=(c[n>>2]|0)+16|0;v=Se(w|0,C|0,c[a>>2]|0,c[a+4>>2]|0)|0;a=(c[(c[n>>2]|0)+40>>2]|0)+(c[j>>2]<<4)+8|0;c[a>>2]=v;c[a+4>>2]=C;a=j;v=Me(c[a>>2]|0,c[a+4>>2]|0,1,0)|0;a=j;c[a>>2]=v;c[a+4>>2]=C}c[q>>2]=Vd(c[(c[g>>2]|0)+112>>2]|0,c[n>>2]|0,c[c[n>>2]>>2]|0)|0}while(0);if((c[q>>2]|0)<0)ze(c[n>>2]|0);c[f>>2]=c[q>>2];t=c[f>>2]|0;i=d;return t|0}c[f>>2]=-13;t=c[f>>2]|0;i=d;return t|0}function _d(a,d){a=a|0;d=d|0;var e=0,f=0,g=0,h=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[g>>2]=a;c[h>>2]=d;do if(c[g>>2]|0){if(!(b[(c[g>>2]|0)+118>>1]|0)){c[f>>2]=-5;break}if(!(c[h>>2]|0)){c[f>>2]=-16;break}else{c[f>>2]=0;break}}else c[f>>2]=-2;while(0);i=e;return c[f>>2]|0}function $d(a,b,d){a=a|0;b=b|0;d=d|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0;e=i;i=i+48|0;f=e+36|0;g=e+32|0;h=e+24|0;j=e+16|0;k=e+8|0;l=e;c[g>>2]=a;a=h;c[a>>2]=b;c[a+4>>2]=d;d=j;c[d>>2]=0;c[d+4>>2]=0;d=k;c[d>>2]=0;c[d+4>>2]=0;if(!(c[g>>2]|0)){c[f>>2]=0;m=c[f>>2]|0;i=e;return m|0}d=(c[g>>2]|0)+8|0;a=Ge(c[d>>2]|0,c[d+4>>2]|0,1,0)|0;d=k;c[d>>2]=a;c[d+4>>2]=C;while(1){d=k;a=c[d+4>>2]|0;b=j;n=c[b+4>>2]|0;if(!((a|0)>(n|0)|((a|0)==(n|0)?(c[d>>2]|0)>>>0>(c[b>>2]|0)>>>0:0)))break;b=j;d=k;n=Me(c[b>>2]|0,c[b+4>>2]|0,c[d>>2]|0,c[d+4>>2]|0)|0;d=Me(n|0,C|0,1,0)|0;n=Fe(d|0,C|0,1)|0;d=l;c[d>>2]=n;c[d+4>>2]=C;d=(c[(c[g>>2]|0)+40>>2]|0)+(c[l>>2]<<4)+8|0;n=h;b=l;o=c[b>>2]|0;p=c[b+4>>2]|0;if((c[d>>2]|0)==(c[n>>2]|0)?(c[d+4>>2]|0)==(c[n+4>>2]|0):0){q=6;break}n=(c[(c[g>>2]|0)+40>>2]|0)+(o<<4)+8|0;d=c[n+4>>2]|0;b=h;a=c[b+4>>2]|0;r=l;s=c[r>>2]|0;t=c[r+4>>2]|0;if((d|0)<(a|0)|((d|0)==(a|0)?(c[n>>2]|0)>>>0<(c[b>>2]|0)>>>0:0)){b=j;c[b>>2]=s;c[b+4>>2]=t;continue}else{b=Ge(s|0,t|0,1,0)|0;t=k;c[t>>2]=b;c[t+4>>2]=C;continue}}if((q|0)==6){q=j;c[q>>2]=o;c[q+4>>2]=p}c[f>>2]=(c[(c[g>>2]|0)+40>>2]|0)+(c[j>>2]<<4);m=c[f>>2]|0;i=e;return m|0}function ae(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;c[h>>2]=0;c[h>>2]=0;while(1){if((c[h>>2]|0)>>>0>=(c[c[f>>2]>>2]|0)>>>0){j=6;break}k=c[h>>2]|0;if((c[(c[(c[f>>2]|0)+4>>2]|0)+((c[h>>2]|0)*12|0)>>2]|0)==(c[g>>2]|0)){j=4;break}c[h>>2]=k+1}if((j|0)==4){c[e>>2]=(c[(c[f>>2]|0)+4>>2]|0)+(k*12|0);l=c[e>>2]|0;i=d;return l|0}else if((j|0)==6){c[e>>2]=0;l=c[e>>2]|0;i=d;return l|0}return 0}function be(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0;d=i;i=i+16|0;e=d+12|0;f=d+8|0;g=d+4|0;h=d;c[f>>2]=a;c[g>>2]=b;c[h>>2]=0;b=ae(c[f>>2]|0,c[g>>2]|0)|0;c[h>>2]=b;do if(!b){c[h>>2]=Be(c[(c[f>>2]|0)+4>>2]|0,((c[c[f>>2]>>2]|0)+1|0)*12|0)|0;if(c[h>>2]|0){c[(c[f>>2]|0)+4>>2]=c[h>>2];a=c[f>>2]|0;c[a>>2]=(c[a>>2]|0)+1;c[h>>2]=(c[(c[f>>2]|0)+4>>2]|0)+(((c[c[f>>2]>>2]|0)-1|0)*12|0);c[c[h>>2]>>2]=c[g>>2];c[(c[h>>2]|0)+4>>2]=0;c[(c[h>>2]|0)+8>>2]=0;break}c[e>>2]=0;j=c[e>>2]|0;i=d;return j|0}while(0);c[e>>2]=c[h>>2];j=c[e>>2]|0;i=d;return j|0}function ce(a,e){a=a|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;f=i;i=i+16|0;g=f+8|0;h=f+4|0;j=f;c[h>>2]=a;c[j>>2]=e;if((c[h>>2]|0)==0|(c[j>>2]|0)==0){c[g>>2]=0;k=c[g>>2]|0;i=f;return k|0}else{b[c[j>>2]>>1]=d[c[h>>2]>>0]|0|(d[(c[h>>2]|0)+1>>0]|0)<<8;c[g>>2]=(c[h>>2]|0)+2;k=c[g>>2]|0;i=f;return k|0}return 0}function de(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0,k=0;d=i;i=i+32|0;e=d+16|0;f=d+12|0;g=d+8|0;h=d+4|0;j=d;c[f>>2]=a;c[g>>2]=b;c[h>>2]=-1;c[j>>2]=-1;if((c[f>>2]|0)==0|(c[g>>2]|0)==0){c[e>>2]=0;k=c[e>>2]|0;i=d;return k|0}else{c[f>>2]=ee(c[f>>2]|0,h)|0;c[f>>2]=fe(c[f>>2]|0,j)|0;b=c[j>>2]|0;j=Me(c[h>>2]|0,0,0,b|0)|0;b=c[g>>2]|0;c[b>>2]=j;c[b+4>>2]=C;c[e>>2]=c[f>>2];k=c[e>>2]|0;i=d;return k|0}return 0}function ee(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[g>>2]=a;c[h>>2]=b;if((c[g>>2]|0)==0|(c[h>>2]|0)==0){c[f>>2]=0;j=c[f>>2]|0;i=e;return j|0}else{c[c[h>>2]>>2]=d[c[g>>2]>>0]|0|(d[(c[g>>2]|0)+1>>0]|0)<<8|(d[(c[g>>2]|0)+2>>0]|0)<<16|(d[(c[g>>2]|0)+3>>0]|0)<<24;c[f>>2]=(c[g>>2]|0)+4;j=c[f>>2]|0;i=e;return j|0}return 0}function fe(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0;e=i;i=i+16|0;f=e+8|0;g=e+4|0;h=e;c[g>>2]=a;c[h>>2]=b;if((c[g>>2]|0)==0|(c[h>>2]|0)==0){c[f>>2]=0;j=c[f>>2]|0;i=e;return j|0}else{c[c[h>>2]>>2]=d[c[g>>2]>>0]|0|(d[(c[g>>2]|0)+1>>0]|0)<<8|(d[(c[g>>2]|0)+2>>0]|0)<<16|(d[(c[g>>2]|0)+3>>0]|0)<<24;c[f>>2]=(c[g>>2]|0)+4;j=c[f>>2]|0;i=e;return j|0}return 0}function ge(a,b){a=a|0;b=b|0;var e=0,f=0,g=0,h=0,j=0,k=0,l=0,m=0;e=i;i=i+32|0;f=e+16|0;g=e+12|0;h=e+8|0;j=e;c[f>>2]=a;c[g>>2]=b;c[h>>2]=0;b=j;c[b>>2]=0;c[b+4>>2]=0;b=c[g>>2]|0;c[b>>2]=0;c[b+4>>2]=0;do{b=j;c[b>>2]=d[c[f>>2]>>0];c[b+4>>2]=0;b=Ie(c[j>>2]&127|0,0,c[h>>2]|0)|0;a=c[g>>2]|0;k=a;l=c[k+4>>2]|C;m=a;c[m>>2]=c[k>>2]|b;c[m+4>>2]=l;c[h>>2]=(c[h>>2]|0)+7;c[f>>2]=(c[f>>2]|0)+1}while(0!=0?1:(c[j>>2]&128|0)!=128);i=e;return c[f>>2]|0}function he(){var a=0;c[644]=0;a=ob(32)|0;c[646]=a;Gb(a,-1,8,0)|0;c[648]=Hd()|0;return}function ie(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;d=i;i=i+16|0;e=d+8|0;f=d;c[662]=1;do if((c[644]|0)==2){if((c[650]|0)!=0?(ua()|0)==0:0)break;if((c[652]|0)!=0?(Ja()|0)==0:0)break;c[662]=0}while(0);do if((b|0)>0){g=Mb(c[646]|0,a,b)|0;if((g|0)<0){c[f>>2]=g;za(2656,f|0)|0;break}if((g|0)<(b|0)){c[e>>2]=g;c[e+4>>2]=b;za(2688,e|0)|0}}while(0);i=d;return c[662]^1|0}function je(){Id(c[648]|0)|0;pb(c[646]|0)|0;return}function ke(){var a=0,b=0,d=0,e=0;a=i;i=i+16|0;b=a;d=b;c[d>>2]=-1;c[d+4>>2]=-1;if(!(c[654]|0)){e=-1;i=a;return e|0}Md(c[648]|0,b)|0;e=c[b>>2]|0;i=a;return e|0}function le(){var a=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0,l=0.0,m=0,n=0.0,o=0.0,p=0,q=0,r=0.0,s=0.0,t=0.0,u=0.0,v=0.0;a=i;i=i+48|0;d=a+42|0;e=a+40|0;f=a+32|0;g=a+24|0;h=a+16|0;j=a;k=a+8|0;if(!(c[654]|0)){l=-1.0;i=a;return +l}b[d>>1]=-1;b[e>>1]=-1;Kd(c[648]|0,d)|0;Ld(c[648]|0,e)|0;e=c[656]|0;if(!e)m=0;else{c[f>>2]=e;m=1}e=c[658]|0;if(!e)if(!m){n=-1.0;o=-1.0}else{p=1;q=7}else{c[f+(m<<2)>>2]=e;p=m+1|0;q=7}if((q|0)==7){r=-1.0;q=0;s=-1.0;while(1){m=g;c[m>>2]=-1;c[m+4>>2]=-1;m=h;c[m>>2]=-1;c[m+4>>2]=-1;m=j;c[m>>2]=-1;c[m+4>>2]=-1;m=k;c[m>>2]=-1;c[m+4>>2]=-1;m=c[f+(q<<2)>>2]|0;Od(c[648]|0,m,g)|0;Pd(c[648]|0,m,h)|0;Qd(c[648]|0,m,j)|0;Rd(c[648]|0,m,k)|0;m=g;e=h;t=(+((c[m>>2]|0)>>>0)+4294967296.0*+(c[m+4>>2]|0))/(+((c[e>>2]|0)>>>0)+4294967296.0*+(c[e+4>>2]|0));u=r==-1.0|t<r?t:r;e=j;m=k;t=(+((c[e>>2]|0)>>>0)+4294967296.0*+(c[e+4>>2]|0))/(+((c[m>>2]|0)>>>0)+4294967296.0*+(c[m+4>>2]|0));v=s==-1.0|t>s?t:s;q=q+1|0;if((q|0)==(p|0)){n=u;o=v;break}else{r=u;s=v}}}l=o-n;i=a;return +l}function me(){return c[654]|0}function ne(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,j=0,k=0;b=i;i=i+16|0;d=b;e=b+8|0;f=d;c[f>>2]=-1;c[f+4>>2]=-1;if(!(c[654]|0)){g=-1;i=b;return g|0}f=c[656]|0;if(!f){h=c[658]|0;if(!h){j=e;k=0}else{c[e>>2]=h;j=e;k=1}}else{c[e>>2]=f;j=e;k=1}Nd(c[648]|0,j,k,a,((a|0)<0)<<31>>31,d)|0;g=c[d>>2]|0;i=b;return g|0}function oe(){Ob(c[646]|0)|0;Pb(c[646]|0,0,1)|0;return}function pe(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0;e=i;i=i+16|0;a=e+8|0;f=e;c[662]=0;g=c[644]|0;if(!g){if(!(c[b+8>>2]|0))if(!(c[660]|0)){c[644]=2;na(c[640]|0,c[642]|0);re(b,d);h=0;i=e;return h|0}else{c[644]=1;h=qe(b,d)|0;i=e;return h|0}j=Xb(c[646]|0,d)|0;if(!(c[656]|j)){c[650]=j;c[640]=2744;c[656]=d;xa(c[b>>2]|0,c[b+4>>2]|0,-1.0,-1.0);h=0;i=e;return h|0}k=(c[658]|0)==0;if((j|0)==1&k){c[652]=1;c[642]=2752;c[658]=d;ma(c[b>>2]|0,c[b+4>>2]|0,-1.0);h=0;i=e;return h|0}if((j|0)==13&k){c[652]=13;c[642]=2760;c[658]=d;ma(c[b>>2]|0,c[b+4>>2]|0,-1.0);h=0;i=e;return h|0}if(!((j|0)==6&(c[660]|0)==0)){h=0;i=e;return h|0}c[660]=d;j=Jd(c[648]|0,b)|0;if(!j){c[654]=1;h=0;i=e;return h|0}if((j|0)>0){h=0;i=e;return h|0}c[f>>2]=j;za(2768,f|0)|0;h=-1;i=e;return h|0}else if((g|0)==2){re(b,d);h=0;i=e;return h|0}else if((g|0)==1){h=qe(b,d)|0;i=e;return h|0}else{za(2808,a|0)|0;h=-1;i=e;return h|0}return 0}function qe(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,j=0.0,k=0,l=0,m=0,n=0.0,o=0;d=i;i=i+32|0;e=d+16|0;f=d+8|0;g=d;h=qb(c[646]|0)|0;j=(+(h>>>0)+4294967296.0*+(C|0))/1.0e3;h=rb(c[646]|0)|0;k=C;l=nc(c[646]|0,b)|0;m=f;c[m>>2]=0;c[m+4>>2]=0;m=g;c[m>>2]=0;c[m+4>>2]=0;pc(c[646]|0,b,f,g)|0;m=Fe(h|0,k|0,l|0)|0;l=g;g=f;n=(+(m>>>0)+4294967296.0*+(C|0))*(+((c[l>>2]|0)>>>0)+4294967296.0*+(c[l+4>>2]|0))/(+((c[g>>2]|0)>>>0)+4294967296.0*+(c[g+4>>2]|0));do if((c[660]|0)==(b|0)){g=Jd(c[648]|0,a)|0;if((g|0)<0){c[e>>2]=g;za(2848,e|0)|0;o=-1;i=d;return o|0}else{if(!(c[a+12>>2]|0))break;c[654]=1;c[644]=2;na(c[640]|0,c[642]|0);break}}while(0);if((c[656]|0)==(b|0))xa(c[a>>2]|0,c[a+4>>2]|0,+j,+n);if((c[658]|0)!=(b|0)){o=0;i=d;return o|0}ma(c[a>>2]|0,c[a+4>>2]|0,+j);o=0;i=d;return o|0}function re(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0.0,j=0,k=0,l=0,m=0,n=0;d=i;i=i+16|0;e=d+8|0;f=d;g=qb(c[646]|0)|0;h=(+(g>>>0)+4294967296.0*+(C|0))/1.0e3;g=rb(c[646]|0)|0;j=C;k=nc(c[646]|0,b)|0;l=e;c[l>>2]=0;c[l+4>>2]=0;l=f;c[l>>2]=0;c[l+4>>2]=0;pc(c[646]|0,b,e,f)|0;l=f;f=c[l>>2]|0;m=c[l+4>>2]|0;l=e;e=c[l>>2]|0;n=c[l+4>>2]|0;if((c[656]|0)==(b|0)){l=Fe(g|0,j|0,k|0)|0;xa(c[a>>2]|0,c[a+4>>2]|0,+h,+((+(l>>>0)+4294967296.0*+(C|0))*(+(f>>>0)+4294967296.0*+(m|0))/(+(e>>>0)+4294967296.0*+(n|0))))}if((c[658]|0)!=(b|0)){i=d;return}ma(c[a>>2]|0,c[a+4>>2]|0,+h);i=d;return}function se(a){a=a|0;return (a+-65|0)>>>0<26|0}function te(a){a=a|0;var b=0;b=(se(a)|0)==0;return (b?a:a|32)|0}function ue(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0;f=d&255;g=(e|0)!=0;a:do if(g&(b&3|0)!=0){h=d&255;i=e;j=b;while(1){if((a[j>>0]|0)==h<<24>>24){k=i;l=j;m=6;break a}n=j+1|0;o=i+-1|0;p=(o|0)!=0;if(p&(n&3|0)!=0){i=o;j=n}else{q=o;r=p;s=n;m=5;break}}}else{q=e;r=g;s=b;m=5}while(0);if((m|0)==5)if(r){k=q;l=s;m=6}else{t=0;u=s}b:do if((m|0)==6){s=d&255;if((a[l>>0]|0)==s<<24>>24){t=k;u=l}else{q=_(f,16843009)|0;c:do if(k>>>0>3){r=k;b=l;while(1){g=c[b>>2]^q;if((g&-2139062144^-2139062144)&g+-16843009){v=r;w=b;break}g=b+4|0;e=r+-4|0;if(e>>>0>3){r=e;b=g}else{x=e;y=g;m=11;break c}}z=v;A=w}else{x=k;y=l;m=11}while(0);if((m|0)==11)if(!x){t=0;u=y;break}else{z=x;A=y}while(1){if((a[A>>0]|0)==s<<24>>24){t=z;u=A;break b}q=A+1|0;z=z+-1|0;if(!z){t=0;u=q;break}else A=q}}}while(0);return ((t|0)!=0?u:0)|0}function ve(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0;if(!d){e=0;return e|0}else{f=d;g=b;h=c}while(1){c=a[g>>0]|0;b=a[h>>0]|0;if(c<<24>>24!=b<<24>>24){i=c;j=b;break}f=f+-1|0;if(!f){e=0;k=5;break}else{g=g+1|0;h=h+1|0}}if((k|0)==5)return e|0;e=(i&255)-(j&255)|0;return e|0}function we(b,c){b=b|0;c=c|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;e=a[b>>0]|0;a:do if(!(e<<24>>24)){f=0;g=c}else{h=e;i=e&255;j=b;k=c;while(1){l=a[k>>0]|0;if(!(l<<24>>24)){f=h;g=k;break a}if(h<<24>>24!=l<<24>>24?(l=te(i)|0,(l|0)!=(te(d[k>>0]|0)|0)):0){m=j;n=k;break}j=j+1|0;l=k+1|0;o=a[j>>0]|0;if(!(o<<24>>24)){f=0;g=l;break a}else{h=o;i=o&255;k=l}}f=a[m>>0]|0;g=n}while(0);n=te(f&255)|0;return n-(te(d[g>>0]|0)|0)|0}function xe(b,c){b=b|0;c=c|0;var d=0,e=0,f=0,g=0;d=a[b>>0]|0;e=a[c>>0]|0;if(d<<24>>24==0?1:d<<24>>24!=e<<24>>24){f=d;g=e}else{e=b;b=c;do{e=e+1|0;b=b+1|0;c=a[e>>0]|0;d=a[b>>0]|0}while(!(c<<24>>24==0?1:c<<24>>24!=d<<24>>24));f=c;g=d}return (f&255)-(g&255)|0} +function ye(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=0,_=0,$=0,aa=0,ba=0,ca=0,da=0,ea=0,fa=0,ga=0,ha=0,ia=0,ja=0,ka=0,la=0,ma=0,na=0,oa=0,pa=0,qa=0,sa=0,ta=0,ua=0,wa=0,xa=0,ya=0,za=0,Aa=0,Ba=0,Ca=0,Fa=0,Ha=0,Ia=0,Ja=0,Ka=0,La=0,Ma=0,Na=0,Oa=0,Pa=0,Qa=0,Ra=0,Sa=0,Ta=0,Ua=0,Va=0,Wa=0,Xa=0;do if(a>>>0<245){b=a>>>0<11?16:a+11&-8;d=b>>>3;e=c[722]|0;f=e>>>d;if(f&3){g=(f&1^1)+d|0;h=g<<1;i=2928+(h<<2)|0;j=2928+(h+2<<2)|0;h=c[j>>2]|0;k=h+8|0;l=c[k>>2]|0;do if((i|0)!=(l|0)){if(l>>>0<(c[726]|0)>>>0)Ea();m=l+12|0;if((c[m>>2]|0)==(h|0)){c[m>>2]=i;c[j>>2]=l;break}else Ea()}else c[722]=e&~(1<<g);while(0);l=g<<3;c[h+4>>2]=l|3;j=h+(l|4)|0;c[j>>2]=c[j>>2]|1;n=k;return n|0}j=c[724]|0;if(b>>>0>j>>>0){if(f){l=2<<d;i=f<<d&(l|0-l);l=(i&0-i)+-1|0;i=l>>>12&16;m=l>>>i;l=m>>>5&8;o=m>>>l;m=o>>>2&4;p=o>>>m;o=p>>>1&2;q=p>>>o;p=q>>>1&1;r=(l|i|m|o|p)+(q>>>p)|0;p=r<<1;q=2928+(p<<2)|0;o=2928+(p+2<<2)|0;p=c[o>>2]|0;m=p+8|0;i=c[m>>2]|0;do if((q|0)!=(i|0)){if(i>>>0<(c[726]|0)>>>0)Ea();l=i+12|0;if((c[l>>2]|0)==(p|0)){c[l>>2]=q;c[o>>2]=i;s=c[724]|0;break}else Ea()}else{c[722]=e&~(1<<r);s=j}while(0);j=r<<3;e=j-b|0;c[p+4>>2]=b|3;i=p+b|0;c[p+(b|4)>>2]=e|1;c[p+j>>2]=e;if(s){j=c[727]|0;o=s>>>3;q=o<<1;d=2928+(q<<2)|0;f=c[722]|0;k=1<<o;if(f&k){o=2928+(q+2<<2)|0;h=c[o>>2]|0;if(h>>>0<(c[726]|0)>>>0)Ea();else{t=o;u=h}}else{c[722]=f|k;t=2928+(q+2<<2)|0;u=d}c[t>>2]=j;c[u+12>>2]=j;c[j+8>>2]=u;c[j+12>>2]=d}c[724]=e;c[727]=i;n=m;return n|0}i=c[723]|0;if(i){e=(i&0-i)+-1|0;i=e>>>12&16;d=e>>>i;e=d>>>5&8;j=d>>>e;d=j>>>2&4;q=j>>>d;j=q>>>1&2;k=q>>>j;q=k>>>1&1;f=c[3192+((e|i|d|j|q)+(k>>>q)<<2)>>2]|0;q=(c[f+4>>2]&-8)-b|0;k=f;j=f;while(1){f=c[k+16>>2]|0;if(!f){d=c[k+20>>2]|0;if(!d){v=q;w=j;break}else x=d}else x=f;f=(c[x+4>>2]&-8)-b|0;d=f>>>0<q>>>0;q=d?f:q;k=x;j=d?x:j}j=c[726]|0;if(w>>>0<j>>>0)Ea();k=w+b|0;if(w>>>0>=k>>>0)Ea();q=c[w+24>>2]|0;m=c[w+12>>2]|0;do if((m|0)==(w|0)){p=w+20|0;r=c[p>>2]|0;if(!r){d=w+16|0;f=c[d>>2]|0;if(!f){y=0;break}else{z=f;A=d}}else{z=r;A=p}while(1){p=z+20|0;r=c[p>>2]|0;if(r){z=r;A=p;continue}p=z+16|0;r=c[p>>2]|0;if(!r){B=z;C=A;break}else{z=r;A=p}}if(C>>>0<j>>>0)Ea();else{c[C>>2]=0;y=B;break}}else{p=c[w+8>>2]|0;if(p>>>0<j>>>0)Ea();r=p+12|0;if((c[r>>2]|0)!=(w|0))Ea();d=m+8|0;if((c[d>>2]|0)==(w|0)){c[r>>2]=m;c[d>>2]=p;y=m;break}else Ea()}while(0);do if(q){m=c[w+28>>2]|0;j=3192+(m<<2)|0;if((w|0)==(c[j>>2]|0)){c[j>>2]=y;if(!y){c[723]=c[723]&~(1<<m);break}}else{if(q>>>0<(c[726]|0)>>>0)Ea();m=q+16|0;if((c[m>>2]|0)==(w|0))c[m>>2]=y;else c[q+20>>2]=y;if(!y)break}m=c[726]|0;if(y>>>0<m>>>0)Ea();c[y+24>>2]=q;j=c[w+16>>2]|0;do if(j)if(j>>>0<m>>>0)Ea();else{c[y+16>>2]=j;c[j+24>>2]=y;break}while(0);j=c[w+20>>2]|0;if(j)if(j>>>0<(c[726]|0)>>>0)Ea();else{c[y+20>>2]=j;c[j+24>>2]=y;break}}while(0);if(v>>>0<16){q=v+b|0;c[w+4>>2]=q|3;j=w+(q+4)|0;c[j>>2]=c[j>>2]|1}else{c[w+4>>2]=b|3;c[w+(b|4)>>2]=v|1;c[w+(v+b)>>2]=v;j=c[724]|0;if(j){q=c[727]|0;m=j>>>3;j=m<<1;p=2928+(j<<2)|0;d=c[722]|0;r=1<<m;if(d&r){m=2928+(j+2<<2)|0;f=c[m>>2]|0;if(f>>>0<(c[726]|0)>>>0)Ea();else{D=m;E=f}}else{c[722]=d|r;D=2928+(j+2<<2)|0;E=p}c[D>>2]=q;c[E+12>>2]=q;c[q+8>>2]=E;c[q+12>>2]=p}c[724]=v;c[727]=k}n=w+8|0;return n|0}else F=b}else F=b}else if(a>>>0<=4294967231){p=a+11|0;q=p&-8;j=c[723]|0;if(j){r=0-q|0;d=p>>>8;if(d)if(q>>>0>16777215)G=31;else{p=(d+1048320|0)>>>16&8;f=d<<p;d=(f+520192|0)>>>16&4;m=f<<d;f=(m+245760|0)>>>16&2;i=14-(d|p|f)+(m<<f>>>15)|0;G=q>>>(i+7|0)&1|i<<1}else G=0;i=c[3192+(G<<2)>>2]|0;a:do if(!i){H=r;I=0;J=0;K=86}else{f=r;m=0;p=q<<((G|0)==31?0:25-(G>>>1)|0);d=i;e=0;while(1){h=c[d+4>>2]&-8;o=h-q|0;if(o>>>0<f>>>0)if((h|0)==(q|0)){L=o;M=d;N=d;K=90;break a}else{O=o;P=d}else{O=f;P=e}o=c[d+20>>2]|0;d=c[d+16+(p>>>31<<2)>>2]|0;h=(o|0)==0|(o|0)==(d|0)?m:o;if(!d){H=O;I=h;J=P;K=86;break}else{f=O;m=h;p=p<<1;e=P}}}while(0);if((K|0)==86){if((I|0)==0&(J|0)==0){i=2<<G;r=j&(i|0-i);if(!r){F=q;break}i=(r&0-r)+-1|0;r=i>>>12&16;b=i>>>r;i=b>>>5&8;k=b>>>i;b=k>>>2&4;e=k>>>b;k=e>>>1&2;p=e>>>k;e=p>>>1&1;Q=c[3192+((i|r|b|k|e)+(p>>>e)<<2)>>2]|0;R=0}else{Q=I;R=J}if(!Q){S=H;T=R}else{L=H;M=Q;N=R;K=90}}if((K|0)==90)while(1){K=0;e=(c[M+4>>2]&-8)-q|0;p=e>>>0<L>>>0;k=p?e:L;e=p?M:N;p=c[M+16>>2]|0;if(p){L=k;M=p;N=e;K=90;continue}M=c[M+20>>2]|0;if(!M){S=k;T=e;break}else{L=k;N=e;K=90}}if((T|0)!=0?S>>>0<((c[724]|0)-q|0)>>>0:0){j=c[726]|0;if(T>>>0<j>>>0)Ea();e=T+q|0;if(T>>>0>=e>>>0)Ea();k=c[T+24>>2]|0;p=c[T+12>>2]|0;do if((p|0)==(T|0)){b=T+20|0;r=c[b>>2]|0;if(!r){i=T+16|0;m=c[i>>2]|0;if(!m){U=0;break}else{V=m;W=i}}else{V=r;W=b}while(1){b=V+20|0;r=c[b>>2]|0;if(r){V=r;W=b;continue}b=V+16|0;r=c[b>>2]|0;if(!r){X=V;Y=W;break}else{V=r;W=b}}if(Y>>>0<j>>>0)Ea();else{c[Y>>2]=0;U=X;break}}else{b=c[T+8>>2]|0;if(b>>>0<j>>>0)Ea();r=b+12|0;if((c[r>>2]|0)!=(T|0))Ea();i=p+8|0;if((c[i>>2]|0)==(T|0)){c[r>>2]=p;c[i>>2]=b;U=p;break}else Ea()}while(0);do if(k){p=c[T+28>>2]|0;j=3192+(p<<2)|0;if((T|0)==(c[j>>2]|0)){c[j>>2]=U;if(!U){c[723]=c[723]&~(1<<p);break}}else{if(k>>>0<(c[726]|0)>>>0)Ea();p=k+16|0;if((c[p>>2]|0)==(T|0))c[p>>2]=U;else c[k+20>>2]=U;if(!U)break}p=c[726]|0;if(U>>>0<p>>>0)Ea();c[U+24>>2]=k;j=c[T+16>>2]|0;do if(j)if(j>>>0<p>>>0)Ea();else{c[U+16>>2]=j;c[j+24>>2]=U;break}while(0);j=c[T+20>>2]|0;if(j)if(j>>>0<(c[726]|0)>>>0)Ea();else{c[U+20>>2]=j;c[j+24>>2]=U;break}}while(0);b:do if(S>>>0>=16){c[T+4>>2]=q|3;c[T+(q|4)>>2]=S|1;c[T+(S+q)>>2]=S;k=S>>>3;if(S>>>0<256){j=k<<1;p=2928+(j<<2)|0;b=c[722]|0;i=1<<k;if(b&i){k=2928+(j+2<<2)|0;r=c[k>>2]|0;if(r>>>0<(c[726]|0)>>>0)Ea();else{Z=k;_=r}}else{c[722]=b|i;Z=2928+(j+2<<2)|0;_=p}c[Z>>2]=e;c[_+12>>2]=e;c[T+(q+8)>>2]=_;c[T+(q+12)>>2]=p;break}p=S>>>8;if(p)if(S>>>0>16777215)$=31;else{j=(p+1048320|0)>>>16&8;i=p<<j;p=(i+520192|0)>>>16&4;b=i<<p;i=(b+245760|0)>>>16&2;r=14-(p|j|i)+(b<<i>>>15)|0;$=S>>>(r+7|0)&1|r<<1}else $=0;r=3192+($<<2)|0;c[T+(q+28)>>2]=$;c[T+(q+20)>>2]=0;c[T+(q+16)>>2]=0;i=c[723]|0;b=1<<$;if(!(i&b)){c[723]=i|b;c[r>>2]=e;c[T+(q+24)>>2]=r;c[T+(q+12)>>2]=e;c[T+(q+8)>>2]=e;break}b=c[r>>2]|0;c:do if((c[b+4>>2]&-8|0)!=(S|0)){r=S<<(($|0)==31?0:25-($>>>1)|0);i=b;while(1){j=i+16+(r>>>31<<2)|0;p=c[j>>2]|0;if(!p){aa=j;ba=i;break}if((c[p+4>>2]&-8|0)==(S|0)){ca=p;break c}else{r=r<<1;i=p}}if(aa>>>0<(c[726]|0)>>>0)Ea();else{c[aa>>2]=e;c[T+(q+24)>>2]=ba;c[T+(q+12)>>2]=e;c[T+(q+8)>>2]=e;break b}}else ca=b;while(0);b=ca+8|0;i=c[b>>2]|0;r=c[726]|0;if(i>>>0>=r>>>0&ca>>>0>=r>>>0){c[i+12>>2]=e;c[b>>2]=e;c[T+(q+8)>>2]=i;c[T+(q+12)>>2]=ca;c[T+(q+24)>>2]=0;break}else Ea()}else{i=S+q|0;c[T+4>>2]=i|3;b=T+(i+4)|0;c[b>>2]=c[b>>2]|1}while(0);n=T+8|0;return n|0}else F=q}else F=q}else F=-1;while(0);T=c[724]|0;if(T>>>0>=F>>>0){S=T-F|0;ca=c[727]|0;if(S>>>0>15){c[727]=ca+F;c[724]=S;c[ca+(F+4)>>2]=S|1;c[ca+T>>2]=S;c[ca+4>>2]=F|3}else{c[724]=0;c[727]=0;c[ca+4>>2]=T|3;S=ca+(T+4)|0;c[S>>2]=c[S>>2]|1}n=ca+8|0;return n|0}ca=c[725]|0;if(ca>>>0>F>>>0){S=ca-F|0;c[725]=S;ca=c[728]|0;c[728]=ca+F;c[ca+(F+4)>>2]=S|1;c[ca+4>>2]=F|3;n=ca+8|0;return n|0}do if(!(c[840]|0)){ca=va(30)|0;if(!(ca+-1&ca)){c[842]=ca;c[841]=ca;c[843]=-1;c[844]=-1;c[845]=0;c[833]=0;c[840]=(Ga(0)|0)&-16^1431655768;break}else Ea()}while(0);ca=F+48|0;S=c[842]|0;T=F+47|0;ba=S+T|0;aa=0-S|0;S=ba&aa;if(S>>>0<=F>>>0){n=0;return n|0}$=c[832]|0;if(($|0)!=0?(_=c[830]|0,Z=_+S|0,Z>>>0<=_>>>0|Z>>>0>$>>>0):0){n=0;return n|0}d:do if(!(c[833]&4)){$=c[728]|0;e:do if($){Z=3336;while(1){_=c[Z>>2]|0;if(_>>>0<=$>>>0?(U=Z+4|0,(_+(c[U>>2]|0)|0)>>>0>$>>>0):0){da=Z;ea=U;break}Z=c[Z+8>>2]|0;if(!Z){K=174;break e}}Z=ba-(c[725]|0)&aa;if(Z>>>0<2147483647){U=ra(Z|0)|0;_=(U|0)==((c[da>>2]|0)+(c[ea>>2]|0)|0);X=_?Z:0;if(_)if((U|0)==(-1|0))fa=X;else{ga=U;ha=X;K=194;break d}else{ia=U;ja=Z;ka=X;K=184}}else fa=0}else K=174;while(0);do if((K|0)==174){$=ra(0)|0;if(($|0)!=(-1|0)){q=$;X=c[841]|0;Z=X+-1|0;if(!(Z&q))la=S;else la=S-q+(Z+q&0-X)|0;X=c[830]|0;q=X+la|0;if(la>>>0>F>>>0&la>>>0<2147483647){Z=c[832]|0;if((Z|0)!=0?q>>>0<=X>>>0|q>>>0>Z>>>0:0){fa=0;break}Z=ra(la|0)|0;q=(Z|0)==($|0);X=q?la:0;if(q){ga=$;ha=X;K=194;break d}else{ia=Z;ja=la;ka=X;K=184}}else fa=0}else fa=0}while(0);f:do if((K|0)==184){X=0-ja|0;do if(ca>>>0>ja>>>0&(ja>>>0<2147483647&(ia|0)!=(-1|0))?(Z=c[842]|0,$=T-ja+Z&0-Z,$>>>0<2147483647):0)if((ra($|0)|0)==(-1|0)){ra(X|0)|0;fa=ka;break f}else{ma=$+ja|0;break}else ma=ja;while(0);if((ia|0)==(-1|0))fa=ka;else{ga=ia;ha=ma;K=194;break d}}while(0);c[833]=c[833]|4;na=fa;K=191}else{na=0;K=191}while(0);if((((K|0)==191?S>>>0<2147483647:0)?(fa=ra(S|0)|0,S=ra(0)|0,fa>>>0<S>>>0&((fa|0)!=(-1|0)&(S|0)!=(-1|0))):0)?(ma=S-fa|0,S=ma>>>0>(F+40|0)>>>0,S):0){ga=fa;ha=S?ma:na;K=194}if((K|0)==194){na=(c[830]|0)+ha|0;c[830]=na;if(na>>>0>(c[831]|0)>>>0)c[831]=na;na=c[728]|0;g:do if(na){ma=3336;do{S=c[ma>>2]|0;fa=ma+4|0;ia=c[fa>>2]|0;if((ga|0)==(S+ia|0)){oa=S;pa=fa;qa=ia;sa=ma;K=204;break}ma=c[ma+8>>2]|0}while((ma|0)!=0);if(((K|0)==204?(c[sa+12>>2]&8|0)==0:0)?na>>>0<ga>>>0&na>>>0>=oa>>>0:0){c[pa>>2]=qa+ha;ma=(c[725]|0)+ha|0;ia=na+8|0;fa=(ia&7|0)==0?0:0-ia&7;ia=ma-fa|0;c[728]=na+fa;c[725]=ia;c[na+(fa+4)>>2]=ia|1;c[na+(ma+4)>>2]=40;c[729]=c[844];break}ma=c[726]|0;if(ga>>>0<ma>>>0){c[726]=ga;ta=ga}else ta=ma;ma=ga+ha|0;ia=3336;while(1){if((c[ia>>2]|0)==(ma|0)){ua=ia;wa=ia;K=212;break}ia=c[ia+8>>2]|0;if(!ia){xa=3336;break}}if((K|0)==212)if(!(c[wa+12>>2]&8)){c[ua>>2]=ga;ia=wa+4|0;c[ia>>2]=(c[ia>>2]|0)+ha;ia=ga+8|0;ma=(ia&7|0)==0?0:0-ia&7;ia=ga+(ha+8)|0;fa=(ia&7|0)==0?0:0-ia&7;ia=ga+(fa+ha)|0;S=ma+F|0;ka=ga+S|0;ja=ia-(ga+ma)-F|0;c[ga+(ma+4)>>2]=F|3;h:do if((ia|0)!=(na|0)){if((ia|0)==(c[727]|0)){T=(c[724]|0)+ja|0;c[724]=T;c[727]=ka;c[ga+(S+4)>>2]=T|1;c[ga+(T+S)>>2]=T;break}T=ha+4|0;ca=c[ga+(T+fa)>>2]|0;if((ca&3|0)==1){la=ca&-8;ea=ca>>>3;i:do if(ca>>>0>=256){da=c[ga+((fa|24)+ha)>>2]|0;aa=c[ga+(ha+12+fa)>>2]|0;do if((aa|0)==(ia|0)){ba=fa|16;X=ga+(T+ba)|0;$=c[X>>2]|0;if(!$){Z=ga+(ba+ha)|0;ba=c[Z>>2]|0;if(!ba){ya=0;break}else{za=ba;Aa=Z}}else{za=$;Aa=X}while(1){X=za+20|0;$=c[X>>2]|0;if($){za=$;Aa=X;continue}X=za+16|0;$=c[X>>2]|0;if(!$){Ba=za;Ca=Aa;break}else{za=$;Aa=X}}if(Ca>>>0<ta>>>0)Ea();else{c[Ca>>2]=0;ya=Ba;break}}else{X=c[ga+((fa|8)+ha)>>2]|0;if(X>>>0<ta>>>0)Ea();$=X+12|0;if((c[$>>2]|0)!=(ia|0))Ea();Z=aa+8|0;if((c[Z>>2]|0)==(ia|0)){c[$>>2]=aa;c[Z>>2]=X;ya=aa;break}else Ea()}while(0);if(!da)break;aa=c[ga+(ha+28+fa)>>2]|0;X=3192+(aa<<2)|0;do if((ia|0)!=(c[X>>2]|0)){if(da>>>0<(c[726]|0)>>>0)Ea();Z=da+16|0;if((c[Z>>2]|0)==(ia|0))c[Z>>2]=ya;else c[da+20>>2]=ya;if(!ya)break i}else{c[X>>2]=ya;if(ya)break;c[723]=c[723]&~(1<<aa);break i}while(0);aa=c[726]|0;if(ya>>>0<aa>>>0)Ea();c[ya+24>>2]=da;X=fa|16;Z=c[ga+(X+ha)>>2]|0;do if(Z)if(Z>>>0<aa>>>0)Ea();else{c[ya+16>>2]=Z;c[Z+24>>2]=ya;break}while(0);Z=c[ga+(T+X)>>2]|0;if(!Z)break;if(Z>>>0<(c[726]|0)>>>0)Ea();else{c[ya+20>>2]=Z;c[Z+24>>2]=ya;break}}else{Z=c[ga+((fa|8)+ha)>>2]|0;aa=c[ga+(ha+12+fa)>>2]|0;da=2928+(ea<<1<<2)|0;do if((Z|0)!=(da|0)){if(Z>>>0<ta>>>0)Ea();if((c[Z+12>>2]|0)==(ia|0))break;Ea()}while(0);if((aa|0)==(Z|0)){c[722]=c[722]&~(1<<ea);break}do if((aa|0)==(da|0))Fa=aa+8|0;else{if(aa>>>0<ta>>>0)Ea();X=aa+8|0;if((c[X>>2]|0)==(ia|0)){Fa=X;break}Ea()}while(0);c[Z+12>>2]=aa;c[Fa>>2]=Z}while(0);Ha=ga+((la|fa)+ha)|0;Ia=la+ja|0}else{Ha=ia;Ia=ja}ea=Ha+4|0;c[ea>>2]=c[ea>>2]&-2;c[ga+(S+4)>>2]=Ia|1;c[ga+(Ia+S)>>2]=Ia;ea=Ia>>>3;if(Ia>>>0<256){T=ea<<1;ca=2928+(T<<2)|0;da=c[722]|0;X=1<<ea;do if(!(da&X)){c[722]=da|X;Ja=2928+(T+2<<2)|0;Ka=ca}else{ea=2928+(T+2<<2)|0;$=c[ea>>2]|0;if($>>>0>=(c[726]|0)>>>0){Ja=ea;Ka=$;break}Ea()}while(0);c[Ja>>2]=ka;c[Ka+12>>2]=ka;c[ga+(S+8)>>2]=Ka;c[ga+(S+12)>>2]=ca;break}T=Ia>>>8;do if(!T)La=0;else{if(Ia>>>0>16777215){La=31;break}X=(T+1048320|0)>>>16&8;da=T<<X;la=(da+520192|0)>>>16&4;$=da<<la;da=($+245760|0)>>>16&2;ea=14-(la|X|da)+($<<da>>>15)|0;La=Ia>>>(ea+7|0)&1|ea<<1}while(0);T=3192+(La<<2)|0;c[ga+(S+28)>>2]=La;c[ga+(S+20)>>2]=0;c[ga+(S+16)>>2]=0;ca=c[723]|0;ea=1<<La;if(!(ca&ea)){c[723]=ca|ea;c[T>>2]=ka;c[ga+(S+24)>>2]=T;c[ga+(S+12)>>2]=ka;c[ga+(S+8)>>2]=ka;break}ea=c[T>>2]|0;j:do if((c[ea+4>>2]&-8|0)!=(Ia|0)){T=Ia<<((La|0)==31?0:25-(La>>>1)|0);ca=ea;while(1){da=ca+16+(T>>>31<<2)|0;$=c[da>>2]|0;if(!$){Ma=da;Na=ca;break}if((c[$+4>>2]&-8|0)==(Ia|0)){Oa=$;break j}else{T=T<<1;ca=$}}if(Ma>>>0<(c[726]|0)>>>0)Ea();else{c[Ma>>2]=ka;c[ga+(S+24)>>2]=Na;c[ga+(S+12)>>2]=ka;c[ga+(S+8)>>2]=ka;break h}}else Oa=ea;while(0);ea=Oa+8|0;ca=c[ea>>2]|0;T=c[726]|0;if(ca>>>0>=T>>>0&Oa>>>0>=T>>>0){c[ca+12>>2]=ka;c[ea>>2]=ka;c[ga+(S+8)>>2]=ca;c[ga+(S+12)>>2]=Oa;c[ga+(S+24)>>2]=0;break}else Ea()}else{ca=(c[725]|0)+ja|0;c[725]=ca;c[728]=ka;c[ga+(S+4)>>2]=ca|1}while(0);n=ga+(ma|8)|0;return n|0}else xa=3336;while(1){S=c[xa>>2]|0;if(S>>>0<=na>>>0?(ka=c[xa+4>>2]|0,ja=S+ka|0,ja>>>0>na>>>0):0){Pa=S;Qa=ka;Ra=ja;break}xa=c[xa+8>>2]|0}ma=Pa+(Qa+-39)|0;ja=Pa+(Qa+-47+((ma&7|0)==0?0:0-ma&7))|0;ma=na+16|0;ka=ja>>>0<ma>>>0?na:ja;ja=ka+8|0;S=ga+8|0;ia=(S&7|0)==0?0:0-S&7;S=ha+-40-ia|0;c[728]=ga+ia;c[725]=S;c[ga+(ia+4)>>2]=S|1;c[ga+(ha+-36)>>2]=40;c[729]=c[844];S=ka+4|0;c[S>>2]=27;c[ja>>2]=c[834];c[ja+4>>2]=c[835];c[ja+8>>2]=c[836];c[ja+12>>2]=c[837];c[834]=ga;c[835]=ha;c[837]=0;c[836]=ja;ja=ka+28|0;c[ja>>2]=7;if((ka+32|0)>>>0<Ra>>>0){ia=ja;do{ja=ia;ia=ia+4|0;c[ia>>2]=7}while((ja+8|0)>>>0<Ra>>>0)}if((ka|0)!=(na|0)){ia=ka-na|0;c[S>>2]=c[S>>2]&-2;c[na+4>>2]=ia|1;c[ka>>2]=ia;ja=ia>>>3;if(ia>>>0<256){fa=ja<<1;ca=2928+(fa<<2)|0;ea=c[722]|0;T=1<<ja;if(ea&T){ja=2928+(fa+2<<2)|0;Z=c[ja>>2]|0;if(Z>>>0<(c[726]|0)>>>0)Ea();else{Sa=ja;Ta=Z}}else{c[722]=ea|T;Sa=2928+(fa+2<<2)|0;Ta=ca}c[Sa>>2]=na;c[Ta+12>>2]=na;c[na+8>>2]=Ta;c[na+12>>2]=ca;break}ca=ia>>>8;if(ca)if(ia>>>0>16777215)Ua=31;else{fa=(ca+1048320|0)>>>16&8;T=ca<<fa;ca=(T+520192|0)>>>16&4;ea=T<<ca;T=(ea+245760|0)>>>16&2;Z=14-(ca|fa|T)+(ea<<T>>>15)|0;Ua=ia>>>(Z+7|0)&1|Z<<1}else Ua=0;Z=3192+(Ua<<2)|0;c[na+28>>2]=Ua;c[na+20>>2]=0;c[ma>>2]=0;T=c[723]|0;ea=1<<Ua;if(!(T&ea)){c[723]=T|ea;c[Z>>2]=na;c[na+24>>2]=Z;c[na+12>>2]=na;c[na+8>>2]=na;break}ea=c[Z>>2]|0;k:do if((c[ea+4>>2]&-8|0)!=(ia|0)){Z=ia<<((Ua|0)==31?0:25-(Ua>>>1)|0);T=ea;while(1){fa=T+16+(Z>>>31<<2)|0;ca=c[fa>>2]|0;if(!ca){Va=fa;Wa=T;break}if((c[ca+4>>2]&-8|0)==(ia|0)){Xa=ca;break k}else{Z=Z<<1;T=ca}}if(Va>>>0<(c[726]|0)>>>0)Ea();else{c[Va>>2]=na;c[na+24>>2]=Wa;c[na+12>>2]=na;c[na+8>>2]=na;break g}}else Xa=ea;while(0);ea=Xa+8|0;ia=c[ea>>2]|0;ma=c[726]|0;if(ia>>>0>=ma>>>0&Xa>>>0>=ma>>>0){c[ia+12>>2]=na;c[ea>>2]=na;c[na+8>>2]=ia;c[na+12>>2]=Xa;c[na+24>>2]=0;break}else Ea()}}else{ia=c[726]|0;if((ia|0)==0|ga>>>0<ia>>>0)c[726]=ga;c[834]=ga;c[835]=ha;c[837]=0;c[731]=c[840];c[730]=-1;ia=0;do{ea=ia<<1;ma=2928+(ea<<2)|0;c[2928+(ea+3<<2)>>2]=ma;c[2928+(ea+2<<2)>>2]=ma;ia=ia+1|0}while((ia|0)!=32);ia=ga+8|0;ma=(ia&7|0)==0?0:0-ia&7;ia=ha+-40-ma|0;c[728]=ga+ma;c[725]=ia;c[ga+(ma+4)>>2]=ia|1;c[ga+(ha+-36)>>2]=40;c[729]=c[844]}while(0);ha=c[725]|0;if(ha>>>0>F>>>0){ga=ha-F|0;c[725]=ga;ha=c[728]|0;c[728]=ha+F;c[ha+(F+4)>>2]=ga|1;c[ha+4>>2]=F|3;n=ha+8|0;return n|0}}c[(Da()|0)>>2]=12;n=0;return n|0}function ze(a){a=a|0;var b=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0;if(!a)return;b=a+-8|0;d=c[726]|0;if(b>>>0<d>>>0)Ea();e=c[a+-4>>2]|0;f=e&3;if((f|0)==1)Ea();g=e&-8;h=a+(g+-8)|0;do if(!(e&1)){i=c[b>>2]|0;if(!f)return;j=-8-i|0;k=a+j|0;l=i+g|0;if(k>>>0<d>>>0)Ea();if((k|0)==(c[727]|0)){m=a+(g+-4)|0;n=c[m>>2]|0;if((n&3|0)!=3){o=k;p=l;break}c[724]=l;c[m>>2]=n&-2;c[a+(j+4)>>2]=l|1;c[h>>2]=l;return}n=i>>>3;if(i>>>0<256){i=c[a+(j+8)>>2]|0;m=c[a+(j+12)>>2]|0;q=2928+(n<<1<<2)|0;if((i|0)!=(q|0)){if(i>>>0<d>>>0)Ea();if((c[i+12>>2]|0)!=(k|0))Ea()}if((m|0)==(i|0)){c[722]=c[722]&~(1<<n);o=k;p=l;break}if((m|0)!=(q|0)){if(m>>>0<d>>>0)Ea();q=m+8|0;if((c[q>>2]|0)==(k|0))r=q;else Ea()}else r=m+8|0;c[i+12>>2]=m;c[r>>2]=i;o=k;p=l;break}i=c[a+(j+24)>>2]|0;m=c[a+(j+12)>>2]|0;do if((m|0)==(k|0)){q=a+(j+20)|0;n=c[q>>2]|0;if(!n){s=a+(j+16)|0;t=c[s>>2]|0;if(!t){u=0;break}else{v=t;w=s}}else{v=n;w=q}while(1){q=v+20|0;n=c[q>>2]|0;if(n){v=n;w=q;continue}q=v+16|0;n=c[q>>2]|0;if(!n){x=v;y=w;break}else{v=n;w=q}}if(y>>>0<d>>>0)Ea();else{c[y>>2]=0;u=x;break}}else{q=c[a+(j+8)>>2]|0;if(q>>>0<d>>>0)Ea();n=q+12|0;if((c[n>>2]|0)!=(k|0))Ea();s=m+8|0;if((c[s>>2]|0)==(k|0)){c[n>>2]=m;c[s>>2]=q;u=m;break}else Ea()}while(0);if(i){m=c[a+(j+28)>>2]|0;q=3192+(m<<2)|0;if((k|0)==(c[q>>2]|0)){c[q>>2]=u;if(!u){c[723]=c[723]&~(1<<m);o=k;p=l;break}}else{if(i>>>0<(c[726]|0)>>>0)Ea();m=i+16|0;if((c[m>>2]|0)==(k|0))c[m>>2]=u;else c[i+20>>2]=u;if(!u){o=k;p=l;break}}m=c[726]|0;if(u>>>0<m>>>0)Ea();c[u+24>>2]=i;q=c[a+(j+16)>>2]|0;do if(q)if(q>>>0<m>>>0)Ea();else{c[u+16>>2]=q;c[q+24>>2]=u;break}while(0);q=c[a+(j+20)>>2]|0;if(q)if(q>>>0<(c[726]|0)>>>0)Ea();else{c[u+20>>2]=q;c[q+24>>2]=u;o=k;p=l;break}else{o=k;p=l}}else{o=k;p=l}}else{o=b;p=g}while(0);if(o>>>0>=h>>>0)Ea();b=a+(g+-4)|0;u=c[b>>2]|0;if(!(u&1))Ea();if(!(u&2)){if((h|0)==(c[728]|0)){d=(c[725]|0)+p|0;c[725]=d;c[728]=o;c[o+4>>2]=d|1;if((o|0)!=(c[727]|0))return;c[727]=0;c[724]=0;return}if((h|0)==(c[727]|0)){d=(c[724]|0)+p|0;c[724]=d;c[727]=o;c[o+4>>2]=d|1;c[o+d>>2]=d;return}d=(u&-8)+p|0;x=u>>>3;do if(u>>>0>=256){y=c[a+(g+16)>>2]|0;w=c[a+(g|4)>>2]|0;do if((w|0)==(h|0)){v=a+(g+12)|0;r=c[v>>2]|0;if(!r){f=a+(g+8)|0;e=c[f>>2]|0;if(!e){z=0;break}else{A=e;B=f}}else{A=r;B=v}while(1){v=A+20|0;r=c[v>>2]|0;if(r){A=r;B=v;continue}v=A+16|0;r=c[v>>2]|0;if(!r){C=A;D=B;break}else{A=r;B=v}}if(D>>>0<(c[726]|0)>>>0)Ea();else{c[D>>2]=0;z=C;break}}else{v=c[a+g>>2]|0;if(v>>>0<(c[726]|0)>>>0)Ea();r=v+12|0;if((c[r>>2]|0)!=(h|0))Ea();f=w+8|0;if((c[f>>2]|0)==(h|0)){c[r>>2]=w;c[f>>2]=v;z=w;break}else Ea()}while(0);if(y){w=c[a+(g+20)>>2]|0;l=3192+(w<<2)|0;if((h|0)==(c[l>>2]|0)){c[l>>2]=z;if(!z){c[723]=c[723]&~(1<<w);break}}else{if(y>>>0<(c[726]|0)>>>0)Ea();w=y+16|0;if((c[w>>2]|0)==(h|0))c[w>>2]=z;else c[y+20>>2]=z;if(!z)break}w=c[726]|0;if(z>>>0<w>>>0)Ea();c[z+24>>2]=y;l=c[a+(g+8)>>2]|0;do if(l)if(l>>>0<w>>>0)Ea();else{c[z+16>>2]=l;c[l+24>>2]=z;break}while(0);l=c[a+(g+12)>>2]|0;if(l)if(l>>>0<(c[726]|0)>>>0)Ea();else{c[z+20>>2]=l;c[l+24>>2]=z;break}}}else{l=c[a+g>>2]|0;w=c[a+(g|4)>>2]|0;y=2928+(x<<1<<2)|0;if((l|0)!=(y|0)){if(l>>>0<(c[726]|0)>>>0)Ea();if((c[l+12>>2]|0)!=(h|0))Ea()}if((w|0)==(l|0)){c[722]=c[722]&~(1<<x);break}if((w|0)!=(y|0)){if(w>>>0<(c[726]|0)>>>0)Ea();y=w+8|0;if((c[y>>2]|0)==(h|0))E=y;else Ea()}else E=w+8|0;c[l+12>>2]=w;c[E>>2]=l}while(0);c[o+4>>2]=d|1;c[o+d>>2]=d;if((o|0)==(c[727]|0)){c[724]=d;return}else F=d}else{c[b>>2]=u&-2;c[o+4>>2]=p|1;c[o+p>>2]=p;F=p}p=F>>>3;if(F>>>0<256){u=p<<1;b=2928+(u<<2)|0;d=c[722]|0;E=1<<p;if(d&E){p=2928+(u+2<<2)|0;h=c[p>>2]|0;if(h>>>0<(c[726]|0)>>>0)Ea();else{G=p;H=h}}else{c[722]=d|E;G=2928+(u+2<<2)|0;H=b}c[G>>2]=o;c[H+12>>2]=o;c[o+8>>2]=H;c[o+12>>2]=b;return}b=F>>>8;if(b)if(F>>>0>16777215)I=31;else{H=(b+1048320|0)>>>16&8;G=b<<H;b=(G+520192|0)>>>16&4;u=G<<b;G=(u+245760|0)>>>16&2;E=14-(b|H|G)+(u<<G>>>15)|0;I=F>>>(E+7|0)&1|E<<1}else I=0;E=3192+(I<<2)|0;c[o+28>>2]=I;c[o+20>>2]=0;c[o+16>>2]=0;G=c[723]|0;u=1<<I;a:do if(G&u){H=c[E>>2]|0;b:do if((c[H+4>>2]&-8|0)!=(F|0)){b=F<<((I|0)==31?0:25-(I>>>1)|0);d=H;while(1){h=d+16+(b>>>31<<2)|0;p=c[h>>2]|0;if(!p){J=h;K=d;break}if((c[p+4>>2]&-8|0)==(F|0)){L=p;break b}else{b=b<<1;d=p}}if(J>>>0<(c[726]|0)>>>0)Ea();else{c[J>>2]=o;c[o+24>>2]=K;c[o+12>>2]=o;c[o+8>>2]=o;break a}}else L=H;while(0);H=L+8|0;d=c[H>>2]|0;b=c[726]|0;if(d>>>0>=b>>>0&L>>>0>=b>>>0){c[d+12>>2]=o;c[H>>2]=o;c[o+8>>2]=d;c[o+12>>2]=L;c[o+24>>2]=0;break}else Ea()}else{c[723]=G|u;c[E>>2]=o;c[o+24>>2]=E;c[o+12>>2]=o;c[o+8>>2]=o}while(0);o=(c[730]|0)+-1|0;c[730]=o;if(!o)M=3344;else return;while(1){o=c[M>>2]|0;if(!o)break;else M=o+8|0}c[730]=-1;return}function Ae(a,b){a=a|0;b=b|0;var d=0,e=0;if(a){d=_(b,a)|0;if((b|a)>>>0>65535)e=((d>>>0)/(a>>>0)|0|0)==(b|0)?d:-1;else e=d}else e=0;d=ye(e)|0;if(!d)return d|0;if(!(c[d+-4>>2]&3))return d|0;He(d|0,0,e|0)|0;return d|0}function Be(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0;if(!a){d=ye(b)|0;return d|0}if(b>>>0>4294967231){c[(Da()|0)>>2]=12;d=0;return d|0}e=Ce(a+-8|0,b>>>0<11?16:b+11&-8)|0;if(e){d=e+8|0;return d|0}e=ye(b)|0;if(!e){d=0;return d|0}f=c[a+-4>>2]|0;g=(f&-8)-((f&3|0)==0?8:4)|0;Ke(e|0,a|0,(g>>>0<b>>>0?g:b)|0)|0;ze(a);d=e;return d|0}function Ce(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0;d=a+4|0;e=c[d>>2]|0;f=e&-8;g=a+f|0;h=c[726]|0;i=e&3;if(!((i|0)!=1&a>>>0>=h>>>0&a>>>0<g>>>0))Ea();j=a+(f|4)|0;k=c[j>>2]|0;if(!(k&1))Ea();if(!i){if(b>>>0<256){l=0;return l|0}if(f>>>0>=(b+4|0)>>>0?(f-b|0)>>>0<=c[842]<<1>>>0:0){l=a;return l|0}l=0;return l|0}if(f>>>0>=b>>>0){i=f-b|0;if(i>>>0<=15){l=a;return l|0}c[d>>2]=e&1|b|2;c[a+(b+4)>>2]=i|3;c[j>>2]=c[j>>2]|1;De(a+b|0,i);l=a;return l|0}if((g|0)==(c[728]|0)){i=(c[725]|0)+f|0;if(i>>>0<=b>>>0){l=0;return l|0}j=i-b|0;c[d>>2]=e&1|b|2;c[a+(b+4)>>2]=j|1;c[728]=a+b;c[725]=j;l=a;return l|0}if((g|0)==(c[727]|0)){j=(c[724]|0)+f|0;if(j>>>0<b>>>0){l=0;return l|0}i=j-b|0;if(i>>>0>15){c[d>>2]=e&1|b|2;c[a+(b+4)>>2]=i|1;c[a+j>>2]=i;m=a+(j+4)|0;c[m>>2]=c[m>>2]&-2;n=a+b|0;o=i}else{c[d>>2]=e&1|j|2;i=a+(j+4)|0;c[i>>2]=c[i>>2]|1;n=0;o=0}c[724]=o;c[727]=n;l=a;return l|0}if(k&2){l=0;return l|0}n=(k&-8)+f|0;if(n>>>0<b>>>0){l=0;return l|0}o=n-b|0;i=k>>>3;do if(k>>>0>=256){j=c[a+(f+24)>>2]|0;m=c[a+(f+12)>>2]|0;do if((m|0)==(g|0)){p=a+(f+20)|0;q=c[p>>2]|0;if(!q){r=a+(f+16)|0;s=c[r>>2]|0;if(!s){t=0;break}else{u=s;v=r}}else{u=q;v=p}while(1){p=u+20|0;q=c[p>>2]|0;if(q){u=q;v=p;continue}p=u+16|0;q=c[p>>2]|0;if(!q){w=u;x=v;break}else{u=q;v=p}}if(x>>>0<h>>>0)Ea();else{c[x>>2]=0;t=w;break}}else{p=c[a+(f+8)>>2]|0;if(p>>>0<h>>>0)Ea();q=p+12|0;if((c[q>>2]|0)!=(g|0))Ea();r=m+8|0;if((c[r>>2]|0)==(g|0)){c[q>>2]=m;c[r>>2]=p;t=m;break}else Ea()}while(0);if(j){m=c[a+(f+28)>>2]|0;p=3192+(m<<2)|0;if((g|0)==(c[p>>2]|0)){c[p>>2]=t;if(!t){c[723]=c[723]&~(1<<m);break}}else{if(j>>>0<(c[726]|0)>>>0)Ea();m=j+16|0;if((c[m>>2]|0)==(g|0))c[m>>2]=t;else c[j+20>>2]=t;if(!t)break}m=c[726]|0;if(t>>>0<m>>>0)Ea();c[t+24>>2]=j;p=c[a+(f+16)>>2]|0;do if(p)if(p>>>0<m>>>0)Ea();else{c[t+16>>2]=p;c[p+24>>2]=t;break}while(0);p=c[a+(f+20)>>2]|0;if(p)if(p>>>0<(c[726]|0)>>>0)Ea();else{c[t+20>>2]=p;c[p+24>>2]=t;break}}}else{p=c[a+(f+8)>>2]|0;m=c[a+(f+12)>>2]|0;j=2928+(i<<1<<2)|0;if((p|0)!=(j|0)){if(p>>>0<h>>>0)Ea();if((c[p+12>>2]|0)!=(g|0))Ea()}if((m|0)==(p|0)){c[722]=c[722]&~(1<<i);break}if((m|0)!=(j|0)){if(m>>>0<h>>>0)Ea();j=m+8|0;if((c[j>>2]|0)==(g|0))y=j;else Ea()}else y=m+8|0;c[p+12>>2]=m;c[y>>2]=p}while(0);if(o>>>0<16){c[d>>2]=n|e&1|2;y=a+(n|4)|0;c[y>>2]=c[y>>2]|1;l=a;return l|0}else{c[d>>2]=e&1|b|2;c[a+(b+4)>>2]=o|3;e=a+(n|4)|0;c[e>>2]=c[e>>2]|1;De(a+b|0,o);l=a;return l|0}return 0}function De(a,b){a=a|0;b=b|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0;d=a+b|0;e=c[a+4>>2]|0;do if(!(e&1)){f=c[a>>2]|0;if(!(e&3))return;g=a+(0-f)|0;h=f+b|0;i=c[726]|0;if(g>>>0<i>>>0)Ea();if((g|0)==(c[727]|0)){j=a+(b+4)|0;k=c[j>>2]|0;if((k&3|0)!=3){l=g;m=h;break}c[724]=h;c[j>>2]=k&-2;c[a+(4-f)>>2]=h|1;c[d>>2]=h;return}k=f>>>3;if(f>>>0<256){j=c[a+(8-f)>>2]|0;n=c[a+(12-f)>>2]|0;o=2928+(k<<1<<2)|0;if((j|0)!=(o|0)){if(j>>>0<i>>>0)Ea();if((c[j+12>>2]|0)!=(g|0))Ea()}if((n|0)==(j|0)){c[722]=c[722]&~(1<<k);l=g;m=h;break}if((n|0)!=(o|0)){if(n>>>0<i>>>0)Ea();o=n+8|0;if((c[o>>2]|0)==(g|0))p=o;else Ea()}else p=n+8|0;c[j+12>>2]=n;c[p>>2]=j;l=g;m=h;break}j=c[a+(24-f)>>2]|0;n=c[a+(12-f)>>2]|0;do if((n|0)==(g|0)){o=16-f|0;k=a+(o+4)|0;q=c[k>>2]|0;if(!q){r=a+o|0;o=c[r>>2]|0;if(!o){s=0;break}else{t=o;u=r}}else{t=q;u=k}while(1){k=t+20|0;q=c[k>>2]|0;if(q){t=q;u=k;continue}k=t+16|0;q=c[k>>2]|0;if(!q){v=t;w=u;break}else{t=q;u=k}}if(w>>>0<i>>>0)Ea();else{c[w>>2]=0;s=v;break}}else{k=c[a+(8-f)>>2]|0;if(k>>>0<i>>>0)Ea();q=k+12|0;if((c[q>>2]|0)!=(g|0))Ea();r=n+8|0;if((c[r>>2]|0)==(g|0)){c[q>>2]=n;c[r>>2]=k;s=n;break}else Ea()}while(0);if(j){n=c[a+(28-f)>>2]|0;i=3192+(n<<2)|0;if((g|0)==(c[i>>2]|0)){c[i>>2]=s;if(!s){c[723]=c[723]&~(1<<n);l=g;m=h;break}}else{if(j>>>0<(c[726]|0)>>>0)Ea();n=j+16|0;if((c[n>>2]|0)==(g|0))c[n>>2]=s;else c[j+20>>2]=s;if(!s){l=g;m=h;break}}n=c[726]|0;if(s>>>0<n>>>0)Ea();c[s+24>>2]=j;i=16-f|0;k=c[a+i>>2]|0;do if(k)if(k>>>0<n>>>0)Ea();else{c[s+16>>2]=k;c[k+24>>2]=s;break}while(0);k=c[a+(i+4)>>2]|0;if(k)if(k>>>0<(c[726]|0)>>>0)Ea();else{c[s+20>>2]=k;c[k+24>>2]=s;l=g;m=h;break}else{l=g;m=h}}else{l=g;m=h}}else{l=a;m=b}while(0);s=c[726]|0;if(d>>>0<s>>>0)Ea();v=a+(b+4)|0;w=c[v>>2]|0;if(!(w&2)){if((d|0)==(c[728]|0)){u=(c[725]|0)+m|0;c[725]=u;c[728]=l;c[l+4>>2]=u|1;if((l|0)!=(c[727]|0))return;c[727]=0;c[724]=0;return}if((d|0)==(c[727]|0)){u=(c[724]|0)+m|0;c[724]=u;c[727]=l;c[l+4>>2]=u|1;c[l+u>>2]=u;return}u=(w&-8)+m|0;t=w>>>3;do if(w>>>0>=256){p=c[a+(b+24)>>2]|0;e=c[a+(b+12)>>2]|0;do if((e|0)==(d|0)){k=a+(b+20)|0;n=c[k>>2]|0;if(!n){f=a+(b+16)|0;j=c[f>>2]|0;if(!j){x=0;break}else{y=j;z=f}}else{y=n;z=k}while(1){k=y+20|0;n=c[k>>2]|0;if(n){y=n;z=k;continue}k=y+16|0;n=c[k>>2]|0;if(!n){A=y;B=z;break}else{y=n;z=k}}if(B>>>0<s>>>0)Ea();else{c[B>>2]=0;x=A;break}}else{k=c[a+(b+8)>>2]|0;if(k>>>0<s>>>0)Ea();n=k+12|0;if((c[n>>2]|0)!=(d|0))Ea();f=e+8|0;if((c[f>>2]|0)==(d|0)){c[n>>2]=e;c[f>>2]=k;x=e;break}else Ea()}while(0);if(p){e=c[a+(b+28)>>2]|0;h=3192+(e<<2)|0;if((d|0)==(c[h>>2]|0)){c[h>>2]=x;if(!x){c[723]=c[723]&~(1<<e);break}}else{if(p>>>0<(c[726]|0)>>>0)Ea();e=p+16|0;if((c[e>>2]|0)==(d|0))c[e>>2]=x;else c[p+20>>2]=x;if(!x)break}e=c[726]|0;if(x>>>0<e>>>0)Ea();c[x+24>>2]=p;h=c[a+(b+16)>>2]|0;do if(h)if(h>>>0<e>>>0)Ea();else{c[x+16>>2]=h;c[h+24>>2]=x;break}while(0);h=c[a+(b+20)>>2]|0;if(h)if(h>>>0<(c[726]|0)>>>0)Ea();else{c[x+20>>2]=h;c[h+24>>2]=x;break}}}else{h=c[a+(b+8)>>2]|0;e=c[a+(b+12)>>2]|0;p=2928+(t<<1<<2)|0;if((h|0)!=(p|0)){if(h>>>0<s>>>0)Ea();if((c[h+12>>2]|0)!=(d|0))Ea()}if((e|0)==(h|0)){c[722]=c[722]&~(1<<t);break}if((e|0)!=(p|0)){if(e>>>0<s>>>0)Ea();p=e+8|0;if((c[p>>2]|0)==(d|0))C=p;else Ea()}else C=e+8|0;c[h+12>>2]=e;c[C>>2]=h}while(0);c[l+4>>2]=u|1;c[l+u>>2]=u;if((l|0)==(c[727]|0)){c[724]=u;return}else D=u}else{c[v>>2]=w&-2;c[l+4>>2]=m|1;c[l+m>>2]=m;D=m}m=D>>>3;if(D>>>0<256){w=m<<1;v=2928+(w<<2)|0;u=c[722]|0;C=1<<m;if(u&C){m=2928+(w+2<<2)|0;d=c[m>>2]|0;if(d>>>0<(c[726]|0)>>>0)Ea();else{E=m;F=d}}else{c[722]=u|C;E=2928+(w+2<<2)|0;F=v}c[E>>2]=l;c[F+12>>2]=l;c[l+8>>2]=F;c[l+12>>2]=v;return}v=D>>>8;if(v)if(D>>>0>16777215)G=31;else{F=(v+1048320|0)>>>16&8;E=v<<F;v=(E+520192|0)>>>16&4;w=E<<v;E=(w+245760|0)>>>16&2;C=14-(v|F|E)+(w<<E>>>15)|0;G=D>>>(C+7|0)&1|C<<1}else G=0;C=3192+(G<<2)|0;c[l+28>>2]=G;c[l+20>>2]=0;c[l+16>>2]=0;E=c[723]|0;w=1<<G;if(!(E&w)){c[723]=E|w;c[C>>2]=l;c[l+24>>2]=C;c[l+12>>2]=l;c[l+8>>2]=l;return}w=c[C>>2]|0;a:do if((c[w+4>>2]&-8|0)==(D|0))H=w;else{C=D<<((G|0)==31?0:25-(G>>>1)|0);E=w;while(1){F=E+16+(C>>>31<<2)|0;v=c[F>>2]|0;if(!v){I=F;J=E;break}if((c[v+4>>2]&-8|0)==(D|0)){H=v;break a}else{C=C<<1;E=v}}if(I>>>0<(c[726]|0)>>>0)Ea();c[I>>2]=l;c[l+24>>2]=J;c[l+12>>2]=l;c[l+8>>2]=l;return}while(0);J=H+8|0;I=c[J>>2]|0;D=c[726]|0;if(!(I>>>0>=D>>>0&H>>>0>=D>>>0))Ea();c[I+12>>2]=l;c[J>>2]=l;c[l+8>>2]=I;c[l+12>>2]=H;c[l+24>>2]=0;return}function Ee(){}function Fe(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>c;return a>>>c|(b&(1<<c)-1)<<32-c}C=(b|0)<0?-1:0;return b>>c-32|0}function Ge(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=b-d>>>0;e=b-d-(c>>>0>a>>>0|0)>>>0;return (C=e,a-c>>>0|0)|0}function He(b,d,e){b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,i=0;f=b+e|0;if((e|0)>=20){d=d&255;g=b&3;h=d|d<<8|d<<16|d<<24;i=f&~3;if(g){g=b+4-g|0;while((b|0)<(g|0)){a[b>>0]=d;b=b+1|0}}while((b|0)<(i|0)){c[b>>2]=h;b=b+4|0}}while((b|0)<(f|0)){a[b>>0]=d;b=b+1|0}return b-e|0}function Ie(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b<<c|(a&(1<<c)-1<<32-c)>>>32-c;return a<<c}C=a<<c-32;return 0}function Je(b){b=b|0;var c=0;c=b;while(a[c>>0]|0)c=c+1|0;return c-b|0}function Ke(b,d,e){b=b|0;d=d|0;e=e|0;var f=0;if((e|0)>=4096)return sa(b|0,d|0,e|0)|0;f=b|0;if((b&3)==(d&3)){while(b&3){if(!e)return f|0;a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}while((e|0)>=4){c[b>>2]=c[d>>2];b=b+4|0;d=d+4|0;e=e-4|0}}while((e|0)>0){a[b>>0]=a[d>>0]|0;b=b+1|0;d=d+1|0;e=e-1|0}return f|0}function Le(b,c,d){b=b|0;c=c|0;d=d|0;var e=0,f=0;while((e|0)<(d|0)){a[b+e>>0]=f?0:a[c+e>>0]|0;f=f?1:(a[c+e>>0]|0)==0;e=e+1|0}return b|0}function Me(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=a+c>>>0;return (C=b+d+(e>>>0<a>>>0|0)>>>0,e|0)|0}function Ne(b,c,d){b=b|0;c=c|0;d=d|0;var e=0;if((c|0)<(b|0)&(b|0)<(c+d|0)){e=b;c=c+d|0;b=b+d|0;while((d|0)>0){b=b-1|0;c=c-1|0;d=d-1|0;a[b>>0]=a[c>>0]|0}b=e}else Ke(b,c,d)|0;return b|0}function Oe(b,c){b=b|0;c=c|0;var d=0;do{a[b+d>>0]=a[c+d>>0];d=d+1|0}while(a[c+(d-1)>>0]|0);return b|0}function Pe(a,b,c){a=a|0;b=b|0;c=c|0;if((c|0)<32){C=b>>>c;return a>>>c|(b&(1<<c)-1)<<32-c}C=0;return b>>>c-32|0}function Qe(b){b=b|0;var c=0;c=a[m+(b&255)>>0]|0;if((c|0)<8)return c|0;c=a[m+(b>>8&255)>>0]|0;if((c|0)<8)return c+8|0;c=a[m+(b>>16&255)>>0]|0;if((c|0)<8)return c+16|0;return (a[m+(b>>>24)>>0]|0)+24|0}function Re(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;c=a&65535;d=b&65535;e=_(d,c)|0;f=a>>>16;a=(e>>>16)+(_(d,f)|0)|0;d=b>>>16;b=_(d,c)|0;return (C=(a>>>16)+(_(d,f)|0)+(((a&65535)+b|0)>>>16)|0,a+b<<16|e&65535|0)|0}function Se(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0;e=b>>31|((b|0)<0?-1:0)<<1;f=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;g=d>>31|((d|0)<0?-1:0)<<1;h=((d|0)<0?-1:0)>>31|((d|0)<0?-1:0)<<1;i=Ge(e^a,f^b,e,f)|0;b=C;a=g^e;e=h^f;return Ge((Xe(i,b,Ge(g^c,h^d,g,h)|0,C,0)|0)^a,C^e,a,e)|0}function Te(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0,h=0,j=0,k=0,l=0,m=0;f=i;i=i+8|0;g=f|0;h=b>>31|((b|0)<0?-1:0)<<1;j=((b|0)<0?-1:0)>>31|((b|0)<0?-1:0)<<1;k=e>>31|((e|0)<0?-1:0)<<1;l=((e|0)<0?-1:0)>>31|((e|0)<0?-1:0)<<1;m=Ge(h^a,j^b,h,j)|0;b=C;Xe(m,b,Ge(k^d,l^e,k,l)|0,C,g)|0;l=Ge(c[g>>2]^h,c[g+4>>2]^j,h,j)|0;j=C;i=f;return (C=j,l)|0}function Ue(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;e=a;a=c;c=Re(e,a)|0;f=C;return (C=(_(b,a)|0)+(_(d,e)|0)+f|f&0,c|0|0)|0}function Ve(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return Xe(a,b,c,d,0)|0}function We(a,b,d,e){a=a|0;b=b|0;d=d|0;e=e|0;var f=0,g=0;f=i;i=i+8|0;g=f|0;Xe(a,b,d,e,g)|0;i=f;return (C=c[g+4>>2]|0,c[g>>2]|0)|0}function Xe(a,b,d,e,f){a=a|0;b=b|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,D=0,E=0,F=0,G=0,H=0;g=a;h=b;i=h;j=d;k=e;l=k;if(!i){m=(f|0)!=0;if(!l){if(m){c[f>>2]=(g>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(g>>>0)/(j>>>0)>>>0;return (C=n,o)|0}else{if(!m){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=b&0;n=0;o=0;return (C=n,o)|0}}m=(l|0)==0;do if(j){if(!m){p=(aa(l|0)|0)-(aa(i|0)|0)|0;if(p>>>0<=31){q=p+1|0;r=31-p|0;s=p-31>>31;t=q;u=g>>>(q>>>0)&s|i<<r;v=i>>>(q>>>0)&s;w=0;x=g<<r;break}if(!f){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return (C=n,o)|0}r=j-1|0;if(r&j){s=(aa(j|0)|0)+33-(aa(i|0)|0)|0;q=64-s|0;p=32-s|0;y=p>>31;z=s-32|0;A=z>>31;t=s;u=p-1>>31&i>>>(z>>>0)|(i<<p|g>>>(s>>>0))&A;v=A&i>>>(s>>>0);w=g<<q&y;x=(i<<q|g>>>(z>>>0))&y|g<<p&s-33>>31;break}if(f){c[f>>2]=r&g;c[f+4>>2]=0}if((j|0)==1){n=h|b&0;o=a|0|0;return (C=n,o)|0}else{r=Qe(j|0)|0;n=i>>>(r>>>0)|0;o=i<<32-r|g>>>(r>>>0)|0;return (C=n,o)|0}}else{if(m){if(f){c[f>>2]=(i>>>0)%(j>>>0);c[f+4>>2]=0}n=0;o=(i>>>0)/(j>>>0)>>>0;return (C=n,o)|0}if(!g){if(f){c[f>>2]=0;c[f+4>>2]=(i>>>0)%(l>>>0)}n=0;o=(i>>>0)/(l>>>0)>>>0;return (C=n,o)|0}r=l-1|0;if(!(r&l)){if(f){c[f>>2]=a|0;c[f+4>>2]=r&i|b&0}n=0;o=i>>>((Qe(l|0)|0)>>>0);return (C=n,o)|0}r=(aa(l|0)|0)-(aa(i|0)|0)|0;if(r>>>0<=30){s=r+1|0;p=31-r|0;t=s;u=i<<p|g>>>(s>>>0);v=i>>>(s>>>0);w=0;x=g<<p;break}if(!f){n=0;o=0;return (C=n,o)|0}c[f>>2]=a|0;c[f+4>>2]=h|b&0;n=0;o=0;return (C=n,o)|0}while(0);if(!t){B=x;D=w;E=v;F=u;G=0;H=0}else{b=d|0|0;d=k|e&0;e=Me(b|0,d|0,-1,-1)|0;k=C;h=x;x=w;w=v;v=u;u=t;t=0;do{a=h;h=x>>>31|h<<1;x=t|x<<1;g=v<<1|a>>>31|0;a=v>>>31|w<<1|0;Ge(e,k,g,a)|0;i=C;l=i>>31|((i|0)<0?-1:0)<<1;t=l&1;v=Ge(g,a,l&b,(((i|0)<0?-1:0)>>31|((i|0)<0?-1:0)<<1)&d)|0;w=C;u=u-1|0}while((u|0)!=0);B=h;D=x;E=w;F=v;G=0;H=t}t=D;D=0;if(f){c[f>>2]=F;c[f+4>>2]=E}n=(t|0)>>>31|(B|D)<<1|(D<<1|t>>>31)&0|G;o=(t<<1|0>>>31)&-2|H;return (C=n,o)|0}function Ye(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;return La[a&1](b|0,c|0,d|0)|0}function Ze(a,b){a=a|0;b=b|0;Ma[a&1](b|0)}function _e(a,b){a=a|0;b=b|0;return Na[a&7](b|0)|0}function $e(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;return Oa[a&15](b|0,c|0,d|0,e|0)|0}function af(a,b,c){a=a|0;b=b|0;c=c|0;return Pa[a&1](b|0,c|0)|0}function bf(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;return Qa[a&31](b|0,c|0,d|0,e|0,f|0)|0}function cf(a,b,c){a=a|0;b=b|0;c=c|0;ba(0);return 0}function df(a){a=a|0;ba(1)}function ef(a){a=a|0;ba(2);return 0}function ff(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;ba(3);return 0}function gf(a,b){a=a|0;b=b|0;ba(4);return 0}function hf(a,b,c,d,e){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;ba(5);return 0} + +// EMSCRIPTEN_END_FUNCS +var La=[cf,wc];var Ma=[df,xc];var Na=[ef,tc,Jb,Kb,Lb,Vc,Nb,ef];var Oa=[ff,_c,cd,fd,md,rd,wd,Ad,pe,ff,ff,ff,ff,ff,ff,ff];var Pa=[gf,uc];var Qa=[hf,Xc,$c,ad,dd,ed,gd,hd,jd,kd,ld,nd,pd,qd,sd,td,ud,yd,zd,Cd,Dd,Ed,Fd,hf,hf,hf,hf,hf,hf,hf,hf,hf];return{_i64Subtract:Ge,_ogv_demuxer_keypoint_offset:ne,_memset:He,_ogv_demuxer_process:ie,_strncpy:Le,_ogv_demuxer_flush:oe,_bitshift64Ashr:Fe,_ogv_demuxer_init:he,_strlen:Je,_ogv_demuxer_destroy:je,_malloc:ye,_i64Add:Me,_ogv_demuxer_seekable:me,_ogv_demuxer_media_duration:le,_ogv_demuxer_media_length:ke,_memmove:Ne,_free:ze,_memcpy:Ke,_strcpy:Oe,_bitshift64Shl:Ie,runPostSets:Ee,stackAlloc:Ra,stackSave:Sa,stackRestore:Ta,establishStackSpace:Ua,setThrew:Va,setTempRet0:Ya,getTempRet0:Za,dynCall_iiii:Ye,dynCall_vi:Ze,dynCall_ii:_e,dynCall_iiiii:$e,dynCall_iii:af,dynCall_iiiiii:bf}}) + + +// EMSCRIPTEN_END_ASM +(Module.asmGlobalArg,Module.asmLibraryArg,buffer);var runPostSets=Module["runPostSets"]=asm["runPostSets"];var _i64Subtract=Module["_i64Subtract"]=asm["_i64Subtract"];var _ogv_demuxer_keypoint_offset=Module["_ogv_demuxer_keypoint_offset"]=asm["_ogv_demuxer_keypoint_offset"];var _memcpy=Module["_memcpy"]=asm["_memcpy"];var _ogv_demuxer_process=Module["_ogv_demuxer_process"]=asm["_ogv_demuxer_process"];var _strncpy=Module["_strncpy"]=asm["_strncpy"];var _ogv_demuxer_flush=Module["_ogv_demuxer_flush"]=asm["_ogv_demuxer_flush"];var _bitshift64Ashr=Module["_bitshift64Ashr"]=asm["_bitshift64Ashr"];var _ogv_demuxer_init=Module["_ogv_demuxer_init"]=asm["_ogv_demuxer_init"];var _memset=Module["_memset"]=asm["_memset"];var _ogv_demuxer_destroy=Module["_ogv_demuxer_destroy"]=asm["_ogv_demuxer_destroy"];var _malloc=Module["_malloc"]=asm["_malloc"];var _i64Add=Module["_i64Add"]=asm["_i64Add"];var _ogv_demuxer_seekable=Module["_ogv_demuxer_seekable"]=asm["_ogv_demuxer_seekable"];var _ogv_demuxer_media_duration=Module["_ogv_demuxer_media_duration"]=asm["_ogv_demuxer_media_duration"];var _strlen=Module["_strlen"]=asm["_strlen"];var _ogv_demuxer_media_length=Module["_ogv_demuxer_media_length"]=asm["_ogv_demuxer_media_length"];var _memmove=Module["_memmove"]=asm["_memmove"];var _free=Module["_free"]=asm["_free"];var _strcpy=Module["_strcpy"]=asm["_strcpy"];var _bitshift64Shl=Module["_bitshift64Shl"]=asm["_bitshift64Shl"];var dynCall_iiii=Module["dynCall_iiii"]=asm["dynCall_iiii"];var dynCall_vi=Module["dynCall_vi"]=asm["dynCall_vi"];var dynCall_ii=Module["dynCall_ii"]=asm["dynCall_ii"];var dynCall_iiiii=Module["dynCall_iiiii"]=asm["dynCall_iiiii"];var dynCall_iii=Module["dynCall_iii"]=asm["dynCall_iii"];var dynCall_iiiiii=Module["dynCall_iiiiii"]=asm["dynCall_iiiiii"];Runtime.stackAlloc=asm["stackAlloc"];Runtime.stackSave=asm["stackSave"];Runtime.stackRestore=asm["stackRestore"];Runtime.establishStackSpace=asm["establishStackSpace"];Runtime.setTempRet0=asm["setTempRet0"];Runtime.getTempRet0=asm["getTempRet0"];var i64Math=(function(){var goog={math:{}};goog.math.Long=(function(low,high){this.low_=low|0;this.high_=high|0});goog.math.Long.IntCache_={};goog.math.Long.fromInt=(function(value){if(-128<=value&&value<128){var cachedObj=goog.math.Long.IntCache_[value];if(cachedObj){return cachedObj}}var obj=new goog.math.Long(value|0,value<0?-1:0);if(-128<=value&&value<128){goog.math.Long.IntCache_[value]=obj}return obj});goog.math.Long.fromNumber=(function(value){if(isNaN(value)||!isFinite(value)){return goog.math.Long.ZERO}else if(value<=-goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MIN_VALUE}else if(value+1>=goog.math.Long.TWO_PWR_63_DBL_){return goog.math.Long.MAX_VALUE}else if(value<0){return goog.math.Long.fromNumber(-value).negate()}else{return new goog.math.Long(value%goog.math.Long.TWO_PWR_32_DBL_|0,value/goog.math.Long.TWO_PWR_32_DBL_|0)}});goog.math.Long.fromBits=(function(lowBits,highBits){return new goog.math.Long(lowBits,highBits)});goog.math.Long.fromString=(function(str,opt_radix){if(str.length==0){throw Error("number format error: empty string")}var radix=opt_radix||10;if(radix<2||36<radix){throw Error("radix out of range: "+radix)}if(str.charAt(0)=="-"){return goog.math.Long.fromString(str.substring(1),radix).negate()}else if(str.indexOf("-")>=0){throw Error('number format error: interior "-" character: '+str)}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,8));var result=goog.math.Long.ZERO;for(var i=0;i<str.length;i+=8){var size=Math.min(8,str.length-i);var value=parseInt(str.substring(i,i+size),radix);if(size<8){var power=goog.math.Long.fromNumber(Math.pow(radix,size));result=result.multiply(power).add(goog.math.Long.fromNumber(value))}else{result=result.multiply(radixToPower);result=result.add(goog.math.Long.fromNumber(value))}}return result});goog.math.Long.TWO_PWR_16_DBL_=1<<16;goog.math.Long.TWO_PWR_24_DBL_=1<<24;goog.math.Long.TWO_PWR_32_DBL_=goog.math.Long.TWO_PWR_16_DBL_*goog.math.Long.TWO_PWR_16_DBL_;goog.math.Long.TWO_PWR_31_DBL_=goog.math.Long.TWO_PWR_32_DBL_/2;goog.math.Long.TWO_PWR_48_DBL_=goog.math.Long.TWO_PWR_32_DBL_*goog.math.Long.TWO_PWR_16_DBL_;goog.math.Long.TWO_PWR_64_DBL_=goog.math.Long.TWO_PWR_32_DBL_*goog.math.Long.TWO_PWR_32_DBL_;goog.math.Long.TWO_PWR_63_DBL_=goog.math.Long.TWO_PWR_64_DBL_/2;goog.math.Long.ZERO=goog.math.Long.fromInt(0);goog.math.Long.ONE=goog.math.Long.fromInt(1);goog.math.Long.NEG_ONE=goog.math.Long.fromInt(-1);goog.math.Long.MAX_VALUE=goog.math.Long.fromBits(4294967295|0,2147483647|0);goog.math.Long.MIN_VALUE=goog.math.Long.fromBits(0,2147483648|0);goog.math.Long.TWO_PWR_24_=goog.math.Long.fromInt(1<<24);goog.math.Long.prototype.toInt=(function(){return this.low_});goog.math.Long.prototype.toNumber=(function(){return this.high_*goog.math.Long.TWO_PWR_32_DBL_+this.getLowBitsUnsigned()});goog.math.Long.prototype.toString=(function(opt_radix){var radix=opt_radix||10;if(radix<2||36<radix){throw Error("radix out of range: "+radix)}if(this.isZero()){return"0"}if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){var radixLong=goog.math.Long.fromNumber(radix);var div=this.div(radixLong);var rem=div.multiply(radixLong).subtract(this);return div.toString(radix)+rem.toInt().toString(radix)}else{return"-"+this.negate().toString(radix)}}var radixToPower=goog.math.Long.fromNumber(Math.pow(radix,6));var rem=this;var result="";while(true){var remDiv=rem.div(radixToPower);var intval=rem.subtract(remDiv.multiply(radixToPower)).toInt();var digits=intval.toString(radix);rem=remDiv;if(rem.isZero()){return digits+result}else{while(digits.length<6){digits="0"+digits}result=""+digits+result}}});goog.math.Long.prototype.getHighBits=(function(){return this.high_});goog.math.Long.prototype.getLowBits=(function(){return this.low_});goog.math.Long.prototype.getLowBitsUnsigned=(function(){return this.low_>=0?this.low_:goog.math.Long.TWO_PWR_32_DBL_+this.low_});goog.math.Long.prototype.getNumBitsAbs=(function(){if(this.isNegative()){if(this.equals(goog.math.Long.MIN_VALUE)){return 64}else{return this.negate().getNumBitsAbs()}}else{var val=this.high_!=0?this.high_:this.low_;for(var bit=31;bit>0;bit--){if((val&1<<bit)!=0){break}}return this.high_!=0?bit+33:bit+1}});goog.math.Long.prototype.isZero=(function(){return this.high_==0&&this.low_==0});goog.math.Long.prototype.isNegative=(function(){return this.high_<0});goog.math.Long.prototype.isOdd=(function(){return(this.low_&1)==1});goog.math.Long.prototype.equals=(function(other){return this.high_==other.high_&&this.low_==other.low_});goog.math.Long.prototype.notEquals=(function(other){return this.high_!=other.high_||this.low_!=other.low_});goog.math.Long.prototype.lessThan=(function(other){return this.compare(other)<0});goog.math.Long.prototype.lessThanOrEqual=(function(other){return this.compare(other)<=0});goog.math.Long.prototype.greaterThan=(function(other){return this.compare(other)>0});goog.math.Long.prototype.greaterThanOrEqual=(function(other){return this.compare(other)>=0});goog.math.Long.prototype.compare=(function(other){if(this.equals(other)){return 0}var thisNeg=this.isNegative();var otherNeg=other.isNegative();if(thisNeg&&!otherNeg){return-1}if(!thisNeg&&otherNeg){return 1}if(this.subtract(other).isNegative()){return-1}else{return 1}});goog.math.Long.prototype.negate=(function(){if(this.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.MIN_VALUE}else{return this.not().add(goog.math.Long.ONE)}});goog.math.Long.prototype.add=(function(other){var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00+b00;c16+=c00>>>16;c00&=65535;c16+=a16+b16;c32+=c16>>>16;c16&=65535;c32+=a32+b32;c48+=c32>>>16;c32&=65535;c48+=a48+b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.subtract=(function(other){return this.add(other.negate())});goog.math.Long.prototype.multiply=(function(other){if(this.isZero()){return goog.math.Long.ZERO}else if(other.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){return other.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}else if(other.equals(goog.math.Long.MIN_VALUE)){return this.isOdd()?goog.math.Long.MIN_VALUE:goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().multiply(other.negate())}else{return this.negate().multiply(other).negate()}}else if(other.isNegative()){return this.multiply(other.negate()).negate()}if(this.lessThan(goog.math.Long.TWO_PWR_24_)&&other.lessThan(goog.math.Long.TWO_PWR_24_)){return goog.math.Long.fromNumber(this.toNumber()*other.toNumber())}var a48=this.high_>>>16;var a32=this.high_&65535;var a16=this.low_>>>16;var a00=this.low_&65535;var b48=other.high_>>>16;var b32=other.high_&65535;var b16=other.low_>>>16;var b00=other.low_&65535;var c48=0,c32=0,c16=0,c00=0;c00+=a00*b00;c16+=c00>>>16;c00&=65535;c16+=a16*b00;c32+=c16>>>16;c16&=65535;c16+=a00*b16;c32+=c16>>>16;c16&=65535;c32+=a32*b00;c48+=c32>>>16;c32&=65535;c32+=a16*b16;c48+=c32>>>16;c32&=65535;c32+=a00*b32;c48+=c32>>>16;c32&=65535;c48+=a48*b00+a32*b16+a16*b32+a00*b48;c48&=65535;return goog.math.Long.fromBits(c16<<16|c00,c48<<16|c32)});goog.math.Long.prototype.div=(function(other){if(other.isZero()){throw Error("division by zero")}else if(this.isZero()){return goog.math.Long.ZERO}if(this.equals(goog.math.Long.MIN_VALUE)){if(other.equals(goog.math.Long.ONE)||other.equals(goog.math.Long.NEG_ONE)){return goog.math.Long.MIN_VALUE}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ONE}else{var halfThis=this.shiftRight(1);var approx=halfThis.div(other).shiftLeft(1);if(approx.equals(goog.math.Long.ZERO)){return other.isNegative()?goog.math.Long.ONE:goog.math.Long.NEG_ONE}else{var rem=this.subtract(other.multiply(approx));var result=approx.add(rem.div(other));return result}}}else if(other.equals(goog.math.Long.MIN_VALUE)){return goog.math.Long.ZERO}if(this.isNegative()){if(other.isNegative()){return this.negate().div(other.negate())}else{return this.negate().div(other).negate()}}else if(other.isNegative()){return this.div(other.negate()).negate()}var res=goog.math.Long.ZERO;var rem=this;while(rem.greaterThanOrEqual(other)){var approx=Math.max(1,Math.floor(rem.toNumber()/other.toNumber()));var log2=Math.ceil(Math.log(approx)/Math.LN2);var delta=log2<=48?1:Math.pow(2,log2-48);var approxRes=goog.math.Long.fromNumber(approx);var approxRem=approxRes.multiply(other);while(approxRem.isNegative()||approxRem.greaterThan(rem)){approx-=delta;approxRes=goog.math.Long.fromNumber(approx);approxRem=approxRes.multiply(other)}if(approxRes.isZero()){approxRes=goog.math.Long.ONE}res=res.add(approxRes);rem=rem.subtract(approxRem)}return res});goog.math.Long.prototype.modulo=(function(other){return this.subtract(this.div(other).multiply(other))});goog.math.Long.prototype.not=(function(){return goog.math.Long.fromBits(~this.low_,~this.high_)});goog.math.Long.prototype.and=(function(other){return goog.math.Long.fromBits(this.low_&other.low_,this.high_&other.high_)});goog.math.Long.prototype.or=(function(other){return goog.math.Long.fromBits(this.low_|other.low_,this.high_|other.high_)});goog.math.Long.prototype.xor=(function(other){return goog.math.Long.fromBits(this.low_^other.low_,this.high_^other.high_)});goog.math.Long.prototype.shiftLeft=(function(numBits){numBits&=63;if(numBits==0){return this}else{var low=this.low_;if(numBits<32){var high=this.high_;return goog.math.Long.fromBits(low<<numBits,high<<numBits|low>>>32-numBits)}else{return goog.math.Long.fromBits(0,low<<numBits-32)}}});goog.math.Long.prototype.shiftRight=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>numBits)}else{return goog.math.Long.fromBits(high>>numBits-32,high>=0?0:-1)}}});goog.math.Long.prototype.shiftRightUnsigned=(function(numBits){numBits&=63;if(numBits==0){return this}else{var high=this.high_;if(numBits<32){var low=this.low_;return goog.math.Long.fromBits(low>>>numBits|high<<32-numBits,high>>>numBits)}else if(numBits==32){return goog.math.Long.fromBits(high,0)}else{return goog.math.Long.fromBits(high>>>numBits-32,0)}}});var navigator={appName:"Modern Browser"};var dbits;var canary=0xdeadbeefcafe;var j_lm=(canary&16777215)==15715070;function BigInteger(a,b,c){if(a!=null)if("number"==typeof a)this.fromNumber(a,b,c);else if(b==null&&"string"!=typeof a)this.fromString(a,256);else this.fromString(a,b)}function nbi(){return new BigInteger(null)}function am1(i,x,w,j,c,n){while(--n>=0){var v=x*this[i++]+w[j]+c;c=Math.floor(v/67108864);w[j++]=v&67108863}return c}function am2(i,x,w,j,c,n){var xl=x&32767,xh=x>>15;while(--n>=0){var l=this[i]&32767;var h=this[i++]>>15;var m=xh*l+h*xl;l=xl*l+((m&32767)<<15)+w[j]+(c&1073741823);c=(l>>>30)+(m>>>15)+xh*h+(c>>>30);w[j++]=l&1073741823}return c}function am3(i,x,w,j,c,n){var xl=x&16383,xh=x>>14;while(--n>=0){var l=this[i]&16383;var h=this[i++]>>14;var m=xh*l+h*xl;l=xl*l+((m&16383)<<14)+w[j]+c;c=(l>>28)+(m>>14)+xh*h;w[j++]=l&268435455}return c}if(j_lm&&navigator.appName=="Microsoft Internet Explorer"){BigInteger.prototype.am=am2;dbits=30}else if(j_lm&&navigator.appName!="Netscape"){BigInteger.prototype.am=am1;dbits=26}else{BigInteger.prototype.am=am3;dbits=28}BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz";var BI_RC=new Array;var rr,vv;rr="0".charCodeAt(0);for(vv=0;vv<=9;++vv)BI_RC[rr++]=vv;rr="a".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;rr="A".charCodeAt(0);for(vv=10;vv<36;++vv)BI_RC[rr++]=vv;function int2char(n){return BI_RM.charAt(n)}function intAt(s,i){var c=BI_RC[s.charCodeAt(i)];return c==null?-1:c}function bnpCopyTo(r){for(var i=this.t-1;i>=0;--i)r[i]=this[i];r.t=this.t;r.s=this.s}function bnpFromInt(x){this.t=1;this.s=x<0?-1:0;if(x>0)this[0]=x;else if(x<-1)this[0]=x+DV;else this.t=0}function nbv(i){var r=nbi();r.fromInt(i);return r}function bnpFromString(s,b){var k;if(b==16)k=4;else if(b==8)k=3;else if(b==256)k=8;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else{this.fromRadix(s,b);return}this.t=0;this.s=0;var i=s.length,mi=false,sh=0;while(--i>=0){var x=k==8?s[i]&255:intAt(s,i);if(x<0){if(s.charAt(i)=="-")mi=true;continue}mi=false;if(sh==0)this[this.t++]=x;else if(sh+k>this.DB){this[this.t-1]|=(x&(1<<this.DB-sh)-1)<<sh;this[this.t++]=x>>this.DB-sh}else this[this.t-1]|=x<<sh;sh+=k;if(sh>=this.DB)sh-=this.DB}if(k==8&&(s[0]&128)!=0){this.s=-1;if(sh>0)this[this.t-1]|=(1<<this.DB-sh)-1<<sh}this.clamp();if(mi)BigInteger.ZERO.subTo(this,this)}function bnpClamp(){var c=this.s&this.DM;while(this.t>0&&this[this.t-1]==c)--this.t}function bnToString(b){if(this.s<0)return"-"+this.negate().toString(b);var k;if(b==16)k=4;else if(b==8)k=3;else if(b==2)k=1;else if(b==32)k=5;else if(b==4)k=2;else return this.toRadix(b);var km=(1<<k)-1,d,m=false,r="",i=this.t;var p=this.DB-i*this.DB%k;if(i-->0){if(p<this.DB&&(d=this[i]>>p)>0){m=true;r=int2char(d)}while(i>=0){if(p<k){d=(this[i]&(1<<p)-1)<<k-p;d|=this[--i]>>(p+=this.DB-k)}else{d=this[i]>>(p-=k)&km;if(p<=0){p+=this.DB;--i}}if(d>0)m=true;if(m)r+=int2char(d)}}return m?r:"0"}function bnNegate(){var r=nbi();BigInteger.ZERO.subTo(this,r);return r}function bnAbs(){return this.s<0?this.negate():this}function bnCompareTo(a){var r=this.s-a.s;if(r!=0)return r;var i=this.t;r=i-a.t;if(r!=0)return this.s<0?-r:r;while(--i>=0)if((r=this[i]-a[i])!=0)return r;return 0}function nbits(x){var r=1,t;if((t=x>>>16)!=0){x=t;r+=16}if((t=x>>8)!=0){x=t;r+=8}if((t=x>>4)!=0){x=t;r+=4}if((t=x>>2)!=0){x=t;r+=2}if((t=x>>1)!=0){x=t;r+=1}return r}function bnBitLength(){if(this.t<=0)return 0;return this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(n,r){var i;for(i=this.t-1;i>=0;--i)r[i+n]=this[i];for(i=n-1;i>=0;--i)r[i]=0;r.t=this.t+n;r.s=this.s}function bnpDRShiftTo(n,r){for(var i=n;i<this.t;++i)r[i-n]=this[i];r.t=Math.max(this.t-n,0);r.s=this.s}function bnpLShiftTo(n,r){var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<cbs)-1;var ds=Math.floor(n/this.DB),c=this.s<<bs&this.DM,i;for(i=this.t-1;i>=0;--i){r[i+ds+1]=this[i]>>cbs|c;c=(this[i]&bm)<<bs}for(i=ds-1;i>=0;--i)r[i]=0;r[ds]=c;r.t=this.t+ds+1;r.s=this.s;r.clamp()}function bnpRShiftTo(n,r){r.s=this.s;var ds=Math.floor(n/this.DB);if(ds>=this.t){r.t=0;return}var bs=n%this.DB;var cbs=this.DB-bs;var bm=(1<<bs)-1;r[0]=this[ds]>>bs;for(var i=ds+1;i<this.t;++i){r[i-ds-1]|=(this[i]&bm)<<cbs;r[i-ds]=this[i]>>bs}if(bs>0)r[this.t-ds-1]|=(this.s&bm)<<cbs;r.t=this.t-ds;r.clamp()}function bnpSubTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]-a[i];r[i++]=c&this.DM;c>>=this.DB}if(a.t<this.t){c-=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB}c+=this.s}else{c+=this.s;while(i<a.t){c-=a[i];r[i++]=c&this.DM;c>>=this.DB}c-=a.s}r.s=c<0?-1:0;if(c<-1)r[i++]=this.DV+c;else if(c>0)r[i++]=c;r.t=i;r.clamp()}function bnpMultiplyTo(a,r){var x=this.abs(),y=a.abs();var i=x.t;r.t=i+y.t;while(--i>=0)r[i]=0;for(i=0;i<y.t;++i)r[i+x.t]=x.am(0,y[i],r,i,0,x.t);r.s=0;r.clamp();if(this.s!=a.s)BigInteger.ZERO.subTo(r,r)}function bnpSquareTo(r){var x=this.abs();var i=r.t=2*x.t;while(--i>=0)r[i]=0;for(i=0;i<x.t-1;++i){var c=x.am(i,x[i],r,2*i,0,1);if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1))>=x.DV){r[i+x.t]-=x.DV;r[i+x.t+1]=1}}if(r.t>0)r[r.t-1]+=x.am(i,x[i],r,2*i,0,1);r.s=0;r.clamp()}function bnpDivRemTo(m,q,r){var pm=m.abs();if(pm.t<=0)return;var pt=this.abs();if(pt.t<pm.t){if(q!=null)q.fromInt(0);if(r!=null)this.copyTo(r);return}if(r==null)r=nbi();var y=nbi(),ts=this.s,ms=m.s;var nsh=this.DB-nbits(pm[pm.t-1]);if(nsh>0){pm.lShiftTo(nsh,y);pt.lShiftTo(nsh,r)}else{pm.copyTo(y);pt.copyTo(r)}var ys=y.t;var y0=y[ys-1];if(y0==0)return;var yt=y0*(1<<this.F1)+(ys>1?y[ys-2]>>this.F2:0);var d1=this.FV/yt,d2=(1<<this.F1)/yt,e=1<<this.F2;var i=r.t,j=i-ys,t=q==null?nbi():q;y.dlShiftTo(j,t);if(r.compareTo(t)>=0){r[r.t++]=1;r.subTo(t,r)}BigInteger.ONE.dlShiftTo(ys,t);t.subTo(y,y);while(y.t<ys)y[y.t++]=0;while(--j>=0){var qd=r[--i]==y0?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);if((r[i]+=y.am(0,qd,r,j,0,ys))<qd){y.dlShiftTo(j,t);r.subTo(t,r);while(r[i]<--qd)r.subTo(t,r)}}if(q!=null){r.drShiftTo(ys,q);if(ts!=ms)BigInteger.ZERO.subTo(q,q)}r.t=ys;r.clamp();if(nsh>0)r.rShiftTo(nsh,r);if(ts<0)BigInteger.ZERO.subTo(r,r)}function bnMod(a){var r=nbi();this.abs().divRemTo(a,null,r);if(this.s<0&&r.compareTo(BigInteger.ZERO)>0)a.subTo(r,r);return r}function Classic(m){this.m=m}function cConvert(x){if(x.s<0||x.compareTo(this.m)>=0)return x.mod(this.m);else return x}function cRevert(x){return x}function cReduce(x){x.divRemTo(this.m,null,x)}function cMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}function cSqrTo(x,r){x.squareTo(r);this.reduce(r)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;function bnpInvDigit(){if(this.t<1)return 0;var x=this[0];if((x&1)==0)return 0;var y=x&3;y=y*(2-(x&15)*y)&15;y=y*(2-(x&255)*y)&255;y=y*(2-((x&65535)*y&65535))&65535;y=y*(2-x*y%this.DV)%this.DV;return y>0?this.DV-y:-y}function Montgomery(m){this.m=m;this.mp=m.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<m.DB-15)-1;this.mt2=2*m.t}function montConvert(x){var r=nbi();x.abs().dlShiftTo(this.m.t,r);r.divRemTo(this.m,null,r);if(x.s<0&&r.compareTo(BigInteger.ZERO)>0)this.m.subTo(r,r);return r}function montRevert(x){var r=nbi();x.copyTo(r);this.reduce(r);return r}function montReduce(x){while(x.t<=this.mt2)x[x.t++]=0;for(var i=0;i<this.m.t;++i){var j=x[i]&32767;var u0=j*this.mpl+((j*this.mph+(x[i]>>15)*this.mpl&this.um)<<15)&x.DM;j=i+this.m.t;x[j]+=this.m.am(0,u0,x,i,0,this.m.t);while(x[j]>=x.DV){x[j]-=x.DV;x[++j]++}}x.clamp();x.drShiftTo(this.m.t,x);if(x.compareTo(this.m)>=0)x.subTo(this.m,x)}function montSqrTo(x,r){x.squareTo(r);this.reduce(r)}function montMulTo(x,y,r){x.multiplyTo(y,r);this.reduce(r)}Montgomery.prototype.convert=montConvert;Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return(this.t>0?this[0]&1:this.s)==0}function bnpExp(e,z){if(e>4294967295||e<1)return BigInteger.ONE;var r=nbi(),r2=nbi(),g=z.convert(this),i=nbits(e)-1;g.copyTo(r);while(--i>=0){z.sqrTo(r,r2);if((e&1<<i)>0)z.mulTo(r2,g,r);else{var t=r;r=r2;r2=t}}return z.revert(r)}function bnModPowInt(e,m){var z;if(e<256||m.isEven())z=new Classic(m);else z=new Montgomery(m);return this.exp(e,z)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnpFromRadix(s,b){this.fromInt(0);if(b==null)b=10;var cs=this.chunkSize(b);var d=Math.pow(b,cs),mi=false,j=0,w=0;for(var i=0;i<s.length;++i){var x=intAt(s,i);if(x<0){if(s.charAt(i)=="-"&&this.signum()==0)mi=true;continue}w=b*w+x;if(++j>=cs){this.dMultiply(d);this.dAddOffset(w,0);j=0;w=0}}if(j>0){this.dMultiply(Math.pow(b,j));this.dAddOffset(w,0)}if(mi)BigInteger.ZERO.subTo(this,this)}function bnpChunkSize(r){return Math.floor(Math.LN2*this.DB/Math.log(r))}function bnSigNum(){if(this.s<0)return-1;else if(this.t<=0||this.t==1&&this[0]<=0)return 0;else return 1}function bnpDMultiply(n){this[this.t]=this.am(0,n-1,this,0,0,this.t);++this.t;this.clamp()}function bnpDAddOffset(n,w){if(n==0)return;while(this.t<=w)this[this.t++]=0;this[w]+=n;while(this[w]>=this.DV){this[w]-=this.DV;if(++w>=this.t)this[this.t++]=0;++this[w]}}function bnpToRadix(b){if(b==null)b=10;if(this.signum()==0||b<2||b>36)return"0";var cs=this.chunkSize(b);var a=Math.pow(b,cs);var d=nbv(a),y=nbi(),z=nbi(),r="";this.divRemTo(d,y,z);while(y.signum()>0){r=(a+z.intValue()).toString(b).substr(1)+r;y.divRemTo(d,y,z)}return z.intValue().toString(b)+r}function bnIntValue(){if(this.s<0){if(this.t==1)return this[0]-this.DV;else if(this.t==0)return-1}else if(this.t==1)return this[0];else if(this.t==0)return 0;return(this[1]&(1<<32-this.DB)-1)<<this.DB|this[0]}function bnpAddTo(a,r){var i=0,c=0,m=Math.min(a.t,this.t);while(i<m){c+=this[i]+a[i];r[i++]=c&this.DM;c>>=this.DB}if(a.t<this.t){c+=a.s;while(i<this.t){c+=this[i];r[i++]=c&this.DM;c>>=this.DB}c+=this.s}else{c+=this.s;while(i<a.t){c+=a[i];r[i++]=c&this.DM;c>>=this.DB}c+=a.s}r.s=c<0?-1:0;if(c>0)r[i++]=c;else if(c<-1)r[i++]=this.DV+c;r.t=i;r.clamp()}BigInteger.prototype.fromRadix=bnpFromRadix;BigInteger.prototype.chunkSize=bnpChunkSize;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.dMultiply=bnpDMultiply;BigInteger.prototype.dAddOffset=bnpDAddOffset;BigInteger.prototype.toRadix=bnpToRadix;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.addTo=bnpAddTo;var Wrapper={abs:(function(l,h){var x=new goog.math.Long(l,h);var ret;if(x.isNegative()){ret=x.negate()}else{ret=x}HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_}),ensureTemps:(function(){if(Wrapper.ensuredTemps)return;Wrapper.ensuredTemps=true;Wrapper.two32=new BigInteger;Wrapper.two32.fromString("4294967296",10);Wrapper.two64=new BigInteger;Wrapper.two64.fromString("18446744073709551616",10);Wrapper.temp1=new BigInteger;Wrapper.temp2=new BigInteger}),lh2bignum:(function(l,h){var a=new BigInteger;a.fromString(h.toString(),10);var b=new BigInteger;a.multiplyTo(Wrapper.two32,b);var c=new BigInteger;c.fromString(l.toString(),10);var d=new BigInteger;c.addTo(b,d);return d}),stringify:(function(l,h,unsigned){var ret=(new goog.math.Long(l,h)).toString();if(unsigned&&ret[0]=="-"){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(ret,10);ret=new BigInteger;Wrapper.two64.addTo(bignum,ret);ret=ret.toString(10)}return ret}),fromString:(function(str,base,min,max,unsigned){Wrapper.ensureTemps();var bignum=new BigInteger;bignum.fromString(str,base);var bigmin=new BigInteger;bigmin.fromString(min,10);var bigmax=new BigInteger;bigmax.fromString(max,10);if(unsigned&&bignum.compareTo(BigInteger.ZERO)<0){var temp=new BigInteger;bignum.addTo(Wrapper.two64,temp);bignum=temp}var error=false;if(bignum.compareTo(bigmin)<0){bignum=bigmin;error=true}else if(bignum.compareTo(bigmax)>0){bignum=bigmax;error=true}var ret=goog.math.Long.fromString(bignum.toString());HEAP32[tempDoublePtr>>2]=ret.low_;HEAP32[tempDoublePtr+4>>2]=ret.high_;if(error)throw"range error"})};return Wrapper})();function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}ExitStatus.prototype=new Error;ExitStatus.prototype.constructor=ExitStatus;var initialStackTop;var preloadStartTime=null;var calledMain=false;dependenciesFulfilled=function runCaller(){if(!Module["calledRun"])run();if(!Module["calledRun"])dependenciesFulfilled=runCaller};Module["callMain"]=Module.callMain=function callMain(args){assert(runDependencies==0,"cannot call main when async dependencies remain! (listen on __ATMAIN__)");assert(__ATPRERUN__.length==0,"cannot call main when preRun functions remain to be called");args=args||[];ensureInitRuntime();var argc=args.length+1;function pad(){for(var i=0;i<4-1;i++){argv.push(0)}}var argv=[allocate(intArrayFromString(Module["thisProgram"]),"i8",ALLOC_NORMAL)];pad();for(var i=0;i<argc-1;i=i+1){argv.push(allocate(intArrayFromString(args[i]),"i8",ALLOC_NORMAL));pad()}argv.push(0);argv=allocate(argv,"i32",ALLOC_NORMAL);initialStackTop=STACKTOP;try{var ret=Module["_main"](argc,argv,0);exit(ret,true)}catch(e){if(e instanceof ExitStatus){return}else if(e=="SimulateInfiniteLoop"){Module["noExitRuntime"]=true;return}else{if(e&&typeof e==="object"&&e.stack)Module.printErr("exception thrown: "+[e,e.stack]);throw e}}finally{calledMain=true}};function run(args){args=args||Module["arguments"];if(preloadStartTime===null)preloadStartTime=Date.now();if(runDependencies>0){return}preRun();if(runDependencies>0)return;if(Module["calledRun"])return;function doRun(){if(Module["calledRun"])return;Module["calledRun"]=true;if(ABORT)return;ensureInitRuntime();preMain();if(ENVIRONMENT_IS_WEB&&preloadStartTime!==null){Module.printErr("pre-main prep time: "+(Date.now()-preloadStartTime)+" ms")}if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(Module["_main"]&&shouldRunNow)Module["callMain"](args);postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout((function(){setTimeout((function(){Module["setStatus"]("")}),1);doRun()}),1)}else{doRun()}}Module["run"]=Module.run=run;function exit(status,implicit){if(implicit&&Module["noExitRuntime"]){return}if(Module["noExitRuntime"]){}else{ABORT=true;EXITSTATUS=status;STACKTOP=initialStackTop;exitRuntime();if(Module["onExit"])Module["onExit"](status)}if(ENVIRONMENT_IS_NODE){process["stdout"]["once"]("drain",(function(){process["exit"](status)}));console.log(" ");setTimeout((function(){process["exit"](status)}),500)}else if(ENVIRONMENT_IS_SHELL&&typeof quit==="function"){quit(status)}throw new ExitStatus(status)}Module["exit"]=Module.exit=exit;var abortDecorators=[];function abort(what){if(what!==undefined){Module.print(what);Module.printErr(what);what=JSON.stringify(what)}else{what=""}ABORT=true;EXITSTATUS=1;var extra="\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.";var output="abort("+what+") at "+stackTrace()+extra;if(abortDecorators){abortDecorators.forEach((function(decorator){output=decorator(output,what)}))}throw output}Module["abort"]=Module.abort=abort;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=false;if(Module["noInitialRun"]){shouldRunNow=false}Module["noExitRuntime"]=true;run();var inputBuffer,inputBufferSize;function reallocInputBuffer(size){if(inputBuffer&&inputBufferSize>=size){return inputBuffer}if(inputBuffer){Module._free(inputBuffer)}inputBufferSize=size;inputBuffer=Module._malloc(inputBufferSize);return inputBuffer}Module.loadedmetadata=false;Module.videoCodec=null;Module.audioCodec=null;Module.duration=NaN;Module.audioPackets=[];Object.defineProperty(Module,"hasAudio",{get:(function(){return Module.loadedMetadata&&Module.audioCodec})});Object.defineProperty(Module,"audioReady",{get:(function(){return Module.audioPackets.length>0})});Object.defineProperty(Module,"audioTimestamp",{get:(function(){if(Module.audioPackets.length>0){return Module.audioPackets[0].timestamp}else{return-1}})});Module.videoPackets=[];Object.defineProperty(Module,"hasVideo",{get:(function(){return Module.loadedMetadata&&Module.videoCodec})});Object.defineProperty(Module,"frameReady",{get:(function(){return Module.videoPackets.length>0})});Object.defineProperty(Module,"frameTimestamp",{get:(function(){if(Module.videoPackets.length>0){return Module.videoPackets[0].timestamp}else{return-1}})});Object.defineProperty(Module,"keyframeTimestamp",{get:(function(){if(Module.videoPackets.length>0){return Module.videoPackets[0].keyframeTimestamp}else{return-1}})});Object.defineProperty(Module,"processing",{get:function getProcessing(){return false}});Object.defineProperty(Module,"seekable",{get:(function(){return!!Module._ogv_demuxer_seekable()})});Module.init=(function(callback){Module._ogv_demuxer_init();callback()});Module.process=(function(data,callback){var len=data.byteLength;var buffer=reallocInputBuffer(len);Module.HEAPU8.set(new Uint8Array(data),buffer);var ret=Module._ogv_demuxer_process(buffer,len);callback(ret)});Module.dequeueVideoPacket=(function(callback){if(Module.videoPackets.length){var packet=Module.videoPackets.shift().data;callback(packet)}else{callback(null)}});Module.dequeueAudioPacket=(function(callback){if(Module.audioPackets.length){var packet=Module.audioPackets.shift().data;callback(packet)}else{callback(null)}});Module.getKeypointOffset=(function(timeSeconds,callback){var offset=Module._ogv_demuxer_keypoint_offset(timeSeconds*1e3);callback(offset)});Module.flush=(function(callback){Module.audioPackets.splice(0,Module.audioPackets.length);Module.videoPackets.splice(0,Module.videoPackets.length);Module._ogv_demuxer_flush();callback()}) + + + + + + return Module; +}; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-support.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-support.js new file mode 100644 index 00000000..5c2933ed --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-support.js @@ -0,0 +1,201 @@ +// +// -- ogv-support.js +// https://github.com/brion/ogv.js +// Copyright (c) 2013-2015 Brion Vibber +// + +(function() { + + +/** + * A quick CPU/JS engine benchmark to guesstimate whether we're + * fast enough to handle 360p video in JavaScript. + */ +function BogoSlow() { + var self = this; + + var timer; + if (window.performance && window.performance.now) { + timer = function() { + return window.performance.now(); + }; + } else { + timer = function() { + return Date.now(); + }; + } + + var savedSpeed = null; + function run() { + var ops = 0; + var fibonacci = function(n) { + ops++; + if (n < 2) { + return n; + } else { + return fibonacci(n - 2) + fibonacci(n - 1); + } + }; + + var start = timer(); + + fibonacci(30); + + var delta = timer() - start; + savedSpeed = (ops / delta); + } + + /** + * Return a scale value of operations/sec from the benchmark. + * If the benchmark has already been run, uses a memoized result. + * + * @property {number} + */ + Object.defineProperty(self, 'speed', { + get: function() { + if (savedSpeed === null) { + run(); + } + return savedSpeed; + } + }); + + /** + * Return the defined cutoff speed value for 'slow' devices, + * based on results measured from some test devices. + * + * @property {number} + */ + Object.defineProperty(self, 'slowCutoff', { + get: function() { + // 2012 Retina MacBook Pro (Safari 7) ~150,000 + // 2009 Dell T5500 (IE 11) ~100,000 + // iPad Air (iOS 7) ~65,000 + // 2010 MBP / OS X 10.9 (Safari 7) ~62,500 + // 2010 MBP / Win7 VM (IE 11) ~50,000+- + // ^ these play 360p ok + // ----------- line of moderate doom ---------- + return 50000; + // v these play 160p ok + // iPad Mini non-Retina (iOS 8 beta) ~25,000 + // Dell Inspiron Duo (IE 11) ~25,000 + // Surface RT (IE 11) ~18,000 + // iPod Touch 5th-gen (iOS 8 beta) ~16,000 + } + }); + + /** + * Return the defined cutoff speed value for 'too slow' devices, + * based on results measured from some test devices. + * + * @property {number} + */ + Object.defineProperty(self, 'tooSlowCutoff', { + get: function() { + // ------------ line of total doom ------------ + return 12000; + // v these are toooooo slow and explode + // Chrome on iPhone 5s (iOS 8) ~8,000 + // iPod 4th-gen (iOS 6.1) ~6,750 + // iPhone 3Gs (iOS 6.1) ~4,500 + } + }); + + /** + * 'Slow' devices can play audio and should sorta play our + * extra-tiny Wikimedia 160p15 transcodes + * + * @property {boolean} + */ + Object.defineProperty(self, 'slow', { + get: function() { + return (self.speed < self.slowCutoff); + } + }); + + /** + * 'Too slow' devices aren't reliable at all + * + * @property {boolean} + */ + Object.defineProperty(self, 'tooSlow', { + get: function() { + return (self.speed < self.tooSlowCutoff); + } + }); +} + + + +OGVCompat = { + benchmark: new BogoSlow(), + + hasTypedArrays: function() { + // emscripten-compiled code requires typed arrays + return !!window.Uint32Array; + }, + + hasWebAudio: function() { + return !!(window.AudioContext || window.webkitAudioContext); + }, + + hasFlash: function() { + if (navigator.userAgent.indexOf('Trident') !== -1) { + // We only do the ActiveX test because we only need Flash in + // Internet Explorer 10/11. Other browsers use Web Audio directly + // (Edge, Safari) or native playback, so there's no need to test + // other ways of loading Flash. + try { + var obj = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); + return true; + } catch(e) { + return false; + } + } + return false; + }, + + hasAudio: function() { + return this.hasWebAudio() || this.hasFlash(); + }, + + isBlacklisted: function(userAgent) { + // JIT bugs in old Safari versions + var blacklist = [ + /\(i.* OS [67]_.* like Mac OS X\).* Mobile\/.* Safari\//, + /\(Macintosh.* Version\/6\..* Safari\/\d/ + ]; + var blacklisted = false; + blacklist.forEach(function(regex) { + if (userAgent.match(regex)) { + blacklisted = true; + } + }); + return blacklisted; + }, + + isSlow: function() { + return this.benchmark.slow; + }, + + isTooSlow: function() { + return this.benchmark.tooSlow; + }, + + supported: function(component) { + if (component === 'OGVDecoder') { + return (this.hasTypedArrays() && !this.isBlacklisted(navigator.userAgent)); + } + if (component === 'OGVPlayer') { + return (this.supported('OGVDecoder') && this.hasAudio() && !this.isTooSlow()); + } + return false; + } +}; + + + this.OGVCompat = OGVCompat; + +})(); + +this.OGVVersion = "1.0-20150904182230-dd3c8e8"; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-version.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-version.js new file mode 100644 index 00000000..e6a7a670 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-version.js @@ -0,0 +1 @@ +this.OGVVersion = "1.0-20150904182230-dd3c8e8"; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-audio.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-audio.js new file mode 100644 index 00000000..c7c0ff25 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-audio.js @@ -0,0 +1,317 @@ +(function() { + var global = this; + + var scriptMap = { + OGVDemuxerOgg: 'ogv-demuxer-ogg.js', + OGVDemuxerWebM: 'ogv-demuxer-webm.js', + OGVDecoderAudioOpus: 'ogv-decoder-audio-opus.js', + OGVDecoderAudioVorbis: 'ogv-decoder-audio-vorbis.js', + OGVDecoderVideoTheora: 'ogv-decoder-video-theora.js', + OGVDecoderVideoVP8: 'ogv-decoder-video-vp8.js' + }; + + var proxyMap = { + OGVDecoderAudioOpus: 'OGVDecoderAudioProxy', + OGVDecoderAudioVorbis: 'OGVDecoderAudioProxy', + OGVDecoderVideoTheora: 'OGVDecoderVideoProxy', + OGVDecoderVideoVP8: 'OGVDecoderVideoProxy' + }; + var workerMap = { + OGVDecoderAudioProxy: 'ogv-worker-audio.js', + OGVDecoderVideoProxy: 'ogv-worker-video.js' + }; + + function urlForClass(className) { + var scriptName = scriptMap[className]; + if (scriptName) { + return urlForScript(scriptName); + } else { + throw new Error('asked for URL for unknown class ' + className); + } + }; + + function urlForScript(scriptName) { + if (scriptName) { + var base = OGVLoader.base; + if (base) { + base += '/'; + } + return base + scriptName + '?version=' + encodeURIComponent(OGVVersion); + } else { + throw new Error('asked for URL for unknown script ' + scriptName); + } + }; + + var scriptStatus = {}, + scriptCallbacks = {}; + function loadWebScript(src, callback) { + if (scriptStatus[src] == 'done') { + callback(); + } else if (scriptStatus[src] == 'loading') { + scriptCallbacks[src].push(callback); + } else { + scriptStatus[src] = 'loading'; + scriptCallbacks[src] = [callback]; + + var scriptNode = document.createElement('script'); + function done(event) { + var callbacks = scriptCallbacks[src]; + delete scriptCallbacks[src]; + scriptStatus[src] = 'done'; + + callbacks.forEach(function(cb) { + cb(); + }); + } + scriptNode.addEventListener('load', done); + scriptNode.addEventListener('error', done); + scriptNode.src = src; + document.querySelector('head').appendChild(scriptNode); + } + } + + function defaultBase() { + if (typeof global.window === 'object') { + + // for browser, try to autodetect + var scriptNodes = document.querySelectorAll('script'), + regex = /^(?:(.*)\/)ogv(?:-support)?\.js(?:\?|#|$)/, + path; + for (var i = 0; i < scriptNodes.length; i++) { + path = scriptNodes[i].getAttribute('src'); + if (path) { + matches = path.match(regex); + if (matches) { + return matches[1]; + } + } + } + + } else { + + // for workers, assume current directory + // if not a worker, too bad. + return ''; + + } + } + + OGVLoader = { + base: defaultBase(), + + loadClass: function(className, callback, options) { + options = options || {}; + if (options.worker) { + this.workerProxy(className, callback); + } else if (typeof global[className] === 'function') { + // already loaded! + callback(global[className]); + } else if (typeof global.window === 'object') { + loadWebScript(urlForClass(className), function() { + callback(global[className]); + }); + } else if (typeof global.importScripts === 'function') { + // worker has convenient sync importScripts + global.importScripts(urlForClass(className)); + callback(global[className]); + } + }, + + workerProxy: function(className, callback) { + var proxyClass = proxyMap[className], + workerScript = workerMap[proxyClass]; + + if (!proxyClass) { + throw new Error('Requested worker for class with no proxy: ' + className); + } + if (!workerScript) { + throw new Error('Requested worker for class with no worker: ' + className); + } + + this.loadClass(proxyClass, function(classObj) { + var construct = function(options) { + var worker = new Worker(urlForScript(workerScript)); + return new classObj(worker, className, options); + }; + callback(construct); + }); + } + }; +})(); +/** + * Web Worker wrapper for codec fun + */ +function OGVWorkerSupport(propList, handlers) { + + var transferables = (function() { + var buffer = new ArrayBuffer(1024), + bytes = new Uint8Array(buffer); + try { + postMessage({ + action: 'transferTest', + bytes: bytes + }, [buffer]); + if (buffer.byteLength) { + // No transferable support + return false; + } else { + return true; + } + } catch (e) { + return false; + } + })(); + + var self = this; + self.target = null; + + var sentProps = {}; + + function copyObject(obj) { + var copy = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + copy[prop] = obj[prop]; + } + } + return copy; + } + + function copyAudioBuffer(data) { + if (data == null) { + return null; + } else { + // Array of Float32Arrays + var copy = []; + for (var i = 0; i < data.length; i++) { + copy[i] = new Float32Array(data[i]); + } + return copy; + } + } + + function copyByteArray(bytes) { + var heap = bytes.buffer; + if (typeof heap.slice === 'function') { + var extract = heap.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength); + return new Uint8Array(extract); + } else { + // Hella slow in IE 10/11! + // But only game in town on IE 10. + return new Uint8Array(bytes); + } + } + + function copyFrameBuffer(buffer) { + if (buffer == null) { + return null; + } else { + var copy = copyObject(buffer); + copy.bytesY = copyByteArray(buffer.bytesY); + copy.bytesCb = copyByteArray(buffer.bytesCb); + copy.bytesCr = copyByteArray(buffer.bytesCr); + return copy; + } + } + + handlers.construct = function(args, callback) { + var className = args[0], + options = args[1]; + + OGVLoader.loadClass(className, function(classObj) { + self.target = new classObj(options); + callback(); + }); + }; + + addEventListener('message', function workerOnMessage(event) { + var data = event.data; + + if (data && data.action == 'transferTest') { + // ignore + return; + } + + if (typeof data !== 'object' || typeof data.action !== 'string' || typeof data.callbackId !== 'string' || typeof data.args !== 'object') { + console.log('invalid message data', data); + } else if (!(data.action in handlers)) { + console.log('invalid message action', data.action); + } else { + handlers[data.action].call(self, data.args, function(args) { + args = args || []; + + // Collect and send any changed properties... + var props = {}, + transfers = []; + propList.forEach(function(propName) { + var propVal = self.target[propName]; + + if (sentProps[propName] !== propVal) { + // Save this value for later reference... + sentProps[propName] = propVal; + + if (propName == 'duration' && isNaN(propVal) && isNaN(sentProps[propName])) { + // NaN is not === itself. Nice! + // no need to update it here. + } else if (propName == 'audioBuffer') { + // Don't send the entire emscripten heap! + propVal = copyAudioBuffer(propVal); + props[propName] = propVal; + if (propVal) { + for (i = 0; i < propVal.length; i++) { + transfers.push(propVal[i].buffer); + } + } + } else if (propName == 'frameBuffer') { + // Don't send the entire emscripten heap! + propVal = copyFrameBuffer(propVal); + props[propName] = propVal; + if (propVal) { + transfers.push(propVal.bytesY.buffer); + transfers.push(propVal.bytesCb.buffer); + transfers.push(propVal.bytesCr.buffer); + } + } else { + props[propName] = propVal; + } + } + }); + + var out = { + action: 'callback', + callbackId: data.callbackId, + args: args, + props: props + }; + if (transferables) { + postMessage(out, transfers); + } else { + postMessage(out); + } + }); + } + }); + +} +proxy = new OGVWorkerSupport([ + 'loadedMetadata', + 'audioFormat', + 'audioBuffer' +], { + init: function(args, callback) { + this.target.init(callback); + }, + + processHeader: function(args, callback) { + this.target.processHeader(args[0], function(ok) { + callback([ok]); + }); + }, + + processAudio: function(args, callback) { + this.target.processAudio(args[0], function(ok) { + callback([ok]); + }); + } +}); +this.OGVVersion = "1.0-20150904182230-dd3c8e8"; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js new file mode 100644 index 00000000..3afd769b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-worker-video.js @@ -0,0 +1,317 @@ +(function() { + var global = this; + + var scriptMap = { + OGVDemuxerOgg: 'ogv-demuxer-ogg.js', + OGVDemuxerWebM: 'ogv-demuxer-webm.js', + OGVDecoderAudioOpus: 'ogv-decoder-audio-opus.js', + OGVDecoderAudioVorbis: 'ogv-decoder-audio-vorbis.js', + OGVDecoderVideoTheora: 'ogv-decoder-video-theora.js', + OGVDecoderVideoVP8: 'ogv-decoder-video-vp8.js' + }; + + var proxyMap = { + OGVDecoderAudioOpus: 'OGVDecoderAudioProxy', + OGVDecoderAudioVorbis: 'OGVDecoderAudioProxy', + OGVDecoderVideoTheora: 'OGVDecoderVideoProxy', + OGVDecoderVideoVP8: 'OGVDecoderVideoProxy' + }; + var workerMap = { + OGVDecoderAudioProxy: 'ogv-worker-audio.js', + OGVDecoderVideoProxy: 'ogv-worker-video.js' + }; + + function urlForClass(className) { + var scriptName = scriptMap[className]; + if (scriptName) { + return urlForScript(scriptName); + } else { + throw new Error('asked for URL for unknown class ' + className); + } + }; + + function urlForScript(scriptName) { + if (scriptName) { + var base = OGVLoader.base; + if (base) { + base += '/'; + } + return base + scriptName + '?version=' + encodeURIComponent(OGVVersion); + } else { + throw new Error('asked for URL for unknown script ' + scriptName); + } + }; + + var scriptStatus = {}, + scriptCallbacks = {}; + function loadWebScript(src, callback) { + if (scriptStatus[src] == 'done') { + callback(); + } else if (scriptStatus[src] == 'loading') { + scriptCallbacks[src].push(callback); + } else { + scriptStatus[src] = 'loading'; + scriptCallbacks[src] = [callback]; + + var scriptNode = document.createElement('script'); + function done(event) { + var callbacks = scriptCallbacks[src]; + delete scriptCallbacks[src]; + scriptStatus[src] = 'done'; + + callbacks.forEach(function(cb) { + cb(); + }); + } + scriptNode.addEventListener('load', done); + scriptNode.addEventListener('error', done); + scriptNode.src = src; + document.querySelector('head').appendChild(scriptNode); + } + } + + function defaultBase() { + if (typeof global.window === 'object') { + + // for browser, try to autodetect + var scriptNodes = document.querySelectorAll('script'), + regex = /^(?:(.*)\/)ogv(?:-support)?\.js(?:\?|#|$)/, + path; + for (var i = 0; i < scriptNodes.length; i++) { + path = scriptNodes[i].getAttribute('src'); + if (path) { + matches = path.match(regex); + if (matches) { + return matches[1]; + } + } + } + + } else { + + // for workers, assume current directory + // if not a worker, too bad. + return ''; + + } + } + + OGVLoader = { + base: defaultBase(), + + loadClass: function(className, callback, options) { + options = options || {}; + if (options.worker) { + this.workerProxy(className, callback); + } else if (typeof global[className] === 'function') { + // already loaded! + callback(global[className]); + } else if (typeof global.window === 'object') { + loadWebScript(urlForClass(className), function() { + callback(global[className]); + }); + } else if (typeof global.importScripts === 'function') { + // worker has convenient sync importScripts + global.importScripts(urlForClass(className)); + callback(global[className]); + } + }, + + workerProxy: function(className, callback) { + var proxyClass = proxyMap[className], + workerScript = workerMap[proxyClass]; + + if (!proxyClass) { + throw new Error('Requested worker for class with no proxy: ' + className); + } + if (!workerScript) { + throw new Error('Requested worker for class with no worker: ' + className); + } + + this.loadClass(proxyClass, function(classObj) { + var construct = function(options) { + var worker = new Worker(urlForScript(workerScript)); + return new classObj(worker, className, options); + }; + callback(construct); + }); + } + }; +})(); +/** + * Web Worker wrapper for codec fun + */ +function OGVWorkerSupport(propList, handlers) { + + var transferables = (function() { + var buffer = new ArrayBuffer(1024), + bytes = new Uint8Array(buffer); + try { + postMessage({ + action: 'transferTest', + bytes: bytes + }, [buffer]); + if (buffer.byteLength) { + // No transferable support + return false; + } else { + return true; + } + } catch (e) { + return false; + } + })(); + + var self = this; + self.target = null; + + var sentProps = {}; + + function copyObject(obj) { + var copy = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + copy[prop] = obj[prop]; + } + } + return copy; + } + + function copyAudioBuffer(data) { + if (data == null) { + return null; + } else { + // Array of Float32Arrays + var copy = []; + for (var i = 0; i < data.length; i++) { + copy[i] = new Float32Array(data[i]); + } + return copy; + } + } + + function copyByteArray(bytes) { + var heap = bytes.buffer; + if (typeof heap.slice === 'function') { + var extract = heap.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength); + return new Uint8Array(extract); + } else { + // Hella slow in IE 10/11! + // But only game in town on IE 10. + return new Uint8Array(bytes); + } + } + + function copyFrameBuffer(buffer) { + if (buffer == null) { + return null; + } else { + var copy = copyObject(buffer); + copy.bytesY = copyByteArray(buffer.bytesY); + copy.bytesCb = copyByteArray(buffer.bytesCb); + copy.bytesCr = copyByteArray(buffer.bytesCr); + return copy; + } + } + + handlers.construct = function(args, callback) { + var className = args[0], + options = args[1]; + + OGVLoader.loadClass(className, function(classObj) { + self.target = new classObj(options); + callback(); + }); + }; + + addEventListener('message', function workerOnMessage(event) { + var data = event.data; + + if (data && data.action == 'transferTest') { + // ignore + return; + } + + if (typeof data !== 'object' || typeof data.action !== 'string' || typeof data.callbackId !== 'string' || typeof data.args !== 'object') { + console.log('invalid message data', data); + } else if (!(data.action in handlers)) { + console.log('invalid message action', data.action); + } else { + handlers[data.action].call(self, data.args, function(args) { + args = args || []; + + // Collect and send any changed properties... + var props = {}, + transfers = []; + propList.forEach(function(propName) { + var propVal = self.target[propName]; + + if (sentProps[propName] !== propVal) { + // Save this value for later reference... + sentProps[propName] = propVal; + + if (propName == 'duration' && isNaN(propVal) && isNaN(sentProps[propName])) { + // NaN is not === itself. Nice! + // no need to update it here. + } else if (propName == 'audioBuffer') { + // Don't send the entire emscripten heap! + propVal = copyAudioBuffer(propVal); + props[propName] = propVal; + if (propVal) { + for (i = 0; i < propVal.length; i++) { + transfers.push(propVal[i].buffer); + } + } + } else if (propName == 'frameBuffer') { + // Don't send the entire emscripten heap! + propVal = copyFrameBuffer(propVal); + props[propName] = propVal; + if (propVal) { + transfers.push(propVal.bytesY.buffer); + transfers.push(propVal.bytesCb.buffer); + transfers.push(propVal.bytesCr.buffer); + } + } else { + props[propName] = propVal; + } + } + }); + + var out = { + action: 'callback', + callbackId: data.callbackId, + args: args, + props: props + }; + if (transferables) { + postMessage(out, transfers); + } else { + postMessage(out); + } + }); + } + }); + +} +proxy = new OGVWorkerSupport([ + 'loadedMetadata', + 'videoFormat', + 'frameBuffer' +], { + init: function(args, callback) { + this.target.init(callback); + }, + + processHeader: function(args, callback) { + this.target.processHeader(args[0], function(ok) { + callback([ok]); + }); + }, + + processFrame: function(args, callback) { + this.target.processFrame(args[0], function(ok) { + callback([ok]); + }); + } +}); +this.OGVVersion = "1.0-20150904182230-dd3c8e8"; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv.js new file mode 100644 index 00000000..a29b4b3b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv.js @@ -0,0 +1,3966 @@ +// +// -- ogv.js +// https://github.com/brion/ogv.js +// Copyright (c) 2013-2015 Brion Vibber +// + +(function() { + +// -- OGVLoader.js + +(function() { + var global = this; + + var scriptMap = { + OGVDemuxerOgg: 'ogv-demuxer-ogg.js', + OGVDemuxerWebM: 'ogv-demuxer-webm.js', + OGVDecoderAudioOpus: 'ogv-decoder-audio-opus.js', + OGVDecoderAudioVorbis: 'ogv-decoder-audio-vorbis.js', + OGVDecoderVideoTheora: 'ogv-decoder-video-theora.js', + OGVDecoderVideoVP8: 'ogv-decoder-video-vp8.js' + }; + + var proxyMap = { + OGVDecoderAudioOpus: 'OGVDecoderAudioProxy', + OGVDecoderAudioVorbis: 'OGVDecoderAudioProxy', + OGVDecoderVideoTheora: 'OGVDecoderVideoProxy', + OGVDecoderVideoVP8: 'OGVDecoderVideoProxy' + }; + var workerMap = { + OGVDecoderAudioProxy: 'ogv-worker-audio.js', + OGVDecoderVideoProxy: 'ogv-worker-video.js' + }; + + function urlForClass(className) { + var scriptName = scriptMap[className]; + if (scriptName) { + return urlForScript(scriptName); + } else { + throw new Error('asked for URL for unknown class ' + className); + } + }; + + function urlForScript(scriptName) { + if (scriptName) { + var base = OGVLoader.base; + if (base) { + base += '/'; + } + return base + scriptName + '?version=' + encodeURIComponent(OGVVersion); + } else { + throw new Error('asked for URL for unknown script ' + scriptName); + } + }; + + var scriptStatus = {}, + scriptCallbacks = {}; + function loadWebScript(src, callback) { + if (scriptStatus[src] == 'done') { + callback(); + } else if (scriptStatus[src] == 'loading') { + scriptCallbacks[src].push(callback); + } else { + scriptStatus[src] = 'loading'; + scriptCallbacks[src] = [callback]; + + var scriptNode = document.createElement('script'); + function done(event) { + var callbacks = scriptCallbacks[src]; + delete scriptCallbacks[src]; + scriptStatus[src] = 'done'; + + callbacks.forEach(function(cb) { + cb(); + }); + } + scriptNode.addEventListener('load', done); + scriptNode.addEventListener('error', done); + scriptNode.src = src; + document.querySelector('head').appendChild(scriptNode); + } + } + + function defaultBase() { + if (typeof global.window === 'object') { + + // for browser, try to autodetect + var scriptNodes = document.querySelectorAll('script'), + regex = /^(?:(.*)\/)ogv(?:-support)?\.js(?:\?|#|$)/, + path; + for (var i = 0; i < scriptNodes.length; i++) { + path = scriptNodes[i].getAttribute('src'); + if (path) { + matches = path.match(regex); + if (matches) { + return matches[1]; + } + } + } + + } else { + + // for workers, assume current directory + // if not a worker, too bad. + return ''; + + } + } + + OGVLoader = { + base: defaultBase(), + + loadClass: function(className, callback, options) { + options = options || {}; + if (options.worker) { + this.workerProxy(className, callback); + } else if (typeof global[className] === 'function') { + // already loaded! + callback(global[className]); + } else if (typeof global.window === 'object') { + loadWebScript(urlForClass(className), function() { + callback(global[className]); + }); + } else if (typeof global.importScripts === 'function') { + // worker has convenient sync importScripts + global.importScripts(urlForClass(className)); + callback(global[className]); + } + }, + + workerProxy: function(className, callback) { + var proxyClass = proxyMap[className], + workerScript = workerMap[proxyClass]; + + if (!proxyClass) { + throw new Error('Requested worker for class with no proxy: ' + className); + } + if (!workerScript) { + throw new Error('Requested worker for class with no worker: ' + className); + } + + this.loadClass(proxyClass, function(classObj) { + var construct = function(options) { + var worker = new Worker(urlForScript(workerScript)); + return new classObj(worker, className, options); + }; + callback(construct); + }); + } + }; +})(); + + +// -- StreamFile.js + +/** + * Quickie wrapper around XHR to fetch a file as array buffer chunks. + * + * Call streamFile.readBytes() after an onread event's data has been + * processed to trigger the next read. + * + * IE 10: uses MSStream / MSStreamReader for true streaming + * Firefox: uses moz-chunked-arraybuffer to buffer & deliver during download + * Safari, Chrome: uses binary string to buffer & deliver during download + * + * @author Brion Vibber <brion@pobox.com> + * @copyright 2014 + * @license MIT-style + */ +function StreamFile(options) { + var self = this, + url = options.url, + started = false, + onstart = options.onstart || function(){}, + onbuffer = options.onbuffer || function(){}, + onread = options.onread || function(){}, + ondone = options.ondone || function(){}, + onerror = options.onerror || function(){}, + bufferSize = options.bufferSize || 8192, + minBufferSize = options.minBufferSize || 65536, + seekPosition = options.seekPosition || 0, + bufferPosition = seekPosition, + chunkSize = options.chunkSize || 1024 * 1024, // read/buffer up to a megabyte at a time + waitingForInput = false, + doneBuffering = false, + bytesTotal = 0, + bytesRead = 0, + buffers = [], + cachever = 0, + responseHeaders = {}; + + + + // -- internal private methods + var internal = { + /** + * @var {XMLHttpRequest} + */ + xhr: null, + + /** + * Test if a given responseType value is valid on an XHR + * + * @return boolean + */ + tryMethod: function(rt) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", url); + try { + // Set the response type and see if it explodes! + xhr.responseType = rt; + } catch (e) { + // Safari 6 throws a DOM Exception on invalid setting + return false; + } + // Other browsers just don't accept the setting, so check + // whether it made it through. + return (xhr.responseType == rt); + }, + + setBytesTotal: function(xhr) { + if (xhr.status == 206) { + bytesTotal = internal.getXHRRangeTotal(xhr); + } else { + var contentLength = xhr.getResponseHeader('Content-Length'); + if (contentLength === null || contentLength === '') { + // Unknown file length... maybe streaming live? + bytesTotal = 0; + } else { + bytesTotal = parseInt(contentLength, 10); + } + } + }, + + // Save HTTP response headers from the HEAD request for later + processResponseHeaders: function(xhr) { + responseHeaders = {}; + var allResponseHeaders = xhr.getAllResponseHeaders(), + headerLines = allResponseHeaders.split(/\n/); + headerLines.forEach(function(line) { + var bits = line.split(/:\s*/, 2); + if (bits.length > 1) { + var name = bits[0].toLowerCase(), + value = bits[1]; + responseHeaders[name] = value; + } + }); + }, + + openXHR: function() { + var getUrl = url; + if (cachever) { + // + // Safari sometimes messes up and gives us the wrong chunk. + // Seems to be a general problem with Safari and cached XHR ranges. + // + // Interestingly, it allows you to request _later_ ranges successfully, + // but when requesting _earlier_ ranges it returns the latest one retrieved. + // So we only need to update the cache-buster when we rewind. + // + // https://bugs.webkit.org/show_bug.cgi?id=82672 + // + getUrl += '?ogvjs_cachever=' + cachever; + } + + var xhr = internal.xhr = new XMLHttpRequest(); + xhr.open("GET", getUrl); + + internal.setXHROptions(xhr); + + var range = null; + if (seekPosition || chunkSize) { + range = 'bytes=' + seekPosition + '-'; + } + if (chunkSize) { + if (bytesTotal) { + range += Math.min(seekPosition + chunkSize, bytesTotal) - 1; + } else { + range += (seekPosition + chunkSize) - 1; + } + } + if (range !== null) { + xhr.setRequestHeader('Range', range); + } + + bytesRead = 0; + + xhr.onreadystatechange = function(event) { + if (xhr.readyState == 2) { + if (xhr.status == 206) { + var foundPosition = internal.getXHRRangeStart(xhr); + if (seekPosition != foundPosition) { + // + // Safari sometimes messes up and gives us the wrong chunk. + // Seems to be a general problem with Safari and cached XHR ranges. + // + // Interestingly, it allows you to request _later_ ranges successfully, + // but when requesting _earlier_ ranges it returns the latest one retrieved. + // So we only need to update the cache-buster when we rewind and actually + // get an incorrect range. + // + // https://bugs.webkit.org/show_bug.cgi?id=82672 + // + console.log('Expected start at ' + seekPosition + ' but got ' + foundPosition + + '; working around Safari range caching bug: https://bugs.webkit.org/show_bug.cgi?id=82672'); + cachever++; + internal.abortXHR(xhr); + internal.openXHR(); + return; + } + } + if (!started) { + internal.setBytesTotal(xhr); + internal.processResponseHeaders(xhr); + started = true; + onstart(); + } + //internal.onXHRHeadersReceived(xhr); + // @todo check that partial content was supported if relevant + } else if (xhr.readyState == 3) { + internal.onXHRLoading(xhr); + } else if (xhr.readyState == 4) { + // Complete. + internal.onXHRDone(xhr); + } + }; + + xhr.send(); + }, + + getXHRRangeMatches: function(xhr) { + // Note Content-Range must be whitelisted for CORS requests + var contentRange = xhr.getResponseHeader('Content-Range'); + return contentRange && contentRange.match(/^bytes (\d+)-(\d+)\/(\d+)/); + }, + + getXHRRangeStart: function(xhr) { + var matches = internal.getXHRRangeMatches(xhr); + if (matches) { + return parseInt(matches[1], 10); + } else { + return 0; + } + }, + + getXHRRangeTotal: function(xhr) { + var matches = internal.getXHRRangeMatches(xhr); + if (matches) { + return parseInt(matches[3], 10); + } else { + return 0; + } + }, + + setXHROptions: function(xhr) { + throw new Error('abstract function'); + }, + + /* + onXHRHeadersReceived: function(xhr) { + if (xhr.status >= 400) { + // errrorrrrrrr + console.log("HTTP " + xhr.status + ": " +xhr.statusText); + onerror(); + xhr.abort(); + } else { + internal.setBytesTotal(xhr); + internal.processResponseHeaders(xhr); + started = true; + onstart(); + } + }, + */ + + onXHRLoading: function(xhr) { + throw new Error('abstract function'); + }, + + onXHRDone: function(xhr) { + doneBuffering = true; + }, + + abortXHR: function(xhr) { + xhr.onreadystatechange = null; + xhr.abort(); + }, + + bufferData: function(buffer) { + if (buffer) { + buffers.push(buffer); + onbuffer(); + + internal.readNextChunk(); + } + }, + + bytesBuffered: function() { + var bytes = 0; + buffers.forEach(function(buffer) { + bytes += buffer.byteLength; + }); + return bytes; + }, + + dataToRead: function() { + return internal.bytesBuffered() > 0; + }, + + popBuffer: function() { + var bufferOut = new ArrayBuffer(bufferSize), + bytesOut = new Uint8Array(bufferOut), + byteLength = 0; + + function stuff(bufferIn) { + var bytesIn = new Uint8Array(bufferIn); + bytesOut.set(bytesIn, byteLength); + byteLength += bufferIn.byteLength; + } + + while (byteLength < minBufferSize) { + var needBytes = minBufferSize - byteLength, + nextBuffer = buffers.shift(); + if (!nextBuffer) { + break; + } + + if (needBytes >= nextBuffer.byteLength) { + // if it fits, it sits + stuff(nextBuffer); + } else { + // Split the buffer and requeue the rest + var croppedBuffer = nextBuffer.slice(0, needBytes), + remainderBuffer = nextBuffer.slice(needBytes); + buffers.unshift(remainderBuffer); + stuff(croppedBuffer); + break; + } + } + + bytesRead += byteLength; + bufferPosition += byteLength; + return bufferOut.slice(0, byteLength); + }, + + clearReadState: function() { + bytesRead = 0; + doneBuffering = false; + waitingForInput = true; + }, + + clearBuffers: function() { + internal.clearReadState(); + buffers.splice(0, buffers.length); + bufferPosition = seekPosition; + }, + + // Read the next binary buffer out of the buffered data + readNextChunk: function() { + if (waitingForInput) { + waitingForInput = false; + onread(internal.popBuffer()); + if (doneBuffering && !internal.dataToRead()) { + internal.onReadDone(); + } + } + }, + + onReadDone: function() { + ondone(); + }, + + // See if we can seek within already-buffered data + quickSeek: function(pos) { + return false; + } + + }; + + // -- Public methods + self.readBytes = function() { + if (internal.dataToRead()) { + var buffer = internal.popBuffer(); + onread(buffer); + if (doneBuffering && self.bytesBuffered < Math.min(bufferPosition + chunkSize, self.bytesTotal)) { + seekPosition += chunkSize; + internal.clearReadState(); + internal.openXHR(); + } + } else if (doneBuffering) { + // We're out of data! + internal.onReadDone(); + } else { + // Nothing queued... + waitingForInput = true; + } + }; + + self.abort = function() { + if (internal.xhr) { + internal.abortXHR(internal.xhr); + internal.xhr = null; + internal.clearBuffers(); + } + }; + + self.seek = function(bytePosition) { + if (internal.quickSeek(bytePosition)) { + //console.log('quick seek successful'); + } else { + self.abort(); + seekPosition = bytePosition; + internal.clearBuffers(); + internal.openXHR(); + } + }; + + self.getResponseHeader = function(headerName) { + var lowerName = headerName.toLowerCase(), + value = responseHeaders[lowerName]; + if (value === undefined) { + return null; + } else { + return value; + } + }; + + // -- public properties + Object.defineProperty(self, 'bytesTotal', { + get: function() { + return bytesTotal; + } + }); + + Object.defineProperty(self, 'bytesBuffered', { + get: function() { + return bufferPosition + internal.bytesBuffered(); + } + }); + + Object.defineProperty(self, 'bytesRead', { + get: function() { + return seekPosition + bytesRead; + } + }); + + Object.defineProperty(self, 'seekable', { + get: function() { + return (self.bytesTotal > 0); + } + }); + + // Handy way to call super functions + var orig = {}; + for (var prop in internal) { + orig[prop] = internal[prop]; + } + + // -- Backend selection and method overrides + if (internal.tryMethod('moz-chunked-arraybuffer')) { + internal.setXHROptions = function(xhr) { + xhr.responseType = 'moz-chunked-arraybuffer'; + + xhr.onprogress = function() { + // xhr.response is a per-chunk ArrayBuffer + internal.bufferData(xhr.response); + }; + }; + + internal.abortXHR = function(xhr) { + xhr.onprogress = null; + orig.abortXHR(xhr); + }; + + internal.onXHRLoading = function(xhr) { + // we have to get from the 'progress' event + }; + + } else if (internal.tryMethod('ms-stream')) { + // IE 10 supports returning a Stream from XHR. + + // Don't bother reading in chunks, MSStream handles it for us + chunkSize = 0; + + var stream, streamReader; + var restarted = false; + + internal.setXHROptions = function(xhr) { + xhr.responseType = 'ms-stream'; + }; + + internal.abortXHR = function(xhr) { + restarted = true; + if (streamReader) { + streamReader.abort(); + streamReader = null; + } + if (stream) { + stream.msClose(); + stream = null; + } + orig.abortXHR(xhr); + }; + + internal.onXHRLoading = function(xhr) { + // Transfer us over to the StreamReader... + stream = xhr.response; + xhr.onreadystatechange = null; + if (waitingForInput) { + waitingForInput = false; + self.readBytes(); + } + }; + + internal.bytesBuffered = function() { + // We don't know how much ahead is buffered, it's opaque. + // Just return what we've read. + return 0; + }; + + self.readBytes = function() { + if (stream) { + streamReader = new MSStreamReader(); + streamReader.onload = function(event) { + var buffer = event.target.result, + len = buffer.byteLength; + if (len > 0) { + bytesRead += len; + bufferPosition += len; + onread(buffer); + } else { + // Zero length means end of stream. + ondone(); + } + }; + streamReader.onerror = function(event) { + onerror('mystery error streaming'); + }; + streamReader.readAsArrayBuffer(stream, bufferSize); + } else { + waitingForInput = true; + } + }; + + } else if ((new XMLHttpRequest()).overrideMimeType !== undefined) { + + // Use old binary string method since we can read reponseText + // progressively and extract ArrayBuffers from that. + + internal.setXHROptions = function(xhr) { + xhr.responseType = "text"; + xhr.overrideMimeType('text/plain; charset=x-user-defined'); + }; + + var lastPosition = 0; + + // Is there a better way to do this conversion? :( + var stringToArrayBuffer = function(chunk) { + var len = chunk.length, + buffer = new ArrayBuffer(len), + bytes = new Uint8Array(buffer); + for (var i = 0; i < len; i++) { + bytes[i] = chunk.charCodeAt(i); + } + return buffer; + }; + + internal.clearReadState = function() { + orig.clearReadState(); + lastPosition = 0; + }; + + internal.onXHRLoading = function(xhr) { + // xhr.responseText is a binary string of entire file so far + var str = xhr.responseText; + if (lastPosition < str.length) { + var chunk = str.slice(lastPosition), + buffer = stringToArrayBuffer(chunk); + lastPosition = str.length; + internal.bufferData(buffer); + } + }; + + /* + internal.quickSeek = function(pos) { + var bufferedPos = pos - seekPosition; + if (bufferedPos < 0) { + return false; + } else if (bufferedPos >= internal.xhr.responseText.length) { + return false; + } else { + lastPosition = bufferedPos; + bytesRead = lastPosition; + setTimeout(function() { + onbuffer() + }, 0); + return true; + } + }; + */ + } else { + throw new Error("No streaming HTTP input method found."); + } + + internal.openXHR(); +} + + +// -- AudioFeeder.js + +var AudioFeeder; + +(function() { + var global = this, + AudioContext = global.AudioContext || global.webkitAudioContext; + + /** + * Object that we can throw audio data into and have it drain out. + * + * Because changing the number of channels on the fly is hard, hardcoding + * to 2 output channels. That's also all we can do on IE with Flash output. + * + * @param options: dictionary of config settings: + * 'base' - Base URL to find additional resources in, + * such as the Flash audio output shim + */ + AudioFeeder = function(options) { + var self = this; + options = options || {}; + + // Look for W3C Audio API + if (!AudioContext) { + // use Flash fallback + var flashOptions = {}; + if (typeof options.base === 'string') { + flashOptions.swf = options.base + '/dynamicaudio.swf?version=' + OGVVersion; + } + this.flashaudio = new DynamicAudio( flashOptions ); + } + + var bufferSize = this.bufferSize = 4096, + channels = 0, // call init()! + rate = 0; // call init()! + + // Always create stereo output. For iOS we have to set this stuff up + // before we've actually gotten the info from the codec because we + // must initialize from a UI event. Bah! + var outputChannels = 2; + + function freshBuffer() { + var buffer = []; + for (var channel = 0; channel < outputChannels; channel++) { + buffer[channel] = new Float32Array(bufferSize); + } + return buffer; + } + + var buffers = [], + context, + node, + pendingBuffer = freshBuffer(), + pendingPos = 0, + muted = false, + queuedTime = 0, + playbackTimeAtBufferTail = -1, + targetRate, + dropped = 0, + delayedTime = 0; + + if(AudioContext) { + if (typeof options.audioContext !== 'undefined') { + // We were passed a pre-existing AudioContext object, + // in the hopes this gets around iOS's weird activation rules. + context = options.audioContext; + } else { + AudioFeeder.initSharedAudioContext(); + context = AudioFeeder.sharedAudioContext; + } + playbackTimeAtBufferTail = context.currentTime; + + if (context.createScriptProcessor) { + node = context.createScriptProcessor(bufferSize, 0, outputChannels); + } else if (context.createJavaScriptNode) { + node = context.createJavaScriptNode(bufferSize, 0, outputChannels); + } else { + throw new Error("Bad version of web audio API?"); + } + targetRate = this.targetRate = context.sampleRate; + } else { + targetRate = this.targetRate = 44100; // flash fallback + } + + function popNextBuffer() { + // hack hack + // fixme: grab the right number of samples + // and... rescale + if (buffers.length > 0) { + return buffers.shift(); + } + } + + function audioProcess(event) { + var channel, input, output, i, playbackTime; + if (typeof event.playbackTime === 'number') { + playbackTime = event.playbackTime; + } else { + // Safari 6.1 hack + playbackTime = context.currentTime + (bufferSize / targetRate); + } + + var expectedTime = playbackTimeAtBufferTail; + if (expectedTime < playbackTime) { + // we may have lost some time while something ran too slow + delayedTime += (playbackTime - expectedTime); + } + + var inputBuffer = popNextBuffer(bufferSize); + if (!inputBuffer) { + // We might be in a throttled background tab; go ping the decoder + // and let it know we need more data now! + if (self.onstarved) { + self.onstarved(); + inputBuffer = popNextBuffer(bufferSize); + } + } + + // If we haven't got enough data, write a buffer of of silence to + // both channels + if (!inputBuffer) { + for (channel = 0; channel < outputChannels; channel++) { + output = event.outputBuffer.getChannelData(channel); + for (i = 0; i < bufferSize; i++) { + output[i] = 0; + } + } + dropped++; + return; + } + + var volume = (muted ? 0 : 1); + for (channel = 0; channel < outputChannels; channel++) { + input = inputBuffer[channel]; + output = event.outputBuffer.getChannelData(channel); + for (i = 0; i < Math.min(bufferSize, input.length); i++) { + output[i] = input[i] * volume; + } + } + queuedTime += (bufferSize / context.sampleRate); + playbackTimeAtBufferTail = playbackTime + (bufferSize / context.sampleRate); + } + + /** + * This is horribly naive and wrong. + * Replace me with a better algo! + */ + function resample(samples) { + if (rate == targetRate && channels == outputChannels) { + return samples; + } else { + var newSamples = []; + for (var channel = 0; channel < outputChannels; channel++) { + var inputChannel = channel; + if (channel >= channels) { + inputChannel = 0; + } + var input = samples[inputChannel], + output = new Float32Array(Math.round(input.length * targetRate / rate)); + for (var i = 0; i < output.length; i++) { + output[i] = input[(i * rate / targetRate) | 0]; + } + newSamples.push(output); + } + return newSamples; + } + } + + /** + * Resampling, scaling and reordering for the Flash fallback. + * The Flash fallback expects 44.1 kHz, stereo + * Resampling: This is horribly naive and wrong. + * TODO: Replace me with a better algo! + */ + function resampleFlash(samples) { + var sampleincr = rate / 44100; + var samplecount = (samples[0].length * (44100 / rate)) | 0; + var newSamples = new Int16Array(samplecount * 2); + var chanLeft = samples[0]; + var chanRight = channels > 1 ? samples[1] : chanLeft; + var multiplier = 16384; // smaller than 32768 to allow some headroom from those floats + for(var s = 0; s < samplecount; s++) { + var idx = (s * sampleincr) | 0; + var idx_out = s * 2; + // Use a smaller + newSamples[idx_out] = chanLeft[idx] * multiplier; + newSamples[idx_out + 1] = chanRight[idx] * multiplier; + } + return newSamples; + } + + function resampleFlashMuted(samples) { + // if muted: generate fitting number of samples for audio clock + var samplecount = (samples[0].length * (44100 / rate)) | 0; + return new Int16Array(samplecount * 2); + } + + + function pushSamples(samples) { + var firstChannel = samples[0], + sampleCount = firstChannel.length; + for (var i = 0; i < sampleCount; i++) { + for (var channel = 0; channel < outputChannels; channel++) { + pendingBuffer[channel][pendingPos] = samples[channel][i]; + } + if (++pendingPos == bufferSize) { + buffers.push(pendingBuffer); + pendingPos = 0; + pendingBuffer = freshBuffer(); + } + } + } + + this.init = function(numChannels, sampleRate) { + // warning: can't change channels here reliably + rate = sampleRate; + channels = numChannels; + pendingBuffer = freshBuffer(); + }; + + var hexDigits = ['0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; + var hexBytes = []; + for (var i = 0; i < 256; i++) { + hexBytes[i] = hexDigits[(i & 0x0f)] + + hexDigits[(i & 0xf0) >> 4]; + } + function hexString(buffer) { + var samples = new Uint8Array(buffer); + var digits = "", + len = samples.length; + for (var i = 0; i < len; i++) { + // Note that in IE 11 strong concatenation is twice as fast as + // the traditional make-an-array-and-join here. + digits += hexBytes[samples[i]]; + } + return digits; + } + + var flashBuffer = '', + flushTimeout = null; + function flushFlashBuffer() { + var chunk = flashBuffer; + if (self.flashaudio.flashElement.write) { + self.flashaudio.flashElement.write(chunk); + } else { + self.waitUntilReady(function() { + self.flashaudio.flashElement.write(chunk); + }); + } + flashBuffer = ''; + flushTimeout = null; + } + this.bufferData = function(samplesPerChannel) { + if(this.flashaudio) { + var resamples = !muted ? resampleFlash(samplesPerChannel) : resampleFlashMuted(samplesPerChannel); + var flashElement = this.flashaudio.flashElement; + if(resamples.length > 0) { + var str = hexString(resamples.buffer); + flashBuffer += str; + if (!flushTimeout) { + // consolidate multiple consecutive tiny buffers in one pass; + // pushing data to Flash is relatively expensive on slow machines + flushTimeout = setTimeout(flushFlashBuffer, 0); + } + } + } else if (buffers) { + var samples = resample(samplesPerChannel); + pushSamples(samples); + } else { + console.log('no valid whatsit'); + self.close(); + } + }; + + function samplesQueued() { + if (buffers) { + var numSamplesQueued = 0; + buffers.forEach(function(buffer) { + numSamplesQueued += buffer[0].length; + }); + + var bufferedSamples = numSamplesQueued; + var remainingSamples = Math.floor(Math.max(0, (playbackTimeAtBufferTail - context.currentTime)) * context.sampleRate); + + return bufferedSamples + remainingSamples; + } else { + return 0; + } + } + + var cachedFlashState = null, + cachedFlashTime = 0, + cachedFlashInterval = 40; // resync state no more often than every X ms + + /** + * @return { + * playbackPosition: {number} seconds, with a system-provided base time + * samplesQueued: {int} + * dropped: {int} + * } + */ + this.getPlaybackState = function() { + if (this.flashaudio) { + var flashElement = this.flashaudio.flashElement; + if (flashElement.write) { + var now = Date.now(), + delta = now - cachedFlashTime, + state; + if (cachedFlashState && delta < cachedFlashInterval) { + state = { + playbackPosition: cachedFlashState.playbackPosition + delta / 1000, + samplesQueued: cachedFlashState.samplesQueued - delta * targetRate / 1000, + dropped: cachedFlashState.dropped, + delayed: cachedFlashState.delayed + }; + } else { + state = flashElement.getPlaybackState(); + cachedFlashState = state; + cachedFlashTime = now; + } + state.samplesQueued += flashBuffer.length / 2; + return state; + } else { + //console.log('getPlaybackState USED TOO EARLY'); + return { + playbackPosition: 0, + samplesQueued: 0, + dropped: 0, + delayed: 0 + }; + } + } else { + return { + playbackPosition: queuedTime - Math.max(0, playbackTimeAtBufferTail - context.currentTime), + samplesQueued: samplesQueued(), + dropped: dropped, + delayed: delayedTime + }; + } + }; + + this.mute = function() { + this.muted = muted = true; + }; + + this.unmute = function() { + this.muted = muted = false; + }; + + this.close = function() { + this.stop(); + + if(this.flashaudio) { + var wrapper = this.flashaudio.flashWrapper; + wrapper.parentNode.removeChild(wrapper); + this.flashaudio = null; + } + + context = null; + buffers = null; + }; + + this.waitUntilReady = function(callback) { + var times = 0, + maxTimes = 100; + function pingFlashPlugin() { + setTimeout(function doPingFlashPlugin() { + times++; + if (self.flashaudio && self.flashaudio.flashElement.write) { + callback(this); + } else if (times > maxTimes) { + console.log("Failed to initialize Flash audio shim"); + self.close(); + callback(null); + } else { + pingFlashPlugin(); + } + }, 20); + } + if (self.flashaudio) { + pingFlashPlugin(); + } else { + setTimeout(callback, 0); + } + }; + + this.start = function() { + if (this.flashaudio) { + this.flashaudio.flashElement.start(); + } else { + node.onaudioprocess = audioProcess; + node.connect(context.destination); + playbackTimeAtBufferTail = context.currentTime; + } + }; + + this.stop = function() { + if (this.flashaudio) { + this.flashaudio.flashElement.stop(); + } else { + if (node) { + node.onaudioprocess = null; + node.disconnect(); + } + } + }; + + /** + * A callback when we find we're out of buffered data. + */ + this.onstarved = null; + }; + + AudioFeeder.sharedAudioContext = null; + AudioFeeder.initSharedAudioContext = function() { + if (AudioFeeder.sharedAudioContext === null) { + if ( AudioContext ) { + // We're only allowed 4 contexts on many browsers + // and there's no way to discard them (!)... + var context = AudioFeeder.sharedAudioContext = new AudioContext(), + node; + if ( context.createScriptProcessor ) { + node = context.createScriptProcessor( 1024, 0, 2 ); + } else if ( context.createJavaScriptNode ) { + node = context.createJavaScriptNode( 1024, 0, 2 ); + } else { + throw new Error( "Bad version of web audio API?" ); + } + + // Don't actually run any audio, just start & stop the node + node.connect( context.destination ); + node.disconnect(); + } + } + }; + + + /** Flash fallback **/ + + /* + The Flash fallback is based on https://github.com/an146/dynamicaudio.js + + This is the contents of the LICENSE file: + + Copyright (c) 2010, Ben Firshman + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The names of its contributors may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + + function DynamicAudio(args) { + if (this instanceof arguments.callee) { + if (typeof this.init === "function") { + this.init.apply(this, (args && args.callee) ? args : arguments); + } + } else { + return new arguments.callee(arguments); + } + } + + + DynamicAudio.nextId = 1; + + DynamicAudio.prototype = { + nextId: null, + swf: 'dynamicaudio.swf?' + Math.random(), + + flashWrapper: null, + flashElement: null, + + init: function(opts) { + var self = this; + self.id = DynamicAudio.nextId++; + + if (opts && typeof opts.swf !== 'undefined') { + self.swf = opts.swf; + } + + + self.flashWrapper = document.createElement('div'); + self.flashWrapper.id = 'dynamicaudio-flashwrapper-'+self.id; + // Credit to SoundManager2 for this: + var s = self.flashWrapper.style; + s.position = 'fixed'; + s.width = '11px'; // must be at least 6px for flash to run fast + s.height = '11px'; + s.bottom = s.left = '0px'; + s.overflow = 'hidden'; + self.flashElement = document.createElement('div'); + self.flashElement.id = 'dynamicaudio-flashelement-'+self.id; + self.flashWrapper.appendChild(self.flashElement); + + document.body.appendChild(self.flashWrapper); + + var id = self.flashElement.id; + + self.flashWrapper.innerHTML = "<object id='"+id+"' width='10' height='10' type='application/x-shockwave-flash' data='"+self.swf+"' style='visibility: visible;'><param name='allowscriptaccess' value='always'></object>"; + self.flashElement = document.getElementById(id); + }, + }; + +})(); + + +// -- FrameSink.js + +/** + * @param HTMLCanvasElement canvas + * @constructor + */ +function FrameSink(canvas, videoInfo) { + var self = this, + ctx = canvas.getContext('2d'), + imageData = null, + resampleCanvas = null, + resampleContext = null; + + +/** + * Basic YCbCr->RGB conversion + * + * @author Brion Vibber <brion@pobox.com> + * @copyright 2014 + * @license MIT-style + * + * @param ybcbr {bytesY, bytesCb, bytesCr, strideY, strideCb, strideCr, width, height, hdec, vdec} + * @param TypedArray output: CanvasPixelArray or Uint8ClampedArray to draw RGBA into + * Assumes that the output array already has alpha channel set to opaque. + */ +function convertYCbCr(ybcbr, output) { + var width = ybcbr.width, + height = ybcbr.height, + hdec = ybcbr.hdec, + vdec = ybcbr.vdec, + bytesY = ybcbr.bytesY, + bytesCb = ybcbr.bytesCb, + bytesCr = ybcbr.bytesCr, + strideY = ybcbr.strideY, + strideCb = ybcbr.strideCb, + strideCr = ybcbr.strideCr, + outStride = 4 * width, + YPtr = 0, Y0Ptr = 0, Y1Ptr = 0, + CbPtr = 0, CrPtr = 0, + outPtr = 0, outPtr0 = 0, outPtr1 = 0, + colorCb = 0, colorCr = 0, + multY = 0, multCrR = 0, multCbCrG = 0, multCbB = 0, + x = 0, y = 0, xdec = 0, ydec = 0; + + if (hdec == 1 && vdec == 1) { + // Optimize for 4:2:0, which is most common + outPtr0 = 0; + outPtr1 = outStride; + ydec = 0; + for (y = 0; y < height; y += 2) { + Y0Ptr = y * strideY; + Y1Ptr = Y0Ptr + strideY; + CbPtr = ydec * strideCb; + CrPtr = ydec * strideCr; + for (x = 0; x < width; x += 2) { + colorCb = bytesCb[CbPtr++]; + colorCr = bytesCr[CrPtr++]; + + // Quickie YUV conversion + // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion + // multiplied by 256 for integer-friendliness + multCrR = (409 * colorCr) - 57088; + multCbCrG = (100 * colorCb) + (208 * colorCr) - 34816; + multCbB = (516 * colorCb) - 70912; + + multY = (298 * bytesY[Y0Ptr++]); + output[outPtr0++] = (multY + multCrR) >> 8; + output[outPtr0++] = (multY - multCbCrG) >> 8; + output[outPtr0++] = (multY + multCbB) >> 8; + outPtr0++; + + multY = (298 * bytesY[Y0Ptr++]); + output[outPtr0++] = (multY + multCrR) >> 8; + output[outPtr0++] = (multY - multCbCrG) >> 8; + output[outPtr0++] = (multY + multCbB) >> 8; + outPtr0++; + + multY = (298 * bytesY[Y1Ptr++]); + output[outPtr1++] = (multY + multCrR) >> 8; + output[outPtr1++] = (multY - multCbCrG) >> 8; + output[outPtr1++] = (multY + multCbB) >> 8; + outPtr1++; + + multY = (298 * bytesY[Y1Ptr++]); + output[outPtr1++] = (multY + multCrR) >> 8; + output[outPtr1++] = (multY - multCbCrG) >> 8; + output[outPtr1++] = (multY + multCbB) >> 8; + outPtr1++; + } + outPtr0 += outStride; + outPtr1 += outStride; + ydec++; + } + } else { + outPtr = 0; + for (y = 0; y < height; y++) { + xdec = 0; + ydec = y >> vdec; + YPtr = y * strideY; + CbPtr = ydec * strideCb; + CrPtr = ydec * strideCr; + + for (x = 0; x < width; x++) { + xdec = x >> hdec; + colorCb = bytesCb[CbPtr + xdec]; + colorCr = bytesCr[CrPtr + xdec]; + + // Quickie YUV conversion + // https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.2020_conversion + // multiplied by 256 for integer-friendliness + multCrR = (409 * colorCr) - 57088; + multCbCrG = (100 * colorCb) + (208 * colorCr) - 34816; + multCbB = (516 * colorCb) - 70912; + + multY = 298 * bytesY[YPtr++]; + output[outPtr++] = (multY + multCrR) >> 8; + output[outPtr++] = (multY - multCbCrG) >> 8; + output[outPtr++] = (multY + multCbB) >> 8; + outPtr++; + } + } + } +} + + + function initImageData(width, height) { + imageData = ctx.createImageData(width, height); + + // Prefill the alpha to opaque + var data = imageData.data, + pixelCount = width * height * 4; + for (var i = 0; i < pixelCount; i += 4) { + data[i + 3] = 255; + } + } + + function initResampleCanvas() { + resampleCanvas = document.createElement('canvas'); + resampleCanvas.width = videoInfo.picWidth; + resampleCanvas.height = videoInfo.picHeight; + resampleContext = resampleCanvas.getContext('2d'); + } + + /** + * Actually draw a frame into the canvas. + */ + self.drawFrame = function drawFrame(yCbCrBuffer) { + if (imageData === null || + imageData.width != yCbCrBuffer.width || + imageData.height != yCbCrBuffer.height) { + initImageData(yCbCrBuffer.width, yCbCrBuffer.height); + } + convertYCbCr(yCbCrBuffer, imageData.data); + + var resample = (videoInfo.picWidth != videoInfo.displayWidth || videoInfo.picHeight != videoInfo.displayHeight); + if (resample) { + // hack for non-square aspect-ratio + // putImageData doesn't resample, so we have to draw in two steps. + if (!resampleCanvas) { + initResampleCanvas(); + } + drawContext = resampleContext; + } else { + drawContext = ctx; + } + + drawContext.putImageData(imageData, + 0, 0, + videoInfo.picX, videoInfo.picY, + videoInfo.picWidth, videoInfo.picHeight); + + if (resample) { + ctx.drawImage(resampleCanvas, 0, 0, videoInfo.displayWidth, videoInfo.displayHeight); + } + }; + + return self; +} + + + +// -- WebGLFrameSink.js + + +/** + * Warning: canvas must not have been used for 2d drawing prior! + * + * @param HTMLCanvasElement canvas + * @constructor + */ +function WebGLFrameSink(canvas, videoInfo) { + var self = this, + gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'), + debug = false; // swap this to enable more error checks, which can slow down rendering + + if (gl === null) { + throw new Error('WebGL unavailable'); + } + + // GL! + function checkError() { + if (debug) { + err = gl.getError(); + if (err !== 0) { + throw new Error("GL error " + err); + } + } + } + + function compileShader(type, source) { + var shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + var err = gl.getShaderInfoLog(shader); + gl.deleteShader(shader); + throw new Error('GL shader compilation for ' + type + ' failed: ' + err); + } + + return shader; + } + + + var vertexShader, + fragmentShader, + program, + buffer, + err; + + // In the world of GL there are no rectangles. + // There are only triangles. + // THERE IS NO SPOON. + var rectangle = new Float32Array([ + // First triangle (top left, clockwise) + -1.0, -1.0, + +1.0, -1.0, + -1.0, +1.0, + + // Second triangle (bottom right, clockwise) + -1.0, +1.0, + +1.0, -1.0, + +1.0, +1.0 + ]); + + var textures = {}; + function attachTexture(name, register, index, width, height, data) { + var texture, + texWidth = WebGLFrameSink.stripe ? (width / 4) : width, + format = WebGLFrameSink.stripe ? gl.RGBA : gl.LUMINANCE, + filter = WebGLFrameSink.stripe ? gl.NEAREST : gl.LINEAR; + + if (textures[name]) { + // Reuse & update the existing texture + texture = textures[name]; + } else { + textures[name] = texture = gl.createTexture(); + checkError(); + + gl.uniform1i(gl.getUniformLocation(program, name), index); + checkError(); + } + gl.activeTexture(register); + checkError(); + gl.bindTexture(gl.TEXTURE_2D, texture); + checkError(); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + checkError(); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + checkError(); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter); + checkError(); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter); + checkError(); + + gl.texImage2D( + gl.TEXTURE_2D, + 0, // mip level + format, // internal format + texWidth, + height, + 0, // border + format, // format + gl.UNSIGNED_BYTE, //type + data // data! + ); + checkError(); + + return texture; + } + + function buildStripe(width, height) { + var len = width * height, + out = new Uint32Array(len); + for (var i = 0; i < len; i += 4) { + out[i ] = 0x000000ff; + out[i + 1] = 0x0000ff00; + out[i + 2] = 0x00ff0000; + out[i + 3] = 0xff000000; + } + return new Uint8Array(out.buffer); + } + + function init(yCbCrBuffer) { + vertexShader = compileShader(gl.VERTEX_SHADER, "attribute vec2 aPosition;\nattribute vec2 aLumaPosition;\nattribute vec2 aChromaPosition;\nvarying vec2 vLumaPosition;\nvarying vec2 vChromaPosition;\nvoid main() {\n gl_Position = vec4(aPosition, 0, 1);\n vLumaPosition = aLumaPosition;\n vChromaPosition = aChromaPosition;\n}\n"); + if (WebGLFrameSink.stripe) { + fragmentShader = compileShader(gl.FRAGMENT_SHADER, "// inspired by https://github.com/mbebenita/Broadway/blob/master/Player/canvas.js\n// extra 'stripe' texture fiddling to work around IE 11's poor performance on gl.LUMINANCE and gl.ALPHA textures\n\nprecision mediump float;\nuniform sampler2D uStripeLuma;\nuniform sampler2D uStripeChroma;\nuniform sampler2D uTextureY;\nuniform sampler2D uTextureCb;\nuniform sampler2D uTextureCr;\nvarying vec2 vLumaPosition;\nvarying vec2 vChromaPosition;\nvoid main() {\n // Y, Cb, and Cr planes are mapped into a pseudo-RGBA texture\n // so we can upload them without expanding the bytes on IE 11\n // which doesn\\'t allow LUMINANCE or ALPHA textures.\n // The stripe textures mark which channel to keep for each pixel.\n vec4 vStripeLuma = texture2D(uStripeLuma, vLumaPosition);\n vec4 vStripeChroma = texture2D(uStripeChroma, vChromaPosition);\n\n // Each texture extraction will contain the relevant value in one\n // channel only.\n vec4 vY = texture2D(uTextureY, vLumaPosition) * vStripeLuma;\n vec4 vCb = texture2D(uTextureCb, vChromaPosition) * vStripeChroma;\n vec4 vCr = texture2D(uTextureCr, vChromaPosition) * vStripeChroma;\n\n // Now assemble that into a YUV vector, and premultipy the Y...\n vec3 YUV = vec3(\n (vY.x + vY.y + vY.z + vY.w) * 1.1643828125,\n (vCb.x + vCb.y + vCb.z + vCb.w),\n (vCr.x + vCr.y + vCr.z + vCr.w)\n );\n // And convert that to RGB!\n gl_FragColor = vec4(\n YUV.x + 1.59602734375 * YUV.z - 0.87078515625,\n YUV.x - 0.39176171875 * YUV.y - 0.81296875 * YUV.z + 0.52959375,\n YUV.x + 2.017234375 * YUV.y - 1.081390625,\n 1\n );\n}\n"); + } else { + fragmentShader = compileShader(gl.FRAGMENT_SHADER, "// inspired by https://github.com/mbebenita/Broadway/blob/master/Player/canvas.js\n\nprecision mediump float;\nuniform sampler2D uTextureY;\nuniform sampler2D uTextureCb;\nuniform sampler2D uTextureCr;\nvarying vec2 vLumaPosition;\nvarying vec2 vChromaPosition;\nvoid main() {\n // Y, Cb, and Cr planes are uploaded as LUMINANCE textures.\n float fY = texture2D(uTextureY, vLumaPosition).x;\n float fCb = texture2D(uTextureCb, vChromaPosition).x;\n float fCr = texture2D(uTextureCr, vChromaPosition).x;\n\n // Premultipy the Y...\n float fYmul = fY * 1.1643828125;\n\n // And convert that to RGB!\n gl_FragColor = vec4(\n fYmul + 1.59602734375 * fCr - 0.87078515625,\n fYmul - 0.39176171875 * fCb - 0.81296875 * fCr + 0.52959375,\n fYmul + 2.017234375 * fCb - 1.081390625,\n 1\n );\n}\n"); + } + + program = gl.createProgram(); + gl.attachShader(program, vertexShader); + checkError(); + + gl.attachShader(program, fragmentShader); + checkError(); + + gl.linkProgram(program); + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + var err = gl.getProgramInfoLog(program); + gl.deleteProgram(program); + throw new Error('GL program linking failed: ' + err); + } + + gl.useProgram(program); + checkError(); + + if (WebGLFrameSink.stripe) { + attachTexture( + 'uStripeLuma', + gl.TEXTURE3, + 3, + yCbCrBuffer.strideY * 4, + yCbCrBuffer.height, + buildStripe(yCbCrBuffer.strideY, yCbCrBuffer.height) + ); + checkError(); + + attachTexture( + 'uStripeChroma', + gl.TEXTURE4, + 4, + yCbCrBuffer.strideCb * 4, + yCbCrBuffer.height >> yCbCrBuffer.vdec, + buildStripe(yCbCrBuffer.strideCb, yCbCrBuffer.height >> yCbCrBuffer.vdec) + ); + checkError(); + } + } + + self.drawFrame = function(yCbCrBuffer) { + if (!program) { + init(yCbCrBuffer); + } + + // Set up the rectangle and draw it + + // + // Set up geometry + // + + buffer = gl.createBuffer(); + checkError(); + + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + checkError(); + + gl.bufferData(gl.ARRAY_BUFFER, rectangle, gl.STATIC_DRAW); + checkError(); + + var positionLocation = gl.getAttribLocation(program, 'aPosition'); + checkError(); + + gl.enableVertexAttribArray(positionLocation); + checkError(); + + gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); + checkError(); + + + // Set up the texture geometry... + function setupTexturePosition(varname, texWidth, texHeight) { + // Warning: assumes that the stride for Cb and Cr is the same size in output pixels + var textureX0 = videoInfo.picX / texWidth; + var textureX1 = (videoInfo.picX + videoInfo.picWidth) / texWidth; + var textureY0 = (videoInfo.picY + videoInfo.picHeight) / texHeight; + var textureY1 = videoInfo.picY / texHeight; + var textureRectangle = new Float32Array([ + textureX0, textureY0, + textureX1, textureY0, + textureX0, textureY1, + textureX0, textureY1, + textureX1, textureY0, + textureX1, textureY1 + ]); + + var texturePositionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, texturePositionBuffer); + checkError(); + + gl.bufferData(gl.ARRAY_BUFFER, textureRectangle, gl.STATIC_DRAW); + checkError(); + + var texturePositionLocation = gl.getAttribLocation(program, varname); + checkError(); + + gl.enableVertexAttribArray(texturePositionLocation); + checkError(); + + gl.vertexAttribPointer(texturePositionLocation, 2, gl.FLOAT, false, 0, 0); + checkError(); + } + setupTexturePosition('aLumaPosition', yCbCrBuffer.strideY, yCbCrBuffer.height); + setupTexturePosition('aChromaPosition', yCbCrBuffer.strideCb << yCbCrBuffer.hdec, yCbCrBuffer.height); + + // Create the textures... + var textureY = attachTexture( + 'uTextureY', + gl.TEXTURE0, + 0, + yCbCrBuffer.strideY, + yCbCrBuffer.height, + yCbCrBuffer.bytesY + ); + var textureCb = attachTexture( + 'uTextureCb', + gl.TEXTURE1, + 1, + yCbCrBuffer.strideCb, + yCbCrBuffer.height >> yCbCrBuffer.vdec, + yCbCrBuffer.bytesCb + ); + var textureCr = attachTexture( + 'uTextureCr', + gl.TEXTURE2, + 2, + yCbCrBuffer.strideCr, + yCbCrBuffer.height >> yCbCrBuffer.vdec, + yCbCrBuffer.bytesCr + ); + + // Aaaaand draw stuff. + gl.drawArrays(gl.TRIANGLES, 0, rectangle.length / 2); + checkError(); + }; + + return self; +} + +// For Windows; luminance and alpha textures are ssllooww to upload, +// so we pack into RGBA and unpack in the shaders. +// +// This seems to affect all browsers on Windows, probably due to fun +// mismatches between GL and D3D. +WebGLFrameSink.stripe = (function() { + if (navigator.userAgent.indexOf('Windows') !== -1) { + return true; + } + return false; +})(); + +/** + * Static function to check if WebGL will be available with appropriate features. + * + * @return boolean + */ +WebGLFrameSink.isAvailable = function() { + var canvas = document.createElement('canvas'), + gl; + canvas.width = 1; + canvas.height = 1; + var options = { + failIfMajorPerformanceCaveat: true + }; + try { + gl = canvas.getContext('webgl', options) || canvas.getContext('experimental-webgl', options); + } catch (e) { + return false; + } + if (gl) { + var register = gl.TEXTURE0, + width = 4, + height = 4, + texture = gl.createTexture(), + data = new Uint8Array(width * height), + texWidth = WebGLFrameSink.stripe ? (width / 4) : width, + format = WebGLFrameSink.stripe ? gl.RGBA : gl.LUMINANCE, + filter = WebGLFrameSink.stripe ? gl.NEAREST : gl.LINEAR; + + gl.activeTexture(register); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter); + gl.texImage2D( + gl.TEXTURE_2D, + 0, // mip level + format, // internal format + texWidth, + height, + 0, // border + format, // format + gl.UNSIGNED_BYTE, //type + data // data! + ); + + var err = gl.getError(); + if (err) { + // Doesn't support luminance textures? + return false; + } else { + return true; + } + } else { + return false; + } +}; + + + +// -- Bisector.js + +/** + * Give as your 'process' function something that will trigger an async + * operation, then call the left() or right() methods to run another + * iteration, bisecting to the given direction. + * + * Caller is responsible for determining when done. + * + * @params options object { + * start: number, + * end: number, + * process: function(start, position, end) + * } + */ +function Bisector(options) { + var start = options.start, + end = options.end, + position = 0, + self = this, + n = 0; + + function iterate() { + n++; + position = Math.floor((start + end) / 2); + return options.process(start, end, position); + } + + self.start = function() { + iterate(); + return self; + }; + + self.left = function() { + end = position; + return iterate(); + }; + + self.right = function() { + start = position; + return iterate(); + }; +} + + +// -- OGVMediaType.js + +function OGVMediaType(contentType) { + contentType = '' + contentType; + + var self = this; + self.major = null; + self.minor = null; + self.codecs = null; + + function trim(str) { + return str.replace(/^\s+/, '').replace(/\s+$/, ''); + } + + function split(str, sep, limit) { + var bits = str.split(sep, limit).map(function(substr) { + return trim(substr); + }); + if (typeof limit === 'number') { + while (bits.length < limit) { + bits.push(null); + } + } + return bits; + } + + var parts = split(contentType, ';'); + if (parts.length) { + var base = parts.shift(); + if (base) { + var bits = split(base, '/', 2); + self.major = bits[0]; + self.minor = bits[1]; + } + + parts.forEach(function(str) { + var matches = str.match(/^codecs\s*=\s*"(.*?)"$/); + if (matches) { + self.codecs = split(matches[1], ','); + } + }); + } +} + + +// -- OGVWrapperCodec.js + +/** + * Proxy object for web worker interface for codec classes. + * + * Used by the high-level player interface. + * + * @author Brion Vibber <brion@pobox.com> + * @copyright 2015 + * @license MIT-style + */ +OGVWrapperCodec = (function(options) { + options = options || {}; + var self = this, + suffix = '?version=' + encodeURIComponent(OGVVersion), + base = (typeof options.base === 'string') ? (options.base + '/') : '', + type = (typeof options.type === 'string') ? options.type : 'video/ogg', + processing = false, + demuxer = null, + videoDecoder = null, + audioDecoder = null; + + var loadedMetadata = false; + Object.defineProperty(self, 'loadedMetadata', { + get: function() { + return loadedMetadata; + } + }); + + Object.defineProperty(self, 'processing', { + get: function() { + return processing + || (videoDecoder && videoDecoder.processing) + || (audioDecoder && audioDecoder.processing); + } + }); + + Object.defineProperty(self, 'duration', { + get: function() { + if (self.loadedMetadata) { + return demuxer.duration; + } else { + return NaN; + } + } + }); + + Object.defineProperty(self, 'hasAudio', { + get: function() { + return self.loadedMetadata && !!audioDecoder; + } + }); + + Object.defineProperty(self, 'audioReady', { + get: function() { + return self.hasAudio && demuxer.audioReady; + } + }); + + Object.defineProperty(self, 'audioTimestamp', { + get: function() { + return demuxer.audioTimestamp; + } + }); + + Object.defineProperty(self, 'audioFormat', { + get: function() { + if (self.hasAudio) { + return audioDecoder.audioFormat; + } else { + return null; + } + } + }); + + Object.defineProperty(self, 'audioBuffer', { + get: function() { + if (self.hasAudio) { + return audioDecoder.audioBuffer; + } else { + return null; + } + } + }); + + Object.defineProperty(self, 'hasVideo', { + get: function() { + return self.loadedMetadata && !!videoDecoder; + } + }); + + Object.defineProperty(self, 'frameReady', { + get: function() { + return self.hasVideo && demuxer.frameReady; + } + }); + + Object.defineProperty(self, 'frameTimestamp', { + get: function() { + return demuxer.frameTimestamp; + } + }); + + Object.defineProperty(self, 'keyframeTimestamp', { + get: function() { + return demuxer.keyframeTimestamp; + } + }); + + Object.defineProperty(self, 'videoFormat', { + get: function() { + if (self.hasVideo) { + return videoDecoder.videoFormat; + } else { + return null; + } + } + }); + + Object.defineProperty(self, 'frameBuffer', { + get: function() { + if (self.hasVideo) { + return videoDecoder.frameBuffer; + } else { + return null; + } + } + }); + + Object.defineProperty(self, 'seekable', { + get: function() { + return demuxer.seekable; + } + }); + + // - public methods + self.init = function(callback) { + var demuxerClassName; + if (options.type === 'video/webm') { + demuxerClassName = 'OGVDemuxerWebM'; + } else { + demuxerClassName = 'OGVDemuxerOgg'; + } + OGVLoader.loadClass(demuxerClassName, function(demuxerClass) { + demuxer = new demuxerClass(); + demuxer.init(callback); + }); + }; + + self.destroy = function() { + demuxer = null; + videoDecoder = null; + audioDecoder = null; + }; + + var inputQueue = []; + self.receiveInput = function(data, callback) { + inputQueue.push(data); + callback(); + }; + + var audioClassMap = { + vorbis: 'OGVDecoderAudioVorbis', + opus: 'OGVDecoderAudioOpus' + }; + function loadAudioCodec(callback) { + if (demuxer.audioCodec) { + var className = audioClassMap[demuxer.audioCodec]; + processing = true; + OGVLoader.loadClass(className, function(audioCodecClass) { + var audioOptions = {}; + if (demuxer.audioFormat) { + audioOptions.audioFormat = demuxer.audioFormat; + } + audioDecoder = new audioCodecClass(audioOptions); + audioDecoder.init(function() { + loadedAudioMetadata = audioDecoder.loadedMetadata; + processing = false; + callback(); + }); + }, { + worker: options.worker + }); + } else { + callback(); + } + } + + var videoClassMap = { + theora: 'OGVDecoderVideoTheora', + vp8: 'OGVDecoderVideoVP8', + vp9: 'OGVDecoderVideoVP9' + }; + function loadVideoCodec(callback) { + if (demuxer.videoCodec) { + var className = videoClassMap[demuxer.videoCodec]; + processing = true; + OGVLoader.loadClass(className, function(videoCodecClass) { + var videoOptions = {}; + if (demuxer.videoFormat) { + videoOptions.videoFormat = demuxer.videoFormat; + } + videoDecoder = new videoCodecClass(videoOptions); + videoDecoder.init(function() { + loadedVideoMetadata = videoDecoder.loadedMetadata; + processing = false; + callback(); + }); + }, { + worker: options.worker + }); + } else { + callback(); + } + } + + var loadedDemuxerMetadata = false, + loadedAudioMetadata = false, + loadedVideoMetadata = false; + + self.process = function(callback) { + if (processing) { + throw new Error('reentrancy fail on OGVWrapperCodec.process'); + } + processing = true; + function finish(result) { + processing = false; + callback(result); + } + + function doProcessData() { + if (inputQueue.length) { + var data = inputQueue.shift(); + demuxer.process(data, function(more) { + if (!more && inputQueue.length) { + // we've got more to process already + more = true; + } + finish(more); + }); + } else { + // out of data! ask for more + finish(false); + } + } + + if (demuxer.loadedMetadata && !loadedDemuxerMetadata) { + + // Demuxer just reached its metadata. Load the relevant codecs! + loadAudioCodec(function() { + loadVideoCodec(function() { + loadedDemuxerMetadata = true; + loadedAudioMetadata = !audioDecoder; + loadedVideoMetadata = !videoDecoder; + loadedAllMetadata = loadedAudioMetadata && loadedVideoMetadata; + finish(true); + }); + }); + + } else if (loadedDemuxerMetadata && !loadedAudioMetadata) { + + if (audioDecoder.loadedMetadata) { + + loadedAudioMetadata = true; + loadedAllMetadata = loadedAudioMetadata && loadedVideoMetadata; + finish(true); + + } else if (demuxer.audioReady) { + + demuxer.dequeueAudioPacket(function(packet) { + audioDecoder.processHeader(packet, function(ret) { + finish(true); + }); + }); + + } else { + + doProcessData(); + + } + + } else if (loadedAudioMetadata && !loadedVideoMetadata) { + + if (videoDecoder.loadedMetadata) { + + loadedVideoMetadata = true; + loadedAllMetadata = loadedAudioMetadata && loadedVideoMetadata; + finish(true); + + } else if (demuxer.frameReady) { + + processing = true; + demuxer.dequeueVideoPacket(function(packet) { + videoDecoder.processHeader(packet, function() { + finish(true); + }); + }); + + } else { + + doProcessData(); + + } + + } else if (loadedVideoMetadata && !self.loadedMetadata && loadedAllMetadata) { + + // Ok we've found all the metadata there is. Enjoy. + loadedMetadata = true; + finish(true); + + } else if (self.loadedMetadata && (!self.hasAudio || demuxer.audioReady) && (!self.hasVideo || demuxer.frameReady)) { + + // Already queued up some packets. Go read them! + finish(true); + + } else { + + // We need to process more of the data we've already received, + // or ask for more if we ran out! + doProcessData(); + + } + + }; + + self.decodeFrame = function(callback) { + var timestamp = self.frameTimestamp, + keyframeTimestamp = self.keyframeTimestamp; + demuxer.dequeueVideoPacket(function(packet) { + videoDecoder.processFrame(packet, function(ok) { + // hack + if (self.frameBuffer) { + self.frameBuffer.timestamp = timestamp; + self.frameBuffer.keyframeTimestamp = keyframeTimestamp; + } + callback(ok); + }); + }); + }; + + self.decodeAudio = function(callback) { + demuxer.dequeueAudioPacket(function(packet) { + audioDecoder.processAudio(packet, function(ok) { + callback(ok); + }); + }); + } + + self.discardFrame = function(callback) { + demuxer.dequeueVideoPacket(function(packet) { + callback(); + }); + }; + + self.discardAudio = function(callback) { + demuxer.dequeueAudioPacket(function(packet) { + callback(ok); + }); + }; + + self.flush = function(callback) { + inputQueue.splice(0, inputQueue.length); + demuxer.flush(callback); + }; + + self.getKeypointOffset = function(timeSeconds, callback) { + demuxer.getKeypointOffset(timeSeconds, callback); + }; + + return self; +}); + + +// -- OGVProxyClass.js + +/** + * Proxy object for web worker interface for codec classes. + * + * Used by the high-level player interface. + * + * @author Brion Vibber <brion@pobox.com> + * @copyright 2015 + * @license MIT-style + */ +function OGVProxyClass(initialProps, methods) { + return function(worker, className, options) { + options = options || {}; + var self = this; + + var transferables = (function() { + var buffer = new ArrayBuffer(1024), + bytes = new Uint8Array(buffer); + try { + worker.postMessage({ + action: 'transferTest', + bytes: bytes + }, [buffer]); + if (buffer.byteLength) { + // No transferable support + return false; + } else { + return true; + } + } catch (e) { + return false; + } + })(); + + // Set up proxied property getters + var props = {}; + for (var iPropName in initialProps) { + if (initialProps.hasOwnProperty(iPropName)) { + (function(propName) { + props[propName] = initialProps[propName]; + Object.defineProperty(self, propName, { + get: function getProperty() { + return props[propName]; + } + }); + })(iPropName); + } + } + + // Current player wants to avoid async confusion. + var processingQueue = 0; + Object.defineProperty(self, 'processing', { + get: function() { + return (processingQueue > 0); + } + }); + + // Set up proxied methods + for (var method in methods) { + if (methods.hasOwnProperty(method)) { + self[method] = methods[method]; + } + } + + // And some infrastructure! + var messageCount = 0, + pendingCallbacks = {}; + this.proxy = function(action, args, callback, transfers) { + var callbackId = 'callback-' + (++messageCount) + '-' + action; + if (callback) { + pendingCallbacks[callbackId] = callback; + } + var out = { + 'action': action, + 'callbackId': callbackId, + 'args': args || [] + }; + processingQueue++; + if (transferables) { + worker.postMessage(out, transfers || []); + } else { + worker.postMessage(out); + } + }; + + worker.addEventListener('message', function proxyOnMessage(event) { + processingQueue--; + if (event.data.action !== 'callback') { + // ignore + return; + } + + var data = event.data, + callbackId = data.callbackId, + args = data.args, + callback = pendingCallbacks[callbackId]; + + // Save any updated properties returned to us... + if (data.props) { + for (var propName in data.props) { + if (data.props.hasOwnProperty(propName)) { + props[propName] = data.props[propName]; + } + } + } + + if (callback) { + delete pendingCallbacks[callbackId]; + callback.apply(this, args); + } + }); + + // Tell the proxy to load and initialize the appropriate class + self.proxy('construct', [className, options], function() {}); + + return self; + }; +} + + +// -- OGVDecoderAudioProxy.js + +OGVDecoderAudioProxy = OGVProxyClass({ + loadedMetadata: false, + audioFormat: null, + audioBuffer: null +}, { + init: function(callback) { + this.proxy('init', [], callback); + }, + + processHeader: function(data, callback) { + this.proxy('processHeader', [data], callback, [data]); + }, + + processAudio: function(data, callback) { + this.proxy('processAudio', [data], callback, [data]); + } +}); + + +// -- OGVDecoderVideoProxy.js + +OGVDecoderVideoProxy = OGVProxyClass({ + loadedMetadata: false, + videoFormat: null, + frameBuffer: null +}, { + init: function(callback) { + this.proxy('init', [], callback); + }, + + processHeader: function(data, callback) { + this.proxy('processHeader', [data], callback, [data]); + }, + + processFrame: function(data, callback) { + this.proxy('processFrame', [data], callback, [data]); + } +}); + + +// -- OGVPlayer.js + +/** + * Constructor for an analogue of the TimeRanges class + * returned by various HTMLMediaElement properties + * + * Pass an array of two-element arrays, each containing a start and end time. + */ +OGVTimeRanges = window.OGVTimeRanges = function(ranges) { + Object.defineProperty(this, 'length', { + get: function getLength() { + return ranges.length; + } + }); + this.start = function(i) { + return ranges[i][0]; + }; + this.end = function(i) { + return ranges[i][1]; + }; + return this; +}; + +/** + * Player class -- instantiate one of these to get an 'ogvjs' HTML element + * which has a similar interface to the HTML audio/video elements. + * + * @param options: optional dictionary of options: + * 'base': string; base URL for additional resources, such as Flash audio shim + * 'webGL': bool; pass true to use WebGL acceleration if available + * 'forceWebGL': bool; pass true to require WebGL even if not detected + */ +OGVPlayer = window.OGVPlayer = function(options) { + options = options || {}; + + var instanceId = 'ogvjs' + (++OGVPlayer.instanceCount); + + var codecClassName = null, + codecClass = null, + codecType = null; + + var webGLdetected = WebGLFrameSink.isAvailable(); + var useWebGL = (options.webGL !== false) && webGLdetected; + if(!!options.forceWebGL) { + useWebGL = true; + if(!webGLdetected) { + console.log("No support for WebGL detected, but WebGL forced on!"); + } + } + + // Experimental options + var enableWebM = !!options.enableWebM; + + // Running the codec in a worker thread equals happy times! + var enableWorker = !!window.Worker; + if (typeof options.worker !== 'undefined') { + enableWorker = !!options.worker; + } + + var State = { + INITIAL: 'INITIAL', + SEEKING_END: 'SEEKING_END', + LOADED: 'LOADED', + READY: 'READY', + PLAYING: 'PLAYING', + SEEKING: 'SEEKING', + ENDED: 'ENDED' + }, state = State.INITIAL; + + var SeekState = { + NOT_SEEKING: 'NOT_SEEKING', + BISECT_TO_TARGET: 'BISECT_TO_TARGET', + BISECT_TO_KEYPOINT: 'BISECT_TO_KEYPOINT', + LINEAR_TO_TARGET: 'LINEAR_TO_TARGET' + }, seekState = SeekState.NOT_SEEKING; + + var audioOptions = {}, + codecOptions = {}; + options.base = options.base || OGVLoader.base; + if (typeof options.base === 'string') { + // Pass the resource dir down to AudioFeeder, so it can load the dynamicaudio.swf + audioOptions.base = options.base; + + // And to the worker thread, so it can load the codec JS + codecOptions.base = options.base; + } + if (typeof options.audioContext !== 'undefined') { + // Try passing a pre-created audioContext in? + audioOptions.audioContext = options.audioContext; + } + codecOptions.worker = enableWorker; + + var canvas = document.createElement('canvas'); + var frameSink; + + // Return a magical custom element! + var self = document.createElement('ogvjs'); + self.className = instanceId; + + canvas.style.position = 'absolute'; + canvas.style.top = '0'; + canvas.style.left = '0'; + canvas.style.width = '100%'; + canvas.style.height = '100%'; + canvas.style.objectFit = 'contain'; + self.appendChild(canvas); + + var getTimestamp; + if (window.performance === undefined || window.performance.now === undefined) { + getTimestamp = Date.now; + } else { + getTimestamp = window.performance.now.bind(window.performance); + } + function time(cb) { + var start = getTimestamp(); + cb(); + var delta = getTimestamp() - start; + lastFrameDecodeTime += delta; + return delta; + } + + var then = getTimestamp(); + function log(msg) { + if (options.debug) { + /* + var now = getTimestamp(), + delta = now - then; + + console.log('+' + delta + 'ms proc: ' + msg); + then = now; + */ + console.log('OGVPlayer: ' + msg); + } + } + + function fireEvent(eventName, props) { + var event; + props = props || {}; + + if (typeof window.Event == 'function') { + // standard event creation + event = new CustomEvent(eventName); + } else { + // IE back-compat mode + // https://msdn.microsoft.com/en-us/library/dn905219%28v=vs.85%29.aspx + event = document.createEvent('Event'); + event.initEvent(eventName, false, false); + } + + for (var prop in props) { + if (props.hasOwnProperty(prop)) { + event[prop] = props[prop]; + } + } + + self.dispatchEvent(event); + } + + var codec, + actionQueue = [], + audioFeeder; + var muted = false, + initialPlaybackPosition = 0.0, + initialPlaybackOffset = 0.0; + function initAudioFeeder() { + audioFeeder = new AudioFeeder( audioOptions ); + if (muted) { + audioFeeder.mute(); + } + audioFeeder.onstarved = function() { + // If we're in a background tab, timers may be throttled. + // When audio buffers run out, go decode some more stuff. + if (nextProcessingTimer) { + clearTimeout(nextProcessingTimer); + nextProcessingTimer = null; + pingProcessing(); + } + }; + audioFeeder.init(audioInfo.channels, audioInfo.rate); + } + + function startPlayback(offset) { + if (audioFeeder) { + audioFeeder.start(); + var state = audioFeeder.getPlaybackState(); + initialPlaybackPosition = state.playbackPosition; + } else { + initialPlaybackPosition = getTimestamp() / 1000; + } + if (offset !== undefined) { + initialPlaybackOffset = offset; + } + log('continuing at ' + initialPlaybackPosition + ', ' + initialPlaybackOffset); + } + + function stopPlayback() { + if (audioFeeder) { + audioFeeder.stop(); + } + initialPlaybackOffset = getPlaybackTime(); + log('pausing at ' + initialPlaybackOffset); + } + + /** + * Get audio playback time position in file's units + * + * @return {number} seconds since file start + */ + function getPlaybackTime(state) { + var position; + if (audioFeeder) { + state = state || audioFeeder.getPlaybackState(); + position = state.playbackPosition; + } else { + position = getTimestamp() / 1000; + } + return (position - initialPlaybackPosition) + initialPlaybackOffset; + } + + var stream, + byteLength = 0, + duration = null, + lastSeenTimestamp = null, + nextProcessingTimer, + started = false, + paused = true, + ended = false, + startedPlaybackInDocument = false, + waitingOnInput = false; + + var framesPlayed = 0; + // Benchmark data, exposed via getPlaybackStats() + var framesProcessed = 0, // frames + targetPerFrameTime = 1000 / 60, // ms + totalFrameTime = 0, // ms + totalFrameCount = 0, // frames + playTime = 0, // ms + demuxingTime = 0, // ms + videoDecodingTime = 0, // ms + audioDecodingTime = 0, // ms + bufferTime = 0, // ms + drawingTime = 0, // ms + totalJitter = 0; // sum of ms we're off from expected frame delivery time + // Benchmark data that doesn't clear + var droppedAudio = 0, // number of times we were starved for audio + delayedAudio = 0; // seconds audio processing was delayed by blocked CPU + var poster = '', thumbnail; + + function stopVideo() { + log("STOPPING"); + // kill the previous video if any + state = State.INITIAL; + started = false; + paused = true; + ended = true; + frameEndTimestamp = 0.0; + audioEndTimestamp = 0.0; + lastFrameDecodeTime = 0.0; + + if (stream) { + stream.abort(); + stream = null; + } + if (codec) { + codec.destroy(); + codec = null; + } + if (audioFeeder) { + audioFeeder.close(); + audioFeeder = undefined; + } + if (nextProcessingTimer) { + clearTimeout(nextProcessingTimer); + nextProcessingTimer = null; + } + } + + var lastFrameTime = getTimestamp(), + frameEndTimestamp = 0.0, + audioEndTimestamp = 0.0, + yCbCrBuffer = null; + var lastFrameDecodeTime = 0.0; + var lastFrameTimestamp = 0.0; + + function doFrameComplete() { + if (startedPlaybackInDocument && !document.body.contains(self)) { + // We've been de-parented since we last ran + // Stop playback at next opportunity! + setTimeout(function() { + self.stop(); + }, 0); + } + + var newFrameTimestamp = getTimestamp(), + wallClockTime = newFrameTimestamp - lastFrameTimestamp, + jitter = Math.abs(wallClockTime - targetPerFrameTime); + totalJitter += jitter; + playTime += wallClockTime; + + fireEvent('framecallback', { + cpuTime: lastFrameDecodeTime, + clockTime: wallClockTime + }); + lastFrameDecodeTime = 0; + lastFrameTimestamp = newFrameTimestamp; + } + + + // -- seek functions + var seekTargetTime = 0.0, + seekTargetKeypoint = 0.0, + bisectTargetTime = 0.0, + lastSeekPosition, + lastFrameSkipped, + seekBisector; + + function startBisection(targetTime) { + bisectTargetTime = targetTime; + seekBisector = new Bisector({ + start: 0, + end: stream.bytesTotal - 1, + process: function(start, end, position) { + if (position == lastSeekPosition) { + return false; + } else { + lastSeekPosition = position; + lastFrameSkipped = false; + codec.flush(function() { + stream.seek(position); + readBytesAndWait(); + }); + return true; + } + } + }); + seekBisector.start(); + } + + function seek(toTime) { + if (stream.bytesTotal === 0) { + throw new Error('Cannot bisect a non-seekable stream'); + } + state = State.SEEKING; + seekTargetTime = toTime; + seekTargetKeypoint = -1; + lastFrameSkipped = false; + lastSeekPosition = -1; + + actionQueue.push(function() { + stopPlayback(); + + codec.flush(function() { + codec.getKeypointOffset(toTime, function(offset) { + if (offset > 0) { + // This file has an index! + // + // Start at the keypoint, then decode forward to the desired time. + // + seekState = SeekState.LINEAR_TO_TARGET; + stream.seek(offset); + readBytesAndWait(); + } else { + // No index. + // + // Bisect through the file finding our target time, then we'll + // have to do it again to reach the keypoint, and *then* we'll + // have to decode forward back to the desired time. + // + seekState = SeekState.BISECT_TO_TARGET; + startBisection(seekTargetTime); + } + }); + }); + }); + } + + function continueSeekedPlayback() { + seekState = SeekState.NOT_SEEKING; + state = State.PLAYING; + frameEndTimestamp = codec.frameTimestamp; + audioEndTimestamp = codec.audioTimestamp; + if (codec.hasAudio) { + seekTargetTime = codec.audioTimestamp; + } else { + seekTargetTime = codec.frameTimestamp; + } + startPlayback(seekTargetTime); + if (paused) { + stopPlayback(); // :P + } else { + if (isProcessing()) { + // wait for whatever's going on to complete + } else { + pingProcessing(0); + } + } + } + + /** + * @return {boolean} true to continue processing, false to wait for input data + */ + function doProcessLinearSeeking() { + var frameDuration; + if (codec.hasVideo) { + frameDuration = targetPerFrameTime; + } else { + frameDuration = 1 / 256; // approximate packet audio size, fake! + } + + if (codec.hasVideo) { + if (!codec.frameReady) { + // Haven't found a frame yet, process more data + pingProcessing(); + return; + } else if (codec.frameTimestamp < 0 || codec.frameTimestamp + frameDuration < seekTargetTime) { + // Haven't found a time yet, or haven't reached the target time. + // Decode it in case we're at our keyframe or a following intraframe... + codec.decodeFrame(function() { + pingProcessing(); + }); + return; + } else { + // Reached or surpassed the target time. + if (codec.hasAudio) { + // Keep processing the audio track + // fall through... + } else { + continueSeekedPlayback(); + return; + } + } + } + if (codec.hasAudio) { + if (!codec.audioReady) { + // Haven't found an audio packet yet, process more data + pingProcessing(); + return; + } + if (codec.audioTimestamp < 0 || codec.audioTimestamp + frameDuration < seekTargetTime) { + // Haven't found a time yet, or haven't reached the target time. + // Decode it so when we reach the target we've got consistent data. + codec.decodeAudio(function() { + pingProcessing(); + }); + return; + } else { + continueSeekedPlayback(); + return; + } + } + } + + function doProcessBisectionSeek() { + var frameDuration, + timestamp; + if (codec.hasVideo) { + if (!codec.frameReady) { + // Haven't found a frame yet, process more data + pingProcessing(); + return; + } + timestamp = codec.frameTimestamp; + frameDuration = targetPerFrameTime; + } else if (codec.hasAudio) { + if (!codec.audioReady) { + // Haven't found an audio packet yet, process more data + pingProcessing(); + return; + } + timestamp = codec.audioTimestamp; + frameDuration = 1 / 256; // approximate packet audio size, fake! + } else { + throw new Error('Invalid seek state; no audio or video track available'); + } + + if (timestamp < 0) { + // Haven't found a time yet. + // Decode in case we're at our keyframe or a following intraframe... + if (codec.frameReady) { + codec.decodeFrame(function() { + pingProcessing(); + }); + } else if (codec.audioReady) { + codec.decodeAudio(function() { + pingProcessing(); + }); + } else { + pingProcessing(); + } + } else if (timestamp - frameDuration > bisectTargetTime) { + if (seekBisector.left()) { + // wait for new data to come in + } else { + seekTargetTime = codec.frameTimestamp; + continueSeekedPlayback(); + } + } else if (timestamp + frameDuration < bisectTargetTime) { + if (seekBisector.right()) { + // wait for new data to come in + } else { + seekTargetTime = codec.frameTimestamp; + continueSeekedPlayback(); + } + } else { + // Reached the bisection target! + if (seekState == SeekState.BISECT_TO_TARGET && (codec.hasVideo && codec.keyframeTimestamp < codec.frameTimestamp)) { + // We have to go back and find a keyframe. Sigh. + seekState = SeekState.BISECT_TO_KEYPOINT; + startBisection(codec.keyframeTimestamp); + } else { + // Switch to linear mode to find the final target. + seekState = SeekState.LINEAR_TO_TARGET; + pingProcessing(); + } + } + } + + function setupVideo() { + if (videoInfo.fps > 0) { + targetPerFrameTime = 1000 / videoInfo.fps; + } else { + targetPerFrameTime = 16.667; // recalc this later + } + + canvas.width = videoInfo.displayWidth; + canvas.height = videoInfo.displayHeight; + OGVPlayer.styleManager.appendRule('.' + instanceId, { + width: videoInfo.displayWidth + 'px', + height: videoInfo.displayHeight + 'px' + }); + OGVPlayer.updatePositionOnResize(); + + if (useWebGL) { + frameSink = new WebGLFrameSink(canvas, videoInfo); + } else { + frameSink = new FrameSink(canvas, videoInfo); + } + } + + var depth = 0, + useImmediate = options.useImmediate && !!window.setImmediate, + useTailCalls = !useImmediate, + pendingFrame = 0, + pendingAudio = 0; + + function tailCall(func) { + if (useImmediate) { + setImmediate(func); + } else if (!useTailCalls) { + setTimeout(func, 0); + } else { + func(); + } + } + + function doProcessing() { + nextProcessingTimer = null; + + if (isProcessing()) { + // Called async while waiting for something else to complete... + // let it finish, then we'll get called again to continue. + return; + } + + if (depth > 0 && !useTailCalls) { + throw new Error('REENTRANCY FAIL: doProcessing recursing unexpectedly'); + } + depth++; + + if (actionQueue.length) { + // data or user i/o to process in our serialized event stream + // The function should eventually bring us back here via pingProcessing(), + // directly or via further i/o. + + var action = actionQueue.shift(); + action(); + + } else if (state == State.INITIAL) { + + codec.process(function processInitial(more) { + if (codec.loadedMetadata) { + // we just fell over from headers into content; call onloadedmetadata etc + if (!codec.hasVideo && !codec.hasAudio) { + throw new Error('No audio or video found, something is wrong'); + } + if (codec.hasAudio) { + audioInfo = codec.audioFormat; + } + if (codec.hasVideo) { + videoInfo = codec.videoFormat; + setupVideo(); + } + if (!isNaN(codec.duration)) { + duration = codec.duration; + } + if (duration === null) { + if (stream.seekable) { + state = State.SEEKING_END; + lastSeenTimestamp = -1; + codec.flush(function() { + stream.seek(Math.max(0, stream.bytesTotal - 65536 * 2)); + readBytesAndWait(); + }); + } else { + // Stream not seekable and no x-content-duration; assuming infinite stream. + state = State.LOADED; + pingProcessing(); + } + } else { + // We already know the duration. + state = State.LOADED; + pingProcessing(); + } + } else if (!more) { + // Read more data! + log('reading more cause we are out of data'); + readBytesAndWait(); + } else { + // Keep processing headers + pingProcessing(); + } + }); + + } else if (state == State.SEEKING_END) { + + // Look for the last item. + codec.process(function processSeekingEnd(more) { + if (codec.hasVideo && codec.frameReady) { + lastSeenTimestamp = Math.max(lastSeenTimestamp, codec.frameTimestamp); + codec.discardFrame(function() { + pingProcessing(); + }); + } else if (codec.hasAudio && codec.audioReady) { + lastSeenTimestamp = Math.max(lastSeenTimestamp, codec.audioTimestamp); + codec.decodeAudio(function() { + pingProcessing(); + }); + } else if (!more) { + // Read more data! + if (stream.bytesRead < stream.bytesTotal) { + readBytesAndWait(); + } else { + // We are at the end! + if (lastSeenTimestamp > 0) { + duration = lastSeenTimestamp; + } + + // Ok, seek back to the beginning and resync the streams. + state = State.LOADED; + codec.flush(function() { + stream.seek(0); + readBytesAndWait(); + }); + } + } else { + // Keep processing headers + pingProcessing(); + } + }); + + } else if (state == State.LOADED) { + + state = State.READY; + if (paused) { + // Paused? stop here. + log('pausing stopping at loaded'); + } else { + // Not paused? Continue on to play processing. + log('not paused so continuing'); + pingProcessing(0); + } + fireEvent('loadedmetadata'); + + } else if (state == State.READY) { + + if (paused) { + + // Paused? stop here. + log('paused while in ready'); + + } else { + + function finishStartPlaying() { + log('finishStartPlaying'); + + state = State.PLAYING; + lastFrameTimestamp = getTimestamp(); + + startPlayback(0.0); + pingProcessing(0); + fireEvent('play'); + } + + if (codec.hasAudio) { + initAudioFeeder(); + audioFeeder.waitUntilReady(finishStartPlaying); + } else { + finishStartPlaying(); + } + } + + } else if (state == State.SEEKING) { + + codec.process(function processSeeking(more) { + if (!more) { + readBytesAndWait(); + } else if (seekState == SeekState.NOT_SEEKING) { + throw new Error('seeking in invalid state (not seeking?)'); + } else if (seekState == SeekState.BISECT_TO_TARGET) { + doProcessBisectionSeek(); + } else if (seekState == SeekState.BISECT_TO_KEYPOINT) { + doProcessBisectionSeek(); + } else if (seekState == SeekState.LINEAR_TO_TARGET) { + doProcessLinearSeeking(); + } + }); + + } else if (state == State.PLAYING) { + + var demuxStartTime = getTimestamp(); + codec.process(function doProcessPlay(more) { + var delta = getTimestamp() - demuxStartTime; + demuxingTime += delta; + lastFrameDecodeTime += delta; + + //console.log(more, codec.audioReady, codec.frameReady, codec.audioTimestamp, codec.frameTimestamp); + + if (!more) { + if (stream) { + // Ran out of buffered input + readBytesAndWait(); + } else { + // Ran out of stream! + var finalDelay = 0; + if (codec.hasAudio) { + audioState = audioFeeder.getPlaybackState(); + audioBufferedDuration = (audioState.samplesQueued / audioFeeder.targetRate); + finalDelay = audioBufferedDuration * 1000; + } + if (pendingAudio || pendingFrame || finalDelay > 0) { + pingProcessing(Math.max(0, finalDelay)); + } else { + log("ENDING NOW"); + stopVideo(); + ended = true; + fireEvent('ended'); + } + } + } else if (paused) { + + // ok we're done for now! + + } else { + + if (!((codec.audioReady || !codec.hasAudio) && (codec.frameReady || !codec.frameReady))) { + + log('need more data'); + + // Have to process some more pages to find data. + pingProcessing(); + + } else { + + var audioBufferedDuration = 0, + audioDecodingDuration = 0, + audioState = null, + playbackPosition = 0, + nextDelays = [], + readyForAudioDecode, + readyForFrameDraw, + readyForFrameDecode; + + if (codec.hasAudio && audioFeeder) { + // Drive on the audio clock! + audioState = audioFeeder.getPlaybackState(); + playbackPosition = getPlaybackTime(audioState); + + audioBufferedDuration = (audioState.samplesQueued / audioFeeder.targetRate); + //audioBufferedDuration = audioEndTimestamp - playbackPosition; // @fixme? + + //console.log('audio buffered', audioBufferedDuration, audioDecodingDuration); + + droppedAudio = audioState.dropped; + delayedAudio = audioState.delayed; + //readyForAudioDecode = audioState.samplesQueued <= (audioFeeder.bufferSize * 2); + var bufferDuration = (audioFeeder.bufferSize / audioFeeder.targetRate) * 2; + readyForAudioDecode = codec.audioReady && (audioBufferedDuration <= bufferDuration); + + // Check in when all audio runs out + if (pendingAudio) { + // We'll check in when done decoding + } else if (!codec.audioReady) { + // NEED MOAR BUFFERS + nextDelays.push(-1); + } else if (codec.hasVideo && (playbackPosition - frameEndTimestamp) > bufferDuration) { + // don't get too far ahead of the video if it's slow! + readyForAudioDecode = false; + nextDelays.push((playbackPosition - frameEndTimestamp) * 1000); + } else { + // Check in when the audio buffer runs low again... + nextDelays.push((audioBufferedDuration - bufferDuration) * 1000); + + // @todo figure out why the above doesn't do the job reliably + // with Flash audio shim on IE! + nextDelays.push(bufferDuration * 1000 / 4); + } + } else { + // No audio; drive on the general clock. + // @fixme account for dropped frame times... + playbackPosition = getPlaybackTime(); + } + + if (codec.hasVideo) { + var fudgeDelta = 0.1, + frameDelay = (frameEndTimestamp - playbackPosition) * 1000; + + frameDelay = Math.max(0, frameDelay); + frameDelay = Math.min(frameDelay, targetPerFrameTime); + + readyForFrameDraw = !!yCbCrBuffer && !pendingFrame && (frameDelay <= fudgeDelta); + readyForFrameDecode = !yCbCrBuffer && !pendingFrame && codec.frameReady; + + if (yCbCrBuffer) { + // Check in when the decoded frame is due + nextDelays.push(frameDelay); + } else if (pendingFrame) { + // We'll check in when done decoding + } else if (!codec.frameReady) { + // need more data! + nextDelays.push(-1); + } else { + // Check in when the decoded frame is due + nextDelays.push(frameDelay); + } + } + + log([playbackPosition, frameEndTimestamp, audioEndTimestamp, readyForFrameDraw, readyForFrameDecode, readyForAudioDecode].join(', ')); + + if (readyForFrameDraw) { + + log('ready to draw frame'); + + // Ready to draw the decoded frame... + if (thumbnail) { + self.removeChild(thumbnail); + thumbnail = null; + } + + drawingTime += time(function() { + frameSink.drawFrame(yCbCrBuffer); + }); + yCbCrBuffer = null; + + framesProcessed++; + framesPlayed++; + + doFrameComplete(); + + pingProcessing(0); + + } else if (readyForFrameDecode) { + + log('ready to decode frame'); + + var videoStartTime = getTimestamp(); + pendingFrame++; + if (videoInfo.fps == 0 && (codec.frameTimestamp - frameEndTimestamp) > 0) { + // WebM doesn't encode a frame rate + targetPerFrameTime = (codec.frameTimestamp - frameEndTimestamp) * 1000; + } + totalFrameTime += targetPerFrameTime; + totalFrameCount++; + frameEndTimestamp = codec.frameTimestamp; + var pendingFramePing = false; + codec.decodeFrame(function processingDecodeFrame(ok) { + log('decoded frame'); + var delta = getTimestamp() - videoStartTime; + videoDecodingTime += delta; + lastFrameDecodeTime += delta; + if (ok) { + // Save the buffer until it's time to draw + yCbCrBuffer = codec.frameBuffer; + } else { + // Bad packet or something. + log('Bad video packet or something'); + } + pendingFrame--; + if (!isProcessing()) { + pingProcessing(); + } + }); + if (!isProcessing()) { + pingProcessing(); + } + + } else if (readyForAudioDecode) { + + log('ready for audio'); + + var audioStartTime = getTimestamp(); + pendingAudio++; + audioEndTimestamp = codec.audioTimestamp; + codec.decodeAudio(function processingDecodeAudio(ok) { + log('decoded audio'); + var delta = getTimestamp() - audioStartTime; + audioDecodingTime += delta; + lastFrameDecodeTime += delta; + + if (ok) { + var buffer = codec.audioBuffer; + if (buffer) { + // Keep track of how much time we spend queueing audio as well + // This is slow when using the Flash shim on IE 10/11 + bufferTime += time(function() { + audioFeeder.bufferData(buffer); + }); + audioBufferedDuration += (buffer[0].length / audioInfo.rate) * 1000; + } + } + pendingAudio--; + if (!isProcessing()) { + pingProcessing(); + } + }); + if (!isProcessing()) { + pingProcessing(); + } + + } else { + + var nextDelay = Math.min.apply(Math, nextDelays); + if (nextDelays.length > 0) { + log('idle: ' + nextDelay + ' - ' + nextDelays.join(',')); + if (!codec.hasVideo) { + framesProcessed++; // pretend! + doFrameComplete(); + } + pingProcessing(Math.max(0, nextDelay)); + } else if (pendingFrame || pendingAudio) { + log('waiting on pending events'); + } else { + log('we may be lost'); + } + } + } + } + }); + + } else { + + throw new Error('Unexpected OGVPlayer state ' + state); + + } + + depth--; + } + + /** + * Are we waiting on an async operation we can't interrupt? + */ + function isProcessing() { + return waitingOnInput || (codec && codec.processing); + } + + function readBytesAndWait() { + waitingOnInput = true; + stream.readBytes(); + } + + function pingProcessing(delay) { + if (delay === undefined) { + delay = -1; + } + if (isProcessing()) { + throw new Error('REENTRANCY FAIL: asked to pingProcessing() while already waiting'); + } + if (nextProcessingTimer) { + //log('canceling old processing timer'); + clearTimeout(nextProcessingTimer); + nextProcessingTimer = null; + } + var fudge = -1 / 256; + if (delay > fudge) { + //log('pingProcessing delay: ' + delay); + nextProcessingTimer = setTimeout(doProcessing, delay); + } else { + //log('pingProcessing tail call (' + delay + ')'); + tailCall(doProcessing); + } + } + + var videoInfo, + audioInfo; + + function startProcessingVideo() { + if (started || codec) { + return; + } + + framesProcessed = 0; + demuxingTime = 0; + videoDecodingTime = 0; + audioDecodingTime = 0; + bufferTime = 0; + drawingTime = 0; + started = true; + ended = false; + + codec = new codecClass(codecOptions); + codec.init(function() { + readBytesAndWait(); + }); + } + + function loadCodec(callback) { + // @todo use the demuxer and codec interfaces directly + codecClassName = 'OGVWrapperCodec'; + + // @todo fix detection proper + if (enableWebM && self.src.match(/\.webm$/i)) { + codecOptions.type = 'video/webm'; + } else { + codecOptions.type = 'video/ogg'; + } + + OGVLoader.loadClass(codecClassName, function(classObj) { + codecClass = classObj; + callback(); + }); + } + + /** + * HTMLMediaElement load method + */ + self.load = function() { + if (stream) { + // already loaded. + return; + } + + started = false; + stream = new StreamFile({ + url: self.src, + bufferSize: 65536 * 4, + onstart: function() { + // Fire off the read/decode/draw loop... + byteLength = stream.bytesTotal; + + // If we get X-Content-Duration, that's as good as an explicit hint + var durationHeader = stream.getResponseHeader('X-Content-Duration'); + if (typeof durationHeader === 'string') { + duration = parseFloat(durationHeader); + } + loadCodec(startProcessingVideo); + }, + onread: function(data) { + log('got input'); + waitingOnInput = false; + + // Save chunk to pass into the codec's buffer + actionQueue.push(function doReceiveInput() { + codec.receiveInput(data, function() { + pingProcessing(); + }); + }); + + if (isProcessing()) { + // We're waiting on the codec already... + } else { + pingProcessing(); + } + }, + ondone: function() { + waitingOnInput = false; + + if (state == State.SEEKING) { + pingProcessing(); + } else if (state == State.SEEKING_END) { + pingProcessing(); + } else { + log('closing stream (done)'); + stream = null; + + if (isProcessing()) { + // We're waiting on the codec already... + } else { + // Let the read/decode/draw loop know we're out! + pingProcessing(); + } + } + }, + onerror: function(err) { + console.log("reading error: " + err); + } + }); + }; + + /** + * HTMLMediaElement canPlayType method + */ + self.canPlayType = function(contentType) { + var type = new OGVMediaType(contentType); + if (type.minor === 'ogg' && + (type.major === 'audio' || type.major === 'video' || type.major === 'application')) { + if (type.codecs) { + var supported = ['vorbis', 'opus', 'theora'], + knownCodecs = 0, + unknownCodecs = 0; + type.codecs.forEach(function(codec) { + if (supported.indexOf(codec) >= 0) { + knownCodecs++; + } else { + unknownCodecs++; + } + }); + if (knownCodecs === 0) { + return ''; + } else if (unknownCodecs > 0) { + return ''; + } + // All listed codecs are ones we know. Neat! + return 'probably'; + } else { + return 'maybe'; + } + } else { + // @todo when webm support is more complete, handle it + return ''; + } + }; + + /** + * HTMLMediaElement play method + */ + self.play = function() { + if (!audioOptions.audioContext) { + OGVPlayer.initSharedAudioContext(); + } + + if (paused) { + startedPlaybackInDocument = document.body.contains(self); + + paused = false; + + if (started) { + + log('.play() while already started'); + + actionQueue.push(function() { + startPlayback(); + fireEvent('play'); + pingProcessing(0); + }); + if (isProcessing()) { + // waiting on the codec already + } else { + pingProcessing(); + } + + } else { + + log('.play() before started'); + + // Let playback begin when metadata loading is complete + if (!stream) { + self.load(); + } + + } + } + }; + + /** + * custom getPlaybackStats method + */ + self.getPlaybackStats = function() { + return { + targetPerFrameTime: targetPerFrameTime, + framesProcessed: framesProcessed, + playTime: playTime, + demuxingTime: demuxingTime, + videoDecodingTime: videoDecodingTime, + audioDecodingTime: audioDecodingTime, + bufferTime: bufferTime, + drawingTime: drawingTime, + droppedAudio: droppedAudio, + delayedAudio: delayedAudio, + jitter: totalJitter / framesProcessed + }; + }; + self.resetPlaybackStats = function() { + framesProcessed = 0; + playTime = 0; + demuxingTime = 0; + videoDecodingTime = 0; + audioDecodingTime = 0; + bufferTime = 0; + drawingTime = 0; + totalJitter = 0; + totalFrameTime = 0; + totalFrameCount = 0; + }; + + /** + * HTMLMediaElement pause method + */ + self.pause = function() { + if (!stream) { + paused = true; + self.load(); + } else if (!paused) { + clearTimeout(nextProcessingTimer); + nextProcessingTimer = null; + stopPlayback(); + paused = true; + fireEvent('pause'); + } + }; + + /** + * custom 'stop' method + */ + self.stop = function() { + stopVideo(); + }; + + /** + * HTMLMediaElement src property + */ + self.src = ""; + + /** + * HTMLMediaElement buffered property + */ + Object.defineProperty(self, "buffered", { + get: function getBuffered() { + var estimatedBufferTime; + if (stream && byteLength && duration) { + estimatedBufferTime = (stream.bytesBuffered / byteLength) * duration; + } else { + estimatedBufferTime = 0; + } + return new OGVTimeRanges([[0, estimatedBufferTime]]); + } + }); + + /** + * HTMLMediaElement seekable property + */ + Object.defineProperty(self, "seekable", { + get: function getSeekable() { + if (self.duration < Infinity && stream && stream.seekable && codec && codec.seekable) { + return new OGVTimeRanges([[0, duration]]); + } else { + return new OGVTimeRanges([]); + } + } + }); + + /** + * HTMLMediaElement currentTime property + */ + Object.defineProperty(self, "currentTime", { + get: function getCurrentTime() { + if (state == State.SEEKING) { + return seekTargetTime; + } else { + if (codec) { + if (state == State.PLAYING && !paused) { + return getPlaybackTime(); + } else { + return initialPlaybackOffset; + } + } else { + return 0; + } + } + }, + set: function setCurrentTime(val) { + if (stream && byteLength && duration) { + seek(val); + } + } + }); + + /** + * HTMLMediaElement duration property + */ + Object.defineProperty(self, "duration", { + get: function getDuration() { + if (codec && codec.loadedMetadata) { + if (duration !== null) { + return duration; + } else { + return Infinity; + } + } else { + return NaN; + } + } + }); + + /** + * HTMLMediaElement paused property + */ + Object.defineProperty(self, "paused", { + get: function getPaused() { + return paused; + } + }); + + /** + * HTMLMediaElement ended property + */ + Object.defineProperty(self, "ended", { + get: function getEnded() { + return ended; + } + }); + + /** + * HTMLMediaElement ended property + */ + Object.defineProperty(self, "seeking", { + get: function getEnded() { + return (state == State.SEEKING); + } + }); + + /** + * HTMLMediaElement muted property + */ + Object.defineProperty(self, "muted", { + get: function getMuted() { + return muted; + }, + set: function setMuted(val) { + muted = val; + if (audioFeeder) { + if (muted) { + audioFeeder.mute(); + } else { + audioFeeder.unmute(); + } + } + } + }); + + Object.defineProperty(self, "poster", { + get: function getPoster() { + return poster; + }, + set: function setPoster(val) { + poster = val; + if (!started) { + if (thumbnail) { + self.removeChild(thumbnail); + } + thumbnail = new Image(); + thumbnail.src = poster; + thumbnail.className = 'ogvjs-poster'; + thumbnail.style.position = 'absolute'; + thumbnail.style.top = '0'; + thumbnail.style.left = '0'; + thumbnail.style.width = '100%'; + thumbnail.style.height = '100%'; + thumbnail.style.objectFit = 'contain'; + thumbnail.addEventListener('load', function() { + OGVPlayer.styleManager.appendRule('.' + instanceId, { + width: thumbnail.naturalWidth + 'px', + height: thumbnail.naturalHeight + 'px' + }); + self.appendChild(thumbnail); + OGVPlayer.updatePositionOnResize(); + }); + } + } + }); + + // Video metadata properties... + Object.defineProperty(self, "videoWidth", { + get: function getVideoWidth() { + if (videoInfo) { + return videoInfo.displayWidth; + } else { + return 0; + } + } + }); + Object.defineProperty(self, "videoHeight", { + get: function getVideoHeight() { + if (videoInfo) { + return videoInfo.displayHeight; + } else { + return 0; + } + } + }); + Object.defineProperty(self, "ogvjsVideoFrameRate", { + get: function getOgvJsVideoFrameRate() { + if (videoInfo) { + if (videoInfo.fps == 0) { + return totalFrameCount / (totalFrameTime / 1000); + } else { + return videoInfo.fps; + } + } else { + return 0; + } + } + }); + + // Audio metadata properties... + Object.defineProperty(self, "ogvjsAudioChannels", { + get: function getOgvJsAudioChannels() { + if (audioInfo) { + return audioInfo.channels; + } else { + return 0; + } + } + }); + Object.defineProperty(self, "ogvjsAudioSampleRate", { + get: function getOgvJsAudioChannels() { + if (audioInfo) { + return audioInfo.rate; + } else { + return 0; + } + } + }); + + // Display size... + var width = 0, height = 0; + Object.defineProperty(self, "width", { + get: function getWidth() { + return width; + }, + set: function setWidth(val) { + width = parseInt(val, 10); + self.style.width = width + 'px'; + } + }); + + Object.defineProperty(self, "height", { + get: function getHeight() { + return height; + }, + set: function setHeight(val) { + height = parseInt(val, 10); + self.style.height = height + 'px'; + } + }); + + // Events! + + /** + * custom onframecallback, takes frame decode time in ms + */ + self.onframecallback = null; + + /** + * Called when all metadata is available. + * Note in theory we must know 'duration' at this point. + */ + self.onloadedmetadata = null; + + /** + * Called when we start playback + */ + self.onplay = null; + + /** + * Called when we get paused + */ + self.onpause = null; + + /** + * Called when playback ends + */ + self.onended = null; + + return self; +}; + +OGVPlayer.initSharedAudioContext = function() { + AudioFeeder.initSharedAudioContext(); +}; + +OGVPlayer.instanceCount = 0; + +function StyleManager() { + var self = this; + var el = document.createElement('style'); + el.type = 'text/css'; + el.textContent = 'ogvjs { display: inline-block; position: relative; }'; + document.head.appendChild(el); + + var sheet = el.sheet; + + self.appendRule = function(selector, defs) { + var bits = []; + for (var prop in defs) { + if (defs.hasOwnProperty(prop)) { + bits.push(prop + ':' + defs[prop]); + } + } + var rule = selector + '{' + bits.join(';') + '}'; + sheet.insertRule(rule, sheet.length - 1); + }; +} +OGVPlayer.styleManager = new StyleManager(); + +// IE 10/11 and Edge 12 don't support object-fit. +// Chrome 43 supports it but it doesn't work on <canvas>! +// Safari for iOS 8/9 supports it but positions our <canvas> incorrectly >:( +// Also just for fun, IE 10 doesn't support 'auto' sizing on canvas. o_O +//OGVPlayer.supportsObjectFit = (typeof document.createElement('div').style.objectFit === 'string'); +OGVPlayer.supportsObjectFit = false; +if (OGVPlayer.supportsObjectFit) { + OGVPlayer.updatePositionOnResize = function() { + // no-op + }; +} else { + OGVPlayer.updatePositionOnResize = function() { + function fixup(el, width, height) { + var container = el.offsetParent || el.parentNode, + containerAspect = container.offsetWidth / container.offsetHeight, + intrinsicAspect = width / height; + if (intrinsicAspect > containerAspect) { + var vsize = container.offsetWidth / intrinsicAspect, + vpad = (container.offsetHeight - vsize) / 2; + el.style.width = '100%'; + el.style.height = vsize + 'px'; + el.style.marginLeft = 0; + el.style.marginRight = 0; + el.style.marginTop = vpad + 'px'; + el.style.marginBottom = vpad + 'px'; + } else { + var hsize = container.offsetHeight * intrinsicAspect, + hpad = (container.offsetWidth - hsize) / 2; + el.style.width = hsize + 'px'; + el.style.height = '100%'; + el.style.marginLeft = hpad + 'px'; + el.style.marginRight = hpad + 'px'; + el.style.marginTop = 0; + el.style.marginBottom = 0; + } + } + function queryOver(selector, callback) { + var nodeList = document.querySelectorAll(selector), + nodeArray = Array.prototype.slice.call(nodeList); + nodeArray.forEach(callback); + } + + queryOver('ogvjs > canvas', function(canvas) { + fixup(canvas, canvas.width, canvas.height); + }); + queryOver('ogvjs > img', function(poster) { + fixup(poster, poster.naturalWidth, poster.naturalHeight); + }); + }; + var fullResizeVideo = function() { + // fullscreens may ping us before the resize happens + setTimeout(OGVPlayer.updatePositionOnResize, 0); + }; + + window.addEventListener('resize', OGVPlayer.updatePositionOnResize); + window.addEventListener('orientationchange', OGVPlayer.updatePositionOnResize); + + document.addEventListener('fullscreenchange', fullResizeVideo); + document.addEventListener('mozfullscreenchange', fullResizeVideo); + document.addEventListener('webkitfullscreenchange', fullResizeVideo); + document.addEventListener('MSFullscreenChange', fullResizeVideo); +} + + +// exports +this.OGVLoader = OGVLoader; +this.OGVMediaType = OGVMediaType; +this.OGVTimeRanges = OGVTimeRanges; +this.OGVPlayer = OGVPlayer; + +})(); + +this.OGVVersion = "1.0-20150904182230-dd3c8e8"; diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/readme.md b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/readme.md new file mode 100644 index 00000000..6d58ac6f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/readme.md @@ -0,0 +1,237 @@ +ogv.js +====== + +Media decoder and player for Ogg Vorbis/Opus/Theora and (experimentally) WebM video. + +Based around libogg, libvorbis, libtheora, libopus, libvpx, and libnestegg compiled to JavaScript with Emscripten. + +## Updates + +* 1.0 - 2015-09-04 + * initial stable release, as used on Wikipedia + +## Current status + +As of August 2015, ogv.js can be seen in action [on Wikipedia and Wikimedia Commons](https://commons.wikimedia.org/wiki/Commons:Video) in Safari and IE/Edge where native Ogg and WebM playback is not available. (See [technical details on MediaWiki integration](https://www.mediawiki.org/wiki/Extension:TimedMediaHandler/ogv.js).) + +See also a standalone demo with performance metrics at https://brionv.com/misc/ogv.js/demo/ + +* streaming: yes (with Range header) +* seeking: yes for Ogg (with Range header), no for WebM +* color: yes +* audio: yes, with a/v sync (requires Web Audio or Flash) +* background threading: yes (video, audio decoders in Workers) +* [GPU accelerated drawing: yes (WebGL)](https://github.com/brion/ogv.js/wiki/GPU-acceleration) +* GPU accelerated decoding: no +* SIMD acceleration: no +* controls: no (currently provided by demo or other UI harness) + +Ogg files are fairly well supported, but WebM is still very experimental. + + +## Goals + +Long-form goal is to create a drop-in replacement for the HTML5 video and audio tags which can be used for basic playback of Ogg Theora and Vorbis or WebM media on browsers that don't support Ogg or WebM natively. + +The API isn't quite complete, but works pretty well. + + +## Compatibility + +ogv.js requires a fast JS engine with typed arrays, and either Web Audio or Flash for audio playback. + +The primary target browsers are (testing 360p/30fps): +* Safari 6.1/7/8 on Mac OS X 10.7-10.10 +* Safari on iOS 8 64-bit +* Edge on Windows 10 desktop/tablet +* Internet Explorer 10/11 on Windows 7/8/8.1 (desktop/tablet) + +And for lower-resolution files (testing 160p/15fps): +* Safari on iOS 8 32-bit +* Edge on Windows 10 Mobile +* Internet Explorer 10/11 on Windows RT + +Older versions of Safari have flaky JIT compilers. IE 9 and below lack typed arrays. + +(Note that Windows and Mac OS X can support Ogg and WebM by installing codecs or alternate browsers with built-in support, but this is not possible on iOS, Windows RT, or Windows 10 Mobile.) + +Testing browsers (these support .ogv natively): +* Firefox 40 +* Chrome 44 + + +## Usage + +The `OGVPlayer` class implements a player, and supports a subset of the events, properties and methods from [HTMLMediaElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement) and [HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement). + +``` + // Create a new player with the constructor + var player = new OGVPlayer(); + + // Or with options + var player = new OGVPlayer({ + enableWebM: true + }); + + // Now treat it just like a video or audio element + containerElement.appendChild(player); + player.src = 'path/to/media.ogv'; + player.play(); + player.addEventListener('ended', function() { + // ta-da! + }); +``` + +To check for compatibility before creating a player, include `ogv-support.js` and use the `OGVCompat` API: + +``` + if (OGVCompat.supported('OGVPlayer')) { + // go load the full player from ogv.js and instantiate stuff + } +``` + +This will check for typed arrays, audio/Flash, blacklisted iOS versions, and super-slow/broken JIT compilers. + +If you need a URL versioning/cache-buster parameter for dynamic loading of `ogv.js`, you can use the `OGVVersion` symbol provided by `ogv-support.js` or the even tinier `ogv-version.js`: + +``` + var script = document.createElement('script'); + script.src = 'ogv.js?version=' + encodeURIComponent(OGVVersion); + document.querySelector('head').appendChild(script); +``` + +Usually, ogv.js will auto-detect the path to its resources based on the script element that loads ogv.js or ogv-support.js. If you load ogv.js through a non-customary bundler (such as MediaWiki's ResourceLoader) you may need to override this manually before instantiating players: + +``` + // Path to ogv-demuxer-ogg.js, ogv-worker-audio.js, dynamicaudio.swf etc + OGVLoader.base = '/path/to/resources'; +``` + + +## Performance + +As of 2015, for SD-or-less resolution basic Ogg Theora decoding speed is reliable on desktop and newer high-end mobile devices; current high-end desktops and laptops can even reach HD resolutions. Older and low-end mobile devices may have difficulty on any but audio and the lowest-resolution video files. + +WebM is much slower, and remains experimental. + +*Low-res targets* + +I've gotten acceptable performance for Vorbis audio and 160p/15fps Theora files on 32-bit iOS devices: iPhone 4s, iPod Touch 5th-gen and iPad 3. These have difficulty at 240p and above, and just won't keep up with higher resolutions. + +Meanwhile, newer 64-bit iPhones and iPads are comparable to low-end laptops, and videos at 360p and often 480p play acceptably. Since 32-bit and 64-bit iOS devices have the same user-agent, a benchmark must be used to approximately test minimum CPU speed. + +(On iOS 8, Safari performs significantly better than Chrome or other alternative browsers that are unable to enable the JIT due to iOS limitations on third-party developers. Again, a benchmark must be used to detect slow performance, as the browser remains otherwise compatible.) + + +Windows on 32-bit ARM platforms is similar... IE 11 on Windows RT 8.1 on a Surface tablet (NVidia Tegra 3), and Edge on Windows 10 Mobile build 10166 on a Lumia 635, perform acceptably with audio and with 160p/15fps videos but have trouble starting around 240p. + + +In both cases, a native application looms as a possibly better alternative. See [OGVKit ](https://github.com/brion/OGVKit) and [OgvRt](https://github.com/brion/OgvRT) projects for experiments in those directions. + + +Note that at these lower resolutions, Vorbis audio and Theora video decoding are about equally expensive operations -- dual-core phones and tablets should be able to eek out a little parallelism here thanks to audio and video being in separate Worker threads. + + +*WebGL drawing acceleration* + +Accelerated YCbCr->RGB conversion and drawing is done using WebGL on supporting browsers (Firefox, Chrome, IE 11, Edge, and Safari for iOS 8 & OS X 10.9), and is enabled by default if available. + +WebGL noticeably improves playback performance at HD and SD resolutions. + +Early versions of IE 11 do not support luminance or alpha textures, and in IE 11 update 1 and Edge they are still unexpectedly slow on Windows (in all browsers so far). As a workaround, on Windows the data is packed into RGBA textures for faster texture upload and unpacked in the shader. See [GPU acceleration page](https://github.com/brion/ogv.js/wiki/GPU-acceleration) for more info. + + +It may be possible to do further acceleration of actual decoding operations using WebGL shaders, but this could be ... tricky. WebGL is also only available on the main thread, and there are no compute shaders yet so would have to use fragment shaders. + + +## Difficulties + +*Threading* + +Currently the video and audio codecs run in worker threads by default, while the demuxer +and player logic run on the UI thread. This seems to work pretty well. + +There is some overhead in extracting data out of each emscripten module's heap and in the thread-to-thread communications, but the parallelism and smoother main thread makes up for it. + + +*Streaming download* + +In IE and Edge, the (MS-prefixed) Stream/StreamReader interface is used to read data on demand into ArrayBuffer objects. + +In Firefox, the 'moz-chunked-array' responseType on XHR is used to read data as ArrayBuffer chunks during download. Safari and Chrome use a 'binary string' read which requires manually converting input to ArrayBuffer chunks. + +The Firefox and Safari/Chrome cases have been hacked up to do streaming buffering by chunking the requests at up to a megabyte each, using the HTTP Range header. For cross-site playback, this requires CORS setup to whitelist the Range header! + +[Safari has a bug with Range headers](https://bugs.webkit.org/show_bug.cgi?id=82672) which is worked around as necessary with a 'cache-busting' URL string parameter. Hopefully this will be fixed in future versions of Mac OS X and iOS. + + +*Seeking* + +Seeking is implemented via the HTTP Range: header. + +For Ogg files with keyframe indices in a skeleton index, seeking is very fast. Otherwise, a bisection search is used to locate the target frame or audio position, which is very slow over the internet as it creates a lot of short-lived HTTP requests. + +For WebM files, seeking is not yet supported; this will require refactoring the demuxer modules to present a synchronous i/o abstraction to the demuxer library. + +As with chunked streaming, cross-site playback requires CORS support for the Range header. + + +*Audio output* + +Firefox, Safari, Chrome, and Edge support the W3C Web Audio API. + +IE doesn't support Web Audio, but does bundle the Flash player in Windows 8/8.1/RT. A small Flash shim is included here and used as a fallback -- thanks to Maik Merten for hacking some pieces together and getting this working! + +A/V synchronization is performed on files with both audio and video, and seems to +actually work. Yay! + +Note that autoplay doesn't work on iOS Safari due to limitations with starting audio playback from event handlers. + + +*WebM* + +WebM support was added in June 2015, and is currently very experimental. Not everything works yet, and performance is pretty bad. See [issue tracker for WebM milestone](https://github.com/brion/ogv.js/milestones/WebM%20playback) on the GitHub page. + +The i/o model of the nestegg WebM container demuxing library is a bit different from what ogv.js was designed around so seeking is not yet supported and it may sometimes cut off partway through a file. Needs more work. + +To enable, set `enableWebM: true` in your `options` array. + + +## Upstream library notes + +We've experimented with tremor (libivorbis), an integer-only variant of libvorbis. This actually does *not* decode faster, but does save about 200kb off our generated JavaScript, presumably thanks to not including an encoder in the library. However on slow devices like iPod Touch 5th-generation, it makes a significant negative impact on the decode time so we've gone back to libvorbis. + +The Ogg Skeleton library (libskeleton) is a bit ... unfinished and is slightly modified here. + + +## Building JS components + +Building ogv.js is known to work on Mac OS X and Linux (tested Ubuntu 15.04). + +1. You will need autoconf, automake, libtool, and pkg-config. These can be installed through Homebrew on Mac OS X, or through distribution-specific methods on Linux. +2. Install [Emscripten](http://kripken.github.io/emscripten-site/docs/getting_started/Tutorial.html); currently using the 1.34.1 SDK release for distribution builds. +3. `git submodule update --init` +4. Run `make js` to configure and build the libraries and the C wrapper + + +## Building Flash components + +Rebuilding dynamicaudio.swf shim for IE 10/11: + +1. Install [Apache Flex SDK](http://flex.apache.org/), and put it into PATH +2. `make swf` to rebuild src/dynamicaudio.swf +3. `make` to rebuild the demo and update its .swf + + +## Building the demo + +If you did all the setup above, just run `make demo` or `make`. Look in build/demo/ and enjoy! + + +## License + +libogg, libvorbis, libtheora, libopus, nestegg, and libvpx are available under their respective licenses, and the JavaScript and C wrapper code in this repo is licensed under MIT. + +Based on build scripts from https://github.com/devongovett/ogg.js + +dynamicaudio.as and other Flash-related bits are based on code under BSD license, (c) 2010 Ben Firshman (see src/AudioFeeder.js flash fallback section). diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/af.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/af.json new file mode 100644 index 00000000..14191ff4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/af.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Naudefj" + ] + }, + "mwe-embedplayer-credit-title": "Naam: $1", + "mwe-embedplayer-loading_plugin": "laai uitbreiding ...", + "mwe-embedplayer-add_to_end_of_sequence": "Voeg by aan die einde van die reeks", + "mwe-embedplayer-volume_control": "Volumebeheer", + "mwe-embedplayer-download": "Aflaai", + "mwe-embedplayer-share": "Deel", + "mwe-embedplayer-credits": "Krediete", + "mwe-embedplayer-menu_btn": "Keuses", + "mwe-embedplayer-close_btn": "Sluit", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-uitbreiding", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-selected": "(gekies)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-embed_site_or_blog": "Voeg by jou webblad of webjoernaal" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/aln.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/aln.json new file mode 100644 index 00000000..519ac9d6 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/aln.json @@ -0,0 +1,34 @@ +{ + "@metadata": { + "authors": [ + "Mdupont" + ] + }, + "mwe-embedplayer-share_this_video": "Share this video", + "mwe-embedplayer-video_credits": "kreditĆ« Video", + "mwe-embedplayer-kaltura-platform-title": "video Kaltura me burim tĆ« hapur platformĆ«n", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "AfĆ«r", + "mwe-embedplayer-ogg-player-vlc-player": "VLC player", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 lojtar ZQM", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 lojtar H.264", + "mwe-embedplayer-ogg-player-oggPlugin": "Generic Ogg plugin", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "lojtar Kaltura", + "mwe-embedplayer-ogg-player-selected": "(Zgjedhur)", + "mwe-embedplayer-ogg-player-omtkplayer": "Flash Vorbis OMTK", + "mwe-embedplayer-for_best_experience": "PĆ«r njĆ« pĆ«rvojĆ« mĆ« tĆ« mirĆ« video rishikim tĆ« kĆ«shillojmĆ« <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Firefox fundit</a> .", + "mwe-embedplayer-do_not_warn_again": "ShkarkojĆ« tani pĆ«r tani.", + "mwe-embedplayer-playerSelect": "Lojtaret", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Lexoni kete</a> para se embedding.", + "mwe-embedplayer-embed_site_or_blog": "Embed nĆ« njĆ« faqe", + "mwe-embedplayer-related_videos": "Related videos", + "mwe-embedplayer-seeking": "kĆ«rkojnĆ«", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-flv": "Flash video", + "mwe-embedplayer-video-ogg": "video Ogg", + "mwe-embedplayer-video-audio": "Ogg audio", + "mwe-embedplayer-missing-source": "Nuk ka video burim u gjet." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ar.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ar.json new file mode 100644 index 00000000..8f53df42 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ar.json @@ -0,0 +1,59 @@ +{ + "@metadata": { + "authors": [ + "Alzahrani", + "Meno25", + "OsamaK", + "Ų±ŁŲ®Ł" + ] + }, + "mwe-embedplayer-credit-title": "Ų¹ŁŁŲ§Ł: $1", + "mwe-embedplayer-credit-date": "ŲŖŲ§Ų±ŁŲ®: $1", + "mwe-embedplayer-credit-author": "Ų§ŁŁ
Ų¤ŁŁ: $1", + "mwe-embedplayer-loading_plugin": "ŲŖŲŁ
ŁŁ Ł
ŁŲŁ...", + "mwe-embedplayer-select_playback": "ŲŖŲ¹ŁŁŁ ŲŖŁŲ¶ŁŁŲ§ŲŖ Ų§ŁŲŖŲ“ŲŗŁŁ", + "mwe-embedplayer-add_to_end_of_sequence": "Ų£Ų¶Ł Ų„ŁŁ ŁŁŲ§ŁŲ© Ų§ŁŲ³ŁŲ³ŁŲ©", + "mwe-embedplayer-missing_video_stream": "Ł
ŁŁ Ų§ŁŁŁŲÆŁŁ ŁŁŲ°Ų§ Ų§ŁŁŲ³Ł Ł
ŁŁŁŲÆ", + "mwe-embedplayer-play_clip": "Ų“ŲŗŁŁ Ų§ŁŁ
ŁŲ·Ų¹", + "mwe-embedplayer-pause_clip": "Ų£ŁŲØŲ« Ų§ŁŁ
ŁŲ·Ų¹", + "mwe-embedplayer-volume_control": "Ų§ŁŲŖŲŁŁ
ŲØŲŲ¬Ł
Ų§ŁŲµŁŲŖ", + "mwe-embedplayer-player_options": "Ų®ŁŲ§Ų±Ų§ŲŖ Ų§ŁŁ
ŁŲ“ŲŗŁŁ", + "mwe-embedplayer-player_fullscreen": "Ų§Ł
ŁŲ£ Ų§ŁŲ“Ų§Ų“Ų©", + "mwe-embedplayer-next_clip_msg": "Ų“ŲŗŁŁ Ų§ŁŁ
ŁŲ·Ų¹ Ų§ŁŲŖŲ§ŁŁ", + "mwe-embedplayer-prev_clip_msg": "Ų“ŲŗŁ Ų§ŁŁ
ŁŲ·Ų¹ Ų§ŁŲ³Ų§ŲØŁ", + "mwe-embedplayer-current_clip_msg": "Ł
ŲŖŲ§ŲØŲ¹Ų© ŲŖŲ“ŲŗŁŁ ŁŲ°Ų§ Ų§ŁŁ
ŁŲ·Ų¹", + "mwe-embedplayer-seek_to": "Ų§ŲØŲŲ« ŁŁ $1", + "mwe-embedplayer-paused": "Ų§ŁŁŲ§Ł Ł
Ų¤ŁŲŖ", + "mwe-embedplayer-download_segment": "ŁŲ²ŁŁ Ų§ŁŁ
ŲŲÆŲÆ:", + "mwe-embedplayer-download_full": "ŲŖŲŁ
ŁŁ ŁŲ§Ł
Ł Ł
ŁŁ Ų§ŁŁŁŲÆŁŁ:", + "mwe-embedplayer-download_right_click": "ŁŲŖŲŁ
ŁŁ, Ų§Ų¶ŲŗŲ· ŲØŲ²Ų± Ų§ŁŁŲ§Ų±Ų© Ų§ŁŲ§ŁŁ
Ł ŁŲ§Ų®ŲŖŲ± <i>ŲŁŲø Ų§ŁŲ±Ų§ŲØŲ· ŁŁ...</i>", + "mwe-embedplayer-download_clip": "ŁŲ²ŁŁ Ų§ŁŁŁŲÆŁŁ", + "mwe-embedplayer-download_text": "ŲŖŲŁ
ŁŁ Ų§ŁŁŲµ", + "mwe-embedplayer-download": "ŁŲ²ŁŁ", + "mwe-embedplayer-share": "Ł
Ų“Ų§Ų±ŁŲ©", + "mwe-embedplayer-about-library": "Ų¹Ł Ł
Ų“ŲŗŁ ŁŲ§ŁŲ“ŁŲ±Ų§", + "mwe-embedplayer-clip_linkback": "ŲµŁŲŲ© Ł
ŲµŲÆŲ± Ų§ŁŁ
ŁŲ·Ų¹", + "mwe-embedplayer-choose_player": "Ų§Ų®ŲŖŲ± Ł
Ų“ŲŗŁ Ų§ŁŁŁŲÆŁŁ", + "mwe-embedplayer-no-player": "ŁŲ§ ŁŁŲ¬ŲÆ Ł
Ų“ŲŗŁ ŁŁ $1", + "mwe-embedplayer-share_this_video": "Ų“Ų§Ų±Ł ŁŲ°Ų§ Ų§ŁŁŁŲÆŁŁ", + "mwe-embedplayer-kaltura-platform-title": "ŁŲ§ŁŲ“ŁŲ±Ų§ Ł
ŁŲµŲ© ŁŁŲÆŁŁ Ł
ŁŲŖŁŲŲ© Ų§ŁŁ
ŲµŲÆŲ±", + "mwe-embedplayer-menu_btn": "ŁŲ§Ų¦Ł
Ų©", + "mwe-embedplayer-close_btn": "Ų£ŲŗŁŁ", + "mwe-embedplayer-ogg-player-vlc-player": "Ų§ŁŁ
Ų“ŲŗŁ VLC", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Ų§Ų¶Ų§ŁŲ© ŁŲØŲ±ŁŲ§Ł
Ų¬ ŁŁŁŁ ŲŖŲ§ŁŁ
", + "mwe-embedplayer-ogg-player-cortado": "Ų¬Ų§ŁŲ§ ŁŁŲ±ŲŖŲ§ŲÆŁ", + "mwe-embedplayer-ogg-player-kplayer": "Ł
Ų“ŲŗŁ ŁŲ§ŁŲ“ŁŲ±Ų§", + "mwe-embedplayer-ogg-player-selected": "(Ł
Ų®ŲŖŲ§Ų±)", + "mwe-embedplayer-for_best_experience": "ŁŁŲŲµŁŁ Ų¹ŁŁ Ų£ŁŲ¶Ł ŲŖŲ¬Ų±ŲØŲ© ŁŲ¹Ų±Ų¶ Ų§ŁŁŁŲÆŁŁ ŁŲŁ ŁŁŲµŲ ŲØŁ <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Ł
Ų³ŲŖŲ¹Ų±Ų¶ HTML5 ŁŁŁŁŲÆŁŁ</a>", + "mwe-embedplayer-fullscreen-tip": "Ų§Ų¶ŲŗŲ· <b>F11</b> ŁŲŖŲØŲÆŁŁ <i>Ł
ŲŖŲµŁŲ Ų§ŁŁŲØ</i> ŁŁŲ¶Ų¹ Ų§ŁŲ“Ų§Ų“Ų© Ų§ŁŁŲ§Ł
ŁŲ©", + "mwe-embedplayer-fullscreen-tip-osx": "Ų§Ų¶ŲŗŲ· <b>shift ā F</b> ŁŁŲ¶Ų¹ Ų“Ų§Ų“Ų© ŁŲ§Ł
ŁŲ©", + "mwe-embedplayer-do_not_warn_again": "ŁŲ§ ŲŖŲøŁŲ± ŁŲ°Ł Ų§ŁŲ±Ų³Ų§ŁŲ© ŁŁ Ų§ŁŁ
Ų±Ų© Ų§ŁŁŲ§ŲÆŁ
Ų©", + "mwe-embedplayer-playerSelect": "ŁŲ§Ų¹ŲØŁŁ", + "mwe-embedplayer-related_videos": "ŁŁŲÆŁŁŁŲ§ŲŖ Ų°Ų§ŲŖ ŲµŁŲ©", + "mwe-embedplayer-video-h264": "ŁŁŲÆŁŁ ŲØŲŖŲ±Ł
Ų² H.264", + "mwe-embedplayer-video-webm": "ŁŁŲÆŁŁ ŲØŲŖŲ±Ł
Ų² WebM", + "mwe-embedplayer-video-flv": "ŁŁŲ§Ų“ ŁŁŲÆŁŁ", + "mwe-embedplayer-video-ogg": "ŁŁŲÆŁŁ ŲØŲŖŲ±Ł
Ų² Ogg", + "mwe-embedplayer-video-audio": "ŲµŁŲŖ ŲØŲŖŲ±Ł
Ų² Ogg", + "mwe-embedplayer-missing-source": "ŁŁ
ŁŲ¹Ų«Ų± Ų¹ŁŁ Ł
ŲµŲÆŲ± Ų§ŁŁŁŲÆŁŁ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/arc.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/arc.json new file mode 100644 index 00000000..ef336c30 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/arc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Basharh" + ] + }, + "mwe-embedplayer-credit-author": "Ü£ÜÜÜ”Ü: $1" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ast.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ast.json new file mode 100644 index 00000000..1745c4fb --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ast.json @@ -0,0 +1,89 @@ +{ + "@metadata": { + "authors": [ + "Xuacu" + ] + }, + "mwe-embedplayer-credit-title": "TĆtulu: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "Nun hai crĆ©ditos disponibles", + "mwe-embedplayer-loading_plugin": "Cargando complementu...", + "mwe-embedplayer-select_playback": "Configurar preferencies de reproducciĆ³n", + "mwe-embedplayer-link_back": "Enllazar de vuelta", + "mwe-embedplayer-error_swap_vid": "Error: mwEmbed nun pudo intercambiar la etiqueta de videu pa la interfaz de mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Amestar al final de la secuencia", + "mwe-embedplayer-missing_video_stream": "Falta'l ficheru de videu d'esta canal", + "mwe-embedplayer-play_clip": "Reproducir clip", + "mwe-embedplayer-pause_clip": "Posar clip", + "mwe-embedplayer-volume_control": "Control de volume", + "mwe-embedplayer-player_options": "Opciones del reproductor", + "mwe-embedplayer-timed_text": "Testu sincronizĆ”u", + "mwe-embedplayer-player_fullscreen": "Pantalla completa", + "mwe-embedplayer-next_clip_msg": "Reproducir el siguiente clip", + "mwe-embedplayer-prev_clip_msg": "Reproducir el clip anterior", + "mwe-embedplayer-current_clip_msg": "Siguir reproduciendo esti clip", + "mwe-embedplayer-seek_to": "Buscar $1", + "mwe-embedplayer-paused": "en pausa", + "mwe-embedplayer-download_segment": "Descargar seleiciĆ³n:", + "mwe-embedplayer-download_full": "Descargar el ficheru de videu completu:", + "mwe-embedplayer-download_right_click": "Pa descargar, faiga click col botĆ³n drechu y seleicione <i>Guardar enllaz como...</i>", + "mwe-embedplayer-download_clip": "Descargar el videu", + "mwe-embedplayer-download_text": "Descargar testu", + "mwe-embedplayer-download": "Descargar", + "mwe-embedplayer-share": "Compartir", + "mwe-embedplayer-credits": "CrĆ©ditos", + "mwe-embedplayer-about-library": "Tocante al reproductor Kaltura", + "mwe-embedplayer-about-library-desc": "La biblioteca HTML5 de Kaltura permite-y aprovechar gĆ¼ei les etiquetes de HTML5 <video> y <audio> con una interfaz de reproductor constante ente los navegadores mĆ”s importantes.\n\t\n[$1 MĆ”s informaciĆ³n sobro la biblioteca del reproductor Kaltura].", + "mwe-embedplayer-clip_linkback": "PĆ”xina d'orixe del clip", + "mwe-embedplayer-choose_player": "Escoyer el reproductor de videu", + "mwe-embedplayer-no-player": "Nun hai nengĆŗn reproductor disponible pa $1", + "mwe-embedplayer-share_this_video": "Compartir esti videu", + "mwe-embedplayer-video_credits": "CrĆ©ditos del videu", + "mwe-embedplayer-no-video_credits": "Nun hai crĆ©ditos disponibles", + "mwe-embedplayer-kaltura-platform-title": "Plataforma de videu de cĆ³digu abiertu Kaltura", + "mwe-embedplayer-menu_btn": "MenĆŗ", + "mwe-embedplayer-close_btn": "Zarrar", + "mwe-embedplayer-ogg-player-vlc-player": "Reproductor VLC", + "mwe-embedplayer-ogg-player-oggNative": "Reproductor Ogg HTML5", + "mwe-embedplayer-ogg-player-mp3Native": "Reproductor MP3 HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Reproductor AAC HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Reproductor H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Reproductor WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Complementu Ogg xenĆ©ricu", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "app VLC pa iOS", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Complementu QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Reproductor Kaltura", + "mwe-embedplayer-ogg-player-selected": "(seleicionĆ”u)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Pa una meyor esperiencia de reproducciĆ³n de videu recomendamos un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navegador de videu HTML5</a>.", + "mwe-embedplayer-download-warn": "Nun se detectĆ³ nengĆŗn reproductor compatible integrĆ”u col navegador: pa una reproducciĆ³n integrada nel navegador, descargue la [$1 Ćŗltima versiĆ³n de Firefox]", + "mwe-embedplayer-fullscreen-tip": "Calque <b>F11</b> pa conmutar la pantalla completa del <i>navegador web</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Calque <b>mayĆŗs ā F</b> pa conmutar la pantalla completa", + "mwe-embedplayer-do_not_warn_again": "Nun amosar esti mensaxe nel futuru", + "mwe-embedplayer-playerSelect": "Reproductores", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Llea esto</a> enantes d'inxertar.", + "mwe-embedplayer-embed_site_or_blog": "Inxertar nuna pĆ”xina", + "mwe-embedplayer-embed_wiki": "Inxertar nuna wiki", + "mwe-embedplayer-related_videos": "Videos rellacionaos", + "mwe-embedplayer-seeking": "buscando", + "mwe-embedplayer-buffering": "cargando nel bĆŗfer", + "mwe-embedplayer-video-h264": "Videu H.264", + "mwe-embedplayer-video-webm": "Videu WebM", + "mwe-embedplayer-video-flv": "Videu Flash", + "mwe-embedplayer-video-ogg": "Videu Ogg", + "mwe-embedplayer-video-audio": "SonĆu Ogg", + "mwe-embedplayer-audio-mpeg": "SonĆu MPEG", + "mwe-embedplayer-video-3gp": "Videu 3GP", + "mwe-embedplayer-video-mpeg": "Videu MPEG", + "mwe-embedplayer-video-msvideo": "Videu AVI", + "mwe-embedplayer-missing-source": "Nun s'alcontrĆ³'l videu orixinal.", + "mwe-embedplayer-vlcapp-intro": "Pa ver videos d'esti sitiu nun iPhone o iPad, necesites la $1 de baldre.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "app VLC", + "mwe-embedplayer-vlcapp-downloadapp": "Descarga la app VLC dende la App Store", + "mwe-embedplayer-vlcapp-openvideo": "Abri esti videu na app VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "Descarga esti videu", + "mwe-embedplayer-vlcapp-vlcapppopup": "Pa reproducir videos d'esti sitiu, necesites la app de baldre VLC. ĀæInstalala agora?" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/az.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/az.json new file mode 100644 index 00000000..7ad7f7de --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/az.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Cekli829" + ] + }, + "mwe-embedplayer-credit-date": "Tarix: $1", + "mwe-embedplayer-credit-author": "MĆ¼Éllif: $1", + "mwe-embedplayer-download": "YĆ¼klÉ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ba.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ba.json new file mode 100644 index 00000000..9a304406 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ba.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Haqmar" + ] + }, + "mwe-embedplayer-video-h264": "H.264 Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-webm": "WebM Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-flv": "Flash Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-ogg": "Ogg Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-audio": "Ogg Š°ŃŠ“ŠøŠ¾", + "mwe-embedplayer-audio-mpeg": "MPEG Š°ŃŠ“ŠøŠ¾", + "mwe-embedplayer-video-3gp": "3GP Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-mpeg": "MPEG Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-msvideo": "AVI Š²ŠøŠ“ŠµŠ¾" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/be-tarask.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/be-tarask.json new file mode 100644 index 00000000..6b26cd9f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/be-tarask.json @@ -0,0 +1,86 @@ +{ + "@metadata": { + "authors": [ + "EugeneZelenko", + "Jim-by", + "Wizardist", + "Zedlik" + ] + }, + "mwe-embedplayer-credit-title": "ŠŠ°Š·Š²Š°: $1", + "mwe-embedplayer-credit-date": "ŠŠ°ŃŠ°: $1", + "mwe-embedplayer-credit-author": "ŠŃŃŠ°Ń: $1", + "mwe-embedplayer-nocredits": "ŠŃŠ²ŠµŃŃŠ°Šŗ ŠæŃŠ° Š°ŃŃŠ°ŃŠ°Ń Š½ŃŠ¼Š°", + "mwe-embedplayer-loading_plugin": "ŠŠ°Š³ŃŃŠ¶Š°ŠµŃŃŠ° Š“Š°ŠæŠ°ŃŠ½ŠµŠ½ŃŠ½Šµ ā¦", + "mwe-embedplayer-select_playback": "Š£ŃŃŠ°Š½Š°Š²ŃŃŃ Š½Š°ŃŃŃŠ¾Š¹ŠŗŃ ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š½ŃŠ½Ń", + "mwe-embedplayer-link_back": "ŠŠ“Š²Š°ŃŠ¾ŃŠ½Š°Ń ŃŠæŠ°ŃŃŠ»ŠŗŠ°", + "mwe-embedplayer-error_swap_vid": "ŠŠ°Š¼ŃŠ»ŠŗŠ°: mwEmbed Š½Ń Š·Š¼Š¾Š³ ŠæŠ°Š¼ŃŠ½ŃŃŃ Š²ŃŠ“ŃŠ° ŃŃŠ³ Š“Š»Ń ŃŠ½ŃŃŃŃŃŠ¹ŃŃ mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "ŠŠ°Š“Š°ŃŃ Ń ŠŗŠ°Š½ŠµŃ ŠæŠ°ŃŃŠ»ŃŠ“Š¾ŃŠ½Š°ŃŃŃŃ", + "mwe-embedplayer-missing_video_stream": "ŠŃŠ“ŃŠ°-ŃŠ°Š¹Š» Š“Š»Ń Š³ŃŃŠ°Š³Š° ŃŃŃŃŠ¼ŠµŠ½Ń Š°Š“ŃŃŃŠ½ŃŃŠ°Šµ", + "mwe-embedplayer-play_clip": "ŠŃŠ°Š¹Š³ŃŠ°ŃŃ ŠŗŠ»ŃŠæ", + "mwe-embedplayer-pause_clip": "ŠŃŃŠæŃŠ½ŃŃŃ ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š½ŃŠ½Šµ", + "mwe-embedplayer-volume_control": "Š ŃŠ³ŃŠ»ŃŠ²Š°Š½ŃŠ½Šµ Š³ŃŃŠ½Š°ŃŃŃŃ", + "mwe-embedplayer-player_options": "ŠŠ°Š»Š°Š“Ń ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗŠ°", + "mwe-embedplayer-timed_text": "Š”ŃŠ½Ń
ŃŠ°Š½ŃŠ·Š°Š²Š°Š½Ń ŃŃŠŗŃŃ", + "mwe-embedplayer-player_fullscreen": "ŠŠ° ŃŠ²ŠµŃŃ ŃŠŗŃŠ°Š½", + "mwe-embedplayer-next_clip_msg": "ŠŃŠ°Š¹Š³ŃŠ°ŃŃ Š½Š°ŃŃŃŠæŠ½Ń ŠŗŠ»ŃŠæ", + "mwe-embedplayer-prev_clip_msg": "ŠŃŠ°Š¹Š³ŃŠ°ŃŃ ŠæŠ°ŠæŃŃŃŠ“Š½Ń ŠŗŠ»ŃŠæ", + "mwe-embedplayer-current_clip_msg": "ŠŃŠ°ŃŃŠ³Š²Š°ŃŃ ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š½ŃŠ½Šµ Š³ŃŃŠ°Š¹ ŃŠ°ŃŃŠŗŃ ŃŠ°Š¹Š»Š°", + "mwe-embedplayer-seek_to": "ŠŠµŃŠ°Š¹ŃŃŃŃ Š“Š° $1", + "mwe-embedplayer-paused": "ŠæŠ°ŃŠ·Š°", + "mwe-embedplayer-download_segment": "ŠŃŠ±Š°Ń Š·Š°Š³ŃŃŠ·ŠŗŃ:", + "mwe-embedplayer-download_full": "ŠŠ°Š³ŃŃŠ·ŃŃŃ ŠæŠ¾ŃŠ½Ń Š²ŃŠ“ŃŠ°-ŃŠ°Š¹Š»:", + "mwe-embedplayer-download_right_click": "ŠŠ»Ń Š·Š°Š³ŃŃŠ·ŠŗŃ Š½Š°ŃŃŃŃŠ½ŃŃŠµ ŠæŃŠ°Š²ŃŃ ŠŗŠ½Š¾ŠæŠŗŃ Š¼ŃŃŠŗŃ Ń Š²ŃŠ±ŠµŃŃŃŠµ <i>ŠŠ°Ń
Š°Š²Š°ŃŃ ŃŠæŠ°ŃŃŠ»ŠŗŃ ŃŠŗā¦</i>", + "mwe-embedplayer-download_clip": "ŠŠ°Š³ŃŃŠ·ŃŃŃ Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-download_text": "ŠŠ°Š³ŃŃŠ·ŃŃŃ ŃŃŠŗŃŃ", + "mwe-embedplayer-download": "ŠŠ°Š³ŃŃŠ·ŃŃŃ", + "mwe-embedplayer-share": "ŠŃŠ°Š±ŃŃŃ Š°Š³ŃŠ»ŃŠ½ŃŠ¼", + "mwe-embedplayer-credits": "Š”ŃŠ²Š°ŃŠ°Š»ŃŠ½ŃŠŗŃ", + "mwe-embedplayer-about-library": "ŠŃŠ° ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ Kaltura", + "mwe-embedplayer-about-library-desc": "HTML5 Š¼ŃŠ“ŃŃ-Š±ŃŠ±Š»ŃŃŃŃŠŗŠ° Kaltura Š“Š°Š·Š²Š°Š»ŃŠµ ŠŠ°Š¼ Š²ŃŠŗŠ°ŃŃŃŃŠ¾ŃŠ²Š°ŃŃ ŠæŠµŃŠ°Š²Š°Š³Š°Š¼Ń HTML5 <code><nowiki><video></nowiki></code> Ń <code><nowiki><audio></nowiki></code> ŃŃŠ³Š°Ń ŃŠ¶Š¾ Š·Š°ŃŠ°Š·, Š· Š°Š“Š½Š¾Š»ŃŠŗŠ°Š²ŃŠ¼ ŃŠ½ŃŃŃŃŃŠ¹ŃŠ°Š¼ ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š½ŃŠ½Ń Š²Š° ŃŃŃŃ
Š°ŃŠ½Š¾ŃŠ½ŃŃ
Š±ŃŠ°ŃŠ·ŃŃŠ°Ń
.\n\t\n[$1 Š“Š°Š²ŠµŠ“Š°ŃŃŠ° Š±Š¾Š»ŠµŠ¹ ŠæŃŠ° Š±ŃŠ±Š»ŃŃŃŃŠŗŃ ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗŠ° Kaltura].", + "mwe-embedplayer-clip_linkback": "ŠŃŃŠ½ŃŃŠ½Š°Ń ŃŃŠ°ŃŠ¾Š½ŠŗŠ° ŃŠ°ŃŃŠŗŃ ŃŠ°Š¹Š»Š°", + "mwe-embedplayer-choose_player": "ŠŃŠ±ŠµŃŃŃŠµ Š²ŃŠ“ŃŠ°-ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ", + "mwe-embedplayer-no-player": "ŠŃŠ¼Š° ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗŠ° Š“Š»Ń $1", + "mwe-embedplayer-share_this_video": "ŠŃŠ°Š±ŃŃŃ Š³ŃŃŠ°Šµ Š²ŃŠ“ŃŠ° Š°Š³ŃŠ»ŃŠ½ŃŠ¼", + "mwe-embedplayer-video_credits": "Š”ŃŠ²Š°ŃŠ°Š»ŃŠ½ŃŠŗŃ Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-no-video_credits": "ŠŃŠ²ŠµŃŃŠ°Šŗ ŠæŃŠ° Š°ŃŃŠ°ŃŠ°Ń Š½ŃŠ¼Š°", + "mwe-embedplayer-kaltura-platform-title": "ŠŃŠ“ŃŠ°-ŠæŠ»ŃŃŃŠ¾ŃŠ¼Š° Š· Š²Š¾Š»ŃŠ½ŃŠ¼ ŠŗŃŃŠ½ŃŃŠ½ŃŠ¼ ŠŗŠ¾Š“Š°Š¼ Kaltura", + "mwe-embedplayer-menu_btn": "ŠŃŠ½Ń", + "mwe-embedplayer-close_btn": "ŠŠ°ŠŗŃŃŃŃ", + "mwe-embedplayer-ogg-player-vlc-player": "ŠŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ VLC", + "mwe-embedplayer-ogg-player-oggNative": "ŠŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ HTML5 Ogg", + "mwe-embedplayer-ogg-player-mp3Native": "ŠŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ HTML5 MP3", + "mwe-embedplayer-ogg-player-aacNative": "ŠŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ HTML5 AAC", + "mwe-embedplayer-ogg-player-h264Native": "ŠŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "ŠŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "ŠŠ³ŃŠ»ŃŠ½Š°Šµ Š“Š°ŠæŠ°ŃŠ½ŠµŠ½ŃŠ½Šµ Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "ŠŠ°ŠæŠ°ŃŠ½ŠµŠ½ŃŠ½Šµ QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "ŠŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ Kaltura", + "mwe-embedplayer-ogg-player-selected": "(Š²ŃŠ±ŃŠ°Š½Ń)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "ŠŠ»Ń Š»ŠµŠæŃŠ°Š³Š° ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š½ŃŠ½Ń Š²ŃŠ“ŃŠ° Š¼Ń ŃŃŠŗŠ°Š¼ŃŠ½Š“ŃŠµŠ¼ <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Š±ŃŠ°ŃŠ·ŃŃ Š· ŠæŠ°Š“ŃŃŃŠ¼ŠŗŠ°Š¹ HTML5-Š²ŃŠ“ŃŠ°</a>.", + "mwe-embedplayer-download-warn": "ŠŃ Š·Š½Š¾Š¹Š“Š·ŠµŠ½Ń ŃŠ±ŃŠ“Š°Š²Š°Š½Ń ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ: Š“Š»Ń ŠæŃŠ°Š³Š»ŃŠ“Ń Ń Š±ŃŠ°ŃŠ·ŃŃŃ Š·Š°Š³ŃŃŠ·ŃŃŠµ [$1 Š°ŠæŠ¾ŃŠ½ŃŃ Š²ŃŃŃŃŃ Firefox]", + "mwe-embedplayer-fullscreen-tip": "ŠŠ»ŃŠ²ŃŃŠ° <b>F11</b> ŠæŠµŃŠ°ŠŗŠ»ŃŃŠ°Šµ <i>Š²ŃŠ±-Š±ŃŠ°ŃŠ·ŃŃ</i> Ń ŠæŠ¾ŃŠ½Š°ŃŠŗŃŠ°Š½Š½Ń ŃŃŠ¶ŃŠ¼", + "mwe-embedplayer-fullscreen-tip-osx": "ŠŠ°ŃŃŃŃŠ½ŃŃŠµ <b>shift ā F</b> Š“Š»Ń ŠæŠµŃŠ°Ń
Š¾Š“Ń Ń ŠæŠ¾ŃŠ½Š°ŃŠŗŃŠ°Š½Š½Ń ŃŃŠ¶ŃŠ¼", + "mwe-embedplayer-do_not_warn_again": "ŠŠµ ŠæŠ°ŠŗŠ°Š·Š²Š°ŃŃ Š³ŃŃŠ°Šµ ŠæŠ°Š²ŠµŠ“Š°Š¼Š»ŠµŠ½ŃŠ½Šµ Ń Š±ŃŠ“ŃŃŃŠ½Ń", + "mwe-embedplayer-playerSelect": "ŠŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗŃ", + "mwe-embedplayer-read_before_embed": "ŠŠ°Š»Ń Š»Š°ŃŠŗŠ°, <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ŠæŃŠ°ŃŃŃŠ°Š¹ŃŠµ Š³ŃŃŠ°</a> ŠæŠµŃŠ°Š“ ŃŃŃŠ°ŃŠŗŠ°Š¹!", + "mwe-embedplayer-embed_site_or_blog": "Š£ŃŃŠ°Š²ŃŃŃ Š½Š° ŃŃŠ°ŃŠ¾Š½ŠŗŃ", + "mwe-embedplayer-embed_wiki": "Š£ŃŃŠ°Š²ŃŃŃ Ń Š²ŃŠŗŃ", + "mwe-embedplayer-related_videos": "ŠŃŠ²ŃŠ·Š°Š½ŃŃ Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-seeking": "ŠæŠ¾ŃŃŠŗ", + "mwe-embedplayer-buffering": "Š±ŃŃŃŃŃŠ·Š°ŃŃŃ", + "mwe-embedplayer-video-h264": "H.264 Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-video-webm": "WebM Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-video-flv": "Flash-Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-video-ogg": "Ogg-Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-video-audio": "Ogg-Š°ŃŠ“ŃŃ", + "mwe-embedplayer-audio-mpeg": "MPEG-Š°ŃŠ“ŃŃ", + "mwe-embedplayer-video-3gp": "3GP-Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-video-mpeg": "MPEG-Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-video-msvideo": "AVI-Š²ŃŠ“ŃŠ°", + "mwe-embedplayer-missing-source": "ŠŃ Š·Š½Š¾Š¹Š“Š·ŠµŠ½Š° ŠŗŃŃŠ½ŃŃŠ½Š°Šµ Š²ŃŠ“ŃŠ°." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bg.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bg.json new file mode 100644 index 00000000..3402ed3f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bg.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ", + "DCLXVI" + ] + }, + "mwe-embedplayer-credit-title": "ŠŠ°Š³Š»Š°Š²ŠøŠµ: $1", + "mwe-embedplayer-credit-date": "ŠŠ°ŃŠ°: $1", + "mwe-embedplayer-credit-author": "ŠŠ²ŃŠ¾Ń: $1", + "mwe-embedplayer-close_btn": "ŠŠ°ŃŠ²Š°ŃŃŠ½Šµ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bho.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bho.json new file mode 100644 index 00000000..e19056b0 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bho.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Nepaboy" + ] + }, + "mwe-embedplayer-ogg-player-vlcAppPlayer": "ą¤ą¤ą¤ą¤ą¤ø ą¤ą¤Ŗą„ą¤²ą„ą¤ą„ą¤¶ą¤Ø ą¤ą¤¾ą¤¤ą¤æą¤° ą¤µą¤æą¤ą¤²ą¤øą„", + "mwe-embedplayer-vlcapp-vlcapplinktext": "ą¤µą¤æą¤ą¤²ą¤øą„ ą¤ą¤Ŗą„ą¤²ą„ą¤ą„ą¤¶ą¤Ø", + "mwe-embedplayer-vlcapp-downloadapp": "ą¤ą¤Ŗą„¦ ą¤øą„ą¤ą„ą¤° ą¤øą„ ą¤µą¤æą¤ą¤²ą¤øą„ ą¤ą¤Ŗą„¦ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤” ą¤ą¤°ą„ą¤", + "mwe-embedplayer-vlcapp-openvideo": "ą¤µą¤æą¤ą¤²ą¤øą„ ą¤ą¤Ŗą„¦ ą¤®ą„ą¤ ą¤ ą¤µą„ą¤”ą¤æą¤Æą„ ą¤ą„ą¤²ą„ą¤", + "mwe-embedplayer-vlcapp-downloadvideo": "ą¤ ą¤µą¤æą¤”ą¤æą¤Æą„ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤” ą¤ą¤°ą„ą¤", + "mwe-embedplayer-vlcapp-vlcapppopup": "ą¤ ą¤øą¤¾ą¤ą¤ ą¤Ŗą¤° ą¤µą„ą¤”ą¤æą¤Æą„ ą¤ą¤²ą¤¾ą¤µą„ ą¤ą¤¾ą¤¤ą¤æą¤°, ą¤ą¤Ŗ ą¤ą„ ą¤µą¤æą¤ą¤²ą¤øą„ ą¤ą¤Ŗą„¦ ą¤ą„ ą¤ą¤°ą„ą¤°ą¤¤ ą¤Ŗą¤”ą¤¼ą„ą„¤ ą¤
ą¤ą„ ą¤ą¤Øą¤øą„ą¤ą„ą¤² ą¤ą¤°ą¤¬?" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bn.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bn.json new file mode 100644 index 00000000..063989dc --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bn.json @@ -0,0 +1,74 @@ +{ + "@metadata": { + "authors": [ + "Aftab1995", + "Aftabuzzaman" + ] + }, + "mwe-embedplayer-credit-title": "ą¦¶ą¦æą¦°ą§ą¦Øą¦¾ą¦®: $1", + "mwe-embedplayer-credit-date": "ą¦¤ą¦¾ą¦°ą¦æą¦: $1", + "mwe-embedplayer-credit-author": "ą¦Ŗą§ą¦°ą¦£ą§ą¦¤ą¦¾: $1", + "mwe-embedplayer-nocredits": "ą¦ą§ą¦Ø ą¦ą§ą¦°ą§ą¦”ą¦æą¦ ą¦ą¦Ŗą¦²ą¦¬ą§ą¦§ ą¦Øą¦Æą¦¼", + "mwe-embedplayer-loading_plugin": "ą¦Ŗą§ą¦²ą¦¾ą¦ą¦ą¦Ø ą¦²ą§ą¦” ą¦¹ą¦ą§ą¦ą§ ...", + "mwe-embedplayer-select_playback": "ą¦Ŗą§ą¦²ą§ą¦¬ą§ą¦Æą¦¾ą¦ ą¦Ŗą¦ą¦Øą§ą¦¦ ą¦Øą¦æą¦°ą§ą¦§ą¦¾ą¦°ą¦£ ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-play_clip": "ą¦ą§ą¦²ą¦æą¦Ŗ ą¦ą¦¾ą¦²ą¦¾ą¦Ø", + "mwe-embedplayer-pause_clip": "ą¦ą§ą¦²ą¦æą¦Ŗ ą¦„ą¦¾ą¦®ą¦¾ą¦Ø", + "mwe-embedplayer-volume_control": "ą¦ą¦²ą¦æą¦ą¦® ą¦Øą¦æą¦Æą¦¼ą¦Øą§ą¦¤ą§ą¦°ą¦£", + "mwe-embedplayer-player_options": "ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦° ą¦
ą¦Ŗą¦¶ą¦Ø", + "mwe-embedplayer-timed_text": "ą¦ą¦¾ą¦ą¦®ą¦” ą¦ą§ą¦ą§ą¦øą¦", + "mwe-embedplayer-player_fullscreen": "ą¦Ŗą§ą¦°ą§ą¦£ ą¦øą§ą¦ą§ą¦°ą¦æą¦Ø", + "mwe-embedplayer-next_clip_msg": "ą¦Ŗą¦°ą¦¬ą¦°ą§ą¦¤ą§ ą¦ą§ą¦²ą¦æą¦Ŗ ą¦ą¦¾ą¦²ą¦¾ą¦Ø", + "mwe-embedplayer-prev_clip_msg": "ą¦Ŗą§ą¦°ą§ą¦¬ą¦¬ą¦°ą§ą¦¤ą§ ą¦ą§ą¦²ą¦æą¦Ŗ ą¦ą¦¾ą¦²ą¦¾ą¦Ø", + "mwe-embedplayer-current_clip_msg": "ą¦ą¦ ą¦ą§ą¦²ą¦æą¦Ŗ ą¦
ą¦¬ą¦æą¦°ą¦¤ ą¦ą¦¾ą¦²ą¦¾ą¦Ø", + "mwe-embedplayer-paused": "ą¦„ą¦¾ą¦®ą¦¾ą¦Øą§ ą¦¹ą¦Æą¦¼ą§ą¦ą§", + "mwe-embedplayer-download_segment": "ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦Øą¦æą¦°ą§ą¦¬ą¦¾ą¦ą¦Ø:", + "mwe-embedplayer-download_full_video": "ą¦øą¦®ą§ą¦Ŗą§ą¦°ą§ą¦£ ą¦ą¦æą¦”ą¦æą¦ ą¦«ą¦¾ą¦ą¦² ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą§ą¦Ø:", + "mwe-embedplayer-download_full_audio": "ą¦øą¦®ą§ą¦Ŗą§ą¦°ą§ą¦£ ą¦
ą¦”ą¦æą¦ ą¦«ą¦¾ą¦ą¦² ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą§ą¦Ø:", + "mwe-embedplayer-download_right_click": "ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą¦¤ą§, ą¦”ą¦¾ą¦Ø ą¦ą§ą¦²ą¦æą¦ ą¦ą¦°ą§ <i>Save link as...</i> ą¦Øą¦æą¦°ą§ą¦¬ą¦¾ą¦ą¦Ø ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-download_clip": "ą¦ą¦æą¦”ą¦æą¦ ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-download_text": "ą¦²ą§ą¦ą¦¾ ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-download": "ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦”", + "mwe-embedplayer-share": "ą¦¶ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-credits": "ą¦ą§ą¦¤ą¦æą¦¤ą§ą¦¬", + "mwe-embedplayer-about-library": "Kaltura ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦° ą¦øą¦®ą§ą¦Ŗą¦°ą§ą¦ą§", + "mwe-embedplayer-choose_player": "ą¦ą¦æą¦”ą¦æą¦ ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦° ą¦ą¦Æą¦¼ą¦Ø ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-no-player": "$1-ą¦ą¦° ą¦ą¦Øą§ą¦Æ ą¦ą§ą¦Ø ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦° ą¦ą¦Ŗą¦²ą¦¬ą§ą¦§ ą¦Øą§ą¦", + "mwe-embedplayer-video_credits": "ą¦ą¦æą¦”ą¦æą¦ ą¦ą§ą¦¤ą¦æą¦¤ą§ą¦¬", + "mwe-embedplayer-no-video_credits": "ą¦ą§ą¦Ø ą¦ą§ą¦¤ą¦æą¦¤ą§ą¦¬ ą¦ą¦Ŗą¦²ą¦¬ą§ą¦§ ą¦Øą¦Æą¦¼", + "mwe-embedplayer-menu_btn": "ą¦®ą§ą¦Øą§", + "mwe-embedplayer-close_btn": "ą¦¬ą¦Øą§ą¦§", + "mwe-embedplayer-ogg-player-vlc-player": "ą¦ą¦æą¦ą¦²ą¦øą¦æ ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3 ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-ogg-player-oggPlugin": "ą¦ą§ą¦Øą§ą¦°ą¦æą¦ ą¦
ą¦ ą¦Ŗą§ą¦²ą¦¾ą¦ą¦ą¦Ø", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "iOS ą¦
ą§ą¦Æą¦¾ą¦Ŗą§ą¦° ą¦ą¦Øą§ą¦Æ VLC", + "mwe-embedplayer-ogg-player-flowplayer": "ą¦«ą§ą¦²ą§ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-ogg-player-kplayer": "ą¦ą¦¾ą¦²ą¦ą§ą¦°ą¦¾ ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°", + "mwe-embedplayer-ogg-player-selected": "(ą¦Øą¦æą¦°ą§ą¦¬ą¦¾ą¦ą¦æą¦¤)", + "mwe-embedplayer-do_not_warn_again": "ą¦ą¦¬ą¦æą¦·ą§ą¦Æą¦¤ą§, ą¦ą¦ ą¦¬ą¦¾ą¦°ą§ą¦¤ą¦¾ ą¦Ŗą§ą¦°ą¦¦ą¦°ą§ą¦¶ą¦Ø ą¦ą¦°ą¦¬ą§ą¦Ø ą¦Øą¦¾", + "mwe-embedplayer-playerSelect": "ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦°ą¦ą§ą¦²ą¦æ", + "mwe-embedplayer-read_before_embed": "ą¦ą¦®ą§ą¦¬ą§ą¦” ą¦ą¦°ą¦¾ą¦° ą¦ą¦ą§ <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ą¦ą¦ą¦æ ą¦Ŗą¦”ą¦¼ą§ą¦Ø</a>ą„¤", + "mwe-embedplayer-embed_site_or_blog": "ą¦ą¦ą¦ą¦æ ą¦Ŗą¦¾ą¦¤ą¦¾ą¦Æą¦¼ ą¦ą¦®ą§ą¦¬ą§ą¦” ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-embed_wiki": "ą¦ą¦ą¦ą¦æ ą¦ą¦ą¦ą¦æą¦¤ą§ ą¦ą¦®ą§ą¦¬ą§ą¦” ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-related_videos": "ą¦øą¦®ą§ą¦Ŗą¦°ą§ą¦ą¦æą¦¤ ą¦ą¦æą¦”ą¦æą¦", + "mwe-embedplayer-buffering": "ą¦¬ą¦¾ą¦«ą¦¾ą¦°ą¦æą¦", + "mwe-embedplayer-video-h264": "H.264 ą¦ą¦æą¦”ą¦æą¦", + "mwe-embedplayer-video-webm": "WebM ą¦ą¦æą¦”ą¦æą¦", + "mwe-embedplayer-video-flv": "ą¦«ą§ą¦²ą§ą¦Æą¦¾ą¦¶ ą¦ą¦æą¦”ą¦æą¦", + "mwe-embedplayer-video-ogg": "ą¦
ą¦ ą¦ą¦æą¦”ą¦æą¦", + "mwe-embedplayer-video-audio": "ą¦
ą¦ ą¦
ą¦”ą¦æą¦", + "mwe-embedplayer-audio-mpeg": "ą¦ą¦®ą¦Ŗą¦æą¦ą¦ą¦æ ą¦
ą¦”ą¦æą¦", + "mwe-embedplayer-video-3gp": "ą§©ą¦ą¦æą¦Ŗą¦æ ą¦ą¦æą¦”ą¦æą¦", + "mwe-embedplayer-video-mpeg": "ą¦ą¦®ą¦Ŗą¦æą¦ą¦ą¦æ ą¦ą¦æą¦”ą¦æą¦", + "mwe-embedplayer-video-msvideo": "ą¦ą¦ą¦æą¦ą¦ ą¦ą¦æą¦”ą¦æą¦", + "mwe-embedplayer-missing-source": "ą¦ą§ą¦Ø ą¦ą§ą¦ø ą¦ą¦æą¦”ą¦æą¦ ą¦Ŗą¦¾ą¦ą¦Æą¦¼ą¦¾ ą¦Æą¦¾ą¦Æą¦¼ą¦Øą¦æ", + "mwe-embedplayer-vlcapp-intro": "ą¦ą¦ą¦ą¦æ ą¦ą¦ą¦«ą§ą¦Ø ą¦¬ą¦¾ ą¦ą¦ą¦Ŗą§ą¦Æą¦¾ą¦” ą¦„ą§ą¦ą§ ą¦ą¦ ą¦øą¦¾ą¦ą¦ą§ ą¦ą¦æą¦”ą¦æą¦ ą¦¦ą§ą¦ą¦¾ą¦° ą¦ą¦Øą§ą¦Æ, ą¦ą¦Ŗą¦Øą¦¾ą¦° ą¦¬ą¦æą¦Øą¦¾ą¦®ą§ą¦²ą§ą¦Æą§ą¦° $1 ą¦Ŗą§ą¦°ą¦Æą¦¼ą§ą¦ą¦Øą„¤", + "mwe-embedplayer-vlcapp-vlcapplinktext": "VLC ą¦
ą§ą¦Æą¦¾ą¦Ŗ", + "mwe-embedplayer-vlcapp-downloadapp": "ą¦
ą§ą¦Æą¦¾ą¦Ŗ ą¦øą§ą¦ą§ą¦° ą¦„ą§ą¦ą§ VLC ą¦
ą§ą¦Æą¦¾ą¦Ŗ ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-vlcapp-openvideo": "ą¦ą¦æą¦ą¦²ą¦øą¦æ ą¦
ą§ą¦Æą¦¾ą¦Ŗą§ ą¦ą¦ ą¦ą¦æą¦”ą¦æą¦ ą¦ą§ą¦²ą§ą¦Ø", + "mwe-embedplayer-vlcapp-downloadvideo": "ą¦ą¦ ą¦ą¦æą¦”ą¦æą¦ ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą§ą¦Ø", + "mwe-embedplayer-vlcapp-vlcapppopup": "ą¦ą¦ ą¦øą¦¾ą¦ą¦ą§ ą¦ą¦æą¦”ą¦æą¦ ą¦ą¦¾ą¦²ą¦¾ą¦Øą§ą¦° ą¦ą¦Øą§ą¦Æ, ą¦ą¦Ŗą¦Øą¦¾ą¦° ą¦¬ą¦æą¦Øą¦¾ą¦®ą§ą¦²ą§ą¦Æą§ą¦° ą¦ą¦æą¦ą¦²ą¦øą¦æ ą¦
ą§ą¦Æą¦¾ą¦Ŗą¦ą¦æ ą¦Ŗą§ą¦°ą¦Æą¦¼ą§ą¦ą¦Øą„¤ ą¦ą¦ą¦Ø ą¦ą¦Øą¦øą§ą¦ą¦² ą¦ą¦°ą¦¬ą§ą¦Ø?" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/br.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/br.json new file mode 100644 index 00000000..42ca1e35 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/br.json @@ -0,0 +1,76 @@ +{ + "@metadata": { + "authors": [ + "Fulup", + "Y-M D" + ] + }, + "mwe-embedplayer-credit-title": "Titl : $1", + "mwe-embedplayer-credit-date": "Deiziad : $1", + "mwe-embedplayer-credit-author": "Aozer : $1", + "mwe-embedplayer-loading_plugin": "O kargaƱ ar plugin...", + "mwe-embedplayer-select_playback": "TermeniƱ ar penndibaboĆ¹ lenn", + "mwe-embedplayer-link_back": "Liamm distreiƱ", + "mwe-embedplayer-error_swap_vid": "Fazi : n'eo ket deuet a-benn mwEmbed da eskemm doareenn ar video evit an etrefas mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "OuzhpennaƱ e dibenn ar sekaƱs", + "mwe-embedplayer-missing_video_stream": "Mankout a ra ar restr video evit ar gwazh-maƱ", + "mwe-embedplayer-play_clip": "Lenn ar c'hlip", + "mwe-embedplayer-pause_clip": "EhanaƱ ar c'hlip", + "mwe-embedplayer-volume_control": "Kontrol an tregern", + "mwe-embedplayer-player_options": "DibarzhioĆ¹ al lenner", + "mwe-embedplayer-timed_text": "Testenn o tibunaƱ", + "mwe-embedplayer-player_fullscreen": "Skramm leun", + "mwe-embedplayer-next_clip_msg": "Lenn ar c'hlip da-heul", + "mwe-embedplayer-prev_clip_msg": "Lenn ar c'hlip kent", + "mwe-embedplayer-current_clip_msg": "Kenderc'hel da lenn ar c'hlip-maƱ", + "mwe-embedplayer-seek_to": "Mont da $1", + "mwe-embedplayer-paused": "ehanet", + "mwe-embedplayer-download_segment": "PellgargaƱ an diuzadenn", + "mwe-embedplayer-download_full": "PellgargaƱ ar restr video a-bezh :", + "mwe-embedplayer-download_right_click": "Evit pellgargaƱ, grit ur c'hlik-dehou ha diuzit <i>EnrollaƱ an ere evel...</i>", + "mwe-embedplayer-download_clip": "PellgargaƱ ar video", + "mwe-embedplayer-download_text": "EnrollaƱ an destenn", + "mwe-embedplayer-download": "PellgargaƱ", + "mwe-embedplayer-share": "RannaƱ", + "mwe-embedplayer-credits": "KredoĆ¹", + "mwe-embedplayer-about-library": "Diwar-benn al lenner Kaltura", + "mwe-embedplayer-about-library-desc": "Talvezout a ra al levraoueg Kaltura deoc'h d'ober ho mad eus ar balizennoĆ¹ HTML5 <code><nowiki><video></nowiki></code> ha <code><nowiki><klevet></nowiki></code> diouzhtu gant ul lenner hag un etrefas kenglotus gant ar merdeerioĆ¹ pennaƱ.\n\t\n[$1 Evit gouzout hiroc'h diwar-benn al levraoueg lenn Kaltura].", + "mwe-embedplayer-clip_linkback": "Pajenn mammenn ar c'hlip", + "mwe-embedplayer-choose_player": "Dibab al lenner video", + "mwe-embedplayer-no-player": "N'eus lenner ebet hag a zo dieub evit $1", + "mwe-embedplayer-share_this_video": "RannaƱ ar video-maƱ", + "mwe-embedplayer-video_credits": "KredadoĆ¹ ar video", + "mwe-embedplayer-no-video_credits": "N'eus tamm kred ebet", + "mwe-embedplayer-kaltura-platform-title": "Savenn video e mammenn digor Kaltura", + "mwe-embedplayer-menu_btn": "LaƱser", + "mwe-embedplayer-close_btn": "SerriƱ", + "mwe-embedplayer-ogg-player-vlc-player": "Lenner VLC", + "mwe-embedplayer-ogg-player-oggNative": "Lenner Ogg HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Lenner H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Lenner WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Plugin hollek Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Plugin QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Lenner Kaltura", + "mwe-embedplayer-ogg-player-selected": "(diuzet)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Evit gwelet gwelloc'h e erbedadomp deoc'h : <br /><a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Firefox 3.5</a>.", + "mwe-embedplayer-download-warn": "N'eo ket kenglotus ar Merdeer web detektet; evit lenn er merdeer, pellgargit [$1 stumm nevez Firefox]", + "mwe-embedplayer-fullscreen-tip": "Pouezit war <b>F11</b> da wintaƱ e mod Skramm leun ar <i>merdeer web</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Pouezit war <b>pennlizh. ā F</b> evit gwintaƱ d'ar mod Skramm leun", + "mwe-embedplayer-do_not_warn_again": "Arabat diskouez ar gemennadenn-maƱ ken", + "mwe-embedplayer-playerSelect": "Lennerien", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Lennit an dra-maƱ</a> a-raok ober.", + "mwe-embedplayer-embed_site_or_blog": "EnframmaƱ en ur bajenn", + "mwe-embedplayer-related_videos": "VideoioĆ¹ liammet", + "mwe-embedplayer-seeking": "o klask", + "mwe-embedplayer-buffering": "o krubuilhaƱ", + "mwe-embedplayer-video-h264": "video H.264", + "mwe-embedplayer-video-webm": "Video WebM", + "mwe-embedplayer-video-flv": "video Flash", + "mwe-embedplayer-video-ogg": "video Ogg", + "mwe-embedplayer-video-audio": "Son Ogg", + "mwe-embedplayer-missing-source": "N'eus bet kavet mammenn video ebet." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bs.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bs.json new file mode 100644 index 00000000..2a96f223 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/bs.json @@ -0,0 +1,12 @@ +{ + "@metadata": [], + "mwe-embedplayer-player_fullscreen": "Puni ekran", + "mwe-embedplayer-paused": "zaustavljeno", + "mwe-embedplayer-download": "UÄitavanje", + "mwe-embedplayer-share": "Dijeli", + "mwe-embedplayer-credits": "Zasluge", + "mwe-embedplayer-share_this_video": "Dijeli ovaj video", + "mwe-embedplayer-menu_btn": "Meni", + "mwe-embedplayer-close_btn": "Zatvori", + "mwe-embedplayer-related_videos": "Povezani snimci" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ca.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ca.json new file mode 100644 index 00000000..e64d37b3 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ca.json @@ -0,0 +1,46 @@ +{ + "@metadata": { + "authors": [ + "Pitort", + "Vriullop", + "Xavier Dengra" + ] + }, + "mwe-embedplayer-credit-title": "TĆtol: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "Sense crĆØdits disponibles", + "mwe-embedplayer-loading_plugin": "Carregant el connector...", + "mwe-embedplayer-play_clip": "Reprodueix el tall", + "mwe-embedplayer-pause_clip": "Posa en pausa", + "mwe-embedplayer-volume_control": "Control de volum", + "mwe-embedplayer-player_options": "Opcions del reproductor", + "mwe-embedplayer-timed_text": "Text sincronitzat", + "mwe-embedplayer-player_fullscreen": "Pantalla completa", + "mwe-embedplayer-current_clip_msg": "Continua reproduint", + "mwe-embedplayer-paused": "en pausa", + "mwe-embedplayer-download_full_video": "DescĆ rrega del fitxer audiovisual:", + "mwe-embedplayer-download_right_click": "Per descarregar, cliqueu el botĆ³ dret i seleccioneu <i>Desa l'enllaƧ com a...</i>", + "mwe-embedplayer-download": "DescĆ rrega", + "mwe-embedplayer-share": "Compartir", + "mwe-embedplayer-credits": "CrĆØdits", + "mwe-embedplayer-share_this_video": "Compartiu aquest multimĆØdia", + "mwe-embedplayer-menu_btn": "MenĆŗ", + "mwe-embedplayer-close_btn": "Tanca", + "mwe-embedplayer-for_best_experience": "Per a una millor experiĆØncia de visualitzaciĆ³ es recomana un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download/ca\" target=\"_blank\">reproductor de vĆdeo HTML5</a>.", + "mwe-embedplayer-download-warn": "No s'ha detectat cap reproductor compatible: per tenir un reproductor integrat al navegador, descarregueu la [$1 darrera versiĆ³ de Firefox]", + "mwe-embedplayer-do_not_warn_again": "No mostris mĆ©s aquest missatge en el futur", + "mwe-embedplayer-playerSelect": "Reproductors", + "mwe-embedplayer-embed_site_or_blog": "Incrustat en una pĆ gina", + "mwe-embedplayer-embed_wiki": "Incrustat en un wiki", + "mwe-embedplayer-video-h264": "VĆdeo H.264", + "mwe-embedplayer-video-webm": "VĆdeo WebM", + "mwe-embedplayer-video-flv": "VĆdeo flaix", + "mwe-embedplayer-video-ogg": "VĆdeo Ogg", + "mwe-embedplayer-video-audio": "Ćudio Ogg", + "mwe-embedplayer-audio-mpeg": "Ćudio MPEG", + "mwe-embedplayer-video-3gp": "VĆdeo 3GP", + "mwe-embedplayer-video-mpeg": "VĆdeo MPEG", + "mwe-embedplayer-video-msvideo": "VĆdeo AVI", + "mwe-embedplayer-missing-source": "No s'ha trobat cap font de vĆdeo" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ce.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ce.json new file mode 100644 index 00000000..ea6a1c4f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ce.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Sasan700", + "Š£Š¼Š°Ń" + ] + }, + "mwe-embedplayer-credit-title": "Š¦ÓŠµ: $1", + "mwe-embedplayer-seek_to": "ŠŠµŃ
ŃŠ° Š³ÓŠ¾ $1", + "mwe-embedplayer-download_clip": "Š§ŃŃŠŗŠŗŃ
Š° Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-download_text": "Š§ŃŠ“Š°ŠŗŠŗŃ
Š° Š¹Š¾Š·Š°", + "mwe-embedplayer-download": "Š§ŃŃŠŗŠŗŃ
Š°", + "mwe-embedplayer-close_btn": "ŠÓŠ°ŃÓŠ°Š³ÓŠ°", + "mwe-embedplayer-seeking": "Š»Š°Ń
Š°Ń" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/cs.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/cs.json new file mode 100644 index 00000000..3170abee --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/cs.json @@ -0,0 +1,68 @@ +{ + "@metadata": { + "authors": [ + "Mormegil", + "Vks" + ] + }, + "mwe-embedplayer-credit-title": "NĆ”zev: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-select_playback": "NastavenĆ voleb pÅehrĆ”vĆ”nĆ", + "mwe-embedplayer-link_back": "Odkaz zpÄt", + "mwe-embedplayer-play_clip": "PÅehrĆ”t klip", + "mwe-embedplayer-pause_clip": "Pozastavit klip", + "mwe-embedplayer-volume_control": "OvlĆ”dĆ”nĆ hlasitosti", + "mwe-embedplayer-player_options": "Možnosti pÅehrĆ”vaÄe", + "mwe-embedplayer-timed_text": "Titulky", + "mwe-embedplayer-player_fullscreen": "CelĆ” obrazovka", + "mwe-embedplayer-next_clip_msg": "PÅehrĆ”t dalÅ”Ć klip", + "mwe-embedplayer-prev_clip_msg": "PÅehrĆ”t pÅedchozĆ klip", + "mwe-embedplayer-seek_to": "PÅesun na $1", + "mwe-embedplayer-paused": "pozastaveno", + "mwe-embedplayer-download_full": "StaženĆ celĆ©ho videosouboru:", + "mwe-embedplayer-download_clip": "StĆ”hnout video", + "mwe-embedplayer-download": "StĆ”hnout", + "mwe-embedplayer-share": "SdĆlet", + "mwe-embedplayer-credits": "O souboru", + "mwe-embedplayer-about-library": "O pÅehrĆ”vaÄi Kaltura", + "mwe-embedplayer-about-library-desc": "Knihovna mĆ©diĆ pro HTML5 Kaltura vĆ”m umožÅuje už dnes využĆvat znaÄky HTML5 <video> a <audio> a mĆt konzistentnĆ rozhranĆ prohlĆžeÄe na vÅ”ech hlavnĆch prohlĆžeÄĆch.\n\n[$1 VĆce informacĆ o pÅehrĆ”vacĆ knihovnÄ Kaltura]", + "mwe-embedplayer-choose_player": "Vybrat pÅehrĆ”vaÄ videa", + "mwe-embedplayer-no-player": "Pro $1 nenĆ dostupnĆ½ Å¾Ć”dnĆ½ pÅehrĆ”vaÄ", + "mwe-embedplayer-share_this_video": "SdĆlet toto video", + "mwe-embedplayer-kaltura-platform-title": "OtevÅenĆ” platforma pro video Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "ZavÅĆt", + "mwe-embedplayer-ogg-player-vlc-player": "PÅehrĆ”vaÄ VLC", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 pÅehrĆ”vaÄ Ogg", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 pÅehrĆ”vaÄ H.264", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 pÅehrĆ”vaÄ WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "GenerickĆ½ zĆ”suvnĆ½ modul Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "ZĆ”suvnĆ½ modul QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX prvek QuickTime", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "PÅehrĆ”vaÄ Kaltura", + "mwe-embedplayer-ogg-player-selected": "(vybranĆ½)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Pro pÅĆjemnÄjÅ”Ć pÅehrĆ”vĆ”nĆ videa doporuÄujeme <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5 prohlĆžeÄ videa</a>.", + "mwe-embedplayer-fullscreen-tip": "StisknutĆm <b>F11</b> pÅepĆnĆ”te celoobrazovkovĆ½ režim <i>webovĆ©ho prohlĆžeÄe</i>", + "mwe-embedplayer-fullscreen-tip-osx": "StisknutĆm <b>shift ā F</b> pÅepĆnĆ”te celoobrazovkovĆ½ režim", + "mwe-embedplayer-do_not_warn_again": "PÅĆÅ”tÄ tuto zprĆ”vu nezobrazovat.", + "mwe-embedplayer-playerSelect": "PÅehrĆ”vaÄe", + "mwe-embedplayer-read_before_embed": "PÅed vklĆ”dĆ”nĆm <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ÄtÄte upozornÄnĆ</a>.", + "mwe-embedplayer-embed_site_or_blog": "VloženĆ na strĆ”nku", + "mwe-embedplayer-related_videos": "SouvisejĆcĆ videa", + "mwe-embedplayer-seeking": "pÅesun", + "mwe-embedplayer-buffering": "naÄĆtĆ”nĆ do pamÄti", + "mwe-embedplayer-video-h264": "Video v H.264", + "mwe-embedplayer-video-webm": "Video WebM", + "mwe-embedplayer-video-flv": "Video ve Flashi", + "mwe-embedplayer-video-ogg": "Video v Ogg", + "mwe-embedplayer-video-audio": "Zvuk v Ogg", + "mwe-embedplayer-audio-mpeg": "Audio MPEG", + "mwe-embedplayer-video-3gp": "Video 3GP", + "mwe-embedplayer-video-mpeg": "Video MPEG", + "mwe-embedplayer-video-msvideo": "Video AVI", + "mwe-embedplayer-missing-source": "Nebylo nalezeno zdrojovĆ© video" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/cu.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/cu.json new file mode 100644 index 00000000..8475311f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/cu.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "ŠŠ¹Š" + ] + }, + "mwe-embedplayer-credit-author": "ŃŠ²Š¾ŃŃŃŃ : $1", + "mwe-embedplayer-close_btn": "źŠ°ŠŗŃźŠø" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/de.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/de.json new file mode 100644 index 00000000..9acb4658 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/de.json @@ -0,0 +1,98 @@ +{ + "@metadata": { + "authors": [ + "Kghbln", + "Metalhead64", + "Purodha" + ] + }, + "mwe-embedplayer-credit-title": "Titel: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "Keine Danksagungen verfĆ¼gbar", + "mwe-embedplayer-loading_plugin": "lade Plugin ā¦", + "mwe-embedplayer-select_playback": "Wiedergabeeinstellungen Ƥndern", + "mwe-embedplayer-link_back": "Link zurĆ¼ck", + "mwe-embedplayer-error_swap_vid": "Fehler: mv_embed konnte nicht das Videotag fĆ¼r die mv_embed-OberflƤche auslagern", + "mwe-embedplayer-add_to_end_of_sequence": "Zum Ende der Sequenz hinzufĆ¼gen", + "mwe-embedplayer-missing_video_stream": "Die Videodatei fĆ¼r diesen Stream fehlt", + "mwe-embedplayer-play_clip": "Clip abspielen", + "mwe-embedplayer-pause_clip": "Clip pausieren", + "mwe-embedplayer-volume_control": "LautstƤrkeregelung", + "mwe-embedplayer-player_options": "Playeroptionen", + "mwe-embedplayer-timed_text": "Zeitbezogene Untertitel", + "mwe-embedplayer-player_fullscreen": "Vollbild", + "mwe-embedplayer-next_clip_msg": "NƤchsten Clip wiedergeben", + "mwe-embedplayer-prev_clip_msg": "Vorherigen Clip wiedergeben", + "mwe-embedplayer-current_clip_msg": "Mit der Wiedergabe dieses Clips fortfahren", + "mwe-embedplayer-seek_to": "Suche $1", + "mwe-embedplayer-paused": "pausiert", + "mwe-embedplayer-download_segment": "Auswahl herunterladen:", + "mwe-embedplayer-download_full_video": "Ganze Videodatei herunterladen:", + "mwe-embedplayer-download_full_audio": "Ganze Audiodatei herunterladen:", + "mwe-embedplayer-download_right_click": "Zum Herunterladen die rechte Maustaste nutzen und <i>Link speichern unter ā¦</i> auswƤhlen", + "mwe-embedplayer-download_clip": "Video herunterladen", + "mwe-embedplayer-download_text": "Text herunterladen", + "mwe-embedplayer-download": "Herunterladen", + "mwe-embedplayer-share": "Teilen", + "mwe-embedplayer-credits": "Urheberschaft", + "mwe-embedplayer-about-library": "Ćber den Kaltura-Player", + "mwe-embedplayer-about-library-desc": "Kalturas HTML5-Medienbibliothek ermƶglicht es die Vorteile der beiden HTML5-Tags <code><nowiki><video></nowiki></code> und <code><nowiki><audio></nowiki></code> mit einem einheitlichen Player-Interface bei allen fĆ¼hrenden Webbrowsern nutzen zu kƶnnen.\n\n[$1 Weitere Informationen zu Kalturas HTML5-Medienbibliothek].", + "mwe-embedplayer-clip_linkback": "Clip-Quellseite", + "mwe-embedplayer-choose_player": "Videoplayer auswƤhlen", + "mwe-embedplayer-no-player": "Es ist fĆ¼r $1 kein Player verfĆ¼gbar", + "mwe-embedplayer-share_this_video": "Dieses Video teilen", + "mwe-embedplayer-share_this_audio": "Diese Audiodatei teilen", + "mwe-embedplayer-video_credits": "Videocredits", + "mwe-embedplayer-no-video_credits": "Keine Urheberangaben verfĆ¼gbar", + "mwe-embedplayer-kaltura-platform-title": "Kaltura Open-Source-Video-Plattform", + "mwe-embedplayer-menu_btn": "MenĆ¼", + "mwe-embedplayer-close_btn": "SchlieĆen", + "mwe-embedplayer-ogg-player-vlc-player": "VLC-Player", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg-Player", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5-MP3-Player", + "mwe-embedplayer-ogg-player-aacNative": "HTML5-AAC-Player", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264-Player", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM-Player", + "mwe-embedplayer-ogg-player-oggPlugin": "Allgemeines Ogg-Plugin", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC fĆ¼r die iOS-App", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "IE-WebM-Plugin-Downloader", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-Plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura-Player", + "mwe-embedplayer-ogg-player-selected": "(ausgewƤhlt)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "FĆ¼r eine bessere Videowiedergabe wird ein <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download/de\" target=\"_blank\">HTML5-Videobrowser</a> empfohlen.", + "mwe-embedplayer-download-warn": "Beim Browser wurde ein inkompatibles Wiedergabeprogramm erkannt. FĆ¼r eine im Browser eingebettete Wiedergabe wird die Nutzung der [$1 neuesten Version von Mozilla Firefox] empfohlen.", + "mwe-embedplayer-fullscreen-tip": "Die Taste <b>F11</b> drĆ¼cken, um zum Vollbildmodus des <i>Webbrowsers</i> umzuschalten.", + "mwe-embedplayer-fullscreen-tip-osx": "Die Tasten <b>UMSCHALT ā F</b> drĆ¼cken, um zum Vollbildmodus des <i>Webbrowsers</i> umzuschalten.", + "mwe-embedplayer-do_not_warn_again": "Diese Meldung in Zukunft nicht mehr anzeigen.", + "mwe-embedplayer-playerSelect": "Player", + "mwe-embedplayer-read_before_embed": "Vor dem Einbinden die <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Sicherheitsanmerkungen</a> durchlesen!", + "mwe-embedplayer-embed_site_or_blog": "Auf einer Seite einbinden", + "mwe-embedplayer-embed_wiki": "Auf einem Wiki einbetten", + "mwe-embedplayer-related_videos": "Ćhnliche Videos", + "mwe-embedplayer-seeking": "suchen", + "mwe-embedplayer-buffering": "puffert", + "mwe-embedplayer-video-h264": "H.264-Video", + "mwe-embedplayer-video-webm": "WebM-Video", + "mwe-embedplayer-video-flv": "Flash-Video", + "mwe-embedplayer-video-ogg": "Ogg-Video", + "mwe-embedplayer-video-audio": "Ogg-Audiodatei", + "mwe-embedplayer-audio-mpeg": "MPEG-Audio", + "mwe-embedplayer-video-3gp": "3gp-Video", + "mwe-embedplayer-video-mpeg": "MPEG-Video", + "mwe-embedplayer-video-msvideo": "AVI-Video", + "mwe-embedplayer-missing-source": "Es konnte kein Videoclip gefunden werden.", + "mwe-embedplayer-vlcapp-intro": "Um Videos von dieser Website auf einem iPhone oder iPad anzusehen, musst du die kostenlose $1 herunterladen.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "VLC-App", + "mwe-embedplayer-vlcapp-downloadapp": "Die VLC-App aus dem App Store herunterladen", + "mwe-embedplayer-vlcapp-openvideo": "Dieses Video in der VLC-App ƶffnen", + "mwe-embedplayer-vlcapp-downloadvideo": "Dieses Video herunterladen", + "mwe-embedplayer-vlcapp-vlcapppopup": "Um Videos auf dieser Website abzuspielen, benƶtigst du die kostenlose VLC-App. Jetzt installieren?", + "mwe-embedplayer-iewebmprompt-intro": "Huch! Eine weitere Sache, bevor du dieses Video abspielen kannst ā¦", + "mwe-embedplayer-iewebmprompt-linktext": "Installiere WebM-Medienkomponenten fĆ¼r den Microsoft Internet Explorer", + "mwe-embedplayer-iewebmprompt-outro": "Lade nach der Installation diese Seite neu." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/diq.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/diq.json new file mode 100644 index 00000000..ac3c19da --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/diq.json @@ -0,0 +1,70 @@ +{ + "@metadata": { + "authors": [ + "Erdemaslancan", + "Mirzali" + ] + }, + "mwe-embedplayer-credit-title": "Sername: $1", + "mwe-embedplayer-credit-date": "Tarix: $1", + "mwe-embedplayer-credit-author": "NuÅtoÄ: $1", + "mwe-embedplayer-loading_plugin": "loading plugin ...", + "mwe-embedplayer-select_playback": "tercihĆŖ kaydayiÅi eyar ker", + "mwe-embedplayer-link_back": "tepiya agĆŖrayiÅ re gıre bıd'", + "mwe-embedplayer-error_swap_vid": "xeta: qey mv_embed, mv_embed'i etiketĆŖ videoyi nĆŖÅkeno teqas bıkero", + "mwe-embedplayer-add_to_end_of_sequence": "bıerz peyni rĆŖz", + "mwe-embedplayer-missing_video_stream": "qey no herikyayiÅi dosyaya videoyi nĆŖaseno", + "mwe-embedplayer-play_clip": "klib bıde kaykerdıÅ", + "mwe-embedplayer-pause_clip": "klib bıde vındertıÅ", + "mwe-embedplayer-volume_control": "kontrolĆŖ vengi", + "mwe-embedplayer-player_options": "OpsiyonĆŖ kaykerdoÄi", + "mwe-embedplayer-player_fullscreen": "Tam asenge", + "mwe-embedplayer-next_clip_msg": "klibo bin bıde kaykerdıÅ", + "mwe-embedplayer-prev_clip_msg": "klibo verin bıde kaykerdıÅ", + "mwe-embedplayer-current_clip_msg": "kaykerdıÅĆŖ no klibi re dewam bıker", + "mwe-embedplayer-seek_to": "Åo muddet ser $1", + "mwe-embedplayer-paused": "vındarnaye", + "mwe-embedplayer-download_segment": "tercihi biyar war", + "mwe-embedplayer-download_full_video": "dosyaya videoyi tam biya war:", + "mwe-embedplayer-download_right_click": "qey wari ardıÅi, raÅt bıtıknĆŖ u <i>Hedef bıferq qeyd ker...</i> bıtıknĆŖ", + "mwe-embedplayer-download_clip": "video biyar war", + "mwe-embedplayer-download_text": "Metn biyar war", + "mwe-embedplayer-download": "biyar war", + "mwe-embedplayer-share": "Vıla ke", + "mwe-embedplayer-credits": "ĆŖyĆŖ ke destek dayĆŖ", + "mwe-embedplayer-clip_linkback": "pelĆŖ Ƨımeyi yo klibi", + "mwe-embedplayer-choose_player": "video player bıweƧin", + "mwe-embedplayer-share_this_video": "na video bare/par bıker", + "mwe-embedplayer-video_credits": "ĆŖyĆŖ ke destek dayĆŖ video", + "mwe-embedplayer-menu_btn": "menu", + "mwe-embedplayer-close_btn": "RacnĆŖ", + "mwe-embedplayer-ogg-player-vlc-player": "Kay kerdogĆŖ VLC", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg kayker", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 kayker", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM kayker", + "mwe-embedplayer-ogg-player-oggPlugin": "Cenerik olekenĆŖ Ogg'i", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "KaykerdoÄĆŖ kaltura", + "mwe-embedplayer-ogg-player-selected": "(tercih biyaye)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Seba daĆŖna rınd kaykerdıÅĆŖ videoy ma <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">html5 video arden</a> tewsiya kenime.", + "mwe-embedplayer-do_not_warn_again": "Vındero bahdo, na mesac newkĆŖ memocne", + "mwe-embedplayer-playerSelect": "Kaykeri", + "mwe-embedplayer-read_before_embed": "kerem kerĆŖ verĆŖ nımıtıÅi <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">derheqĆŖ dĆ»r ra nımıtıÅi de malumatĆŖ pawıtıÅan</a> bıwenĆŖ!", + "mwe-embedplayer-embed_site_or_blog": "ZerreyĆŖ keyepel u blogĆŖ xo de bınımnĆŖ", + "mwe-embedplayer-related_videos": "videoyĆŖ ke elaqedari", + "mwe-embedplayer-seeking": "cıgĆŖrayox", + "mwe-embedplayer-buffering": "tamponkerdıÅ", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-webm": "WebM video", + "mwe-embedplayer-video-flv": "Flash video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg audio", + "mwe-embedplayer-audio-mpeg": "MPEG audio", + "mwe-embedplayer-video-3gp": "3GP video", + "mwe-embedplayer-video-mpeg": "MPEG video", + "mwe-embedplayer-video-msvideo": "AVI video" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/dsb.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/dsb.json new file mode 100644 index 00000000..61685dad --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/dsb.json @@ -0,0 +1,83 @@ +{ + "@metadata": { + "authors": [ + "Michawiki" + ] + }, + "mwe-embedplayer-credit-title": "Titel: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Awtor: $1", + "mwe-embedplayer-nocredits": "Žadne ÅŗÄkowanja k dispoziciji", + "mwe-embedplayer-loading_plugin": "Tykac se zacytujo ...", + "mwe-embedplayer-select_playback": "Nastajenje za playback stajiÅ", + "mwe-embedplayer-link_back": "WĆ³tkaz slÄdk", + "mwe-embedplayer-error_swap_vid": "ZmĆ³lka: mv_embed njejo mĆ³gaÅ wideotoflicku za pĆ³wjerch mv_embed wumÄstniÅ", + "mwe-embedplayer-add_to_end_of_sequence": "KĆ³Åcoju sekwence pÅidaÅ", + "mwe-embedplayer-missing_video_stream": "Wideowa dataja za toÅ tu tÅ”ugu felujo", + "mwe-embedplayer-play_clip": "Klip wĆ³tegraÅ", + "mwe-embedplayer-pause_clip": "Klip zastajiÅ", + "mwe-embedplayer-volume_control": "RegulÄrowanje gÅosnosÄi", + "mwe-embedplayer-player_options": "Opcije wĆ³tegrawaka", + "mwe-embedplayer-timed_text": "SynchronizÄrowany tekst", + "mwe-embedplayer-player_fullscreen": "PoÅna wobrazowka", + "mwe-embedplayer-next_clip_msg": "PÅiducy klip wĆ³tegraÅ", + "mwe-embedplayer-prev_clip_msg": "PjerwjejÅ”ny klip wĆ³tegraÅ", + "mwe-embedplayer-current_clip_msg": "Klip dalej wĆ³tegraÅ", + "mwe-embedplayer-seek_to": "$1 pytaÅ", + "mwe-embedplayer-paused": "zastajony", + "mwe-embedplayer-download_segment": "WubÄrk zeÅÄgnuÅ:", + "mwe-embedplayer-download_full": "DopoÅnu wideowu dataju zeÅÄgnuÅ:", + "mwe-embedplayer-download_right_click": "Aby zeÅÄgnuÅ, klikni z pÅ”aweju tastu a wubjeÅ <i>WĆ³tkaz skÅadowaÅ ako...</i>", + "mwe-embedplayer-download_clip": "Wideo zeÅÄgnuÅ", + "mwe-embedplayer-download_text": "Tekst", + "mwe-embedplayer-download": "ZeÅÄgnuÅ", + "mwe-embedplayer-share": "ŹÄliÅ", + "mwe-embedplayer-credits": "ŹÄkowanje", + "mwe-embedplayer-about-library": "WĆ³ wĆ³tegrawaku Kaltura", + "mwe-embedplayer-about-library-desc": "Medijowa biblioteka HTML 5 wĆ³tgrawaka Kaltury zmĆ³Å¾nja lÄpÅ”yny HTML 5-elementowu code><nowiki><video></nowiki></code> a <code><nowiki><audio></nowiki></code> z jadnotnym powjerchom wĆ³tgrawaka pÅi wjeducych wĆ³tglÄdowakach.\n\n[$1 DalÅ”ne informacije wĆ³ bibliotece wĆ³tgrawaka Kaltura].", + "mwe-embedplayer-clip_linkback": "ŽrÄdÅowy bok klipow", + "mwe-embedplayer-choose_player": "WideowĆ³tegrawak wubraÅ", + "mwe-embedplayer-no-player": "Za $1 žeden wĆ³tgrawak k dispoziciji", + "mwe-embedplayer-share_this_video": "ToÅ to wideo ÅŗÄliÅ", + "mwe-embedplayer-video_credits": "ŹÄkowanja za napĆ³ranje wideo", + "mwe-embedplayer-no-video_credits": "Žedne pĆ³daÅa wĆ³ awtorje k dispoziciji", + "mwe-embedplayer-kaltura-platform-title": "Wideowa platforma zjawnego žrÄdÅa Kaltura", + "mwe-embedplayer-menu_btn": "Meni", + "mwe-embedplayer-close_btn": "ZacyniÅ", + "mwe-embedplayer-ogg-player-vlc-player": "GrajadÅo VLC", + "mwe-embedplayer-ogg-player-oggNative": "WĆ³tgrawak HTML5 Ogg", + "mwe-embedplayer-ogg-player-mp3Native": "WĆ³tgrawak HTML5 MP3", + "mwe-embedplayer-ogg-player-aacNative": "WĆ³tgrawak HTML5 AAC", + "mwe-embedplayer-ogg-player-h264Native": "WĆ³tgrawak HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "WĆ³tegrawak HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "Tykac Generic Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Tykac QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "GrajadÅo Kaltura", + "mwe-embedplayer-ogg-player-selected": "(wubrany)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vobis", + "mwe-embedplayer-for_best_experience": "Za lÄpÅ”e wideodožywjenje pĆ³rucujomy <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">wideowobglÄdowak HTML 5</a>.", + "mwe-embedplayer-download-warn": "Njekompatibelne wĆ³tegrawak we wobglÄdowaku namakany: za wĆ³tegrawanje we wobglÄdowaku zeÅÄgni pÅ”osym [$1 nejnowÅ”u wersiju Mozilla Firefox]", + "mwe-embedplayer-fullscreen-tip": "TÅoc <b>F11</b>, aby <i>webwobglÄdowak</i> do poÅneje wobrazowki pÅeÅ”altowaÅ", + "mwe-embedplayer-fullscreen-tip-osx": "TÅoc <b>UMSCH ā F</b>, aby pÅeÅ”altowaÅ do modusa poÅneje wobrazowki", + "mwe-embedplayer-do_not_warn_again": "W pÅichoÅŗe toÅ tu powÄÅŗeÅku wÄcej njepokazaÅ", + "mwe-embedplayer-playerSelect": "WĆ³tgrawaki", + "mwe-embedplayer-read_before_embed": "PÅ”osym cytaj <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">wÄstotne pÅipiski wĆ³ zdalonem zasajÅŗenju</a>, nježli až napÅ”awdu zasajÅŗujoÅ”!", + "mwe-embedplayer-embed_site_or_blog": "Na boku zasajÅŗiÅ", + "mwe-embedplayer-embed_wiki": "We wikiju zasajÅŗiÅ", + "mwe-embedplayer-related_videos": "PÅiwuzne wideo", + "mwe-embedplayer-seeking": "pyta se", + "mwe-embedplayer-buffering": "pufrujo", + "mwe-embedplayer-video-h264": "Wideo H.264", + "mwe-embedplayer-video-webm": "WebM-wideo", + "mwe-embedplayer-video-flv": "Wideo Flash", + "mwe-embedplayer-video-ogg": "Ogg-wideo", + "mwe-embedplayer-video-audio": "Ogg-awdio", + "mwe-embedplayer-audio-mpeg": "MPEG awdio", + "mwe-embedplayer-video-3gp": "3GP wideo", + "mwe-embedplayer-video-mpeg": "MPEG wideo", + "mwe-embedplayer-video-msvideo": "AVI wideo", + "mwe-embedplayer-missing-source": "Žedno žrÄdÅowe wideo namakane." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/el.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/el.json new file mode 100644 index 00000000..3dcbb269 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/el.json @@ -0,0 +1,77 @@ +{ + "@metadata": { + "authors": [ + "Geraki" + ] + }, + "mwe-embedplayer-credit-title": "Ī¤ĪÆĻĪ»ĪæĻ: $1", + "mwe-embedplayer-credit-date": "ĪĪ¼ĪµĻĪæĪ¼Ī·Ī½ĪÆĪ±: $1", + "mwe-embedplayer-credit-author": "Ī£Ļ
Ī³Ī³ĻĪ±ĻĪĪ±Ļ: $1", + "mwe-embedplayer-nocredits": "ĪĪµĪ½ Ī“Ī¹Ī±ĻĪÆĪøĪµĪ½ĻĪ±Ī¹ Ī±Ī½Ī±ĻĪæĻĪĻ", + "mwe-embedplayer-loading_plugin": "Ī¦ĻĻĻĻĻĪ· plugin ...", + "mwe-embedplayer-select_playback": "ĪĻĪ¹ĻĪ¼ĻĻ ĻĻĪæĻĪÆĪ¼Ī·ĻĪ·Ļ Ī±Ī½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī®Ļ", + "mwe-embedplayer-link_back": "Ī£ĻĪ½Ī“ĪµĻĪ· ĻĪÆĻĻ", + "mwe-embedplayer-error_swap_vid": "Ī£ĻĪ¬Ī»Ī¼Ī±: ĻĪæ mwEmbed Ī“ĪµĪ½ Ī®ĻĪ±Ī½ ĻĪµ ĪøĪĻĪ· Ī½Ī± Ī±Ī½ĻĪ±Ī»Ī»Ī¬Ī¾ĪµĪ¹ ĻĪ·Ī½ ĪµĻĪ¹ĪŗĪĻĪ± Ī²ĪÆĪ½ĻĪµĪæ Ī³Ī¹Ī± ĻĪ·Ī½ Ī“Ī¹ĪµĻĪ±ĻĪ® mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Ī ĻĪæĻĪøĪ®ĪŗĪ· ĻĻĪæ ĻĪĪ»ĪæĻ ĻĪ·Ļ Ī±ĪŗĪæĪ»ĪæĻ
ĪøĪÆĪ±Ļ", + "mwe-embedplayer-missing_video_stream": "Ī¤Īæ Ī±ĻĻĪµĪÆĪæ Ī²ĪÆĪ½ĻĪµĪæ Ī³Ī¹Ī± Ī±Ļ
ĻĪ® ĻĪ· ĻĪæĪ® Ī»ĪµĪÆĻĪµĪ¹", + "mwe-embedplayer-play_clip": "ĪĪ½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī® ĪŗĪ»Ī¹Ļ", + "mwe-embedplayer-pause_clip": "Ī Ī±ĻĻĪ· ĪŗĪ»Ī¹Ļ", + "mwe-embedplayer-volume_control": "ĪĪ»ĪµĪ³ĻĪæĻ ĪĪ½ĻĪ±ĻĪ·Ļ Ī®ĻĪæĻ
", + "mwe-embedplayer-player_options": "Ī”Ļ
ĪøĪ¼ĪÆĻĪµĪ¹Ļ Ī±Ī½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī®Ļ", + "mwe-embedplayer-timed_text": "Ī§ĻĪæĪ½Ī¹ĻĪ¼ĪĪ½Īæ ĪŗĪµĪÆĪ¼ĪµĪ½Īæ", + "mwe-embedplayer-player_fullscreen": "Ī Ī»Ī®ĻĪ·Ļ ĪæĪøĻĪ½Ī·", + "mwe-embedplayer-next_clip_msg": "ĪĪ½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī® ĪµĻĻĪ¼ĪµĪ½ĪæĻ
ĪŗĪ»Ī¹Ļ", + "mwe-embedplayer-prev_clip_msg": "ĪĪ½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī® ĻĻĪæĪ·Ī³ĪæĻĪ¼ĪµĪ½ĪæĻ
ĪŗĪ»Ī¹Ļ", + "mwe-embedplayer-current_clip_msg": "Ī£Ļ
Ī½ĪĻĪµĪ¹Ī± Ī±Ī½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī®Ļ Ī±Ļ
ĻĪæĻ ĻĪæĻ
ĪŗĪ»Ī¹Ļ", + "mwe-embedplayer-seek_to": "ĪĪ½Ī±Ī¶Ī®ĻĪ·ĻĪ· Ī³Ī¹Ī± $1", + "mwe-embedplayer-paused": "ĻĪµ ĻĪ±ĻĻĪ·", + "mwe-embedplayer-download_segment": "ĪĪ®ĻĪ· ĪµĻĪ¹Ī»ĪæĪ³Ī®Ļ:", + "mwe-embedplayer-download_full": "ĪĪ±ĻĪµĪ²Ī¬ĻĻĪµ ĻĪæ ĻĪ»Ī®ĻĪµĻ Ī±ĻĻĪµĪÆĪæ Ī²ĪÆĪ½ĻĪµĪæ:", + "mwe-embedplayer-download_right_click": "ĪĪ¹Ī± Ī½Ī± ĪŗĪ±ĻĪµĪ²Ī¬ĻĪµĻĪµ, ĪŗĪ¬Ī½ĻĪµ Ī“ĪµĪ¾ĪÆ ĪŗĪ»Ī¹Īŗ ĪŗĪ±Ī¹ ĪµĻĪ¹Ī»ĪĪ¾ĻĪµ <i>ĪĻĪæĪøĪ®ĪŗĪµĻ
ĻĪ· ĻĻ
Ī½Ī“ĪĻĪ¼ĪæĻ
ĻĻ ...</i>", + "mwe-embedplayer-download_clip": "ĪĪ®ĻĪ· Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-download_text": "ĪĪ±ĻĪµĪ²Ī¬ĻĻĪµ ĻĪæ ĪŗĪµĪÆĪ¼ĪµĪ½Īæ", + "mwe-embedplayer-download": "ĪĪ®ĻĪ·", + "mwe-embedplayer-share": "ĪĪ¹Ī±Ī¼ĪæĪ¹ĻĪ±ĻĪ¼ĻĻ", + "mwe-embedplayer-credits": "Ī£Ļ
Ī½ĻĪµĪ»ĪµĻĻĪĻ", + "mwe-embedplayer-about-library": "Ī£ĻĪµĻĪ¹ĪŗĪ¬ Ī¼Īµ ĻĪ·Ī½ ĪµĻĪ±ĻĪ¼ĪæĪ³Ī® Kaltura", + "mwe-embedplayer-clip_linkback": "Ī£ĪµĪ»ĪÆĪ“Ī± ĻĻĪæĪĪ»ĪµĻ
ĻĪ·Ļ Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-choose_player": "ĪĻĪ¹Ī»ĪĪ¾ĻĪµ ĻĻĻĪ³ĻĪ±Ī¼Ī¼Ī± Ī±Ī½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī®Ļ Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-no-player": "ĪĪ±Ī½ĪĪ½Ī± ĻĻĻĪ³ĻĪ±Ī¼Ī¼Ī± Ī±Ī½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī®Ļ Ī“ĪµĪ½ Ī“Ī¹Ī±ĻĪÆĪøĪµĻĪ±Ī¹ Ī³Ī¹Ī± ĻĪæ $1", + "mwe-embedplayer-share_this_video": "ĪĪæĪ¹ĻĪ±ĻĻĪµĪÆĻĪµ Ī±Ļ
ĻĻ ĻĪæ Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-video_credits": "Ī£Ļ
Ī½ĻĪµĪ»ĪµĻĻĪĻ Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-no-video_credits": "ĪĪµĪ½ Ī“Ī¹Ī±ĻĪÆĪøĪµĪ½ĻĪ±Ī¹ Ī±Ī½Ī±ĻĪæĻĪĻ", + "mwe-embedplayer-kaltura-platform-title": "Kaltura open source video platform", + "mwe-embedplayer-menu_btn": "ĪĪµĪ½ĪæĻ
", + "mwe-embedplayer-close_btn": "ĪĪ»ĪµĪÆĻĪ¹Ī¼Īæ", + "mwe-embedplayer-ogg-player-vlc-player": "VLC player", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg player", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 player", + "mwe-embedplayer-ogg-player-oggPlugin": "ĪĪµĪ½Ī¹ĪŗĻ plugin Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura player", + "mwe-embedplayer-ogg-player-selected": "(ĪµĻĪ¹Ī»ĪµĪ³Ī¼ĪĪ½Īæ)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "ĪĪ¹Ī± Ī¼Ī¹Ī± ĪŗĪ±Ī»ĻĻĪµĻĪ· ĪµĪ¼ĻĪµĪ¹ĻĪÆĪ± Ī±Ī½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī®Ļ Ī²ĪÆĪ½ĻĪµĪæ ĻĪ±Ļ ĻĻĪæĻĪµĪÆĪ½ĪæĻ
Ī¼Īµ ĪĪ½Ī± <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">ĻĪµĻĪ¹Ī·Ī³Ī·ĻĪ® HTML5 video</a>.", + "mwe-embedplayer-fullscreen-tip": "Ī Ī±ĻĪ®ĻĻĪµ <b>F11</b> Ī³Ī¹Ī± ĪµĪ½Ī±Ī»Ī»Ī±Ī³Ī® <i>ĻĪæĻ
ĻĻĪæĪ³ĻĪ¬Ī¼Ī¼Ī±ĻĪæĻ ĻĪµĻĪ¹Ī®Ī³Ī·ĻĪ·Ļ</i> ĻĪµ ĻĪ»Ī®ĻĪ· ĪæĪøĻĪ½Ī·", + "mwe-embedplayer-fullscreen-tip-osx": "Ī Ī±ĻĪ®ĻĻĪµ <b>shift ā F</b> Ī³Ī¹Ī± ĻĪ·Ī½ ĪµĪ½Ī±Ī»Ī»Ī±Ī³Ī® ĻĪ»Ī®ĻĪæĻ
Ļ ĪæĪøĻĪ½Ī·Ļ", + "mwe-embedplayer-do_not_warn_again": "Ī£ĻĪæ Ī¼ĪĪ»Ī»ĪæĪ½, Ī½Ī± Ī¼Ī·Ī½ ĪµĪ¼ĻĪ±Ī½Ī¹ĻĻĪµĪÆ Ī±Ļ
ĻĻ ĻĪæ Ī¼Ī®Ī½Ļ
Ī¼Ī±", + "mwe-embedplayer-playerSelect": "ĪĪæĪ³Ī¹ĻĪ¼Ī¹ĪŗĻ Ī±Ī½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³Ī®Ļ", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ĪĪ¹Ī±Ī²Ī¬ĻĻĪµ Ī±Ļ
ĻĻ</a> ĻĻĪ¹Ī½ Ī±ĻĻ ĻĪ·Ī½ ĪµĪ½ĻĻĪ¼Ī¬ĻĻĻĪ·.", + "mwe-embedplayer-embed_site_or_blog": "ĪĪ½ĻĻĪ¼Ī¬ĻĻĻĪ· ĻĻĪæ ĻĪ¬Ī¹Ļ Ī® Ī¼ĻĪ»ĪæĪ³Īŗ ĻĪ±Ļ", + "mwe-embedplayer-embed_wiki": "ĪĪ½ĻĻĪ¼Ī±ĻĻĻĻĪµ ĻĪµ ĪĪ½Ī± wiki", + "mwe-embedplayer-related_videos": "Ī£ĻĪµĻĪ¹ĪŗĪ¬ Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-seeking": "Ī±Ī½Ī±Ī¶Ī®ĻĪ·ĻĪ·", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-webm": "WebM Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-video-flv": "Flash video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg audio", + "mwe-embedplayer-audio-mpeg": "MPEG Ī®ĻĪæĻ", + "mwe-embedplayer-video-3gp": "3GP Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-video-mpeg": "MPEG Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-video-msvideo": "AVI Ī²ĪÆĪ½ĻĪµĪæ", + "mwe-embedplayer-missing-source": "ĪĪµĪ½ Ī²ĻĪĪøĪ·ĪŗĪµ ĻĪ·Ī³Ī® Ī²ĪÆĪ½ĻĪµĪæ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/en-gb.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/en-gb.json new file mode 100644 index 00000000..ca785d7b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/en-gb.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Shirayuki" + ] + }, + "mwe-embedplayer-do_not_warn_again": "In future, do not show this message" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/en.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/en.json new file mode 100644 index 00000000..91041ffc --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/en.json @@ -0,0 +1,95 @@ +{ + "@metadata": { + "authors": [] + }, + "mwe-embedplayer-credit-title": "Title: $1", + "mwe-embedplayer-credit-date": "Date: $1", + "mwe-embedplayer-credit-author": "Author: $1", + "mwe-embedplayer-nocredits": "No credits available", + "mwe-embedplayer-loading_plugin": "Loading plugin ...", + "mwe-embedplayer-select_playback": "Set playback preference", + "mwe-embedplayer-link_back": "Link back", + "mwe-embedplayer-error_swap_vid": "Error: mwEmbed was unable to swap the video tag for the mwEmbed interface", + "mwe-embedplayer-add_to_end_of_sequence": "Add to end of sequence", + "mwe-embedplayer-missing_video_stream": "The video file for this stream is missing", + "mwe-embedplayer-play_clip": "Play clip", + "mwe-embedplayer-pause_clip": "Pause clip", + "mwe-embedplayer-volume_control": "Volume control", + "mwe-embedplayer-player_options": "Player options", + "mwe-embedplayer-timed_text": "Timed text", + "mwe-embedplayer-player_fullscreen": "Fullscreen", + "mwe-embedplayer-next_clip_msg": "Play next clip", + "mwe-embedplayer-prev_clip_msg": "Play previous clip", + "mwe-embedplayer-current_clip_msg": "Continue playing this clip", + "mwe-embedplayer-seek_to": "Seek $1", + "mwe-embedplayer-paused": "paused", + "mwe-embedplayer-download_segment": "Download selection:", + "mwe-embedplayer-download_full_video": "Download full video file:", + "mwe-embedplayer-download_full_audio": "Download full audio file:", + "mwe-embedplayer-download_right_click": "To download, right click and select <i>Save link as...</i>", + "mwe-embedplayer-download_clip": "Download video", + "mwe-embedplayer-download_text": "Download text", + "mwe-embedplayer-download": "Download", + "mwe-embedplayer-share": "Share", + "mwe-embedplayer-credits": "Credits", + "mwe-embedplayer-about-library": "About Kaltura player", + "mwe-embedplayer-about-library-desc": "Kaltura's HTML5 media library enables you to take advantage of the HTML5 <video> and <audio> tags today with a consistent player interface across all major browsers.\n\n[$1 More about the Kaltura player library].", + "mwe-embedplayer-clip_linkback": "Clip source page", + "mwe-embedplayer-choose_player": "Choose video player", + "mwe-embedplayer-no-player": "No player available for $1", + "mwe-embedplayer-share_this_video": "Share this video", + "mwe-embedplayer-share_this_audio": "Share this audio file", + "mwe-embedplayer-video_credits": "Video credits", + "mwe-embedplayer-no-video_credits": "No credits available", + "mwe-embedplayer-kaltura-platform-title": "Kaltura open source video platform", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Close", + "mwe-embedplayer-ogg-player-vlc-player": "VLC player", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg player", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3 player", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC player", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 player", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM player", + "mwe-embedplayer-ogg-player-vp9Native": "HTML5 VP9 player", + "mwe-embedplayer-ogg-player-oggPlugin": "Generic Ogg plugin", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC for iOS app", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "IE WebM plugin downloader", + "mwe-embedplayer-ogg-player-ogvJsPlayer": "JavaScript Ogg player", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura player", + "mwe-embedplayer-ogg-player-selected": "(selected)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "For a better video playback experience we recommend an <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5 video browser</a>.", + "mwe-embedplayer-download-warn": "No compatible in-browser player was detected: for in-browser playback, please download the [$1 latest Firefox]", + "mwe-embedplayer-fullscreen-tip": "Press <b>F11</b> toggle <i>web browser</i> fullscreen", + "mwe-embedplayer-fullscreen-tip-osx": "Press <b>shift ā F</b> to toggle fullscreen", + "mwe-embedplayer-do_not_warn_again": "In the future, do not show this message", + "mwe-embedplayer-playerSelect": "Players", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Read this</a> before embedding.", + "mwe-embedplayer-embed_site_or_blog": "Embed on a page", + "mwe-embedplayer-embed_wiki": "Embed on a wiki", + "mwe-embedplayer-related_videos": "Related videos", + "mwe-embedplayer-seeking": "seeking", + "mwe-embedplayer-buffering": "buffering", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-webm": "WebM video", + "mwe-embedplayer-video-flv": "Flash video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg audio", + "mwe-embedplayer-audio-mpeg": "MPEG audio", + "mwe-embedplayer-video-3gp": "3GP video", + "mwe-embedplayer-video-mpeg": "MPEG video", + "mwe-embedplayer-video-msvideo": "AVI video", + "mwe-embedplayer-missing-source": "No source video was found", + "mwe-embedplayer-vlcapp-intro": "In order to view videos from this site on an iPhone or iPad, you need the free $1.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "VLC app", + "mwe-embedplayer-vlcapp-downloadapp": "Download the VLC app from the App Store", + "mwe-embedplayer-vlcapp-openvideo": "Open this video in the VLC app", + "mwe-embedplayer-vlcapp-downloadvideo": "Download this video", + "mwe-embedplayer-vlcapp-vlcapppopup": "To play videos on this site, you need the free VLC app. Install now?", + "mwe-embedplayer-iewebmprompt-intro": "Oops! One more thing before you can play this video...", + "mwe-embedplayer-iewebmprompt-linktext": "Install WebM media components for Microsoft Internet Explorer", + "mwe-embedplayer-iewebmprompt-outro": "Reload this page after installing." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/eo.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/eo.json new file mode 100644 index 00000000..bb972255 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/eo.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "Yekrats" + ] + }, + "mwe-embedplayer-player_fullscreen": "Plenekrana", + "mwe-embedplayer-download_full": "ElÅuti kompletan filmetan dosieron:", + "mwe-embedplayer-download_clip": "ElÅuti filmeton", + "mwe-embedplayer-download": "ElÅuti", + "mwe-embedplayer-share": "Konigi", + "mwe-embedplayer-share_this_video": "Konigi Äi tiun filmeton", + "mwe-embedplayer-menu_btn": "Menuo", + "mwe-embedplayer-close_btn": "Fermi", + "mwe-embedplayer-ogg-player-selected": "(elektita)", + "mwe-embedplayer-playerSelect": "Ludantoj", + "mwe-embedplayer-read_before_embed": "Bonvolu legi la <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">sekurecajn notojn pri ekstera enkorpigado</a> antaÅ fakte enkorpigado!", + "mwe-embedplayer-embed_site_or_blog": "Enmeti en paÄo", + "mwe-embedplayer-related_videos": "Rilataj videoj", + "mwe-embedplayer-seeking": "serÄante", + "mwe-embedplayer-buffering": "bufrante", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-flv": "Flash video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg aÅdiaĵo", + "mwe-embedplayer-missing-source": "Neniu fonta video estis trovita" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/es.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/es.json new file mode 100644 index 00000000..8dd70f29 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/es.json @@ -0,0 +1,99 @@ +{ + "@metadata": { + "authors": [ + "Armando-Martin", + "Crazymadlover", + "Translationista", + "Fitoschido", + "Koavf", + "Macofe", + "Laurenslimb" + ] + }, + "mwe-embedplayer-credit-title": "TĆtulo: $1", + "mwe-embedplayer-credit-date": "Fecha: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "No hay crĆ©ditos disponibles", + "mwe-embedplayer-loading_plugin": "Cargando plugin ...", + "mwe-embedplayer-select_playback": "Configurar preferencia de reproducciĆ³n", + "mwe-embedplayer-link_back": "Referir a enlace", + "mwe-embedplayer-error_swap_vid": "Error: mwEmbed no pudo sustituĆr la etiqueta de vĆdeo por la interfaz mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Agregar al final de la secuencia", + "mwe-embedplayer-missing_video_stream": "Falta el archivo de vĆdeo de esta transmisiĆ³n", + "mwe-embedplayer-play_clip": "Reproducir clip", + "mwe-embedplayer-pause_clip": "Pausar clip", + "mwe-embedplayer-volume_control": "Control de volumen", + "mwe-embedplayer-player_options": "Opciones de reproductor", + "mwe-embedplayer-timed_text": "Texto sincronizado", + "mwe-embedplayer-player_fullscreen": "Pantalla completa", + "mwe-embedplayer-next_clip_msg": "Reproducir siguiente clip", + "mwe-embedplayer-prev_clip_msg": "Reproducir clip anterior", + "mwe-embedplayer-current_clip_msg": "Continuar reproduciendo este clip", + "mwe-embedplayer-seek_to": "Buscar $1", + "mwe-embedplayer-paused": "en pausa", + "mwe-embedplayer-download_segment": "Descargar selecciĆ³n:", + "mwe-embedplayer-download_full_video": "Descargar archivo de video completo:", + "mwe-embedplayer-download_right_click": "Para descargar, haga click con el botĆ³n derecho del ratĆ³n y seleccione <i>Guardar enlace como...</i>", + "mwe-embedplayer-download_clip": "Descargar archivo", + "mwe-embedplayer-download_text": "Descargar texto", + "mwe-embedplayer-download": "Descargar", + "mwe-embedplayer-share": "Compartir", + "mwe-embedplayer-credits": "CrĆ©ditos", + "mwe-embedplayer-about-library": "Acerca del reproductor Kaltura", + "mwe-embedplayer-about-library-desc": "La biblioteca HTMl5 de Kaltura permite utilizar etiquetas de <code><nowiki><video></nowiki></code> y <code><nowiki><audio></nowiki></code> ahora con una interfaz de reproductor consistente en los navegadores mĆ”s usados.\n\t\n[$1 MĆ”s acerca de la biblioteca del reproductor Kalltura].", + "mwe-embedplayer-clip_linkback": "PĆ”gina fuente de clip", + "mwe-embedplayer-choose_player": "Elegir reproductor de video", + "mwe-embedplayer-no-player": "No hay ningĆŗn reproductor disponible para $1", + "mwe-embedplayer-share_this_video": "Compartir este video", + "mwe-embedplayer-video_credits": "CrĆ©ditos de video", + "mwe-embedplayer-no-video_credits": "No hay crĆ©ditos disponibles", + "mwe-embedplayer-kaltura-platform-title": "Plataforma de vĆdeo de cĆ³digo abierto Kaltura", + "mwe-embedplayer-menu_btn": "MenĆŗ", + "mwe-embedplayer-close_btn": "Cerrar", + "mwe-embedplayer-ogg-player-vlc-player": "Reproductor de VLC", + "mwe-embedplayer-ogg-player-oggNative": "Reproductor HTML5 Ogg", + "mwe-embedplayer-ogg-player-mp3Native": "Reproductor de MP3 HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Reproductor de AAC HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Reproductor HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "Reproductor WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Plugin Ogg genĆ©rico", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "aplicaciĆ³n VLC para iOS", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Plugin QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Reproductor Kaltura", + "mwe-embedplayer-ogg-player-selected": "(seleccionado)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Para una mejor experiencia de reproducciĆ³n de vĆdeo recomendamos un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navegador de vĆdeo html5</a>.", + "mwe-embedplayer-download-warn": "Se detectĆ³ un reproductor no compatible con el explorador: para reproducciĆ³n integrada en el navegador descargue la [$1 Ćŗltima versiĆ³n de Firefox]", + "mwe-embedplayer-fullscreen-tip": "Presione <b>F11</b> para activar o desactivar la pantalla completa del <i>navegador web</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Presione <b>shift ā F</b> para activar o desactivarl a pantalla completa", + "mwe-embedplayer-do_not_warn_again": "No mostrar este mensaje en el futuro.", + "mwe-embedplayer-playerSelect": "Reproductores", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Leer esto</a> antes de insertar.", + "mwe-embedplayer-embed_site_or_blog": "Insertar en una pĆ”gina", + "mwe-embedplayer-embed_wiki": "Incrustar en un wiki", + "mwe-embedplayer-related_videos": "Videos relacionados", + "mwe-embedplayer-seeking": "buscando", + "mwe-embedplayer-buffering": "cargando en el bĆŗfer", + "mwe-embedplayer-video-h264": "Video H.264", + "mwe-embedplayer-video-webm": "VĆdeo WebM", + "mwe-embedplayer-video-flv": "Video Flash", + "mwe-embedplayer-video-ogg": "Video Ogg", + "mwe-embedplayer-video-audio": "Audio Ogg", + "mwe-embedplayer-audio-mpeg": "Audio MPEG", + "mwe-embedplayer-video-3gp": "VĆdeo 3GP", + "mwe-embedplayer-video-mpeg": "VĆdeo MPEG", + "mwe-embedplayer-video-msvideo": "VĆdeo AVI", + "mwe-embedplayer-missing-source": "No se encontrĆ³ ningĆŗn vĆdeo de origen.", + "mwe-embedplayer-vlcapp-intro": "Para ver videos de este sitio en un iPhone o iPad, necesitas la $1 gratuita.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "aplicaciĆ³n VLC", + "mwe-embedplayer-vlcapp-downloadapp": "Descargar la aplicaciĆ³n VLC desde la App Store", + "mwe-embedplayer-vlcapp-openvideo": "Abre este video en la aplicaciĆ³n VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "Descarga este video", + "mwe-embedplayer-vlcapp-vlcapppopup": "Para reproducir videos en este sitio, necesitas la aplicaciĆ³n gratuita VLC. ĀæInstalar ahora?", + "mwe-embedplayer-iewebmprompt-intro": "Ā”Espere! Una cosa mĆ”s antes de que pueda ver este vĆdeo...", + "mwe-embedplayer-iewebmprompt-linktext": "Instalar componentes multimedia de WebM para Microsoft Internet Explorer", + "mwe-embedplayer-iewebmprompt-outro": "Recargar esta pĆ”gina despuĆ©s de la instalaciĆ³n." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/et.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/et.json new file mode 100644 index 00000000..587c9515 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/et.json @@ -0,0 +1,48 @@ +{ + "@metadata": { + "authors": [ + "Avjoska", + "Pikne" + ] + }, + "mwe-embedplayer-credit-title": "Pealkiri: $1", + "mwe-embedplayer-credit-date": "KuupƤev: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-loading_plugin": "Lisa laadimine...", + "mwe-embedplayer-missing_video_stream": "Selle voogedastuse jaoks puudub videofail.", + "mwe-embedplayer-play_clip": "Esita lƵik", + "mwe-embedplayer-pause_clip": "Peata lƵik", + "mwe-embedplayer-volume_control": "Helitugevuse seadmine", + "mwe-embedplayer-player_options": "Esitaja seaded", + "mwe-embedplayer-timed_text": "Ajastatud tekst", + "mwe-embedplayer-player_fullscreen": "TƤisekraan", + "mwe-embedplayer-paused": "peatatud", + "mwe-embedplayer-download_full": "Laadi alla terve videofail:", + "mwe-embedplayer-download_clip": "Laadi video alla", + "mwe-embedplayer-download_text": "Laadi tekst alla", + "mwe-embedplayer-download": "Laadi alla", + "mwe-embedplayer-share": "Jaga", + "mwe-embedplayer-credits": "Autorsus", + "mwe-embedplayer-clip_linkback": "LƵigu alliklehekĆ¼lg", + "mwe-embedplayer-choose_player": "Videoesitaja valimine", + "mwe-embedplayer-share_this_video": "Selle video jagamine", + "mwe-embedplayer-kaltura-platform-title": "Kaltura avatud lƤhtekoodiga videoplatvorm", + "mwe-embedplayer-menu_btn": "MenĆ¼Ć¼", + "mwe-embedplayer-close_btn": "Sule", + "mwe-embedplayer-do_not_warn_again": "Edaspidi Ƥra seda sƵnumit nƤita", + "mwe-embedplayer-playerSelect": "Esitajad", + "mwe-embedplayer-embed_site_or_blog": "Kasuta lehekĆ¼ljel", + "mwe-embedplayer-embed_wiki": "Kasuta vikis", + "mwe-embedplayer-seeking": "otsimine", + "mwe-embedplayer-buffering": "puhverdamine", + "mwe-embedplayer-video-h264": "H.264-video", + "mwe-embedplayer-video-webm": "WebM-video", + "mwe-embedplayer-video-flv": "Flash-video", + "mwe-embedplayer-video-ogg": "Ogg-video", + "mwe-embedplayer-video-audio": "Ogg-helifail", + "mwe-embedplayer-audio-mpeg": "MPEG-helifail", + "mwe-embedplayer-video-3gp": "3GP-video", + "mwe-embedplayer-video-mpeg": "MPEG-video", + "mwe-embedplayer-video-msvideo": "AVI-video", + "mwe-embedplayer-missing-source": "Allikvideot ei leitud." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/eu.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/eu.json new file mode 100644 index 00000000..ccfe919d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/eu.json @@ -0,0 +1,17 @@ +{ + "@metadata": { + "authors": [ + "Subi" + ] + }, + "mwe-embedplayer-credit-title": "Izenburua: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Egilea: $1", + "mwe-embedplayer-player_fullscreen": "Pantaila osoan", + "mwe-embedplayer-paused": "pausatua", + "mwe-embedplayer-download": "Jaitsi", + "mwe-embedplayer-share": "Partekatu", + "mwe-embedplayer-credits": "Kredituak", + "mwe-embedplayer-menu_btn": "Menua", + "mwe-embedplayer-close_btn": "Itxi" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fa.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fa.json new file mode 100644 index 00000000..1f4f2fe9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fa.json @@ -0,0 +1,87 @@ +{ + "@metadata": { + "authors": [ + "Armin1392", + "Ebraminio", + "Mjbmr", + "Pouyana", + "Reza1615", + "Ł¾Ų§ŁŲ§Ų±ŁŁ
Ų§" + ] + }, + "mwe-embedplayer-credit-title": "Ų¹ŁŁŲ§Ł: $1", + "mwe-embedplayer-credit-date": "ŲŖŲ§Ų±ŪŲ®: $1", + "mwe-embedplayer-credit-author": "ŁŁŪŲ³ŁŲÆŁ = $1", + "mwe-embedplayer-nocredits": "ŁŪŚ Ų§Ų¹ŲŖŲØŲ§Ų±Ū ŲÆŲ± ŲÆŲ³ŲŖŲ±Ų³ ŁŪŲ³ŲŖ", + "mwe-embedplayer-loading_plugin": "ŲÆŲ± ŲŲ§Ł ŲØŲ§Ų±ŚÆŪŲ±Ū Ų§ŁŲ²Ų§ŪŁ...", + "mwe-embedplayer-select_playback": "ŲŖŁŲøŪŁ
Ų§ŁŁŁŪŲŖ Ł¾Ų®Ų“", + "mwe-embedplayer-link_back": "Ł¾ŪŁŁŲÆ ŲØŲ§Ų²ŚÆŲ“ŲŖ", + "mwe-embedplayer-error_swap_vid": "Ų®Ų·Ų§: Ų§Ł
āŲÆŲØŁŪŁāŲ§ŁŁ
ŲØŲÆ ŁŲ§ŲÆŲ± ŲØŁ ŲŖŲ¹ŁŪŲ¶ ŲØŲ±ŚŲ³ŲØ ŁŪŁŁ
ŲØŲ±Ų§Ū Ų±Ų§ŲØŲ· Ų§Ł
āŲÆŲØŁŪŁāŲ§ŁŁ
ŲØŲÆ ŁŲØŁŲÆ", + "mwe-embedplayer-add_to_end_of_sequence": "Ų§Ų¶Ų§ŁŁ Ś©Ų±ŲÆŁ ŲØŁ Ų§ŁŲŖŁŲ§Ū ŲÆŁŲØŲ§ŁŁ", + "mwe-embedplayer-missing_video_stream": "Ł¾ŁŲ“Ł ŲŖŲµŁŪŲ±Ū ŲØŲ±Ų§Ū Ų§ŪŁ Ų¬Ų±ŪŲ§Ł Ų§Ų² ŲÆŲ³ŲŖ Ł
ŪāŲ±ŁŲÆ", + "mwe-embedplayer-play_clip": "ŁŲ“Ų§Ł ŲÆŲ§ŲÆŁ Ś©ŁŪŁ¾", + "mwe-embedplayer-pause_clip": "ŲŖŁŁŁ Ś©ŁŪŁ¾", + "mwe-embedplayer-volume_control": "ŲŖŁŲøŪŁ
ŲµŲÆŲ§", + "mwe-embedplayer-player_options": "ŚÆŲ²ŪŁŁāŁŲ§Ū ŲÆŲ³ŲŖŚÆŲ§Ł Ł¾Ų®Ų“", + "mwe-embedplayer-timed_text": "Ł
ŲŖŁ Ų²Ł
Ų§ŁāŲØŁŲÆŪā Ų“ŲÆŁ", + "mwe-embedplayer-player_fullscreen": "ŲŖŁ
Ų§Ł
ŲµŁŲŁ", + "mwe-embedplayer-next_clip_msg": "ŁŁ
Ų§ŪŲ“ Ś©ŁŪŁ¾ ŲØŲ¹ŲÆŪ", + "mwe-embedplayer-prev_clip_msg": "ŁŁ
Ų§ŪŲ“ Ś©ŁŪŁ¾ ŁŲØŁŪ", + "mwe-embedplayer-current_clip_msg": "Ų§ŲÆŲ§Ł
Ł ŲÆŲ§ŲÆŁ ŁŁ
Ų§ŪŲ“ Ś©ŁŪŁ¾", + "mwe-embedplayer-seek_to": "ŲÆŲ± Ų¬Ų³ŲŖŲ¬ŁŪ $1", + "mwe-embedplayer-paused": "Ł
Ś©Ų«", + "mwe-embedplayer-download_segment": "Ų§ŁŲŖŲ®Ų§ŲØ ŲÆŲ§ŁŁŁŲÆĖ", + "mwe-embedplayer-download_full": "ŲÆŲ±ŪŲ§ŁŲŖ Ł¾Ų±ŁŁŲÆŁŁ ŁŪŲÆŪŁŪŪ Ś©Ų§Ł
Ł:", + "mwe-embedplayer-download_right_click": "ŲØŲ±Ų§Ū ŲØŲ§Ų±ŚÆŪŲ±ŪŲ Ś©ŁŪŚ© Ų±Ų§Ų³ŲŖ Ś©ŁŪŲÆ Ł Ų§ŪŁ ŚÆŲ²ŪŁŁ Ų±Ų§ Ų§ŁŲŖŲ®Ų§ŲØ Ś©ŁŪŲÆ<i>Save link as...</i>", + "mwe-embedplayer-download_clip": "ŲÆŲ±ŪŲ§ŁŲŖ ŁŪŲÆŪŁ", + "mwe-embedplayer-download_text": "ŲÆŲ±ŪŲ§ŁŲŖ Ł
ŲŖŁ", + "mwe-embedplayer-download": "ŲÆŲ±ŪŲ§ŁŲŖ", + "mwe-embedplayer-share": "ŲØŁ Ų§Ų“ŲŖŲ±Ų§Ś© ŚÆŲ°Ų§Ų“ŲŖŁ", + "mwe-embedplayer-credits": "Ų§Ų¹ŲŖŲØŲ§Ų±", + "mwe-embedplayer-about-library": "ŲÆŲ±ŲØŲ§Ų±ŁŁāŚ©Ų§ŁŲŖŲ±Ų§ Ł¾ŁŪŲ±", + "mwe-embedplayer-about-library-desc": "Ś©ŲŖŲ§ŲØŲ®Ų§ŁŁ Ų±Ų³Ų§ŁŁ Ų§ŚāŲŖŪāŲ§Ł
āŲ§ŁŪµ Ś©Ų§ŁŲŖŁŲ±Ų§ ŲØŁ Ų“Ł
Ų§Ų±Ų§ ŁŲ§ŲÆŲ± ŲØŁ Ł
Ų²ŪŲŖ Ų§ŚāŲŖŪāŲ§Ł
āŲ§ŁŪµŁ Ų§ŁāŲŖŪŲŁŪŲÆŪŁŁ Ų¬ŪāŲŖŪŲ Ł Ų§ŁāŲŖŪŲŲµŁŲŖŪāŁŲ¬ŪāŲŖŪŲŲØŲ±ŚŲ³ŲØŁŲ§Ū Ų§Ł
Ų±ŁŲ² ŲØŲ§ Ų±Ų§ŲØŲ· ŲÆŲ³ŲŖŚÆŲ§Ł Ł¾Ų®Ų“ Ų³Ų§Ų²ŚÆŲ§Ų± ŲÆŲ± Ų³Ų±Ų§Ų³Ų± ŁŁ
Ł Ł
Ų±ŁŲ±ŚÆŲ±ŁŲ§Ū Ų§ŲµŁŪ Ł
ŪāŚ©ŁŲÆ.\n[ $1 ŲØŪŲ“ŲŖŲ± ŲÆŲ±ŲØŲ§Ų±Ł Ś©ŲŖŲ§ŲØŲ®Ų§ŁŁ Ł¾Ų®Ų“ Ś©Ų§ŁŲŖŁŲ±Ų§].", + "mwe-embedplayer-clip_linkback": "ŲµŁŲŁŁ Ł
ŁŲØŲ¹ Ś©ŁŪŁ¾", + "mwe-embedplayer-choose_player": "Ų§ŁŲŖŲ®Ų§ŲØ ŲÆŲ³ŲŖŚÆŲ§Ł Ł¾Ų®Ų“ ŁŪŲÆŪŁ", + "mwe-embedplayer-no-player": "ŲÆŲ³ŲŖŲ±Ų³Ū ŲØŁ Ł¾Ų®Ų“āŚ©ŁŁŲÆŁ ŁŲ¬ŁŲÆ ŁŲÆŲ§Ų±ŲÆ $1", + "mwe-embedplayer-share_this_video": "Ų§ŪŁ ŲŖŲµŁŪŲ± Ų±Ų§ ŲØŁ Ų§Ų“ŲŖŲ±Ų§Ś© ŚÆŲ°Ų§Ų±ŪŲÆ", + "mwe-embedplayer-video_credits": "Ų§Ų¹ŲŖŲØŲ§Ų±Ų§ŲŖ ŁŪŲÆŪŁ", + "mwe-embedplayer-no-video_credits": "ŁŪŚ Ų§Ų¹ŲŖŲØŲ§Ų±Ū ŲÆŲ± ŲÆŲ³ŲŖŲ±Ų³ ŁŪŲ³ŲŖ", + "mwe-embedplayer-kaltura-platform-title": "Ł
ŁŲØŲ¹ ŲØŲ§Ų² ŲµŲŁŁ ŁŪŲÆŪŁ Ś©Ų§ŁŲŖŁŲ±Ų§", + "mwe-embedplayer-menu_btn": "ŁŁŲ±Ų³ŲŖ", + "mwe-embedplayer-close_btn": "ŲØŲ³ŲŖŁ", + "mwe-embedplayer-ogg-player-vlc-player": "ŁŪāŲ§ŁāŲ³Ū Ł¾ŁŪŲ±", + "mwe-embedplayer-ogg-player-oggNative": "Ł¾Ų®Ų“ ŲµŁŲŖŪ Ų§ŚāŲŖŪāŲ§Ł
āŲ§ŁŪµ", + "mwe-embedplayer-ogg-player-mp3Native": "Ł¾Ų®Ų“ Ų§Ł
āŁ¾ŪāŲŖŲ±Ū Ų§ŚāŲŖŪāŲ§Ł
āŲ§ŁŪµ", + "mwe-embedplayer-ogg-player-aacNative": "Ł¾Ų®Ų“ Ų§ŪāŲ³ŪāŲ³Ū Ų§ŚāŲŖŪāŲ§Ł
āŲ§ŁŪµ", + "mwe-embedplayer-ogg-player-h264Native": "Ł¾Ų®Ų“ Ų§Ś.Ū²Ū¶Ū“ Ų§ŚāŲŖŪāŲ§Ł
āŲ§ŁŪµ", + "mwe-embedplayer-ogg-player-webmNative": "Ł¾Ų®Ų“ ŁŲØāŲ§Ł
Ų§ŚāŲŖŪāŲ§Ł
āŲ§ŁŪµ", + "mwe-embedplayer-ogg-player-oggPlugin": "Ł¾ŁŲ§ŚÆŪŁ ŲµŁŲŖŪ Ų¹Ł
ŁŁ
Ū", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Ł¾ŁŲ§ŚÆŪŁ Ų²Ł
Ų§Ł Ų²ŁŲÆ", + "mwe-embedplayer-ogg-player-quicktime-activex": "Ų§Ś©ŲŖŪŁāŲ§ŪŚ©Ų³ Ų²Ł
Ų§Ł Ų²ŁŲÆ", + "mwe-embedplayer-ogg-player-flowplayer": "Ł¾Ų®Ų“ Ų¬Ų±ŪŲ§Ł", + "mwe-embedplayer-ogg-player-kplayer": "Ł¾Ų®Ų“ Ś©Ų§ŁŲŖŲ±Ų§", + "mwe-embedplayer-ogg-player-selected": "(Ų§ŁŲŖŲ®Ų§ŲØ Ų“ŲÆŁ)", + "mwe-embedplayer-ogg-player-omtkplayer": "Ų§ŁāŲ§Ł
āŲŖŪāŚ©Ų§ ŁŁŲ“ ŁŁŲ±ŲØŪŲ³", + "mwe-embedplayer-for_best_experience": "ŲØŲ±Ų§Ū ŪŚ© ŲŖŲ¬Ų±ŲØŁ Ł¾Ų®Ų“ ŁŪŲÆŪŁ ŲØŁŲŖŲ±Ų Ł
Ų§ ŪŚ© <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5 video browser</a> Ų±Ų§ ŲŖŁŲµŪŁ Ł
ŪāŚ©ŁŪŁ
.", + "mwe-embedplayer-download-warn": "ŁŪŚ Ł¾Ų®Ų“ ŲÆŲ± Ł
Ų±ŁŲ±ŚÆŲ± Ų³Ų§Ų²ŚÆŲ§Ų±Ū Ų“ŁŲ§Ų³Ų§ŪŪ ŁŲ“ŲÆ: ŲØŲ±Ų§Ū Ł¾Ų®Ų“ ŲÆŲ± Ł
Ų±ŁŲ±ŚÆŲ±Ų ŁŲ·ŁŲ§Ł [ $1 Ų¢Ų®Ų±ŪŁ ŁŲ§ŪŲ±ŁŲ§Ś©Ų³] Ų±Ų§ ŲÆŲ§ŁŁŁŲÆ Ś©ŁŪŲÆ", + "mwe-embedplayer-fullscreen-tip": "ŁŲ“Ų§Ų± ŲÆŲ§ŲÆŁ <b>F11</b> ŲÆŚ©Ł
Ł <i> Ł
Ų±ŁŲ±ŚÆŲ± ŁŲØ </i> ŲŖŁ
Ų§Ł
ŲµŁŲŁ", + "mwe-embedplayer-fullscreen-tip-osx": "ŁŲ“Ų§Ų± ŲÆŲ§ŲÆŁ <b> Ś©ŁŪŲÆ Ł
ŲØŲÆŁ ā F</b> ŲØŁ ŲÆŚ©Ł
Ł ŲŖŁ
Ų§Ł
ŲµŁŲŁ", + "mwe-embedplayer-do_not_warn_again": "ŲÆŲ± Ų¢ŪŁŲÆŁŲ Ų§ŪŁ Ł¾ŪŲ§Ł
Ų±Ų§ ŁŲ“Ų§Ł ŁŲÆŁŪŲÆ", + "mwe-embedplayer-playerSelect": "ŲØŲ§Ų²ŪŚ©ŁŲ§Ł", + "mwe-embedplayer-read_before_embed": "<ahref=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\"> Ų§ŪŁ Ų±Ų§ </a> ŁŲØŁ Ų§Ų² Ų¬Ų§Ų³Ų§Ų²Ū ŲØŲ®ŁŲ§ŁŪŲÆ.", + "mwe-embedplayer-embed_site_or_blog": "ŁŲ±Ų§Ų± ŲÆŲ§ŲÆŁ ŲÆŲ± ŪŚ© ŲµŁŲŁ", + "mwe-embedplayer-embed_wiki": "ŁŲ±Ų§Ų± ŲÆŲ§ŲÆŁ ŲÆŲ± ŪŚ© ŁŪŚ©Ū", + "mwe-embedplayer-related_videos": "Ł
Ų±ŲŖŲØŲ· Ų“ŲÆŁ ŁŪŲÆŪŁāŁŲ§", + "mwe-embedplayer-seeking": "ŲÆŲ± ŲŲ§Ł Ł¾ŪŚÆŲ±ŲÆ", + "mwe-embedplayer-buffering": "ŲÆŲ± ŲŲ§Ł ŲØŲ§ŁŲ±", + "mwe-embedplayer-video-h264": "ŁŪŲÆŪŁ Ų§Ś.Ū²Ū¶Ū“", + "mwe-embedplayer-video-webm": "ŁŪŲÆŪŁ ŁŲØāŲ§Ł
", + "mwe-embedplayer-video-flv": "ŁŁŲ“ ŁŪŲÆŪŁ", + "mwe-embedplayer-video-ogg": "ŲµŁŲŖŪ ŲŖŲµŁŪŲ±Ū", + "mwe-embedplayer-video-audio": "Ų¢ŁŁŚÆ ŲµŁŲŖŪ", + "mwe-embedplayer-audio-mpeg": "Ų§Ł
āŁ¾ŪāŲ§ŪāŲ¬Ū ŲµŁŲŖŪ", + "mwe-embedplayer-video-3gp": "ŁŪŲÆŪŁ Ū³āŲ¬ŪāŁ¾Ū", + "mwe-embedplayer-video-mpeg": "ŁŪŲÆŪŁ Ų§Ł
āŁ¾ŪāŲ§ŪāŲ¬Ū", + "mwe-embedplayer-video-msvideo": "ŁŪŲÆŪŁ Ų§ŪāŁŪāŲ¢Ū", + "mwe-embedplayer-missing-source": "ŁŪŚ Ł
ŁŲØŲ¹ ŁŪŲÆŲ¦ŁŪŪ Ł¾ŪŲÆŲ§ ŁŲ“ŲÆ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fi.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fi.json new file mode 100644 index 00000000..21ac8482 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fi.json @@ -0,0 +1,41 @@ +{ + "@metadata": { + "authors": [ + "Crt", + "Nedergard", + "Nike", + "Silvonen", + "Tofu II", + "MrTapsa" + ] + }, + "mwe-embedplayer-credit-title": "Otsikko: $1", + "mwe-embedplayer-credit-date": "PƤivƤmƤƤrƤ: $1", + "mwe-embedplayer-credit-author": "TekijƤ: $1", + "mwe-embedplayer-loading_plugin": "Ladataan liitƤnnƤistƤ...", + "mwe-embedplayer-player_options": "Soittimen asetukset", + "mwe-embedplayer-timed_text": "Ajastettu teksti", + "mwe-embedplayer-player_fullscreen": "Koko nƤyttƶ", + "mwe-embedplayer-download_full_video": "Lataa koko videotiedosto:", + "mwe-embedplayer-download_full_audio": "Lataa koko ƤƤnitiedosto:", + "mwe-embedplayer-download_clip": "Lataa video", + "mwe-embedplayer-download_text": "Lataa teksti", + "mwe-embedplayer-download": "Lataa", + "mwe-embedplayer-share": "Jaa", + "mwe-embedplayer-about-library": "Tietoja Kaltura-soittimesta", + "mwe-embedplayer-share_this_video": "Jaa tƤmƤ video", + "mwe-embedplayer-share_this_audio": "Jaa tƤmƤ ƤƤnitiedosto", + "mwe-embedplayer-menu_btn": "Valikko", + "mwe-embedplayer-close_btn": "Sulje", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura-soitin", + "mwe-embedplayer-ogg-player-selected": "(valittu)", + "mwe-embedplayer-for_best_experience": "Parempaa videotoistokokemusta varten suosituksena on selain, joka <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">tukee HTML5-videota</a>.", + "mwe-embedplayer-video-h264": "H.264-video", + "mwe-embedplayer-video-webm": "WebM-video", + "mwe-embedplayer-video-flv": "Flash-video", + "mwe-embedplayer-video-ogg": "Ogg-video", + "mwe-embedplayer-video-3gp": "3GP-video", + "mwe-embedplayer-video-mpeg": "MPEG-video", + "mwe-embedplayer-video-msvideo": "AVI-video" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fr.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fr.json new file mode 100644 index 00000000..c7877923 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fr.json @@ -0,0 +1,97 @@ +{ + "@metadata": { + "authors": [ + "Brunoperel", + "Crochet.david", + "Gomoko", + "IAlex", + "Nnemo", + "Peter17", + "Windes" + ] + }, + "mwe-embedplayer-credit-title": "Titre : $1", + "mwe-embedplayer-credit-date": "Date : $1", + "mwe-embedplayer-credit-author": "Auteur : $1", + "mwe-embedplayer-nocredits": "Aucun crĆ©dit disponible", + "mwe-embedplayer-loading_plugin": "chargement du greffon ...", + "mwe-embedplayer-select_playback": "DĆ©finir les prĆ©fĆ©rences de lecture", + "mwe-embedplayer-link_back": "Lien retour", + "mwe-embedplayer-error_swap_vid": "Erreur : mv_embed n'a pas rĆ©ussi Ć Ć©changer l'attribut de la vidĆ©o pour l'interface mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "Ajouter Ć la fin de la sĆ©quence", + "mwe-embedplayer-missing_video_stream": "Le fichier vidĆ©o pour ce flux est manquant", + "mwe-embedplayer-play_clip": "Lire le clip", + "mwe-embedplayer-pause_clip": "Mettre le clip en pause", + "mwe-embedplayer-volume_control": "ContrĆ“le du volume", + "mwe-embedplayer-player_options": "Options du lecteur", + "mwe-embedplayer-timed_text": "Texte synchronisĆ©", + "mwe-embedplayer-player_fullscreen": "Plein Ć©cran", + "mwe-embedplayer-next_clip_msg": "Lire le clip suivant", + "mwe-embedplayer-prev_clip_msg": "Lire le clip prĆ©cĆ©dent", + "mwe-embedplayer-current_clip_msg": "Poursuivre la lecture de ce clip", + "mwe-embedplayer-seek_to": "Atteindre $1", + "mwe-embedplayer-paused": "en pause", + "mwe-embedplayer-download_segment": "TĆ©lĆ©charger la sĆ©lection :", + "mwe-embedplayer-download_full_video": "TĆ©lĆ©charger le fichier de la vidĆ©o complĆØte :", + "mwe-embedplayer-download_right_click": "Pour tĆ©lĆ©charger, cliquez-droit et sĆ©lectionnez <i>Enregistrer la cible du lien sous...</i>", + "mwe-embedplayer-download_clip": "TĆ©lĆ©charger la vidĆ©o", + "mwe-embedplayer-download_text": "TĆ©lĆ©charger le texte", + "mwe-embedplayer-download": "TĆ©lĆ©charger", + "mwe-embedplayer-share": "Partager", + "mwe-embedplayer-credits": "CrĆ©dits", + "mwe-embedplayer-about-library": "Ć propos du lecteur Kaltura", + "mwe-embedplayer-about-library-desc": "La bibliothĆØque HTML5 de Kaltura vous permet de profiter des balises HTML5 <code><nowiki><video></nowiki></code> et <code><nowiki><audio></nowiki></code> dĆØs Ć prĆ©sent avec un lecteur et une interface compatibles avec tous les principaux navigateurs.\n\t\n[$1 Pour en savoir plus sur la bibliothĆØque de lecture Kaltura].", + "mwe-embedplayer-clip_linkback": "Page source du clip", + "mwe-embedplayer-choose_player": "Choisir le lecteur vidĆ©o", + "mwe-embedplayer-no-player": "Aucun lecteur disponible pour $1", + "mwe-embedplayer-share_this_video": "Partager cette vidĆ©o", + "mwe-embedplayer-share_this_audio": "Partager ce fichier audio", + "mwe-embedplayer-video_credits": "CrĆ©dits de la vidĆ©o", + "mwe-embedplayer-no-video_credits": "Aucun crĆ©dit disponible", + "mwe-embedplayer-kaltura-platform-title": "Plateforme vidĆ©o en source ouverte Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Fermer", + "mwe-embedplayer-ogg-player-vlc-player": "Lecteur VLC", + "mwe-embedplayer-ogg-player-oggNative": "Lecteur Ogg HTML5", + "mwe-embedplayer-ogg-player-mp3Native": "Lecteur MP3 HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Lecteur AAC HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Lecteur H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Lecteur WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Module gĆ©nĆ©rique Ogg", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC pour application iOS", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Module QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Lecteur Kaltura", + "mwe-embedplayer-ogg-player-selected": "(sĆ©lectionnĆ©)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Pour un meilleur visionnage de la vidĆ©o, nous recommandons un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navigateur vidĆ©o HTML5</a>.", + "mwe-embedplayer-download-warn": "Aucun navigateur web compatible dĆ©tectĆ©: pour une lecteur intĆ©grĆ© au navigateur, veuillez tĆ©lĆ©charger la [$1 derniĆØre version de Firefox]", + "mwe-embedplayer-fullscreen-tip": "Appuyez sur <b>F11</b> pour basculer le <i>navigateur web</i> en mode plein Ć©cran", + "mwe-embedplayer-fullscreen-tip-osx": "Appuyez sur <b>maj ā F</b> pour basculer en plein Ć©cran", + "mwe-embedplayer-do_not_warn_again": "Ne plus afficher ce message Ć l'avenir", + "mwe-embedplayer-playerSelect": "Lecteurs", + "mwe-embedplayer-read_before_embed": "Veuillez <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">lire ceci</a> avant de procĆ©der !", + "mwe-embedplayer-embed_site_or_blog": "IntĆ©grer dans une page", + "mwe-embedplayer-embed_wiki": "IntĆ©grĆ© dans un wiki", + "mwe-embedplayer-related_videos": "VidĆ©os associĆ©es", + "mwe-embedplayer-seeking": "recherche", + "mwe-embedplayer-buffering": "mise en mĆ©moire tampon", + "mwe-embedplayer-video-h264": "vidĆ©o H.264", + "mwe-embedplayer-video-webm": "VidĆ©o WebM", + "mwe-embedplayer-video-flv": "vidĆ©o Flash", + "mwe-embedplayer-video-ogg": "vidĆ©o Ogg", + "mwe-embedplayer-video-audio": "Audio Ogg", + "mwe-embedplayer-audio-mpeg": "Audio MPEG", + "mwe-embedplayer-video-3gp": "VidĆ©o 3GP", + "mwe-embedplayer-video-mpeg": "VidĆ©o MPEG", + "mwe-embedplayer-video-msvideo": "VidĆ©o AVI", + "mwe-embedplayer-missing-source": "Aucune source vidĆ©o n'a Ć©tĆ© trouvĆ©e.", + "mwe-embedplayer-vlcapp-intro": "Afin de visualiser les vidĆ©os de ce site sur un iPhone ou un iPad, vous avez besoin de $1, gratuite.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "Application VLC", + "mwe-embedplayer-vlcapp-downloadapp": "TĆ©lĆ©charger lāapplication VLC depuis lāApp Store", + "mwe-embedplayer-vlcapp-openvideo": "Ouvrir cette vidĆ©o dans lāapplication VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "TĆ©lĆ©charger cette vidĆ©o", + "mwe-embedplayer-vlcapp-vlcapppopup": "Pour jouer des vidĆ©os sur ce site, vous avez besoin de lāapplication gratuite VLC. Lāinstaller maintenantāÆ?" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/frp.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/frp.json new file mode 100644 index 00000000..d70988ea --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/frp.json @@ -0,0 +1,76 @@ +{ + "@metadata": { + "authors": [ + "ChrisPtDe" + ] + }, + "mwe-embedplayer-credit-title": "Titro : $1", + "mwe-embedplayer-credit-date": "DĆ¢ta : $1", + "mwe-embedplayer-credit-author": "Ćtor : $1", + "mwe-embedplayer-nocredits": "Gins de crĆØdit disponiblo", + "mwe-embedplayer-loading_plugin": "Chargement du modulo dāĆØxtension ...", + "mwe-embedplayer-select_playback": "DĆØfenir les prĆØferences de lĆØctura", + "mwe-embedplayer-link_back": "Lim retĆ“rn", + "mwe-embedplayer-error_swap_vid": "Ćrror : mv_embed at pas reussi a ĆØchangiĆ©r la balisa de la vidĆØĆ“ por lāentĆØrface mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "Apondre a la fin de la sĆØquence", + "mwe-embedplayer-missing_video_stream": "Lo fichiĆ©r vidĆØĆ“ por cĆ©l flux est manquent", + "mwe-embedplayer-play_clip": "LiĆ©re lo clipe", + "mwe-embedplayer-pause_clip": "Betar lo clipe en pousa", + "mwe-embedplayer-volume_control": "ContrĆ“lo du volumo", + "mwe-embedplayer-player_options": "ChouĆØx du liĆ©sor", + "mwe-embedplayer-timed_text": "TĆØxto sincronisĆ¢", + "mwe-embedplayer-player_fullscreen": "Plen ĆØcran", + "mwe-embedplayer-next_clip_msg": "LiĆ©re lo clipe aprĆ©s", + "mwe-embedplayer-prev_clip_msg": "LiĆ©re lo clipe devant", + "mwe-embedplayer-current_clip_msg": "Porsiuvre la lĆØctura de ceti clipe", + "mwe-embedplayer-seek_to": "AvengiĆ©r $1", + "mwe-embedplayer-paused": "en pousa", + "mwe-embedplayer-download_segment": "TĆØlĆØchargiĆ©r lo chouĆØx :", + "mwe-embedplayer-download_full": "TĆØlĆØchargiĆ©r lo fichiĆ©r vidĆØĆ“ complĆØt :", + "mwe-embedplayer-download_right_click": "Por tĆØlĆØchargiĆ©r, clicĆ¢d-drĆŖt et puĆ©s chouĆØsĆ©ssĆ©d <i>Encartar la ciba du lim desot...</i>", + "mwe-embedplayer-download_clip": "TĆØlĆØchargiĆ©r la vidĆØĆ“", + "mwe-embedplayer-download_text": "TĆØlĆØchargiĆ©r lo tĆØxto", + "mwe-embedplayer-download": "TĆØlĆØchargiĆ©r", + "mwe-embedplayer-share": "PartagiĆ©r", + "mwe-embedplayer-credits": "CrĆØdits", + "mwe-embedplayer-about-library": "Sur lo liĆ©sor Kaltura", + "mwe-embedplayer-clip_linkback": "PĆ¢ge sĆ“rsa du clipe", + "mwe-embedplayer-choose_player": "ChouĆØsir lo liĆ©sor vidĆØĆ“", + "mwe-embedplayer-no-player": "Gins de liĆ©sor disponiblo por $1", + "mwe-embedplayer-share_this_video": "PartagiĆ©r ceta vidĆØĆ“", + "mwe-embedplayer-video_credits": "CrĆØdits de la vidĆØĆ“", + "mwe-embedplayer-no-video_credits": "Gins de crĆØdit disponiblo", + "mwe-embedplayer-kaltura-platform-title": "PlatafĆ“rma vidĆØĆ“ a sĆ“rsa uvĆØrta Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "CllĆ“re", + "mwe-embedplayer-ogg-player-vlc-player": "LiĆ©sor VLC", + "mwe-embedplayer-ogg-player-oggNative": "LiĆ©sor Ogg HTML5", + "mwe-embedplayer-ogg-player-h264Native": "LiĆ©sor H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "LiĆ©sor WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Modulo dāĆØxtension gĀ·ĆØnĆØrico Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Modulo dāĆØxtension QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "LiĆ©sor Kaltura", + "mwe-embedplayer-ogg-player-selected": "(chouĆØsi)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-fullscreen-tip": "ApoyĆ©d dessus <b>F11</b> por bascular lo <i>navigator vouĆØbe</i> en plen ĆØcran", + "mwe-embedplayer-fullscreen-tip-osx": "ApoyĆ©d dessus <b>granta lĆØtra (''shift'') ā F</b> por bascular en plen ĆØcran", + "mwe-embedplayer-do_not_warn_again": "Pas mĆ©s fĆ¢re vĆŖre cĆ©l mĆØssĆ¢jo a lāavegnir.", + "mwe-embedplayer-playerSelect": "LiĆ©sors", + "mwe-embedplayer-read_before_embed": "VolyĆ©d <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">liĆ©re cen</a> devant quāapondre !", + "mwe-embedplayer-embed_site_or_blog": "Apondre a una pĆ¢ge", + "mwe-embedplayer-related_videos": "VidĆØĆ“s associyĆŖs", + "mwe-embedplayer-seeking": "rechĆØrche", + "mwe-embedplayer-buffering": "misa en mĆØmouĆØre tampon", + "mwe-embedplayer-video-h264": "VidĆØĆ“ H.264", + "mwe-embedplayer-video-webm": "VidĆØĆ“ WebM", + "mwe-embedplayer-video-flv": "VidĆØĆ“ Flash", + "mwe-embedplayer-video-ogg": "VidĆØĆ“ Ogg", + "mwe-embedplayer-video-audio": "ĆdiĆ“ Ogg", + "mwe-embedplayer-audio-mpeg": "ĆdiĆ“ MPEG", + "mwe-embedplayer-video-3gp": "VidĆØĆ“ 3GP", + "mwe-embedplayer-video-mpeg": "VidĆØĆ“ MPEG", + "mwe-embedplayer-video-msvideo": "VidĆØĆ“ AVI", + "mwe-embedplayer-missing-source": "Niona sĆ“rsa vidĆØĆ“ at Ć©tĆ¢ trovĆ¢." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fy.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fy.json new file mode 100644 index 00000000..7c57dd3e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/fy.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Robin0van0der0vliet" + ] + }, + "mwe-embedplayer-player_fullscreen": "Folsleinskerm", + "mwe-embedplayer-close_btn": "Slute" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ga.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ga.json new file mode 100644 index 00000000..1333c22d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ga.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "mwe-embedplayer-close_btn": "DĆŗn" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/gl.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/gl.json new file mode 100644 index 00000000..252f08a2 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/gl.json @@ -0,0 +1,96 @@ +{ + "@metadata": { + "authors": [ + "ToliƱo", + "Elisardojm" + ] + }, + "mwe-embedplayer-credit-title": "TĆtulo: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "Non hai crĆ©ditos dispoƱibles", + "mwe-embedplayer-loading_plugin": "Cargando o complemento...", + "mwe-embedplayer-select_playback": "Configurar as preferencias de reproduciĆ³n", + "mwe-embedplayer-link_back": "LigazĆ³n de volta", + "mwe-embedplayer-error_swap_vid": "Erro: mwEmbed foi incapaz de cambiar a etiqueta do vĆdeo para a interface mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Engadir ao final da secuencia", + "mwe-embedplayer-missing_video_stream": "Falta o ficheiro de vĆdeo para ese fluxo", + "mwe-embedplayer-play_clip": "Reproducir o vĆdeo", + "mwe-embedplayer-pause_clip": "PĆ³r o vĆdeo en pausa", + "mwe-embedplayer-volume_control": "Control do volume", + "mwe-embedplayer-player_options": "OpciĆ³ns do reprodutor", + "mwe-embedplayer-timed_text": "Texto sincronizado", + "mwe-embedplayer-player_fullscreen": "Pantalla completa", + "mwe-embedplayer-next_clip_msg": "Reproducir o seguinte vĆdeo", + "mwe-embedplayer-prev_clip_msg": "Reproducir o vĆdeo anterior", + "mwe-embedplayer-current_clip_msg": "Continuar a reproduciĆ³n deste vĆdeo", + "mwe-embedplayer-seek_to": "Buscar $1", + "mwe-embedplayer-paused": "en pausa", + "mwe-embedplayer-download_segment": "Descargar a selecciĆ³n:", + "mwe-embedplayer-download_full_video": "Descargar o ficheiro de vĆdeo completo:", + "mwe-embedplayer-download_full_audio": "Descargar o ficheiro de son completo:", + "mwe-embedplayer-download_right_click": "Para descargar, faga clic dereito e seleccione <i>Gardar a ligazĆ³n como...</i>", + "mwe-embedplayer-download_clip": "Descargar o vĆdeo", + "mwe-embedplayer-download_text": "Descargar o texto", + "mwe-embedplayer-download": "Descargar", + "mwe-embedplayer-share": "Compartir", + "mwe-embedplayer-credits": "CrĆ©ditos", + "mwe-embedplayer-about-library": "Acerca do reprodutor Kaltura", + "mwe-embedplayer-about-library-desc": "A biblioteca HTML5 do Kaltura permite sacar proveito das etiquetas <code><nowiki><video></nowiki></code> e <code><nowiki><audio></nowiki></code> do HTML5 cun reprodutor e unha interface compatibles cos principais navegadores.\n\t\n[$1 MĆ”is informaciĆ³n sobre a biblioteca do reprodutor Kaltura].", + "mwe-embedplayer-clip_linkback": "PĆ”xina de orixe do vĆdeo", + "mwe-embedplayer-choose_player": "Escolla o reprodutor de vĆdeo", + "mwe-embedplayer-no-player": "Non hai ningĆŗn reprodutor dispoƱible para $1", + "mwe-embedplayer-share_this_video": "Compartir este vĆdeo", + "mwe-embedplayer-share_this_audio": "Compartir este ficheiro de son", + "mwe-embedplayer-video_credits": "CrĆ©ditos do vĆdeo", + "mwe-embedplayer-no-video_credits": "Non hai crĆ©ditos dispoƱibles", + "mwe-embedplayer-kaltura-platform-title": "Plataforma de vĆdeo de cĆ³digo aberto Kaltura", + "mwe-embedplayer-menu_btn": "MenĆŗ", + "mwe-embedplayer-close_btn": "Pechar", + "mwe-embedplayer-ogg-player-vlc-player": "Reprodutor VLC", + "mwe-embedplayer-ogg-player-oggNative": "Reprodutor Ogg HTML5", + "mwe-embedplayer-ogg-player-mp3Native": "Reprodutor MP3 HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Reprodutor AAC HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Reprodutor H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Reprodutor WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Complemento xenĆ©rico Ogg", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC para aplicaciĆ³n iOS", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Complemento QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Reprodutor Kaltura", + "mwe-embedplayer-ogg-player-selected": "(seleccionado)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Para unha mellor experiencia de reproduciĆ³n de vĆdeo recomendamos un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navegador de vĆdeo HTML5</a>.", + "mwe-embedplayer-download-warn": "Non se detectou ningĆŗn reprodutor integrado compatible co navegador: Para ter unha mellor experiencia de reproduciĆ³n de vĆdeo recomendamos a [$1 Ćŗltima versiĆ³n do Firefox]", + "mwe-embedplayer-fullscreen-tip": "Prema <b>F11</b> para activar ou desactivar a pantalla completa do <i>navegador web</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Prema <b>maiĆŗs ā F</b> para activar ou desactivar a pantalla completa", + "mwe-embedplayer-do_not_warn_again": "Non mostrar esta mensaxe no futuro.", + "mwe-embedplayer-playerSelect": "Reprodutores", + "mwe-embedplayer-read_before_embed": "Por favor, <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">olle isto</a> antes da inserciĆ³n.", + "mwe-embedplayer-embed_site_or_blog": "Integrar nunha pĆ”xina", + "mwe-embedplayer-embed_wiki": "Integrar nun wiki", + "mwe-embedplayer-related_videos": "VĆdeos relacionados", + "mwe-embedplayer-seeking": "procurando", + "mwe-embedplayer-buffering": "cargando no bĆŗfer", + "mwe-embedplayer-video-h264": "VĆdeo H.264", + "mwe-embedplayer-video-webm": "VĆdeo WebM", + "mwe-embedplayer-video-flv": "VĆdeo Flash", + "mwe-embedplayer-video-ogg": "VĆdeo Ogg", + "mwe-embedplayer-video-audio": "Son Ogg", + "mwe-embedplayer-audio-mpeg": "Son MPEG", + "mwe-embedplayer-video-3gp": "VĆdeo 3gp", + "mwe-embedplayer-video-mpeg": "VĆdeo MPEG", + "mwe-embedplayer-video-msvideo": "VĆdeo AVI", + "mwe-embedplayer-missing-source": "Non se atopou o vĆdeo de orixe.", + "mwe-embedplayer-vlcapp-intro": "Para ver vĆdeos deste sitio nun iPhone ou iPad, necesita a $1 gratuĆta.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "AplicaciĆ³n VLC", + "mwe-embedplayer-vlcapp-downloadapp": "Descargar a aplicaciĆ³n VLC desde a App Store", + "mwe-embedplayer-vlcapp-openvideo": "Abrir este vĆdeo na aplicaciĆ³n VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "Descargar este vĆdeo", + "mwe-embedplayer-vlcapp-vlcapppopup": "Para reproducir vĆdeos neste sitio, necesita a aplicaciĆ³n gratuĆta VLC. Instalar agora?", + "mwe-embedplayer-iewebmprompt-intro": "Oops! Unha cousa mĆ”is antes de que poida ver este vĆdeo...", + "mwe-embedplayer-iewebmprompt-linktext": "Instalar compoƱentes multimedia de WebM para Microsoft Internet Explorer", + "mwe-embedplayer-iewebmprompt-outro": "Recargar esta pĆ”xina despois da instalaciĆ³n." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/grc.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/grc.json new file mode 100644 index 00000000..c85efb15 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/grc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Crazymadlover" + ] + }, + "mwe-embedplayer-credit-date": "į¼©Ī¼ĪµĻĪæĪ¼Ī·Ī½ĪÆĪ±: $1" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/gsw.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/gsw.json new file mode 100644 index 00000000..129b03cc --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/gsw.json @@ -0,0 +1,80 @@ +{ + "@metadata": { + "authors": [ + "Als-ChlƤmens", + "Als-Holder" + ] + }, + "mwe-embedplayer-credit-title": "Titel: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-loading_plugin": "Am Lade vum Plugin ...", + "mwe-embedplayer-select_playback": "Yystellige fir s Abspile setze", + "mwe-embedplayer-link_back": "Link retur", + "mwe-embedplayer-error_swap_vid": "FƤhler: mv_embed het s Video-Tag fir d mv_embed-Oberflechi nit chenne uustusche", + "mwe-embedplayer-add_to_end_of_sequence": "Am Ćnd vum Abschnitt yyfiege", + "mwe-embedplayer-missing_video_stream": "D Videodatei fir dƤƤ Strang fƤhlt", + "mwe-embedplayer-play_clip": "Clip abspile", + "mwe-embedplayer-pause_clip": "Clip aahalte", + "mwe-embedplayer-volume_control": "Yystellig fir d Lutsterki", + "mwe-embedplayer-player_options": "Yystellige fir s Abspilprogramm", + "mwe-embedplayer-timed_text": "Ćchtzyt-Text", + "mwe-embedplayer-player_fullscreen": "Vollbildschrim", + "mwe-embedplayer-next_clip_msg": "Dr negscht Clip abspile", + "mwe-embedplayer-prev_clip_msg": "Dr vorig Clip abspile", + "mwe-embedplayer-current_clip_msg": "DƤƤ Clip wyter abspile", + "mwe-embedplayer-seek_to": "$1 sueche", + "mwe-embedplayer-paused": "pausiert", + "mwe-embedplayer-download_segment": "Uuswahl zum Abelade:", + "mwe-embedplayer-download_full": "Di ganz Videodatei abelade:", + "mwe-embedplayer-download_right_click": "Zum Abelade druck uf di rƤcht Muustaschte un wehl <i>Link spychere unter...</i> uus", + "mwe-embedplayer-download_clip": "Video abelade", + "mwe-embedplayer-download_text": "Tekscht abelade", + "mwe-embedplayer-download": "Abelade", + "mwe-embedplayer-share": "Ufteile", + "mwe-embedplayer-credits": "AnerkƤnnige", + "mwe-embedplayer-about-library": "Iber dr Kaltura-Player", + "mwe-embedplayer-about-library-desc": "D HTML5-Mediebibliothek vu Kaltura macht s megli d Vorteil vu dr beide HTML5-Tags <code><nowiki><video></nowiki></code> un <code><nowiki><audio></nowiki></code> mit eim eiheitlige Player-Interface bi allne fierende Webbrowser z bruche.\n\n[$1 Meh Informatione zue dr HTML5-Mediebibliothek vu Kaltura].", + "mwe-embedplayer-clip_linkback": "Clip-QuƤllsyte", + "mwe-embedplayer-choose_player": "Videospiler uuswehle", + "mwe-embedplayer-no-player": "Fir $1 isch kei Player verfiegbar", + "mwe-embedplayer-share_this_video": "Des Video teile", + "mwe-embedplayer-video_credits": "Videokredit", + "mwe-embedplayer-no-video_credits": "Kei UrheberrƤchtsaagabe verfiegbar", + "mwe-embedplayer-kaltura-platform-title": "Kaltura Open-Source-Video-Plattform", + "mwe-embedplayer-menu_btn": "Uuswahl", + "mwe-embedplayer-close_btn": "Zuemache", + "mwe-embedplayer-ogg-player-vlc-player": "VLC-Player", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg-Player", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264-Player", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM-Player", + "mwe-embedplayer-ogg-player-oggPlugin": "Generisch Ogg-Plugin", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-Plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura-Player", + "mwe-embedplayer-ogg-player-selected": "(uusgwehlt)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Fir e besseri Abspilqualitet vu dƤm Video empfƤhle mir:<br /><a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Firefox 3.5</a>.", + "mwe-embedplayer-download-warn": "S Wiidergabeprogramm im Browser isch nit kompatibel. Zume im Browser aaluege, due bitte d [$1 nƶisti Version vo Firefox] abelade.", + "mwe-embedplayer-fullscreen-tip": "D Taschte <b>F11</b> drugge, zume uff de Vollbildmodus vum <i>Webbrowsers</i> umzschalte.", + "mwe-embedplayer-fullscreen-tip-osx": "D Taschte <b>UMSCHALT ā F</b> drugge, zume uff de Vollbildmodus vum <i>Webbrowsers</i> umzschalte.", + "mwe-embedplayer-do_not_warn_again": "Die MƤldig ab jetz nĆ¼mm aazeige.", + "mwe-embedplayer-playerSelect": "Player", + "mwe-embedplayer-read_before_embed": "Bitte lis d <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Sicherheitsnotize iber s Yyfiege</a> voreb Du s wirkli yyfiege tuesch!", + "mwe-embedplayer-embed_site_or_blog": "Yybunde in e Syte", + "mwe-embedplayer-related_videos": "Verwandti Video", + "mwe-embedplayer-seeking": "Am Sueche", + "mwe-embedplayer-buffering": "pufferet", + "mwe-embedplayer-video-h264": "H.264-Video", + "mwe-embedplayer-video-webm": "WebM-Video", + "mwe-embedplayer-video-flv": "Flash-Video", + "mwe-embedplayer-video-ogg": "Ogg-Video", + "mwe-embedplayer-video-audio": "Ogg-Audiodatei", + "mwe-embedplayer-audio-mpeg": "MPEG-Audio", + "mwe-embedplayer-video-3gp": "3gp-Video", + "mwe-embedplayer-video-mpeg": "MPEG-Video", + "mwe-embedplayer-video-msvideo": "AVI-Video", + "mwe-embedplayer-missing-source": "S isch kei Videoclip gfunde wore." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/he.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/he.json new file mode 100644 index 00000000..f12abe37 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/he.json @@ -0,0 +1,83 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Guycn2", + "Inkbug", + "YaronSh" + ] + }, + "mwe-embedplayer-credit-title": "×××Ŗ×Ø×Ŗ: $1", + "mwe-embedplayer-credit-date": "×Ŗ××Ø××: $1", + "mwe-embedplayer-credit-author": "××צ×Ø: $1", + "mwe-embedplayer-nocredits": "××× ×§×Ø×××××", + "mwe-embedplayer-loading_plugin": "××¢×× ×Ŗ ×Ŗ××”×£...", + "mwe-embedplayer-select_playback": "××××Ø×Ŗ ××¢×פ××Ŗ × ××× ×", + "mwe-embedplayer-link_back": "ק×ש××Ø ×××Ø×", + "mwe-embedplayer-error_swap_vid": "ש××××: mwEmbed ×× ××× ××”××× ××××××£ ××Ŗ ×Ŗ× ××××××× ×©× ××שק mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "××”××£ ××Øצף", + "mwe-embedplayer-missing_video_stream": "ק××ׄ ××××××× ×¢×××Ø ××Ø× ×× ××”×Ø", + "mwe-embedplayer-play_clip": "× ××× ×Ŗ ××”×Ø×××", + "mwe-embedplayer-pause_clip": "×ש××××Ŗ ××”×Ø×××", + "mwe-embedplayer-volume_control": "×ק×Ø×Ŗ ×¢×צ××Ŗ ×ש××¢", + "mwe-embedplayer-player_options": "×פש×Ø××××Ŗ ×× ××", + "mwe-embedplayer-timed_text": "××§×”× ××Ŗ××××", + "mwe-embedplayer-player_fullscreen": "××”× ×××", + "mwe-embedplayer-next_clip_msg": "× ××× ×Ŗ ××”×Ø××× ×××", + "mwe-embedplayer-prev_clip_msg": "× ××× ×Ŗ ××”×Ø××× ×ק×××", + "mwe-embedplayer-current_clip_msg": "×××©× × ××× ×Ŗ ××”×Ø×××", + "mwe-embedplayer-seek_to": "××פ×ש $1", + "mwe-embedplayer-paused": "××ש××", + "mwe-embedplayer-download_segment": "×××Ø××Ŗ ×××××Ø×:", + "mwe-embedplayer-download_full": "××××Ø×× ××××©× ××Ŗ ק××ׄ ××××××× ××××:", + "mwe-embedplayer-download_right_click": "××× ××××Ø××, ×××¦× ××פ×Ŗ××Ø ××× × ×©× ××¢×××Ø ××××Ø× ××פש×Ø××Ŗ \"ש×××Ø× ×ש×...\" (<i>Save Link As ...</i>)", + "mwe-embedplayer-download_clip": "×××Ø××Ŗ ×××××××", + "mwe-embedplayer-download_text": "××××Ø×× ××××©× ××Ŗ ××קה×", + "mwe-embedplayer-download": "×××Ø××", + "mwe-embedplayer-share": "ש××Ŗ××£", + "mwe-embedplayer-credits": "×Ŗ××××Ŗ", + "mwe-embedplayer-about-library": "×¢× ×××××Ŗ ×× ×× ×§××××Ø×", + "mwe-embedplayer-about-library-desc": "הפ×Ø×××Ŗ ×× ××× ×Ŗ ×××× ××Ŗ×§× HTML5 ×©× ×§××××Ø× ××פש×Ø×Ŗ ××× ××ש×Ŗ×ש ×פק××××Ŗ <code><nowiki><video></nowiki></code> ×Ö¾<code><nowiki><audio></nowiki></code> ×©× HTML5 ×××× ×¢× ××שק ק×××¢ ××× ××פ××¤× ×× ×× ×¤×צ××.\n\n[$1 ××××¢ × ××”×£ ×¢× ×”×¤×Ø×××Ŗ × ×× ××××× ×©× ×§××××Ø×]", + "mwe-embedplayer-clip_linkback": "××£ ××ק××Ø ×©× ××”×Ø×××", + "mwe-embedplayer-choose_player": "××××Ø×Ŗ × ×× ×××××", + "mwe-embedplayer-no-player": "×× ×× ×¢×××Ø $1 ××× × ××××", + "mwe-embedplayer-share_this_video": "ש××Ŗ××£ ×”×Ø× ××", + "mwe-embedplayer-video_credits": "××צ×Ø× ××”×Ø×", + "mwe-embedplayer-no-video_credits": "×ק×Ø××××× ×× ×××× ××", + "mwe-embedplayer-kaltura-platform-title": "פ××פ××Ø××Ŗ ××××× ×ק×× ×¤×Ŗ×× ×©× ×§××××Ø×", + "mwe-embedplayer-menu_btn": "×Ŗפ×Ø××", + "mwe-embedplayer-close_btn": "××”×××Ø", + "mwe-embedplayer-ogg-player-vlc-player": "× ×× VLC", + "mwe-embedplayer-ogg-player-oggNative": "× ×× Ogg ×©× HTML5", + "mwe-embedplayer-ogg-player-h264Native": "× ×× H.264 ×©× HTML5", + "mwe-embedplayer-ogg-player-webmNative": "× ×× WebM ×©× HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "×Ŗ××”×£ Ogg ××××", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "×Ŗ××”×£ QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "× ×× ×§××××Ø×", + "mwe-embedplayer-ogg-player-selected": "(× ×××Ø)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "××צ××Ŗ ××××× ×ש×פ×Ø×Ŗ ×× ×× × ××××צ×× ×¢× <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">×פ××¤× ×©×Ŗ××× ××××××× ×Ö¾html5</a>.", + "mwe-embedplayer-download-warn": "×× × ××¦× × ×× ×Ŗ××× ××פ×פ×: ××× ×× ×× ××Ŗ×× ××פ××¤× ×ש ××××Ø×× ××Ŗ [$1 ×××Ø×”× ××××©× ××××Ŗ×Ø ×©× ×¤×××Øפ×קה].", + "mwe-embedplayer-fullscreen-tip": "×××¦× <b>F11</b> ××× ×××¢×××Ø ××Ŗ ××פ××¤× ×××¦× ××”× ××× ××××Ø×", + "mwe-embedplayer-fullscreen-tip-osx": "××××¦× ×¢× <b>shift ā F</b> ×פע××× ××”× ×××", + "mwe-embedplayer-do_not_warn_again": "×× ××צ×× ××Ŗ ×××××¢× ××××Ŗ ש××", + "mwe-embedplayer-playerSelect": "× ×× ××", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">×× × ×§Ö“×Ø××</a> ××¤× × ××××¢×.", + "mwe-embedplayer-embed_site_or_blog": "××××¢× ×××Ŗ×Ø ×× ××××× ×©×××", + "mwe-embedplayer-embed_wiki": "××××××¢ ××××ק×", + "mwe-embedplayer-related_videos": "×”×Ø××× ×× ×§×©××Ø××", + "mwe-embedplayer-seeking": "××פ×ש", + "mwe-embedplayer-buffering": "××××Ø×", + "mwe-embedplayer-video-h264": "×”×Ø× H.264", + "mwe-embedplayer-video-webm": "×”×Ø× WebM", + "mwe-embedplayer-video-flv": "×”×Ø× Flash", + "mwe-embedplayer-video-ogg": "×”×Ø× Ogg", + "mwe-embedplayer-video-audio": "ש××¢ Ogg", + "mwe-embedplayer-audio-mpeg": "ש××¢ MPEG", + "mwe-embedplayer-video-3gp": "×”×Ø× 3GP", + "mwe-embedplayer-video-mpeg": "×”×Ø× MPEG", + "mwe-embedplayer-video-msvideo": "×”×Ø× AVI", + "mwe-embedplayer-missing-source": "××”×Ø× ××ק××Ø× ×× × ×צ×" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/hsb.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/hsb.json new file mode 100644 index 00000000..d52ebb0b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/hsb.json @@ -0,0 +1,83 @@ +{ + "@metadata": { + "authors": [ + "Michawiki" + ] + }, + "mwe-embedplayer-credit-title": "Titul: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Awtor: $1", + "mwe-embedplayer-nocredits": "Žane dÅŗakprajenja k dispoziciji", + "mwe-embedplayer-loading_plugin": "tykaÄ so zaÄituje ...", + "mwe-embedplayer-select_playback": "Nastajenje za playback stajiÄ", + "mwe-embedplayer-link_back": "Wotkaz wrĆ³Äo", + "mwe-embedplayer-error_swap_vid": "Zmylk: mv_embed njemĆ³Å¾eÅ”e widejotafliÄku za powjerch mv_embed wumÄniÄ", + "mwe-embedplayer-add_to_end_of_sequence": "Na kĆ³ncu sekwency pÅidaÄ", + "mwe-embedplayer-missing_video_stream": "Widejowa dataja za tutĆ³n prud faluje", + "mwe-embedplayer-play_clip": "Klip wothraÄ", + "mwe-embedplayer-pause_clip": "Klip zastajiÄ", + "mwe-embedplayer-volume_control": "Regulowanje sylnosÄe zwuka", + "mwe-embedplayer-player_options": "Opcije wothrawaka", + "mwe-embedplayer-timed_text": "Synchronizowany tekst", + "mwe-embedplayer-player_fullscreen": "PoÅna wobrazowka", + "mwe-embedplayer-next_clip_msg": "PÅichodny klip wothraÄ", + "mwe-embedplayer-prev_clip_msg": "PÅedchadny klip wothraÄ", + "mwe-embedplayer-current_clip_msg": "TutĆ³n klip dale wothraÄ", + "mwe-embedplayer-seek_to": "$1 pytaÄ", + "mwe-embedplayer-paused": "zastajeny", + "mwe-embedplayer-download_segment": "WubÄr sÄahnyÄ:", + "mwe-embedplayer-download_full": "DospoÅnu widejowu dataju sÄahnyÄ:", + "mwe-embedplayer-download_right_click": "Zo by sÄahnyÅ, klikÅ z prawej tastu a wubjer <i>Wotkaz skÅadowaÄ jako...</i>", + "mwe-embedplayer-download_clip": "Widejo sÄahnyÄ", + "mwe-embedplayer-download_text": "Tekst", + "mwe-embedplayer-download": "SÄahnyÄ", + "mwe-embedplayer-share": "DÅŗÄliÄ", + "mwe-embedplayer-credits": "DÅŗakprajenje", + "mwe-embedplayer-about-library": "Wo wothrawaku Kaltura", + "mwe-embedplayer-about-library-desc": "Medijowa HTML5-biblioteka Kaltury zmĆ³Å¾nja lÄpÅ”iny tafliÄkow <code><nowiki><video></code> a <code><nowiki><audio></code> dÅŗensa z jednotnym powjerchom wothrawaka ze wÅ”Ämi naÄolnymi wobhladowakami wužiwaÄ.\n\n[$1 Wjace wo bibliotece wothrawaka Kaltura]", + "mwe-embedplayer-clip_linkback": "Å½Ć³rÅow strona klipa", + "mwe-embedplayer-choose_player": "Widejowy wothrawak wubraÄ", + "mwe-embedplayer-no-player": "Žadyn wothrawak za $1 k dispoziciji", + "mwe-embedplayer-share_this_video": "Tute widejo zhromadnje wužiwaÄ", + "mwe-embedplayer-video_credits": "DÅŗakprajenja za wutworjenje wideja", + "mwe-embedplayer-no-video_credits": "Žane podaÄa wo awtorach", + "mwe-embedplayer-kaltura-platform-title": "Widejoplatforma Kaltura ze zjawneho Å¾Ć³rÅa", + "mwe-embedplayer-menu_btn": "Meni", + "mwe-embedplayer-close_btn": "ZaÄiniÄ", + "mwe-embedplayer-ogg-player-vlc-player": "Wothrawak VLC", + "mwe-embedplayer-ogg-player-oggNative": "Wothrawak HTML5 Ogg", + "mwe-embedplayer-ogg-player-mp3Native": "Wothrawak HTML5 MP3", + "mwe-embedplayer-ogg-player-aacNative": "Wothrawak HTML5 AAC", + "mwe-embedplayer-ogg-player-h264Native": "Wothrawak HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "Wothrawak za HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "TykaÄ Generic Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "TykaÄ QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Wothrawak Kaltura", + "mwe-embedplayer-ogg-player-selected": "(wubrany)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Za lÄpÅ”e wothrawanje widejow poruÄamy <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">widejowobhladowak za HTML 5</a>.", + "mwe-embedplayer-download-warn": "Njekompatibelne wothrawak we wobhladowaku namakany: za wothrawanje znutÅka wobhladowaka, sÄehÅ proÅ”u [$1 najnowÅ”u wersiju Mozilla Firefox]", + "mwe-embedplayer-fullscreen-tip": "TÅĆ³Ä na <b>F11</b>, zo by <i>webwobhladowak</i> do modusa poÅneje wobrazowki pÅepinaÅ", + "mwe-embedplayer-fullscreen-tip-osx": "StÅĆ³Ä <b>UMSCH ā F</b>, zo by do modusa poÅneje wobrazowki pÅepinyÅ", + "mwe-embedplayer-do_not_warn_again": "W pÅichodÅŗe tutu zdÅŗÄlenku wjace njepokazaÄ", + "mwe-embedplayer-playerSelect": "Wothrawaki", + "mwe-embedplayer-read_before_embed": "ProÅ”u <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Äitaj to</a> do zasadÅŗenja!", + "mwe-embedplayer-embed_site_or_blog": "Na stronje zasadÅŗiÄ", + "mwe-embedplayer-embed_wiki": "We wikiju zasadÅŗiÄ", + "mwe-embedplayer-related_videos": "PÅiwuzne wideja", + "mwe-embedplayer-seeking": "pyta so", + "mwe-embedplayer-buffering": "pufruje so", + "mwe-embedplayer-video-h264": "Wideo H.264", + "mwe-embedplayer-video-webm": "WebM-widejo", + "mwe-embedplayer-video-flv": "Widejo Flash", + "mwe-embedplayer-video-ogg": "Ogg-widejo", + "mwe-embedplayer-video-audio": "Ogg-awdio", + "mwe-embedplayer-audio-mpeg": "MPEG awdio", + "mwe-embedplayer-video-3gp": "3GP widejo", + "mwe-embedplayer-video-mpeg": "MPEG widejo", + "mwe-embedplayer-video-msvideo": "AVI widejo", + "mwe-embedplayer-missing-source": "Žane widejo namakane." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/hu.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/hu.json new file mode 100644 index 00000000..c9c13278 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/hu.json @@ -0,0 +1,75 @@ +{ + "@metadata": { + "authors": [ + "Dani", + "Misibacsi", + "Tacsipacsi", + "Csega" + ] + }, + "mwe-embedplayer-credit-title": "CĆm: $1", + "mwe-embedplayer-credit-date": "DĆ”tum: $1", + "mwe-embedplayer-credit-author": "SzerzÅ: $1", + "mwe-embedplayer-loading_plugin": "bÅvĆtmĆ©ny betƶltĆ©seā¦", + "mwe-embedplayer-select_playback": "HasznĆ”lt lejĆ”tszĆ³ kivĆ”lasztĆ”sa", + "mwe-embedplayer-link_back": "VisszahivatkozĆ”s", + "mwe-embedplayer-error_swap_vid": "Hiba: az mv_embed nem tudta kicserĆ©lni a videĆ³ taget az mv_embed felĆ¼letĆ©re", + "mwe-embedplayer-add_to_end_of_sequence": "HozzĆ”adĆ”s a szekvencia vĆ©gĆ©hez", + "mwe-embedplayer-missing_video_stream": "Az adatfolyamhoz tartozĆ³ videofĆ”jl nincs meg", + "mwe-embedplayer-play_clip": "Klip lejĆ”tszĆ”sa", + "mwe-embedplayer-pause_clip": "Klip pillanatĆ”llj", + "mwe-embedplayer-volume_control": "HangerÅszabĆ”lyzĆ³", + "mwe-embedplayer-player_options": "LejĆ”tszĆ³ beĆ”llĆtĆ”sai", + "mwe-embedplayer-timed_text": "IdÅzĆtett szƶveg", + "mwe-embedplayer-player_fullscreen": "Teljes kĆ©pernyÅ", + "mwe-embedplayer-next_clip_msg": "KƶvetkezÅ klip lejĆ”tszĆ”sa", + "mwe-embedplayer-prev_clip_msg": "ElÅzÅ klip lejĆ”tszĆ”sa", + "mwe-embedplayer-current_clip_msg": "Klip lejĆ”tszĆ”sĆ”nak folytatĆ”sa", + "mwe-embedplayer-seek_to": "$1 keresĆ©se", + "mwe-embedplayer-paused": "szĆ¼neteltetve", + "mwe-embedplayer-download_segment": "KijelƶlĆ©s letƶltĆ©se:", + "mwe-embedplayer-download_full_video": "Teljes videofĆ”jl letƶltĆ©se:", + "mwe-embedplayer-download_full_audio": "Teljes audiofĆ”jl letƶltĆ©se:", + "mwe-embedplayer-download_right_click": "A letƶltĆ©shez kattints jobb gombbal, Ć©s <i>CĆ©l mentĆ©se mĆ”skĆ©ntā¦</i>", + "mwe-embedplayer-download_clip": "VideĆ³ letƶltĆ©se", + "mwe-embedplayer-download_text": "Szƶveg letƶltĆ©se", + "mwe-embedplayer-download": "LetƶltĆ©s", + "mwe-embedplayer-share": "MegosztĆ”s", + "mwe-embedplayer-credits": "KĆ©szĆtÅk", + "mwe-embedplayer-about-library": "A Kaltura lejĆ”tszĆ³ nĆ©vjegye", + "mwe-embedplayer-about-library-desc": "A Kaltura HTML5-ƶs mĆ©dialejĆ”tszĆ³ lehetÅvĆ© teszi, hogy kihasznĆ”ld a HTML5 <code><nowiki><video></nowiki></code> Ć©s <code><nowiki><audio></nowiki></code> elemeit azonos felĆ¼letet biztonsĆtva az ƶsszes lĆ©nyeges bƶngĆ©szÅ esetĆ©n.\n\t\n[$1 TovĆ”bbi informĆ”ciĆ³ a Kaltura lejĆ”tszĆ³rĆ³l].", + "mwe-embedplayer-clip_linkback": "Klip forrĆ”slapja", + "mwe-embedplayer-choose_player": "VideolejĆ”tszĆ³ vĆ”lasztĆ”sa", + "mwe-embedplayer-no-player": "Nincs megfelelÅ lejĆ”tszĆ³ a kƶvetkezÅhƶz: $1", + "mwe-embedplayer-share_this_video": "VideĆ³ megosztĆ”sa", + "mwe-embedplayer-share_this_audio": "AudiofĆ”jl megosztĆ”sa", + "mwe-embedplayer-video_credits": "A videĆ³ kĆ©szĆtÅi", + "mwe-embedplayer-menu_btn": "MenĆ¼", + "mwe-embedplayer-close_btn": "BezĆ”rĆ”s", + "mwe-embedplayer-ogg-player-vlc-player": "VLC player", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg lejĆ”tszĆ³", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 lejĆ”tszĆ³", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM-lejĆ”tszĆ³", + "mwe-embedplayer-ogg-player-oggPlugin": "ĆltalĆ”nos Ogg bÅvĆtmĆ©ny", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-bÅvĆtmĆ©ny", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura lejĆ”tszĆ³", + "mwe-embedplayer-ogg-player-selected": "(kivĆ”lasztva)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "A jobb videolejĆ”tszĆ”si Ć©lmĆ©nyhez <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5-ƶt tĆ”mogatĆ³ bƶngĆ©szÅt</a> ajĆ”nlunk.", + "mwe-embedplayer-do_not_warn_again": "A jƶvÅben ne jelenjen meg ez az Ć¼zenet", + "mwe-embedplayer-playerSelect": "LejĆ”tszĆ³k", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Olvasd el ezt</a>, mielÅtt beillesztenĆ©d.", + "mwe-embedplayer-embed_site_or_blog": "BeĆ”gyazĆ”s egy lapra", + "mwe-embedplayer-related_videos": "KapcsolĆ³dĆ³ videĆ³k", + "mwe-embedplayer-seeking": "keresĆ©s", + "mwe-embedplayer-buffering": "pufferelĆ©s", + "mwe-embedplayer-video-h264": "H.264 videĆ³", + "mwe-embedplayer-video-webm": "WebM-videĆ³", + "mwe-embedplayer-video-flv": "Flash videĆ³", + "mwe-embedplayer-video-ogg": "Ogg videĆ³", + "mwe-embedplayer-video-audio": "Ogg hangfĆ”jl", + "mwe-embedplayer-missing-source": "Nem talĆ”lhatĆ³ forrĆ”svideĆ³" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ia.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ia.json new file mode 100644 index 00000000..94586400 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ia.json @@ -0,0 +1,79 @@ +{ + "@metadata": { + "authors": [ + "McDutchie" + ] + }, + "mwe-embedplayer-credit-title": "Titulo: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-loading_plugin": "cargamento del plug-in ...", + "mwe-embedplayer-select_playback": "Definir preferentia de reproduction", + "mwe-embedplayer-link_back": "Retroligamine", + "mwe-embedplayer-error_swap_vid": "Error: mv_embed non poteva excambiar le etiquetta de video pro le interfacie mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "Adder al fin del sequentia", + "mwe-embedplayer-missing_video_stream": "Le file de video pro iste fluxo es mancante", + "mwe-embedplayer-play_clip": "Reproducer clip", + "mwe-embedplayer-pause_clip": "Pausar clip", + "mwe-embedplayer-volume_control": "Controlo de volumine", + "mwe-embedplayer-player_options": "Optiones de reproductor", + "mwe-embedplayer-timed_text": "Subtitulos", + "mwe-embedplayer-player_fullscreen": "Schermo complete", + "mwe-embedplayer-next_clip_msg": "Reproducer sequente clip", + "mwe-embedplayer-prev_clip_msg": "Reproducer precedente clip", + "mwe-embedplayer-current_clip_msg": "Continuar a reproducer iste clip", + "mwe-embedplayer-seek_to": "Ir a $1", + "mwe-embedplayer-paused": "in pausa", + "mwe-embedplayer-download_segment": "Discargar selection:", + "mwe-embedplayer-download_full": "Discargar file de video complete:", + "mwe-embedplayer-download_right_click": "Pro discargar, face clic a dextra e selige <i>Immagazinar ligamine como...</i> (Save link as...)", + "mwe-embedplayer-download_clip": "Discargar video", + "mwe-embedplayer-download_text": "Discargar texto", + "mwe-embedplayer-download": "Discargar", + "mwe-embedplayer-share": "Divider", + "mwe-embedplayer-credits": "Creditos", + "mwe-embedplayer-about-library": "A proposito del reproductor Kaltura", + "mwe-embedplayer-about-library-desc": "Le bibliotheca multimedia HTML5 de Kaltura te permitte traher avantage del etiquettas HTML5 <code><nowiki><video></nowiki></code> e <code><nowiki><audio></nowiki></code> jam hodie con un interfacie de reproductor consistente trans tote le major navigatores.\n\t\n[$1 Plus a proposito del bibliotheca reproductor Kaltura].", + "mwe-embedplayer-clip_linkback": "Pagina de fonte del clip", + "mwe-embedplayer-choose_player": "Seliger reproductor de video", + "mwe-embedplayer-no-player": "Nulle reproductor disponibile pro $1", + "mwe-embedplayer-share_this_video": "Divider iste video", + "mwe-embedplayer-video_credits": "Creditos de video", + "mwe-embedplayer-no-video_credits": "Nulle credito disponibile", + "mwe-embedplayer-kaltura-platform-title": "Platteforma video a codice aperte Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Clauder", + "mwe-embedplayer-ogg-player-vlc-player": "Reproductor VLC", + "mwe-embedplayer-ogg-player-oggNative": "Reproductor Ogg HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Reproductor H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Lector WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Plug-in generic pro Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Plug-in de QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Le reproductor Kaltura", + "mwe-embedplayer-ogg-player-selected": "(seligite)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Pro un melior experientia de reproduction de video, nos recommenda:<br /><a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Firefox 3.5</a>.", + "mwe-embedplayer-download-warn": "Nulle lector compatibile esseva detegite in le navigator del web. Pro reproduction in le navigator, per favor discarga le [$1 ultime version de Firefox].", + "mwe-embedplayer-fullscreen-tip": "Preme <b>F11</b> pro alternar le <i>navigator del web</i> in plen schermo", + "mwe-embedplayer-fullscreen-tip-osx": "Preme <b>shift ā F</b> pro alternar plen schermo", + "mwe-embedplayer-do_not_warn_again": "In le futuro, non monstrar iste message", + "mwe-embedplayer-playerSelect": "Reproductores", + "mwe-embedplayer-read_before_embed": "Per favor lege le <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">notas de securitate super incastramento remote</a> ante de incastrar un cosa!", + "mwe-embedplayer-embed_site_or_blog": "Incastrar in un pagina", + "mwe-embedplayer-related_videos": "Videos connexe", + "mwe-embedplayer-seeking": "cercante", + "mwe-embedplayer-buffering": "precargamento", + "mwe-embedplayer-video-h264": "Video H.264", + "mwe-embedplayer-video-webm": "Video WebM", + "mwe-embedplayer-video-flv": "Video Flash", + "mwe-embedplayer-video-ogg": "Video Ogg", + "mwe-embedplayer-video-audio": "Audio Ogg", + "mwe-embedplayer-audio-mpeg": "Audio MPEG", + "mwe-embedplayer-video-3gp": "Video 3gp", + "mwe-embedplayer-video-mpeg": "Video MPEG", + "mwe-embedplayer-video-msvideo": "Video AVI", + "mwe-embedplayer-missing-source": "Nulle video de origine ha essite trovate." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/id.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/id.json new file mode 100644 index 00000000..58c68df9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/id.json @@ -0,0 +1,76 @@ +{ + "@metadata": { + "authors": [ + "Farras", + "IvanLanin" + ] + }, + "mwe-embedplayer-credit-title": "Judul: $1", + "mwe-embedplayer-credit-date": "Tanggal: $1", + "mwe-embedplayer-credit-author": "Pembuat: $1", + "mwe-embedplayer-loading_plugin": "memuat pengaya ...", + "mwe-embedplayer-select_playback": "Atur preferensi pemutar", + "mwe-embedplayer-link_back": "Pranala balik", + "mwe-embedplayer-error_swap_vid": "Kesalahan: mv_embed tak dapat menukar tag video untuk antarmuka mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "Tambahkan ke akhir rangkaian", + "mwe-embedplayer-missing_video_stream": "Berkas video untuk aliran tidak ditemukan", + "mwe-embedplayer-play_clip": "Mainkan klip", + "mwe-embedplayer-pause_clip": "Jeda klip", + "mwe-embedplayer-volume_control": "Kontrol volume", + "mwe-embedplayer-player_options": "Pilihan pemutar", + "mwe-embedplayer-timed_text": "Teks berjangka waktu", + "mwe-embedplayer-player_fullscreen": "Layar penuh", + "mwe-embedplayer-next_clip_msg": "Putar klip berikut", + "mwe-embedplayer-prev_clip_msg": "Putar klip sebelumnya", + "mwe-embedplayer-current_clip_msg": "Lanjutkan pemutaran klip ini", + "mwe-embedplayer-seek_to": "Cari $1", + "mwe-embedplayer-paused": "jeda", + "mwe-embedplayer-download_segment": "Unduh pilihan:", + "mwe-embedplayer-download_full": "Unduh berkas video lengkap:", + "mwe-embedplayer-download_right_click": "Untuk mengunduh, klik kanan dan pilih <i>Simpan tautan sebagai...</i>", + "mwe-embedplayer-download_clip": "Unduh video", + "mwe-embedplayer-download_text": "Unduh teks", + "mwe-embedplayer-download": "Unduh", + "mwe-embedplayer-share": "Bagikan", + "mwe-embedplayer-credits": "Kredit", + "mwe-embedplayer-about-library": "About pemutar Kaltura", + "mwe-embedplayer-about-library-desc": "Pustaka media HTML5 Kaltura memungkinkan Anda untuk mengambil keuntungan dari tag HTML5 <nowiki><video></nowiki> dan <nowiki><audio></nowiki> dengan antarmuka pemutar yang konsisten di semua peramban utama.\n\n [$1 Selengkapnya tentang pustaka pemutar Kaltura].", + "mwe-embedplayer-clip_linkback": "Halaman sumber klip", + "mwe-embedplayer-choose_player": "Pilih pemutar video", + "mwe-embedplayer-no-player": "Tidak ada pemutar yang tersedia untuk $1", + "mwe-embedplayer-share_this_video": "Bagikan video ini", + "mwe-embedplayer-video_credits": "Kredit video", + "mwe-embedplayer-no-video_credits": "Kredit tidak tersedia", + "mwe-embedplayer-kaltura-platform-title": "Platform video terbuka Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Tutup", + "mwe-embedplayer-ogg-player-vlc-player": "Pemutar VLC", + "mwe-embedplayer-ogg-player-oggNative": "Pemutar Ogg HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Pemutar H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Pemutar WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Pengaya generik Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Pengaya QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Pemutar Kaltura", + "mwe-embedplayer-ogg-player-selected": "(dipilih)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Untuk pengalaman pemutaran video yang lebih baik kami menyarankan: <br /><a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Firefox 3.5</a>.", + "mwe-embedplayer-download-warn": "Pemutar dalam peramban yang kompatibel tidak ditemukan. Untuk pemutaran dalam peramban silakan unduh [$1 Firefox terbaru]", + "mwe-embedplayer-fullscreen-tip": "Tekan <b>F11</b> untuk beralih ke layar penuh <i>peramban web</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Tekan <b>shift ā F</b> untuk beralih ke layar penuh", + "mwe-embedplayer-do_not_warn_again": "Jangan tampilkan lagi pesan ini", + "mwe-embedplayer-playerSelect": "Pemutar", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Baca ini</a> sebelum mengikutkan.", + "mwe-embedplayer-embed_site_or_blog": "Sertakan pada suatu halaman", + "mwe-embedplayer-related_videos": "Video yang berhubungan", + "mwe-embedplayer-seeking": "mencari", + "mwe-embedplayer-buffering": "menyinggahkan", + "mwe-embedplayer-video-h264": "Video H.264", + "mwe-embedplayer-video-webm": "Video WebM", + "mwe-embedplayer-video-flv": "Video flash", + "mwe-embedplayer-video-ogg": "Video ogg", + "mwe-embedplayer-video-audio": "Audio ogg", + "mwe-embedplayer-missing-source": "Tidak ada video sumber yang ditemukan." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ilo.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ilo.json new file mode 100644 index 00000000..b379d2a9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ilo.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Lam-ang" + ] + }, + "mwe-embedplayer-credit-title": "Titulo: $1", + "mwe-embedplayer-credit-date": "Petsa: $1", + "mwe-embedplayer-credit-author": "Mannurat: $1", + "mwe-embedplayer-nocredits": "Awan dagiti pammadayaw a magun-od", + "mwe-embedplayer-loading_plugin": "Agikarkarga ti plugin ...", + "mwe-embedplayer-select_playback": "Agikabil ti preperensia ti panagy-ayam", + "mwe-embedplayer-link_back": "Agisilpo", + "mwe-embedplayer-error_swap_vid": "Biddut: Ti mwEmbed ket saan a nakaisukat ti etiketa ti video para iti interface ti mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Inayon idiay gibus ti pangsasarunuan" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/is.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/is.json new file mode 100644 index 00000000..3a61ae5e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/is.json @@ -0,0 +1,64 @@ +{ + "@metadata": { + "authors": [ + "SnƦvar" + ] + }, + "mwe-embedplayer-credit-title": "Titill: $1", + "mwe-embedplayer-credit-date": "Dagsetning: $1", + "mwe-embedplayer-credit-author": "Hƶfundur: $1", + "mwe-embedplayer-loading_plugin": "HleĆ° viĆ°bĆ³t...", + "mwe-embedplayer-select_playback": "Setja afspilunar stillingar", + "mwe-embedplayer-link_back": "Tengja tilbaka", + "mwe-embedplayer-error_swap_vid": "Villa: mwEmbad gat ekki skipt myndbands tagi Ćŗt fyrir mwEmbed valmyndina", + "mwe-embedplayer-missing_video_stream": "MyndbandiĆ° fyrir streymiĆ° vantar", + "mwe-embedplayer-play_clip": "Spila myndband", + "mwe-embedplayer-pause_clip": "Gera hlĆ© Ć” spilun", + "mwe-embedplayer-volume_control": "HljĆ³Ć°styrkur", + "mwe-embedplayer-player_options": "Stillingar spilarans", + "mwe-embedplayer-player_fullscreen": "Fylla skjĆ”", + "mwe-embedplayer-next_clip_msg": "Spila nƦsta myndband", + "mwe-embedplayer-prev_clip_msg": "Spila fyrra myndband", + "mwe-embedplayer-current_clip_msg": "Halda Ć”fram spilun", + "mwe-embedplayer-seek_to": "SƦki $1", + "mwe-embedplayer-paused": "Ć biĆ°", + "mwe-embedplayer-download_segment": "HlaĆ°a niĆ°ur hluta:", + "mwe-embedplayer-download_full": "HlaĆ°a niĆ°ur allri skrĆ”nni:", + "mwe-embedplayer-download_right_click": "Til aĆ° hlaĆ°a niĆ°ur, hƦgri smelltu og veldu <i>Vista tengil sem...</i>", + "mwe-embedplayer-download_clip": "SƦkja myndband", + "mwe-embedplayer-download_text": "HlaĆ°a niĆ°ur texta", + "mwe-embedplayer-download": "HlaĆ°a niĆ°ur", + "mwe-embedplayer-share": "Deila", + "mwe-embedplayer-about-library": "Um Kaltura-spilarann", + "mwe-embedplayer-choose_player": "Velja myndbands spilara", + "mwe-embedplayer-no-player": "Enginn spilari til fyrir $1", + "mwe-embedplayer-share_this_video": "Deila Ć¾essu myndbandi", + "mwe-embedplayer-close_btn": "Loka", + "mwe-embedplayer-ogg-player-vlc-player": "VLC-spilari", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg-spilari", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264-spilari", + "mwe-embedplayer-ogg-player-webmNative": "HTML WebM-spilari", + "mwe-embedplayer-ogg-player-oggPlugin": "Almenn Ogg viĆ°bĆ³t", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-viĆ°bĆ³t", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura-spilari", + "mwe-embedplayer-ogg-player-selected": "(valiĆ°)", + "mwe-embedplayer-download-warn": "Enginn samhƦfĆ°ur spilari fannst. Til Ć¾ess aĆ° spila myndbandiĆ° Ć \tvafranum vinsamlegst sĆ³ttu [$1 nĆ½jasta Firefox]", + "mwe-embedplayer-fullscreen-tip": "Til Ć¾ess aĆ° fylla Ćŗt Ć skjĆ”inn, smelltu Ć” <b>F11</b>", + "mwe-embedplayer-fullscreen-tip-osx": "Til Ć¾ess aĆ° fylla Ćŗt Ć skjĆ”inn, smelltu Ć” <b>shift ā F</b>", + "mwe-embedplayer-do_not_warn_again": "Ekki sĆ½na Ć¾essi skilaboĆ° framvegis", + "mwe-embedplayer-playerSelect": "Spilarar", + "mwe-embedplayer-related_videos": "SvipuĆ° myndbƶnd", + "mwe-embedplayer-seeking": "sƦki", + "mwe-embedplayer-buffering": "hleĆ° niĆ°ur Ć biĆ°minni", + "mwe-embedplayer-video-h264": "H.264-myndband", + "mwe-embedplayer-video-webm": "WebM-myndband", + "mwe-embedplayer-video-flv": "Flash-myndband", + "mwe-embedplayer-video-ogg": "Ogg-myndband", + "mwe-embedplayer-video-audio": "Ogg-hljĆ³Ć°skrĆ”", + "mwe-embedplayer-audio-mpeg": "MPEG-hljĆ³Ć°skrĆ”", + "mwe-embedplayer-video-3gp": "3GP-myndband", + "mwe-embedplayer-video-mpeg": "MPEG-myndband", + "mwe-embedplayer-video-msvideo": "AVI-myndband" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/it.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/it.json new file mode 100644 index 00000000..e991b7d8 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/it.json @@ -0,0 +1,92 @@ +{ + "@metadata": { + "authors": [ + "Beta16", + "Darth Kule", + "F. Cosoleto", + "Gianfranco" + ] + }, + "mwe-embedplayer-credit-title": "Titolo: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autore: $1", + "mwe-embedplayer-nocredits": "Crediti non disponibili", + "mwe-embedplayer-loading_plugin": "Caricamento plugin...", + "mwe-embedplayer-select_playback": "Imposta le preferenze per la riproduzione", + "mwe-embedplayer-link_back": "Link di ritorno", + "mwe-embedplayer-error_swap_vid": "Errore: mwEmbed non ĆØ riuscito a scambiare il tag video per l'interfaccia mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Aggiungi alla fine della sequenza", + "mwe-embedplayer-missing_video_stream": "Manca il file video per questo flusso", + "mwe-embedplayer-play_clip": "Riproduci clip", + "mwe-embedplayer-pause_clip": "Pausa clip", + "mwe-embedplayer-volume_control": "Controllo volume", + "mwe-embedplayer-player_options": "Opzioni lettore", + "mwe-embedplayer-timed_text": "Sottotitoli", + "mwe-embedplayer-player_fullscreen": "Schermo intero", + "mwe-embedplayer-next_clip_msg": "Riproduci clip successivo", + "mwe-embedplayer-prev_clip_msg": "Riproduci clip precedente", + "mwe-embedplayer-current_clip_msg": "Continuare a riprodurre questa clip", + "mwe-embedplayer-seek_to": "Salta a $1", + "mwe-embedplayer-paused": "in pausa", + "mwe-embedplayer-download_segment": "Scarica selezione:", + "mwe-embedplayer-download_full": "Scarica file video completo:", + "mwe-embedplayer-download_right_click": "Per scaricare, fare clic col destro e selezionare <i>Salva link con nome...</i>", + "mwe-embedplayer-download_clip": "Scarica video", + "mwe-embedplayer-download_text": "Scarica testo", + "mwe-embedplayer-download": "Scarica", + "mwe-embedplayer-share": "Condividi", + "mwe-embedplayer-credits": "Crediti", + "mwe-embedplayer-about-library": "Informazioni su Kaltura player", + "mwe-embedplayer-about-library-desc": "La libreria multimediale HTML5 di Kaltura consente adesso di utilizzare l'etichette HTML5 <video> and <audio> con una interfaccia del media player coerente in tutti i principali browser.\n\n[$1 Maggiori informazioni sulla libreria Kaltura].", + "mwe-embedplayer-clip_linkback": "Pagina di origine clip", + "mwe-embedplayer-choose_player": "Scegli riproduttore video", + "mwe-embedplayer-no-player": "Nessun lettore disponibile per $1", + "mwe-embedplayer-share_this_video": "Condividi questo video", + "mwe-embedplayer-video_credits": "Crediti video", + "mwe-embedplayer-no-video_credits": "Crediti non disponibili", + "mwe-embedplayer-kaltura-platform-title": "Kaltura - piattaforma video open source", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Chiudi", + "mwe-embedplayer-ogg-player-vlc-player": "Lettore VLC", + "mwe-embedplayer-ogg-player-oggNative": "Lettore HTML5 Ogg", + "mwe-embedplayer-ogg-player-mp3Native": "Lettore HTML5 MP3", + "mwe-embedplayer-ogg-player-aacNative": "Lettore HTML5 AAC", + "mwe-embedplayer-ogg-player-h264Native": "Lettore HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "Lettore HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "Plugin generico Ogg", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC per iOS app", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Player Kaltura", + "mwe-embedplayer-ogg-player-selected": "(selezionato)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Per una migliore esperienza di riproduzione dei video si consiglia un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">browser che supporti i video HTML5</a>.", + "mwe-embedplayer-download-warn": "Rilevato lettore integrato non compatibile: per la riproduzione tramite browser scaricare [$1 l'ultima versione di Firefox].", + "mwe-embedplayer-fullscreen-tip": "Premere <b>F11</b> attiva/disattiva la modalitĆ a schermo intero del <i>browser web</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Premere <b>Maiusc ā F</b> attiva/disattiva la modalitĆ a schermo intero", + "mwe-embedplayer-do_not_warn_again": "In futuro, non mostrare questo messaggio", + "mwe-embedplayer-playerSelect": "Lettori", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Leggi questo</a> prima di incorporare.", + "mwe-embedplayer-embed_site_or_blog": "Incorpora in una pagina", + "mwe-embedplayer-embed_wiki": "Incorpora su un wiki", + "mwe-embedplayer-related_videos": "Video correlati", + "mwe-embedplayer-seeking": "cerca", + "mwe-embedplayer-buffering": "Riempimento buffer", + "mwe-embedplayer-video-h264": "Video H.264", + "mwe-embedplayer-video-webm": "Video WebM", + "mwe-embedplayer-video-flv": "Video Flash", + "mwe-embedplayer-video-ogg": "Video Ogg", + "mwe-embedplayer-video-audio": "Audio Ogg", + "mwe-embedplayer-audio-mpeg": "Audio MPEG", + "mwe-embedplayer-video-3gp": "Video 3GP", + "mwe-embedplayer-video-mpeg": "Video MPEG", + "mwe-embedplayer-video-msvideo": "Video AVI", + "mwe-embedplayer-missing-source": "Non ĆØ stata trovata alcuna sorgente video", + "mwe-embedplayer-vlcapp-intro": "Per poter visualizzare i video da questo sito su un iPhone o iPad, ĆØ necessaria $1 gratuita.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "VLC app", + "mwe-embedplayer-vlcapp-downloadapp": "Scarica l'app VLC da App Store", + "mwe-embedplayer-vlcapp-openvideo": "Apri questo video nell'app VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "Scarica questo video", + "mwe-embedplayer-vlcapp-vlcapppopup": "Per riprodurre i video su questo sito, ĆØ necessaria l'app VLC. Installarla ora?" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ja.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ja.json new file mode 100644 index 00000000..d65876b9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ja.json @@ -0,0 +1,84 @@ +{ + "@metadata": { + "authors": [ + "Shirayuki", + "éåå®ę" + ] + }, + "mwe-embedplayer-credit-title": "ćæć¤ćć«: $1", + "mwe-embedplayer-credit-date": "ę„ä»: $1", + "mwe-embedplayer-credit-author": "ä½č
: $1", + "mwe-embedplayer-nocredits": "čä½č
ę
å ±ćÆććć¾ćć", + "mwe-embedplayer-loading_plugin": "ćć©ć°ć¤ć³ćčŖćæč¾¼ćæäø ...", + "mwe-embedplayer-select_playback": "åēē°å¢ćčØå®", + "mwe-embedplayer-link_back": "ćć©ććÆćććÆ", + "mwe-embedplayer-error_swap_vid": "ćØć©ć¼: mv_embed å½¢å¼ć«ćć£ćåē»ćæć°ć«ē½®ęć§ćć¾ććć§ććć", + "mwe-embedplayer-add_to_end_of_sequence": "ć·ć¼ć±ć³ć¹ć®ēµććć«čæ½å ", + "mwe-embedplayer-missing_video_stream": "ćć®ć¹ććŖć¼ć ć«åæ
č¦ćŖåē»ćć”ć¤ć«ćč¦ć¤ććć¾ćć", + "mwe-embedplayer-play_clip": "ćÆćŖćććåē", + "mwe-embedplayer-pause_clip": "ćÆćŖćććäøęåę¢", + "mwe-embedplayer-volume_control": "é³éčŖæēÆ", + "mwe-embedplayer-player_options": "ćć¬ć¼ć¤ć¼ć®čØå®", + "mwe-embedplayer-timed_text": "åå¹", + "mwe-embedplayer-player_fullscreen": "å
Øē»é¢č”Øē¤ŗ", + "mwe-embedplayer-next_clip_msg": "ꬔć®ćÆćŖćććåē", + "mwe-embedplayer-prev_clip_msg": "åć®ćÆćŖćććåē", + "mwe-embedplayer-current_clip_msg": "ćć®ćÆćŖććć®åēćē¶ćć", + "mwe-embedplayer-seek_to": "$1 ćøć·ć¼ćÆ", + "mwe-embedplayer-paused": "äøęåę¢äø", + "mwe-embedplayer-download_segment": "ćć¦ć³ćć¼ćę¹ę³ćéøę:", + "mwe-embedplayer-download_full": "åē»ćć”ć¤ć«å
Øä½ććć¦ć³ćć¼ć:", + "mwe-embedplayer-download_right_click": "ćć¦ć³ćć¼ćććć«ćÆćå³ćÆćŖććÆćć¦<i>ååćä»ćć¦ćŖć³ćÆå
ćäæå</i>ćéøćć§ćć ćć", + "mwe-embedplayer-download_clip": "åē»ććć¦ć³ćć¼ć", + "mwe-embedplayer-download_text": "ććć¹ćććć¦ć³ćć¼ć", + "mwe-embedplayer-download": "ćć¦ć³ćć¼ć", + "mwe-embedplayer-share": "å
±ę", + "mwe-embedplayer-credits": "ćÆć¬ćøćć", + "mwe-embedplayer-about-library": "Kaltura ćć¬ć¼ć¤ć¼ć«ć¤ćć¦", + "mwe-embedplayer-about-library-desc": "Kaltura ć® HTML5 ć”ćć£ć¢ ć©ć¤ćć©ćŖćÆććć¹ć¦ć®äø»č¦ćć©ć¦ć¶ć¼éć§äøč²«ę§ć®ććåēć¤ć³ćæć¼ćć§ć¤ć¹ć HTML5 ć® <code><nowiki><video></nowiki></code> ćæć°ćØ <code><nowiki><audio></nowiki></code> ćæć°ć§ę“»ēØć§ćć¾ćć\n\n[$1 Kaltura ćć¬ć¼ć¤ć¼ ć©ć¤ćć©ćŖć«ć¤ćć¦ć®č©³ē“°ę
å ±]ć", + "mwe-embedplayer-clip_linkback": "ćÆćŖććć®ę
å ±ćć¼ćø", + "mwe-embedplayer-choose_player": "åē»ć®ćć¬ć¼ć¤ć¼ćéøę", + "mwe-embedplayer-no-player": "$1 ćåēć§ćććć¬ć¼ć¤ć¼ćÆććć¾ćć", + "mwe-embedplayer-share_this_video": "ćć®åē»ćå
±ęćć", + "mwe-embedplayer-video_credits": "åē»ć®ćÆć¬ćøćć", + "mwe-embedplayer-no-video_credits": "čä½č
ę
å ±ćÆććć¾ćć", + "mwe-embedplayer-kaltura-platform-title": "KalturaćŖć¼ćć³ć½ć¼ć¹åē»ćć©ćććć©ć¼ć ", + "mwe-embedplayer-menu_btn": "ć”ćć„ć¼", + "mwe-embedplayer-close_btn": "éćć", + "mwe-embedplayer-ogg-player-vlc-player": "VLC ćć¬ć¼ć¤ć¼", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg ćć¬ć¼ć¤ć¼", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3 ćć¬ć¼ć¤ć¼", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC ćć¬ć¼ć¤ć¼", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 ćć¬ć¼ć¤ć¼", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM ćć¬ć¼ć¤ć¼", + "mwe-embedplayer-ogg-player-oggPlugin": "ę±ēØć® Ogg ćć©ć°ć¤ć³", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTimećć©ć°ć¤ć³", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura ćć¬ć¼ć¤ć¼", + "mwe-embedplayer-ogg-player-selected": "(éøęęøćæ)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "åē»åēåč³Ŗć®åäøć®ććć«ć<a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5 åē»åƾåæć®ćć©ć¦ć¶ć¼</a>ććå§ććć¾ćć", + "mwe-embedplayer-download-warn": "äŗęę§ććŖććć©ć¦ć¶ć¼å
ćć¬ć¼ć¤ć¼ćę¤åŗćć¾ćć: ćć©ć¦ć¶ć¼å
ć§åēććć«ćÆć[$1 ęę°ēć® Firefox] ććć¦ć³ćć¼ććć¦ćć ćć", + "mwe-embedplayer-fullscreen-tip": "<i>ć¦ć§ć ćć©ć¦ć¶ć¼</i>ć®å
Øē»é¢č”Øē¤ŗćåćęæććć«ćÆ <b>F11</b> ćć¼ćę¼ćć¦ćć ćć", + "mwe-embedplayer-fullscreen-tip-osx": "å
Øē»é¢č”Øē¤ŗćåćęæććć«ćÆ <b>shift ⌘ F</b> ćę¼ćć¦ćć ćć", + "mwe-embedplayer-do_not_warn_again": "ä»å¾ććć®ć”ćć»ć¼ćøćč”Øē¤ŗććŖć", + "mwe-embedplayer-playerSelect": "ćć¬ć¼ć¤ć¼", + "mwe-embedplayer-read_before_embed": "åćč¾¼ćåć«<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ę³Øęäŗé
</a>ććčŖćæćć ććć", + "mwe-embedplayer-embed_site_or_blog": "ćć¼ćøć«åćč¾¼ć", + "mwe-embedplayer-embed_wiki": "ć¦ć£ćć«åćč¾¼ć", + "mwe-embedplayer-related_videos": "é¢é£ććåē»", + "mwe-embedplayer-seeking": "ć·ć¼ćÆäø", + "mwe-embedplayer-buffering": "ćććć”ćŖć³ć°", + "mwe-embedplayer-video-h264": "H.264 åē»", + "mwe-embedplayer-video-webm": "WebM åē»", + "mwe-embedplayer-video-flv": "Flash åē»", + "mwe-embedplayer-video-ogg": "Ogg åē»", + "mwe-embedplayer-video-audio": "Ogg é³å£°", + "mwe-embedplayer-audio-mpeg": "MPEG é³å£°", + "mwe-embedplayer-video-3gp": "3GP åē»", + "mwe-embedplayer-video-mpeg": "MPEG åē»", + "mwe-embedplayer-video-msvideo": "AVI åē»", + "mwe-embedplayer-missing-source": "ć½ć¼ć¹ćØćŖćåē»ćč¦ć¤ććć¾ććć§ćć" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ka.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ka.json new file mode 100644 index 00000000..95c48673 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ka.json @@ -0,0 +1,73 @@ +{ + "@metadata": { + "authors": [ + "David1010", + "MIKHEIL" + ] + }, + "mwe-embedplayer-credit-title": "į”įįįį£į į: $1", + "mwe-embedplayer-credit-date": "įįį įį¦į: $1", + "mwe-embedplayer-credit-author": "įįį¢įį į: $1", + "mwe-embedplayer-loading_plugin": "įį¢įįį įįįį įįįįįįį ...", + "mwe-embedplayer-link_back": "į£įį£įįį£įį", + "mwe-embedplayer-add_to_end_of_sequence": "įįįįįįįįįį įįįį” įįįįįØį įįįįį¢įįį", + "mwe-embedplayer-play_clip": "įįįįįį” įįįįį į", + "mwe-embedplayer-pause_clip": "įįįįįį” įØįį©įį įįį", + "mwe-embedplayer-volume_control": "į®įįį” įįįį¢į įįį", + "mwe-embedplayer-player_options": "įįįįįį įįįį” įįį įįįį¢į įįį", + "mwe-embedplayer-timed_text": "į”įįį„į įįįįįį įįį£įį į¢įį„į”į¢į", + "mwe-embedplayer-player_fullscreen": "įįįį įįį įįįį", + "mwe-embedplayer-next_clip_msg": "įØįįįįįį įįįįįį” įįįįį į", + "mwe-embedplayer-prev_clip_msg": "į¬įįį įįįįįį” įįįįį į", + "mwe-embedplayer-current_clip_msg": "įį įįįįįį” įįįįį įį” įįįį į«įįįįį", + "mwe-embedplayer-seek_to": "įįįįį”įįį $1", + "mwe-embedplayer-paused": "įØįį©įį įįį£įįį", + "mwe-embedplayer-download_segment": "įį į©įį£įįį” į©įįįį¢įįį įįį:", + "mwe-embedplayer-download_full_video": "įįįįįįį įįįįį-į¤įįįįį” į©įįįį¢įįį įįį:", + "mwe-embedplayer-download_full_audio": "įįįįįįį įį£įįį-į¤įįįįį” į©įįįį¢įįį įįį:", + "mwe-embedplayer-download_clip": "įįįįįį” į©įįįį¢įįį įįį", + "mwe-embedplayer-download_text": "į¢įį„į”į¢įį” į©įįįį¢įįį įįį", + "mwe-embedplayer-download": "į©įįįį¢įįį įįį", + "mwe-embedplayer-share": "įįįįįį įįį", + "mwe-embedplayer-credits": "įØįįį„įįįįįįį", + "mwe-embedplayer-about-library": "Kaltura player-įį” įØįį”įį®įį", + "mwe-embedplayer-clip_linkback": "įįįįįį” į¬į§įį įį” įįįį įį", + "mwe-embedplayer-choose_player": "įįį į©įįį įįįįįįįįįįį įįį", + "mwe-embedplayer-share_this_video": "įį įįįįįį” įįįįįį įįį", + "mwe-embedplayer-share_this_audio": "įį įį£įįį-į¤įįįįį” įįįįįį įįį", + "mwe-embedplayer-video_credits": "įįįįįį” įØįįį„įįįįįįį", + "mwe-embedplayer-menu_btn": "įįįįį£", + "mwe-embedplayer-close_btn": "įįį®į£į įį", + "mwe-embedplayer-ogg-player-vlc-player": "VLC player", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg player", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3 įįįįįį įįį", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC įįįįįį įįį", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 player", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM player", + "mwe-embedplayer-ogg-player-oggPlugin": "Ogg-įį” į”įįį įį įįįįįįį", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-įį” įįįįįįį", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura player", + "mwe-embedplayer-ogg-player-selected": "(įį į©įį£įįį)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-fullscreen-tip": "į¦įįįįį” <b>F11</b> įįįįį°į§įįį” <i>įįį-įį įį£įįį į</i> į”į į£įįįį įįįįį į įįįįįØį", + "mwe-embedplayer-fullscreen-tip-osx": "įįįįįį įį <b>shift ā F</b> į”į į£įįįį įįįįį į įįįįįį įįįįį”įį”įįįįįį", + "mwe-embedplayer-do_not_warn_again": "įįįįįįįįØį įį¦įį įį©įįįį įį” įØįį¢į§įįįįįįį", + "mwe-embedplayer-playerSelect": "įįįįįį įįįįį", + "mwe-embedplayer-read_before_embed": "įįį®įįį, <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">į¬įįįįįį®įį įį”</a> į©įįØįįįįįįįį!", + "mwe-embedplayer-embed_site_or_blog": "įįįį įįØį į©įįįįį", + "mwe-embedplayer-related_videos": "įįįįįįØįį įįį£įį įįįįįįįį", + "mwe-embedplayer-seeking": "į«įįįį", + "mwe-embedplayer-buffering": "įį£į¤įį įįįįŖįį", + "mwe-embedplayer-video-h264": "H.264 įįįįį", + "mwe-embedplayer-video-webm": "WebM įįįįį", + "mwe-embedplayer-video-flv": "Flash įįįįį", + "mwe-embedplayer-video-ogg": "Ogg įįįįį", + "mwe-embedplayer-video-audio": "Ogg įį£įįį", + "mwe-embedplayer-audio-mpeg": "MPEG įį£įįį", + "mwe-embedplayer-video-3gp": "3GP įįįįį", + "mwe-embedplayer-video-mpeg": "MPEG įįįįį", + "mwe-embedplayer-video-msvideo": "AVI įįįįį", + "mwe-embedplayer-missing-source": "įįįįįį” į¬į§įį į įįį įįįį«įįįį" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ko.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ko.json new file mode 100644 index 00000000..75e9374d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ko.json @@ -0,0 +1,83 @@ +{ + "@metadata": { + "authors": [ + "Priviet", + "ģė¼" + ] + }, + "mwe-embedplayer-credit-title": "ģ ėŖ©: $1", + "mwe-embedplayer-credit-date": "ė ģ§: $1", + "mwe-embedplayer-credit-author": "ģ ģ: $1", + "mwe-embedplayer-nocredits": "ģ¬ģ© ź°ė„ķ ģ ģģ§ģ“ ģģµėė¤", + "mwe-embedplayer-loading_plugin": "ķė¬ź·øģøģ ė¶ė¬ģ¤ė ģ¤...", + "mwe-embedplayer-select_playback": "ģ¬ģ ķź²½ ģ¤ģ ", + "mwe-embedplayer-link_back": "ė§ķ¬ ė°±", + "mwe-embedplayer-error_swap_vid": "ģ¤ė„: mwEmbedė mwEmbed ģøķ°ķģ“ģ¤ģ ėķ ėģģ ķź·øė„¼ ģ ķķ ģ ģģµėė¤", + "mwe-embedplayer-add_to_end_of_sequence": "ģķģ¤ģ ėģ ģ¶ź°", + "mwe-embedplayer-missing_video_stream": "ģ“ ģ¤ķøė¦¼ģ ėķ ėģģ ķģ¼ģ“ ģģµėė¤", + "mwe-embedplayer-play_clip": "ķ“ė¦½ ģ¬ģ", + "mwe-embedplayer-pause_clip": "ķ“ė¦½ ģ¼ģ ģ ģ§", + "mwe-embedplayer-volume_control": "ģė ģ»Øķøė”¤", + "mwe-embedplayer-player_options": "ķė ģ“ģ“ ģ¤ģ ", + "mwe-embedplayer-timed_text": "ģė§", + "mwe-embedplayer-player_fullscreen": "ģ ģ²“ ķė©“", + "mwe-embedplayer-next_clip_msg": "ė¤ģ ķ“ė¦½ ģ¬ģ", + "mwe-embedplayer-prev_clip_msg": "ģ“ģ ķ“ė¦½ ģ¬ģ", + "mwe-embedplayer-current_clip_msg": "ģ“ ķ“ė¦½ ģ¬ģ ź³ģķźø°", + "mwe-embedplayer-seek_to": "$1 ķģ", + "mwe-embedplayer-paused": "ģ¼ģ ģ ģ§ķØ", + "mwe-embedplayer-download_segment": "ģ ķ ė¤ģ“ė”ė:", + "mwe-embedplayer-download_full_video": "ģ ģ²“ ėģģ ķģ¼ ė¤ģ“ė”ė:", + "mwe-embedplayer-download_right_click": "ė¤ģ“ė”ėķė ¤ė©“ ģ¤ė„øģŖ½ģ ķ“ė¦ķź³ <i>ė¤ė„ø ģ“ė¦ģ¼ė” ė§ķ¬ ģ ģ„...</i>ģ ģ ķķģøģ", + "mwe-embedplayer-download_clip": "ėģģ ė¤ģ“ė”ė", + "mwe-embedplayer-download_text": "ķ
ģ¤ķø ė¤ģ“ė”ė", + "mwe-embedplayer-download": "ė¤ģ“ė”ė", + "mwe-embedplayer-share": "ź³µģ ", + "mwe-embedplayer-credits": "ģ ģģ§", + "mwe-embedplayer-about-library": "Kaltura ķė ģ“ģ“ ģ ė³“", + "mwe-embedplayer-about-library-desc": "Kalturaģ HTML5 ėÆøėģ“ ė¼ģ“ėøė¬ė¦¬ė ėŖØė ģ£¼ģ ėøė¼ģ°ģ ģģ ģ¼ź“ė ķė ģ“ģ“ ģøķ°ķģ“ģ¤ė” ģ¤ėė HTML5ģ <video> ė° <audio> ķź·øė„¼ ģ“ģ©ķ ģ ģģµėė¤.\n\n[$1 Kaltura ķė ģ“ģ“ ė¼ģ“ėøė¬ė¦¬ģ ėķ“ ģģøķ ģģė“
ėė¤].", + "mwe-embedplayer-clip_linkback": "ķ“ė¦½ ģė³ø ķģ“ģ§", + "mwe-embedplayer-choose_player": "ėģģ ķė ģ“ģ“ ģ ķ", + "mwe-embedplayer-no-player": "$1ģ ėķ“ ģ¬ģ© ź°ė„ķ ķė ģ“ģ“ź° ģģµėė¤", + "mwe-embedplayer-share_this_video": "ģ“ ėģģ ź³µģ ķźø°", + "mwe-embedplayer-video_credits": "ėģģ ģ ģģ§", + "mwe-embedplayer-no-video_credits": "ģ¬ģ© ź°ė„ķ ģ ģģ§ģ“ ģģµėė¤", + "mwe-embedplayer-kaltura-platform-title": "Kaltura ģ¤ķ ģģ¤ ėģģ ķė«ķ¼", + "mwe-embedplayer-menu_btn": "ė©ė“", + "mwe-embedplayer-close_btn": "ė«źø°", + "mwe-embedplayer-ogg-player-vlc-player": "VLC ķė ģ“ģ“", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg ķė ģ“ģ“", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3 ķė ģ“ģ“", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC ķė ģ“ģ“", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 ķė ģ“ģ“", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM ķė ģ“ģ“", + "mwe-embedplayer-ogg-player-oggPlugin": "ģ¼ė° Ogg ķė¬ź·øģø", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime ķė¬ź·øģø", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura ķė ģ“ģ“", + "mwe-embedplayer-ogg-player-selected": "(ģ ķėØ)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK ķė ģ ė³“ė¹ģ¤", + "mwe-embedplayer-for_best_experience": "ė ėģ ėģģ ģ¬ģģ ģķ“ģė<a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">html5 ėģģ ėøė¼ģ°ģ </a>ė„¼ ź¶ģ„ķ©ėė¤.", + "mwe-embedplayer-download-warn": "ķøķėģ§ ģė ėøė¼ģ°ģ ģģ ķė ģ“ģ“ė„¼ ź°ģ§ķģµėė¤: ėøė¼ģ°ģ ģģ ģ¬ģģ ķė ¤ė©“ [$1 ģµģ Firefox]ė„¼ ė¤ģ“ė”ėķģøģ", + "mwe-embedplayer-fullscreen-tip": "<i>ģ¹ ėøė¼ģ°ģ </i>ė„¼ ģ ģ²“ ķė©“ģ¼ė” ģ ķķė ¤ė©“ <b>F11</b>ģ ėė„“ģøģ", + "mwe-embedplayer-fullscreen-tip-osx": "ģ ģ²“ ķė©“ģ¼ė” ģ ķķė ¤ė©“ <b>shift ā F</b>ė„¼ ėė„“ģøģ", + "mwe-embedplayer-do_not_warn_again": "ėģ¤ģ ģ“ ė©ģģ§ė„¼ ė³“ģ¬ģ£¼ģ§ ģģ", + "mwe-embedplayer-playerSelect": "ķė ģ“ģ“", + "mwe-embedplayer-read_before_embed": "ķ¬ķØķźø° ģ ģ <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ģ“ źøģ ģ½ģ¼ģøģ</a>.", + "mwe-embedplayer-embed_site_or_blog": "ė¬øģģ ķ¬ķØ", + "mwe-embedplayer-embed_wiki": "ģķ¤ģ ķ¬ķØ", + "mwe-embedplayer-related_videos": "ź“ė Ø ėģģ", + "mwe-embedplayer-seeking": "ķģ ģ¤", + "mwe-embedplayer-buffering": "ė²ķ¼ė§", + "mwe-embedplayer-video-h264": "H.264 ėģģ", + "mwe-embedplayer-video-webm": "WebM ėģģ", + "mwe-embedplayer-video-flv": "ķėģ ėģģ", + "mwe-embedplayer-video-ogg": "Ogg ėģģ", + "mwe-embedplayer-video-audio": "Ogg ģė¦¬", + "mwe-embedplayer-audio-mpeg": "MPEG ģė¦¬", + "mwe-embedplayer-video-3gp": "3GP ėģģ", + "mwe-embedplayer-video-mpeg": "MPEG ėģģ", + "mwe-embedplayer-video-msvideo": "AVI ėģģ", + "mwe-embedplayer-missing-source": "ģė³ø ėģģģ ģ°¾ģ ģ ģģµėė¤" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ksh.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ksh.json new file mode 100644 index 00000000..91f9beb5 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ksh.json @@ -0,0 +1,84 @@ +{ + "@metadata": { + "authors": [ + "Purodha" + ] + }, + "mwe-embedplayer-credit-title": "Tittel: $1", + "mwe-embedplayer-credit-date": "Dattum: $1", + "mwe-embedplayer-credit-author": "Schriever: $1", + "mwe-embedplayer-nocredits": "Mer han kein Dangksaaronge ze jriefe", + "mwe-embedplayer-loading_plugin": "Ben dat Ongerprojramm aam laade ā¦", + "mwe-embedplayer-select_playback": "Enstellunge fƶr et Affshpelle maache", + "mwe-embedplayer-link_back": "Lengk retuur", + "mwe-embedplayer-error_swap_vid": "FƤhler: <code lang=\"en\">mv_embed</code> kunnt de EtikƤtte fƶr dƤ Viddejo fƶr <code lang=\"en\">mv_embed</code> sing SchnetshtƤl nit uĆtuusche.", + "mwe-embedplayer-add_to_end_of_sequence": "Aam Engk vun dƤ AfschpellleĆ aanfƶƶje", + "mwe-embedplayer-missing_video_stream": "De Viddejodattei fƶr heh dƤ Daateshrom fƤhlt", + "mwe-embedplayer-play_clip": "Donn dƤ UĆschnedd afshpelle", + "mwe-embedplayer-pause_clip": "Donn dƤ UĆschnedd aanhallde", + "mwe-embedplayer-volume_control": "Enshtellung fƶr de LoutshtƤrk", + "mwe-embedplayer-player_options": "Enschtellunge fƶr Affshpellprojramme", + "mwe-embedplayer-timed_text": "Ongertitele met Zigge", + "mwe-embedplayer-player_fullscreen": "Op der janze Beldscherm jonn", + "mwe-embedplayer-next_clip_msg": "Donn dƤ UĆschnedd donoh shpelle", + "mwe-embedplayer-prev_clip_msg": "Donn dƤ UĆschnedd dovƶƶr shpelle", + "mwe-embedplayer-current_clip_msg": "Donn dƤ UĆschnedd wigger shpelle", + "mwe-embedplayer-seek_to": "Sƶhk bes: $1", + "mwe-embedplayer-paused": "aanjehallde", + "mwe-embedplayer-download_segment": "UĆwahl fƶr erunger ze laade:", + "mwe-embedplayer-download_full_video": "Donn dƤ janze Viddejo erunge laade:", + "mwe-embedplayer-download_right_click": "Zom Eronger laade, kleck met dƤ rƤƤschte TaĆd_aan Dinge MuuĆ, un sƶhk āAfshpeishere onger ā¦ā uĆ", + "mwe-embedplayer-download_clip": "Viddejo erunger lade", + "mwe-embedplayer-download_text": "Tex erungerlaade", + "mwe-embedplayer-download": "Eronger laade", + "mwe-embedplayer-share": "Wigger jƤvve", + "mwe-embedplayer-credits": "Aanerkennunge fƶr BeidrƤƤsch", + "mwe-embedplayer-about-library": "Ćvver der Kaltuura Schpeller", + "mwe-embedplayer-clip_linkback": "DƤm UĆschnett singe QuƤllsigg", + "mwe-embedplayer-choose_player": "Donn en Affshpellprojramm fƶr Viddejos uĆsƶhke", + "mwe-embedplayer-no-player": "Mer han keine Afschpeller fƶr $1", + "mwe-embedplayer-share_this_video": "Donn dƤ Viddejo wigger jƤvve", + "mwe-embedplayer-video_credits": "Aanerkennunge fƶr BeidrƤƤsch aan dƤmm Viddejo", + "mwe-embedplayer-no-video_credits": "Mer han kein Dangksaaronge ze jriefe", + "mwe-embedplayer-kaltura-platform-title": "Kaltuura - Viddejo Projramme med offe QuƤlle", + "mwe-embedplayer-menu_btn": "UĆwahl", + "mwe-embedplayer-close_btn": "Zohmaache", + "mwe-embedplayer-ogg-player-vlc-player": "DƤ <i lang=\"en\">VLC</i>-Affschpeller", + "mwe-embedplayer-ogg-player-oggNative": "HTML5-<i lang=\"en\">Ogg</i>-Affschpeller", + "mwe-embedplayer-ogg-player-mp3Native": "<i lang=\"en\">MP3</i> Speller fƶr <i lang=\"en\">HTML5</i>", + "mwe-embedplayer-ogg-player-aacNative": "HTML5-<i lang=\"en\">MP3</i>-Affschpeller", + "mwe-embedplayer-ogg-player-h264Native": "HTML5-<i lang=\"en\">H.264</i>-Affschpeller", + "mwe-embedplayer-ogg-player-webmNative": "HTML5-<i lang=\"en\">WebM</i>-Affschpeller", + "mwe-embedplayer-ogg-player-oggPlugin": "DƤm <i lang=\"en\">Ogg</i>-Shpeller sing Stanndatt-<i lang=\"en\">plugin</i>", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "Et Zohsaprojramm <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> fƶr der <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Microsoft Internet Explorer\">IE</i> eronger lahde", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "DƤ <i lang=\"en\">QuickTime</i>-Shpeller als <i lang=\"en\">plugin</i>", + "mwe-embedplayer-ogg-player-quicktime-activex": "DƤ <i lang=\"en\">QuickTime</i>-Shpeller ƶvver <i lang=\"en\">ActiveX</i>", + "mwe-embedplayer-ogg-player-cortado": "DƤ <i lang=\"en\">Java Cortado</i> Shpeller", + "mwe-embedplayer-ogg-player-flowplayer": "DƤ <i lang=\"en\">Flow</i>shpeller", + "mwe-embedplayer-ogg-player-kplayer": "DƤ <i lang=\"en\">Kaltura</i> Afshpeller", + "mwe-embedplayer-ogg-player-selected": "(uĆjesƶhk)", + "mwe-embedplayer-ogg-player-omtkplayer": "<i lang=\"en\">OMTK Flash Vorbis</i> Shpeller", + "mwe-embedplayer-for_best_experience": "ƶm en bƤĆere Qualliteit fƶr dƤ Viddejo ze krijje, dom_mer der <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5-Viddejo-Browser</a> ƤmfƤhle.", + "mwe-embedplayer-fullscreen-tip": "Met dƤm <b>F11</b>-Knopp schalldt mer dƤ <i>Brauser</i> op der kumplƤtte Beldscherrem ƶm, un widder retuur.", + "mwe-embedplayer-fullscreen-tip-osx": "Met <b>Ćmschallde-ā-F</b> schalldt mer op der kumplƤtte Beldscherrem ƶm", + "mwe-embedplayer-do_not_warn_again": "Donn heh di Nohreesch en Zohkonf nit norr_ens aanzeije.", + "mwe-embedplayer-playerSelect": "Schpeller", + "mwe-embedplayer-read_before_embed": "BeĆ esu joot un liĆ <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ƶvver de Sesherheit bemm Ennfƶƶje ƶvver et Netz</a> iih dat De jet ennfƶƶschĆ!", + "mwe-embedplayer-embed_site_or_blog": "En en Websigg udder <i lang=\"en\">Blog</i>_erinndonn", + "mwe-embedplayer-embed_wiki": "En e Wiki enboue", + "mwe-embedplayer-related_videos": "Verwandte Viddejos", + "mwe-embedplayer-seeking": "aam Sƶhke", + "mwe-embedplayer-video-h264": "En <i lang=\"en\">H.264</i>-Viddejo-Dattei", + "mwe-embedplayer-video-webm": "En <i lang=\"en\">WebM</i>-Viddejo-Dattei", + "mwe-embedplayer-video-flv": "En <i lang=\"en\">Flash</i>-Viddejo-Dattei", + "mwe-embedplayer-video-ogg": "En <i lang=\"en\">Ogg</i>-Viddejo-Dattei", + "mwe-embedplayer-video-audio": "En <i lang=\"en\">Ogg</i>-Tohn-Dattei", + "mwe-embedplayer-audio-mpeg": "En <i lang=\"en\">MPEG </i>-Tohn-Dattei", + "mwe-embedplayer-video-3gp": "En <i lang=\"en\">3GP</i>-Viddejo-Dattei", + "mwe-embedplayer-video-mpeg": "En <i lang=\"en\">MPEG</i>-Viddejo-Dattei", + "mwe-embedplayer-video-msvideo": "En <i lang=\"en\">AVI</i>-Viddejo-Dattei", + "mwe-embedplayer-missing-source": "Mer han kein Viddejo-QuƤlle-Dattei jefonge", + "mwe-embedplayer-iewebmprompt-intro": "Eine Schrett mih, ih dat De dƤ Viddejo afschpelle kanns ā¦", + "mwe-embedplayer-iewebmprompt-linktext": "Donn de Ongerstƶzong fƶr <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Microsoft Internet Explorer</i> eronger lahde un enschtallehre", + "mwe-embedplayer-iewebmprompt-outro": "Donn heh di Sigg nohm Enschtallehre norr_ens neu lahde." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ku-latn.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ku-latn.json new file mode 100644 index 00000000..c51aa6ca --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ku-latn.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Gomada" + ] + }, + "mwe-embedplayer-credit-title": "Sernav: $1", + "mwe-embedplayer-credit-date": "DĆ®rok: $1", + "mwe-embedplayer-credit-author": "XwedĆ®: $1" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ky.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ky.json new file mode 100644 index 00000000..9098a14a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ky.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Growingup" + ] + }, + "mwe-embedplayer-menu_btn": "ŠŠµŠ½Ń", + "mwe-embedplayer-close_btn": "ŠŠ°Š±ŃŃ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lb.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lb.json new file mode 100644 index 00000000..b3811f5d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lb.json @@ -0,0 +1,55 @@ +{ + "@metadata": { + "authors": [ + "Robby", + "Soued031" + ] + }, + "mwe-embedplayer-credit-title": "Titel: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Auteur: $1", + "mwe-embedplayer-loading_plugin": "Plugin lueden ...", + "mwe-embedplayer-select_playback": "Astellunge vum Ofspillen festleeĆ«n", + "mwe-embedplayer-link_back": "Link zrĆ©ck", + "mwe-embedplayer-add_to_end_of_sequence": "Um Schluss vun der Sequenz derbƤisetzen", + "mwe-embedplayer-missing_video_stream": "De Video-Fichier fir dĆ«se Stream feelt", + "mwe-embedplayer-play_clip": "Clip spillen", + "mwe-embedplayer-pause_clip": "Clip Ć«nnerbriechen", + "mwe-embedplayer-player_options": "Optioune vum Player", + "mwe-embedplayer-player_fullscreen": "Ganzen Ecran", + "mwe-embedplayer-next_clip_msg": "NƤchste Clip spillen", + "mwe-embedplayer-prev_clip_msg": "Virege Clip spillen", + "mwe-embedplayer-current_clip_msg": "DĆ«se Clip weiderspillen", + "mwe-embedplayer-seek_to": "No $1 sichen", + "mwe-embedplayer-paused": "Ć«nnerbrach", + "mwe-embedplayer-download_segment": "Dat wat erausgesicht ass eroflueden:", + "mwe-embedplayer-download_full_video": "Ganze Videofichier eroflueden:", + "mwe-embedplayer-download_full_audio": "Ganzen Audiofichier eroflueden:", + "mwe-embedplayer-download_right_click": "Fir erofzelueden, klickt op dĆ©i riets Maustast a wielt <i>Link spƤicheren als...</i>", + "mwe-embedplayer-download_clip": "Video eroflueden", + "mwe-embedplayer-download_text": "Text eroflueden", + "mwe-embedplayer-download": "Eroflueden", + "mwe-embedplayer-share": "Deelen", + "mwe-embedplayer-clip_linkback": "QuellsƤit vum Clip", + "mwe-embedplayer-share_this_video": "DĆ«se Video deelen", + "mwe-embedplayer-share_this_audio": "DĆ«sen Audio-Fichier deelen", + "mwe-embedplayer-menu_btn": "MenĆ¼", + "mwe-embedplayer-close_btn": "Zoumaachen", + "mwe-embedplayer-ogg-player-vlc-player": "VLC-Player", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC fir iOS-App", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-Plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura-Player", + "mwe-embedplayer-ogg-player-selected": "(erausgesicht)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-do_not_warn_again": "DĆ«se Message an Zukunft net mĆ©i weisen.", + "mwe-embedplayer-playerSelect": "Player", + "mwe-embedplayer-read_before_embed": "Liest w.e.g. virum Abannen d'<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">SĆ©cherheetsinformatiounen iwwer d'Abannen iwwer Remote</a> ier Dir mam Abanne weidermaacht!", + "mwe-embedplayer-embed_site_or_blog": "An Ćr SƤit abauen", + "mwe-embedplayer-related_videos": "Ćhnlech Videoen", + "mwe-embedplayer-seeking": "sichen", + "mwe-embedplayer-missing-source": "Et gouf kee Video fonnt", + "mwe-embedplayer-vlcapp-downloadvideo": "DĆ«se Video eroflueden", + "mwe-embedplayer-iewebmprompt-outro": "No der Installatioun dĆ«s sƤit nei lueden." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lt.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lt.json new file mode 100644 index 00000000..3a3b6f50 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lt.json @@ -0,0 +1,90 @@ +{ + "@metadata": { + "authors": [ + "Hugo.arg", + "Gediminas", + "Pofka" + ] + }, + "mwe-embedplayer-credit-title": "Pavadinimas: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autorius: $1", + "mwe-embedplayer-nocredits": "NÄra duomenų apie kÅ«rÄjus", + "mwe-embedplayer-loading_plugin": "Kraunamas ÄÆskiepis...", + "mwe-embedplayer-select_playback": "Nustatyti grojimo nustatymus", + "mwe-embedplayer-link_back": "AtgalinÄ nuoroda", + "mwe-embedplayer-error_swap_vid": "Klaida: mwEmbed negali pakeisti video žymÄs mwEmbed aplinkai", + "mwe-embedplayer-add_to_end_of_sequence": "PridÄti ÄÆ sekos galÄ
", + "mwe-embedplayer-missing_video_stream": "NÄra vaizdo ÄÆraÅ”o rinkmenos Å”iam srautui", + "mwe-embedplayer-play_clip": "Leisti ÄÆraÅ”Ä
", + "mwe-embedplayer-pause_clip": "Pristabdyti ÄÆraÅ”Ä
", + "mwe-embedplayer-volume_control": "Garso valdymas", + "mwe-embedplayer-player_options": "Grotuvo parinktys", + "mwe-embedplayer-timed_text": "Priskirtas tekstas", + "mwe-embedplayer-player_fullscreen": "Per visÄ
ekranÄ
", + "mwe-embedplayer-next_clip_msg": "Leisti kitÄ
ÄÆraÅ”Ä
", + "mwe-embedplayer-prev_clip_msg": "Leisti praeitÄ
ÄÆraÅ”Ä
", + "mwe-embedplayer-current_clip_msg": "TÄsti Å”io ÄÆraÅ”o atlikimÄ
", + "mwe-embedplayer-seek_to": "Siekti $1", + "mwe-embedplayer-paused": "pristabdyta", + "mwe-embedplayer-download_segment": "Atsisiuntimo bÅ«das:", + "mwe-embedplayer-download_full_video": "Atsisiųsti visÄ
vaizdo ÄÆraÅ”o rinkmenÄ
:", + "mwe-embedplayer-download_right_click": "Atsisiuntimui spauskite deÅ”iniuoju pelÄs mygtuku ir pasirinkite <i>IÅ”saugoti nuorodÄ
kaip...</i>", + "mwe-embedplayer-download_clip": "Atsisiųsti vaizdo ÄÆraÅ”Ä
", + "mwe-embedplayer-download_text": "Atsisiųsti tekstÄ
", + "mwe-embedplayer-download": "Atsisiųsti", + "mwe-embedplayer-share": "Dalintis", + "mwe-embedplayer-credits": "Rinkmenos duomenys", + "mwe-embedplayer-about-library": "Apie Kaltura grotuvÄ
", + "mwe-embedplayer-clip_linkback": "Ä®raÅ”o iÅ”eities puslapis", + "mwe-embedplayer-choose_player": "Pasirinkite vaizdo grotuvÄ
", + "mwe-embedplayer-no-player": "NÄra $1 tinkamo grotuvo", + "mwe-embedplayer-share_this_video": "Dalintis Å”iuo ÄÆraÅ”u", + "mwe-embedplayer-video_credits": "Apie ÄÆraÅ”o kÅ«rÄjus", + "mwe-embedplayer-no-video_credits": "NÄra duomenų apie kÅ«rÄjus", + "mwe-embedplayer-kaltura-platform-title": "āKalturaā atvirojo kodo ÄÆraŔų grotuvo platforma", + "mwe-embedplayer-menu_btn": "Parinktys", + "mwe-embedplayer-close_btn": "Uždaryti", + "mwe-embedplayer-ogg-player-vlc-player": "VLC grotuvas", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg grotuvas", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3 grotuvas", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC grotuvas", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 grotuvas", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM grotuvas", + "mwe-embedplayer-ogg-player-oggPlugin": "Bendrasis Ogg ÄÆskiepis", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC, skirtas iOS taikomajai programai", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime ÄÆskiepis", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura grotuvas", + "mwe-embedplayer-ogg-player-selected": "(pasirinkta)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Geresnei vaizdo ÄÆraÅ”o peržiÅ«ros kokybei siÅ«lome <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5 palaikanÄiÄ
narÅ”yklÄ</a>.", + "mwe-embedplayer-fullscreen-tip": "Spauskite <b>F11</b> mygtukÄ
, kuris nustatys <i>narÅ”yklÄ</i> pilno ekrano režimui", + "mwe-embedplayer-fullscreen-tip-osx": "Spauskite <b>shift ā F</b>, kad pereitumÄte ÄÆ pilno ekrano režimÄ
", + "mwe-embedplayer-do_not_warn_again": "Ateityje nerodyti Å”io praneÅ”imo", + "mwe-embedplayer-playerSelect": "Grotuvai", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Perskaitykite tai</a> prieÅ” talpinant.", + "mwe-embedplayer-embed_site_or_blog": "Ä®terpti puslapyje", + "mwe-embedplayer-embed_wiki": "Talpinti wiki svetainÄje", + "mwe-embedplayer-related_videos": "SusijÄ vaizdo ÄÆraÅ”ai", + "mwe-embedplayer-seeking": "ieÅ”koma", + "mwe-embedplayer-buffering": "duomenų kaupimas", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-webm": "WebM video", + "mwe-embedplayer-video-flv": "Flash video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg audio", + "mwe-embedplayer-audio-mpeg": "MPEG audio", + "mwe-embedplayer-video-3gp": "3GP video", + "mwe-embedplayer-video-mpeg": "MPEG video", + "mwe-embedplayer-video-msvideo": "AVI video", + "mwe-embedplayer-missing-source": "Nerastas vaizdo ÄÆraÅ”o Å”altinis", + "mwe-embedplayer-vlcapp-intro": "Kad galÄtumÄte peržiÅ«rÄti vaizdo ÄÆraÅ”us iPhone ar iPad ÄÆrenginiuose, jums reikia nemokamo $1.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "VLC programÄlÄ", + "mwe-embedplayer-vlcapp-downloadapp": "Atsisiųsti VLC taikomÄ
jÄ
programÄ
iÅ” App Store internetinÄs krautuvÄs", + "mwe-embedplayer-vlcapp-openvideo": "Atverti Å”ÄÆ vaizdo ÄÆraÅ”Ä
VLC taikomÄ
ja programa", + "mwe-embedplayer-vlcapp-downloadvideo": "Atsisiųsti Å”ÄÆ vaizdo ÄÆraÅ”Ä
", + "mwe-embedplayer-vlcapp-vlcapppopup": "Kad galÄtumÄte peržiÅ«rÄti vaizdo ÄÆraÅ”us Å”ioje svetainÄje jums reikia nemokamos VLC taikomosios programos. Ar jÄ
ÄÆraÅ”yti dabar?", + "mwe-embedplayer-iewebmprompt-intro": "Oi! Dar vienas dalykas prieÅ” paleidžiant Å”ÄÆ vaizdo ÄÆraÅ”Ä
..." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lv.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lv.json new file mode 100644 index 00000000..6a9d9d01 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/lv.json @@ -0,0 +1,60 @@ +{ + "@metadata": { + "authors": [ + "Papuass" + ] + }, + "mwe-embedplayer-credit-title": "Nosaukums: $1", + "mwe-embedplayer-credit-date": "Datums: $1", + "mwe-embedplayer-credit-author": "Autors: $1", + "mwe-embedplayer-loading_plugin": "IelÄdÄ spraudni...", + "mwe-embedplayer-play_clip": "AtskaÅot ierakstu", + "mwe-embedplayer-pause_clip": "PauzÄt ierakstu", + "mwe-embedplayer-volume_control": "Skaļuma regulÄÅ”ana", + "mwe-embedplayer-player_options": "AtskaÅotÄja iespÄjas", + "mwe-embedplayer-player_fullscreen": "PilnekrÄna režīms", + "mwe-embedplayer-next_clip_msg": "AtskaÅot nÄkamo ierakstu", + "mwe-embedplayer-prev_clip_msg": "AtskaÅot iepriekÅ”Äjo ierakstu", + "mwe-embedplayer-current_clip_msg": "TurpinÄt atskaÅot Å”o klipu", + "mwe-embedplayer-paused": "nopauzÄts", + "mwe-embedplayer-download_segment": "LejupielÄdes izvÄle:", + "mwe-embedplayer-download_full": "LejupielÄdÄt pilnu video failu:", + "mwe-embedplayer-download_clip": "LejupielÄdÄt video", + "mwe-embedplayer-download_text": "LejupielÄdÄt tekstu", + "mwe-embedplayer-download": "LejupielÄdÄt", + "mwe-embedplayer-share": "DalÄ«ties", + "mwe-embedplayer-about-library": "Par Kaltura atskaÅotÄju", + "mwe-embedplayer-choose_player": "IzvÄlieties video atskaÅotÄju", + "mwe-embedplayer-share_this_video": "DalÄ«ties ar Å”o video", + "mwe-embedplayer-kaltura-platform-title": "Kaltura atvÄrtÄ koda video platforma", + "mwe-embedplayer-menu_btn": "IzvÄlne", + "mwe-embedplayer-close_btn": "AizvÄrt", + "mwe-embedplayer-ogg-player-vlc-player": "VLC atskaÅotÄjs", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg atskaÅotÄjs", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 atskaÅotÄjs", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM atskaÅotÄjs", + "mwe-embedplayer-ogg-player-oggPlugin": "VienkÄrÅ”s Ogg spraudnis", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime spraudnis", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura atskaÅotÄjs", + "mwe-embedplayer-ogg-player-selected": "(izvÄlÄts)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-fullscreen-tip": "Nospiediet <b>F11</b>, lai pÄrslÄgtu <i>tÄ«mekļa pÄrlÅ«ku</i> pilnekrÄna režīmÄ", + "mwe-embedplayer-fullscreen-tip-osx": "Nospiediet <b>shift ā F</b>, lai pÄrslÄgtos pilnekrÄna režīmÄ", + "mwe-embedplayer-do_not_warn_again": "TurpmÄk nerÄdÄ«t Å”o ziÅojumu", + "mwe-embedplayer-playerSelect": "AtskaÅotÄji", + "mwe-embedplayer-embed_site_or_blog": "Iekļaut lapÄ", + "mwe-embedplayer-related_videos": "SaistÄ«tie video", + "mwe-embedplayer-seeking": "meklÄ", + "mwe-embedplayer-buffering": "buferizÄcija", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-webm": "WebM video", + "mwe-embedplayer-video-flv": "Flash video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg audio", + "mwe-embedplayer-audio-mpeg": "MPEG audio", + "mwe-embedplayer-video-3gp": "3GP video", + "mwe-embedplayer-video-mpeg": "MPEG video", + "mwe-embedplayer-video-msvideo": "AVI video" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/mk.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/mk.json new file mode 100644 index 00000000..a31ed300 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/mk.json @@ -0,0 +1,95 @@ +{ + "@metadata": { + "authors": [ + "Bjankuloski06" + ] + }, + "mwe-embedplayer-credit-title": "ŠŠ°ŃŠ»Š¾Š²: $1", + "mwe-embedplayer-credit-date": "ŠŠ°ŃŃŠ¼: $1", + "mwe-embedplayer-credit-author": "ŠŠ²ŃŠ¾Ń: $1", + "mwe-embedplayer-nocredits": "ŠŠµŠ¼Š° Š°Š²ŃŠ¾ŃŃŠŗŠø ŠæŠ¾Š“Š°ŃŠ¾ŃŠø", + "mwe-embedplayer-loading_plugin": "ŠŠ¾ Š²ŃŠøŃŃŠ²Š°Š¼ ŠæŃŠøŠŗŠ»ŃŃŠ¾ŠŗŠ¾Ń...", + "mwe-embedplayer-select_playback": "ŠŠ¾ŃŃŠ°Š²Šø ŠøŠ·Š²ŠµŠ“Š±ŠµŠ½Šø Š½Š°Š³Š¾Š“ŃŠ²Š°ŃŠ°", + "mwe-embedplayer-link_back": "ŠŠ±ŃŠ°ŃŠ½Š° Š²ŃŃŠŗŠ°", + "mwe-embedplayer-error_swap_vid": "ŠŃŠµŃŠŗŠ°: mwEmbed Š½Šµ Š¼Š¾Š¶ŠµŃŠµ Š“Š° ŃŠ° ŃŠ¼ŠµŠ½Šø Š²ŠøŠ“ŠµŠ¾-Š¾Š·Š½Š°ŠŗŠ°ŃŠ° Š·Š° mwEmbed-ŠæŠ¾ŃŃŠµŠ“Š½ŠøŠŗŠ¾Ń", + "mwe-embedplayer-add_to_end_of_sequence": "ŠŠ¾Š“Š°Ń Š½Š° ŠŗŃŠ°ŃŠ¾Ń Š¾Š“ Š½ŠøŠ·Š°ŃŠ°", + "mwe-embedplayer-missing_video_stream": "ŠŠøŠ“ŠµŠ¾-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°ŃŠ° Š·Š° Š¾Š²Š¾Ń ŠŗŠ°Š½Š°Š» Š½ŠµŠ“Š¾ŃŃŠ°ŃŃŠ²Š°", + "mwe-embedplayer-play_clip": "ŠŃŃŃŠø ŃŠ° ŃŠ½ŠøŠ¼ŠŗŠ°ŃŠ°", + "mwe-embedplayer-pause_clip": "ŠŠ°ŃŠ·ŠøŃŠ°Ń ŃŠ½ŠøŠ¼ŠŗŠ°", + "mwe-embedplayer-volume_control": "Š ŠµŠ³ŃŠ»ŠøŃŠ°ŃŠµ Š³Š»Š°ŃŠ½Š¾ŃŃ", + "mwe-embedplayer-player_options": "ŠŠ°Š³Š¾Š“ŃŠ²Š°ŃŠ° Š½Š° ŠøŠ·Š²ŠµŠ“ŃŠ²Š°ŃŠ¾Ń", + "mwe-embedplayer-timed_text": "Š”ŠøŠ½Ń
ŃŠ¾Š½ŠøŠ·ŠøŃŠ°Š½ ŃŠµŠŗŃŃ", + "mwe-embedplayer-player_fullscreen": "ŠŠ° ŃŠµŠ» ŠµŠŗŃŠ°Š½", + "mwe-embedplayer-next_clip_msg": "ŠŃŃŃŠø ŃŠ»ŠµŠ“Š½Š° ŃŠ½ŠøŠ¼ŠŗŠ°", + "mwe-embedplayer-prev_clip_msg": "ŠŃŃŃŠø ŠæŃŠµŃŃ
Š¾Š“Š½Š° ŃŠ½ŠøŠ¼ŠŗŠ°", + "mwe-embedplayer-current_clip_msg": "ŠŃŠ¾Š“Š¾Š»Š¶Šø ŃŠ¾ ŠøŠ·Š²ŠµŠ“Š±Š° Š½Š° ŃŠ½ŠøŠ¼ŠŗŠ°Š²Š°", + "mwe-embedplayer-seek_to": "ŠŃŠµŃŠ“Šø Š½Š° $1", + "mwe-embedplayer-paused": "ŠæŠ°ŃŠ·ŠøŃŠ°Š½Š¾", + "mwe-embedplayer-download_segment": "ŠŃŠµŠ·ŠµŠ¼Šø ŠøŠ·Š±ŃŠ°Š½Š¾:", + "mwe-embedplayer-download_full_video": "ŠŃŠµŠ·ŠµŠ¼ŠµŃŠµ ŃŠ° ŠæŠ¾Š»Š½Š°ŃŠ° Š²ŠøŠ“ŠµŠ¾-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°:", + "mwe-embedplayer-download_full_audio": "ŠŃŠµŠ·ŠµŠ¼ŠµŃŠµ ŃŠ° ŠæŠ¾Š»Š½Š°ŃŠ° Š°ŃŠ“ŠøŠ¾-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°:", + "mwe-embedplayer-download_right_click": "ŠŠ° Š“Š° ŠæŃŠµŠ·ŠµŠ¼ŠµŃŠµ, ŃŃŠøŃŠ½ŠµŃŠµ Š³Š¾ Š“ŠµŃŠ½Š¾ŃŠ¾ ŠŗŠ¾ŠæŃŠµ Šø Š¾Š“Š±ŠµŃŠµŃŠµ āŠ”Š½ŠøŠ¼Šø ŃŠ° Š²ŃŃŠŗŠ°ŃŠ° ŠŗŠ°ŠŗŠ¾...ā", + "mwe-embedplayer-download_clip": "ŠŃŠµŠ·ŠµŠ¼Šø Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-download_text": "ŠŃŠµŠ·ŠµŠ¼Šø ŃŠµŠŗŃŃ", + "mwe-embedplayer-download": "ŠŃŠµŠ·ŠµŠ¼Šø", + "mwe-embedplayer-share": "Š”ŠæŠ¾Š“ŠµŠ»Šø", + "mwe-embedplayer-credits": "ŠŠ²ŃŠ¾ŃŠø", + "mwe-embedplayer-about-library": "ŠŠ° ŠøŠ·Š²ŠµŠ“ŃŠ²Š°ŃŠ¾Ń Kaltura", + "mwe-embedplayer-about-library-desc": "HTML5-Š¼ŃŠ»ŃŠøŠ¼ŠµŠ“ŠøŃŠ°Š»Š½Š°ŃŠ° Š±ŠøŠ±Š»ŠøŠ¾ŃŠµŠŗŠ° Š½Š° Kaltura Š²Šø Š¾Š²Š¾Š·Š¼Š¾Š¶ŃŠ²Š° ŃŃŃŠµ Š²ŠµŠ“Š½Š°Ń Š“Š° ŠŗŠ¾ŃŠøŃŃŠøŃŠµ HTML5-Š¾Š·Š½Š°ŠŗŠø <code><nowiki><video></nowiki></code> Šø <code><nowiki><audio></nowiki></code> ŃŠ¾ ŠµŠ“Š½Š¾Š¾Š±ŃŠ°Š·ŠµŠ½ Šø ŃŃŠ°Š½Š“Š°ŃŠ“ŠµŠ½ ŠæŠ¾ŃŃŠµŠ“Š½ŠøŠŗ Š·Š° ŠøŠ·Š²ŠµŠ“ŃŠ²Š°ŃŠ¾Ń ŠŗŠ°Ń ŃŠøŃŠµ Š½Š°ŃŠ·Š°ŃŃŠ°ŠæŠµŠ½Šø ŠæŃŠµŠ»ŠøŃŃŃŠ²Š°ŃŠø.\n\n[$1 ŠŠ¾Š²ŠµŃŠµ Š·Š° Š±ŠøŠ±Š»ŠøŠ¾ŃŠµŠŗŠ°ŃŠ° Š½Š° ŠøŠ·Š²ŠµŠ“ŃŠ²Š°ŃŠ¾Ń Kaltura].", + "mwe-embedplayer-clip_linkback": "ŠŠ·Š²Š¾ŃŠ½Š° ŃŃŃŠ°Š½ŠøŃŠ° Š½Š° ŃŠ½ŠøŠ¼ŠŗŠ°ŃŠ°", + "mwe-embedplayer-choose_player": "ŠŠ“Š±ŠµŃŠµŃŠµ Š²ŠøŠ“ŠµŠ¾-ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń", + "mwe-embedplayer-no-player": "ŠŠµŠ¼Š° Š“Š¾ŠæŃŃŠ°ŠæŠµŠ½ ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń Š·Š° $1", + "mwe-embedplayer-share_this_video": "Š”ŠæŠ¾Š“ŠµŠ»Šø ŃŠ° ŃŠ½ŠøŠ¼ŠŗŠ°Š²Š°", + "mwe-embedplayer-share_this_audio": "Š”ŠæŠ¾Š“ŠµŠ»Šø ŃŠ° Š°ŃŠ“Š¾-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°Š²Š°", + "mwe-embedplayer-video_credits": "ŠŠ° Š°Š²ŃŠ¾ŃŠøŃŠµ Š½Š° ŃŠ½ŠøŠ¼ŠŗŠ°ŃŠ°", + "mwe-embedplayer-no-video_credits": "ŠŠµŠ¼Š° Š°Š²ŃŠ¾ŃŃŠŗŠø ŠæŠ¾Š“Š°ŃŠ¾ŃŠø", + "mwe-embedplayer-kaltura-platform-title": "ŠŃŠ²Š¾ŃŠµŠ½Š° Š²ŠøŠ“ŠµŠ¾-ŠæŠ»Š°ŃŃŠ¾ŃŠ¼Š° Kaltura", + "mwe-embedplayer-menu_btn": "ŠŠµŠ½Šø", + "mwe-embedplayer-close_btn": "Š”ŠŗŃŠøŃ", + "mwe-embedplayer-ogg-player-vlc-player": "ŠŠ·Š²ŠµŠ“ŃŠ²Š°Ń VLC", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg-ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3-ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC-ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264-ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń", + "mwe-embedplayer-ogg-player-webmNative": "ŠŠ·Š²ŠµŠ“ŃŠ²Š°Ń WebM (HTML5)", + "mwe-embedplayer-ogg-player-oggPlugin": "ŠŠæŃŃ Ogg-ŠæŃŠøŠŗŠ»ŃŃŠ¾Šŗ", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "ŠŠ·Š²ŃŃŠ½ŠøŠŗ VLC Š·Š° iOS", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "ŠŃŠµŠ·ŠµŠ¼Š°Ń Š½Š° WebM-Š“Š¾Š“Š°ŃŠ¾Šŗ Š·Š° Internet Explorer", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "ŠŃŠøŠŗŠ»ŃŃŠ¾Šŗ QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "ŠŠ·Š²ŠµŠ“ŃŠ²Š°Ń Kaltura", + "mwe-embedplayer-ogg-player-selected": "(ŠøŠ·Š±ŃŠ°Š½Š¾)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "ŠŠ° ŠæŠ¾ŠŗŠ²Š°Š»ŠøŃŠµŃŠ½Š¾ ŠæŃŠµŠ³Š»ŠµŠ“ŃŠ²Š°ŃŠµ Š½Š° ŃŠ½ŠøŠ¼ŠŗŠøŃŠµ Š²Šø Š³Š¾ ŠæŃŠµŠæŠ¾ŃŠ°ŃŃŠ²Š°Š¼Šµ <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Š²ŠøŠ“ŠµŠ¾ŠæŃŠµŠ»ŠøŃŃŃŠ²Š°ŃŠ¾Ń ŃŠ¾ HTML5</a>.", + "mwe-embedplayer-download-warn": "ŠŠµ Š½Š°ŃŠ“Š¾Š² ŠæŃŠøŠŗŠ»Š°Š“ŠµŠ½ ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń Š·Š° ŠæŃŃŃŠ°ŃŠµ Š¾Š“ ŠæŃŠµŠ»ŠøŃŃŃŠ²Š°Ń ŠŠŗŠ¾ ŃŠ°ŠŗŠ°ŃŠµ Š“Š° ŠæŃŃŃŠ°ŃŠµ Š¾Š“ ŠæŃŠµŠ»ŠøŃŃŃŠ²Š°Ń, ŠæŃŠµŠ·ŠµŠ¼ŠµŃŠµ Š³Š¾ [$1 Š½Š°ŃŠ½Š¾Š²ŠøŠ¾Ń Firefox]", + "mwe-embedplayer-fullscreen-tip": "ŠŃŠøŃŠøŃŠ½ŠµŃŠµ <b>F11</b> Š·Š° Š“Š° Š³Š¾ ŠæŃŠµŃŃŠ»ŠøŃŠµ <i>ŠæŃŠµŠ»ŠøŃŃŃŠ²Š°ŃŠ¾Ń</i> Š½Š° ŠæŠ¾Š»Š½ ŠµŠŗŃŠ°Š½", + "mwe-embedplayer-fullscreen-tip-osx": "ŠŃŠøŃŠøŃŠ½ŠµŃŠµ <b>shift ā F</b> Š·Š° ŠæŃŠµŠ³Š»ŠµŠ“ Š½Š° ŃŠµŠ» ŠµŠŗŃŠ°Š½", + "mwe-embedplayer-do_not_warn_again": "ŠŃŃŠµŠ³Š° Š½Šµ ŃŠ° ŠæŃŠøŠŗŠ°Š¶ŃŠ²Š°Ń Š¾Š²Š°Š° ŠæŠ¾ŃŠ°ŠŗŠ°", + "mwe-embedplayer-playerSelect": "ŠŠ·Š²ŠµŠ“ŃŠ²Š°Ń", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ŠŃŠ¾ŃŠøŃŠ°ŃŃŠµ Š³Š¾ Š¾Š²Š°</a> ŠæŃŠµŠ“ Š“Š° Š²Š¼ŠµŃŠ½ŃŠ²Š°ŃŠµ.", + "mwe-embedplayer-embed_site_or_blog": "ŠŠ¼ŠµŃŠ½Šø Š²Š¾ ŃŃŃŠ°Š½ŠøŃŠ°", + "mwe-embedplayer-embed_wiki": "ŠŠ¼ŠµŃŠ½Šø Š²Š¾ Š²ŠøŠŗŠø", + "mwe-embedplayer-related_videos": "ŠŠ¾Š²ŃŠ·Š°Š½Šø Š²ŠøŠ“ŠµŠ°", + "mwe-embedplayer-seeking": "Š±Š°ŃŠ°Š¼", + "mwe-embedplayer-buffering": "Š¼ŠµŃŃŃŠŗŠ»Š°Š“ŠøŃŠ°ŃŠµ", + "mwe-embedplayer-video-h264": "H.264 Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-webm": "WebM-Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-flv": "Flash Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-ogg": "Ogg Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-audio": "Ogg Š°ŃŠ“ŠøŠ¾", + "mwe-embedplayer-audio-mpeg": "MPEG Š°ŃŠ“ŠøŠ¾", + "mwe-embedplayer-video-3gp": "3gp Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-mpeg": "MPEG Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-msvideo": "AVI Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-missing-source": "ŠŠµ Šµ ŠæŃŠ¾Š½Š°ŃŠ“ŠµŠ½ ŠøŠ·Š²Š¾Ń Š½Š° ŃŠ½ŠøŠ¼ŠŗŠ°ŃŠ°.", + "mwe-embedplayer-vlcapp-intro": "ŠŠ° Š“Š° Š³Šø Š³Š»ŠµŠ“Š°ŃŠµ Š²ŠøŠ“ŠµŠ°ŃŠ° Š½Š° Š¾Š²Š°Š° ŃŃŃŠ°Š½ŠøŃŠ° Š½Š° iPhone ŠøŠ»Šø iPad, ŃŠµ Š²Šø ŃŃŠµŠ±Š° Š±ŠµŃŠæŠ»Š°ŃŠ½ŠøŠ¾Ń ŠøŠ·Š²ŃŃŠ½ŠøŠŗ $1.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "ŠŠ·Š²ŃŃŠ½ŠøŠŗ VLC", + "mwe-embedplayer-vlcapp-downloadapp": "ŠŃŠµŠ·ŠµŠ¼ŠµŃŠµ Š³Š¾ ŠøŠ·Š²ŃŃŠ½ŠøŠŗŠ¾Ń VLC Š¾Š“ ŠŃŠ¾Š“Š°Š²Š½ŠøŃŠ°ŃŠ° Š·Š° ŠæŃŠøŠ»Š¾Š·Šø (App Store)", + "mwe-embedplayer-vlcapp-openvideo": "ŠŃŠ²Š¾ŃŠø Š³Š¾ Š²ŠøŠ“ŠµŠ¾Š²Š¾ Š²Š¾ ŠøŠ·Š²ŃŃŠ½ŠøŠŗŠ¾Ń VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "ŠŃŠµŠ·ŠµŠ¼Šø Š³Š¾ Š²ŠøŠ“ŠµŠ¾Š²Š¾", + "mwe-embedplayer-vlcapp-vlcapppopup": "ŠŠ° Š“Š° Š³Š»ŠµŠ“Š°ŃŠµ Š²ŠøŠ“ŠµŠ° Š½Š° ŃŃŃŠ°Š½ŃŠ°Š²Š°, ŃŠµ Š²Šø ŃŃŠµŠ±Š° Š±ŠµŃŠæŠ»Š°ŃŠ½ŠøŠ¾Ń ŠøŠ·Š²ŃŃŠ½ŠøŠŗ VLC. ŠŠ° Š³Š¾ ŠæŃŠµŠ·ŠµŠ¼Š°Š¼ ŃŠµŠ³Š°?", + "mwe-embedplayer-iewebmprompt-intro": "Š£ŠæŃ! Š£ŃŃŠµ Š½ŠµŃŃŠ¾ ŠæŃŠµŠ“ Š“Š° Š³Š¾ ŠæŃŃŃŠøŃŠµ Š²ŠøŠ“ŠµŠ¾ŃŠ¾...", + "mwe-embedplayer-iewebmprompt-linktext": "ŠŠ¾ŃŠæŠ¾ŃŃŠ°Š²ŠµŃŠµ Š³Šø Š¼ŠµŠ“ŠøŃŠ¼ŃŠŗŠøŃŠµ Š“ŠµŠ»Š¾Š²Šø Š½Š° WebM Š·Š° Internet Explorer", + "mwe-embedplayer-iewebmprompt-outro": "ŠŃŠµŠ²ŃŠøŃŠ°Ń ŃŠ° ŃŃŃŠ°Š½ŠøŃŠ°ŃŠ° ŠæŠ¾ Š²Š¾ŃŠæŠ¾ŃŃŠ°Š²ŠŗŠ°ŃŠ°." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ml.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ml.json new file mode 100644 index 00000000..03c562be --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ml.json @@ -0,0 +1,96 @@ +{ + "@metadata": { + "authors": [ + "Praveenp" + ] + }, + "mwe-embedplayer-credit-title": "ą“¤ą“²ą“ąµą“ąµą“ąµą“ąµ: $1", + "mwe-embedplayer-credit-date": "ą“¤ąµą“Æą“¤ą“æ: $1", + "mwe-embedplayer-credit-author": "ą“øąµą“°ą“·ąµą“ą“¾ą“µąµ: $1", + "mwe-embedplayer-nocredits": "ą“ą“ą“Ŗąµą“Ŗą“¾ą“ąµą“ąµ¾ ą“²ą“ąµą“Æą“®ą“²ąµą“²", + "mwe-embedplayer-loading_plugin": "ą“Ŗąµą“²ą“ąµą“ą“æąµ» ą“¶ąµą“ą“°ą“æą“ąµą“ąµą“Øąµą“Øąµ...", + "mwe-embedplayer-select_playback": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“¾ą“§ą“æą“ąµ¾ ą“øą“ąµą“ąµą“ą“°ą“æą“ąµą“ąµą“", + "mwe-embedplayer-link_back": "ą“Ŗą“æą“Øąµą“Øą“æą“²ąµą“Æąµą“ąµą“ąµ ą“ą“£ąµą“£ą“æ ą“øąµą“·ąµą“ą“æą“ąµą“ąµą“", + "mwe-embedplayer-error_swap_vid": "ą“Ŗą“æą““ą“µąµ: mwEmbed ą“øą“®ąµą“Ŗąµ¼ą“ąµą“ą“®ąµą“ą“¤ąµą“¤ą“æą“Øą“¾ą“Æąµą“³ąµą“³ ą“ą“²ą“ąµą“ą“æą“¤ąµą“° ą“ą“¾ą“ąµ ą“®ą“¾ą“±ąµą“±ą“¾ąµ» mwEmbed-ą“Øąµ ą“øą“¾ą“§ą“æą“ąµą“ą“æą“²ąµą“²", + "mwe-embedplayer-add_to_end_of_sequence": "ą“Ŗą“°ą“®ąµą“Ŗą“°ą“Æąµą“ąµ ą“ą“ąµą“µą“æąµ½ ą“ąµąµ¼ą“ąµą“ąµą“", + "mwe-embedplayer-missing_video_stream": "ą“ ą“øąµą“ąµą“°ąµą“®ą“æą“Øą“¾ą“Æąµą“³ąµą“³ ą“ą“²ą“ąµą“ą“æą“¤ąµą“° ą“Ŗąµą“°ą“®ą“¾ą“£ą“ ą“ą“¾ą“£ąµą“Øąµą“Øą“æą“²ąµą“²", + "mwe-embedplayer-play_clip": "ą“®ąµą“”ą“æą“Æą“¾ą“¶ą“ą“²ą“ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“ąµą“ąµą“", + "mwe-embedplayer-pause_clip": "ą“®ąµą“”ą“æą“Æą“¾ą“¶ą“ą“²ą“ ą“¤ą“¤ąµą“ą“¾ą“²ą“ ą“Øą“æąµ¼ą“¤ąµą“¤ąµą“", + "mwe-embedplayer-volume_control": "ą“¶ą“¬ąµą“¦ ą“Øą“æą“Æą“Øąµą“¤ąµą“°ą“£ą“", + "mwe-embedplayer-player_options": "ą“Ŗąµą“²ąµą“Æąµ¼ ą“ą“ąµą“ą“æą“ą“ąµą“ąµ¾", + "mwe-embedplayer-timed_text": "ą“øą“®ą“Æą“®ą“Øąµą“øą“°ą“æą“ąµą“ąµą“³ąµą“³ ą“ą““ąµą“¤ąµą“¤ąµ", + "mwe-embedplayer-player_fullscreen": "ą“Ŗąµąµ¼ą“£ąµą“£ą“øąµą“ąµą“°ąµąµ»", + "mwe-embedplayer-next_clip_msg": "ą“
ą“ąµą“¤ąµą“¤ ą“®ąµą“”ą“æą“Æą“¾ą“¶ą“ą“²ą“ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“ąµą“ąµą“", + "mwe-embedplayer-prev_clip_msg": "ą“®ąµąµ» ą“®ąµą“”ą“æą“Æą“¾ą“¶ą“ą“²ą“ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“ąµą“ąµą“", + "mwe-embedplayer-current_clip_msg": "ą“ ą“®ąµą“”ą“æą“Æą“¾ą“¶ą“ą“²ą“ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“ąµą“ąµą“Øąµą“Øą“¤ąµ ą“¤ąµą“ą“°ąµą“", + "mwe-embedplayer-seek_to": "$1 ą“Øąµą“ąµą“ąµą“", + "mwe-embedplayer-paused": "ą“¤ą“¤ąµą“ą“¾ą“²ą“ ą“Øą“æąµ¼ą“¤ąµą“¤ą“æą“µąµą“ąµą“ą“æą“°ą“æą“ąµą“ąµą“Øąµą“Øąµ", + "mwe-embedplayer-download_segment": "ą“¤ą“æą“°ą“ąµą“ąµą“ąµą“¤ąµą“¤ą“¤ąµ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“:", + "mwe-embedplayer-download_full_video": "ą“Ŗąµąµ¼ą“£ąµą“£ ą“ą“²ą“ąµą“ą“æą“¤ąµą“° ą“Ŗąµą“°ą“®ą“¾ą“£ą“ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“:", + "mwe-embedplayer-download_full_audio": "ą“Ŗąµąµ¼ą“£ąµą“£ ą“¶ą“¬ąµą“¦ ą“Ŗąµą“°ą“®ą“¾ą“£ą“ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“:", + "mwe-embedplayer-download_right_click": "ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“µą“¾ą“Øą“¾ą“Æą“æ, ą“±ąµą“±ąµą“±ąµ ą“ąµą“²ą“æą“ąµą“ąµ ą“ąµą“Æąµą“¤ą“¶ąµą“·ą“ <i>Save link as...</i> ą“ą“Øąµą“Øą“¤ąµą“Ŗą“Æąµą“ą“æą“ąµą“ąµą“", + "mwe-embedplayer-download_clip": "ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“", + "mwe-embedplayer-download_text": "ą“ą““ąµą“¤ąµą“¤ąµ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“", + "mwe-embedplayer-download": "ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“", + "mwe-embedplayer-share": "ą“Ŗą“ąµą“ąµ ą“µąµą“Æąµą“ąµą“ąµą“", + "mwe-embedplayer-credits": "ą“ą“ą“Ŗąµą“Ŗą“¾ą“ąµą“ąµ¾", + "mwe-embedplayer-about-library": "ą“ąµ½ą“ąµą“± ą“Ŗąµą“²ąµą“Æąµ¼ ą“µą“æą“µą“°ą“£ą“", + "mwe-embedplayer-about-library-desc": "ą“ąµ½ą“ąµą“±ą“Æąµą“ąµ ą“ą“ąµą“ąµ.ą“±ąµą“±ą“æ.ą“ą“.ą“ąµ½.5 ą“®ąµą“”ą“æą“Æ ą“²ąµą“¬ąµą“°ą“±ą“æ, ą“ą“Øąµą“Øą“¤ąµą“¤ąµ ą“ą“²ąµą“²ą“¾ ą“Ŗąµą“°ą“§ą“¾ą“Ø ą“¬ąµą“°ąµą“øą“±ąµą“ą“³ą“æą“²ąµą“ ą“øąµą“øąµą“„ą“æą“°ą“®ą“¾ą“Æ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“¾ą“§ą“æą“Æąµą“ąµą“ąµą“³ąµą“³ ą“øą“®ąµą“Ŗąµ¼ą“ąµą“ą“®ąµą“ą“¤ąµą“¤ąµą“ąµ ą“ą“ąµą“ąµ.ą“±ąµą“±ą“æ.ą“ą“.ą“ąµ½.5-ą“²ąµ <video>, <audio> ą“ą“Øąµą“Øąµ ą“ą“¾ą“ąµą“ąµ¾ ą“ą“Ŗą“Æąµą“ą“æą“ąµą“ą“¾ąµ» ą“¤ą“¾ą“ąµą“ą“³ąµ ą“
ą“Øąµą“µą“¦ą“æą“ąµą“ąµą“Øąµą“Øąµ.\n\n[$1 ą“ąµ½ą“ąµą“± ą“Ŗąµą“²ąµą“Æąµ¼ ą“²ąµą“¬ąµą“°ą“±ą“æą“Æąµą“ąµą“ąµą“±ą“æą“ąµą“ąµ ą“ąµą“ąµą“¤ąµ½].", + "mwe-embedplayer-clip_linkback": "ą“®ąµą“”ą“æą“Æą“¾ą“¶ą“ą“²ą“¤ąµą“¤ą“æą“Øąµą“±ąµ ą“øąµą“°ąµą“¤ą“øąµ ą“¤ą“¾ąµ¾", + "mwe-embedplayer-choose_player": "ą“ą“²ą“ąµą“ą“æą“¤ąµą“° ą“Ŗąµą“²ąµą“Æąµ¼ ą“¤ą“æą“°ą“ąµą“ąµą“ąµą“ąµą“ąµą“", + "mwe-embedplayer-no-player": "$1 ą“ą“Øąµą“Øą“¤ą“æą“Øąµą“³ąµą“³ ą“Ŗąµą“²ąµą“Æą“±ąµą“ąµ¾ ą“²ą“ąµą“Æą“®ą“²ąµą“²", + "mwe-embedplayer-share_this_video": "ą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ ą“Ŗą“ąµą“ąµ ą“µąµą“Æąµą“ąµą“ąµą“", + "mwe-embedplayer-share_this_audio": "ą“ ą“¶ą“¬ąµą“¦ ą“Ŗąµą“°ą“®ą“¾ą“£ą“ ą“Ŗą“ąµą“ąµ ą“µąµą“Æąµą“ąµą“ąµą“", + "mwe-embedplayer-video_credits": "ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“Øąµą“³ąµą“³ ą“ą“ą“Ŗąµą“Ŗą“¾ą“ąµą“ąµ¾", + "mwe-embedplayer-no-video_credits": "ą“ą“ą“Ŗąµą“Ŗą“¾ą“ąµą“ąµ¾ ą“²ą“ąµą“Æą“®ą“²ąµą“²", + "mwe-embedplayer-kaltura-platform-title": "ą“ąµ½ą“ąµą“± ą“ą“Ŗąµą“Ŗąµŗ ą“øąµą““ąµą“øąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“° ą“Ŗąµą“²ą“¾ą“±ąµą“±ąµāą“«ąµą“", + "mwe-embedplayer-menu_btn": "ą“ą“³ąµą“³ą“ą“ąµą“ą“", + "mwe-embedplayer-close_btn": "ą“
ą“ą“Æąµą“ąµą“ąµą“", + "mwe-embedplayer-ogg-player-vlc-player": "ą“µą“æ.ą“ąµ½.ą“øą“æ. ą“Ŗąµą“²ąµą“Æąµ¼", + "mwe-embedplayer-ogg-player-oggNative": "ą“ą“ąµą“ąµ.ą“±ąµą“±ą“æ.ą“ą“.ą“ąµ½.5 ą“ą“ąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“ą“°ą“£ą“", + "mwe-embedplayer-ogg-player-mp3Native": "ą“ą“ąµą“ąµ.ą“±ąµą“±ą“æ.ą“ą“.ą“ąµ½.5 ą“ą“.ą“Ŗą“æ.3 ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“ą“°ą“£ą“", + "mwe-embedplayer-ogg-player-aacNative": "ą“ą“ąµą“ąµ.ą“±ąµą“±ą“æ.ą“ą“.ą“ąµ½.5 ą“.ą“.ą“øą“æ. ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“ą“°ą“£ą“", + "mwe-embedplayer-ogg-player-h264Native": "ą“ą“ąµą“ąµ.ą“±ąµą“±ą“æ.ą“ą“.ą“ąµ½.5 ą“ą“ąµą“ąµ.264 ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“ą“°ą“£ą“", + "mwe-embedplayer-ogg-player-webmNative": "ą“ą“ąµą“ąµ.ą“±ąµą“±ą“æ.ą“ą“.ą“ąµ½.5 ą“µąµą“¬ąµāą“ą“ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“ą“°ą“£ą“", + "mwe-embedplayer-ogg-player-oggPlugin": "ą“ąµą“Øą“±ą“æą“ąµ ą“ą“ąµ ą“Ŗąµą“²ą“ą“æąµ»", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "ą“ą“ą“ą“øąµ ą“ą“Ŗą“æą“Øąµą“³ąµą“³ ą“µą“æ.ą“ąµ½.ą“øą“æ.", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "ą“.ą“. ą“µąµą“¬ąµą“ą“ ą“Ŗąµą“²ą“ą“æąµ» ą“”ąµąµŗą“²ąµą“”ąµ¼", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "ą“ąµą“µą“æą“ąµą“ąµą“±ąµą“±ąµą“ ą“Ŗąµą“²ą“ą“æąµ»", + "mwe-embedplayer-ogg-player-quicktime-activex": "ą“ąµą“µą“æą“ąµą“ąµą“±ąµą“±ąµą“ ą“ą“ąµą“±ąµą“±ąµą“µąµāāą“ą“ąµą“øąµ", + "mwe-embedplayer-ogg-player-cortado": "ą“ą“¾ą“µ ą“ąµąµ¼ą“±ąµą“±ą“¾ą“”ąµ", + "mwe-embedplayer-ogg-player-flowplayer": "ą“«ąµą“²ąµą“Ŗąµą“²ąµą“Æąµ¼", + "mwe-embedplayer-ogg-player-kplayer": "ą“ąµ½ą“ąµą“± ą“Ŗąµą“²ąµą“Æąµ¼", + "mwe-embedplayer-ogg-player-selected": "(ą“¤ą“æą“°ą“ąµą“ąµą“ąµą“¤ąµą“¤ą“µ)", + "mwe-embedplayer-ogg-player-omtkplayer": "ą“āāą“ą“ą“±ąµą“±ą“æą“ąµ ą“«ąµą“²ą“¾ą“·ąµ ą“µąµąµ¼ą“¬ą“æą“øąµ", + "mwe-embedplayer-for_best_experience": "ą“®ąµą“ąµą“ą“Ŗąµą“Ŗąµą“ąµą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“¾ą“øąµą“µą“¾ą“¦ą“Øą“¤ąµą“¤ą“æą“Øąµ ą“ą“ąµą“ąµ¾ ą“Øą“æąµ¼ą“¦ąµą“¦ąµą“¶ą“æą“ąµą“ąµą“Øąµą“Øą“¤ąµ <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">ą“ą“ąµą“ąµ.ą“±ąµą“±ą“æ.ą“ą“.ą“ąµ½.5 ą“µąµą“”ą“æą“Æąµ ą“¬ąµą“°ąµą“øąµ¼</a> ą“ą“£ąµ.", + "mwe-embedplayer-download-warn": "ą“¬ąµą“°ąµą“øą“±ą“æą“Øąµą“³ąµą“³ą“æąµ½ ą“
ą“Øąµą“°ąµą“Ŗą“®ą“¾ą“Æ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“ą“°ą“£ą“ ą“ą“£ąµą“ąµą“¤ąµą“¤ą“¾ą“Øą“¾ą“Æą“æą“²ąµą“²: ą“¬ąµą“°ąµą“øą“±ą“æą“Øąµą“³ąµą“³ą“æąµ½ ą“¤ą“Øąµą“Øąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“ąµą“ą“¾ąµ», ą“¦ą“Æą“µą“¾ą“Æą“æ [$1 ą“ą“±ąµą“±ą“µąµą“ ą“Ŗąµą“¤ą“æą“Æ ą“«ą“Æąµ¼ą“«ąµą“ąµą“øąµ] ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“", + "mwe-embedplayer-fullscreen-tip": " <i>ą“µąµą“¬ąµ ą“¬ąµą“°ąµą“øąµ¼</i> ą“øąµą“ąµą“°ąµąµ» ą“Øą“æą“±ą“ąµą“ąµ ą“ą“¾ą“£ą“¾ą“Øąµą“ ą“®ą“¾ą“±ąµą“±ą“¾ą“Øąµą“ <b>F11</b> ą“
ą“®ąµ¼ą“¤ąµą“¤ąµą“", + "mwe-embedplayer-fullscreen-tip-osx": "ą“øąµą“ąµą“°ąµąµ» ą“Øą“æą“±ą“ąµą“ąµ ą“ą“¾ą“£ą“¾ą“Øąµą“ ą“®ą“¾ą“±ąµą“±ą“¾ą“Øąµą“ <b>ą“·ą“æą“«ąµą“±ąµą“±ąµ ā F</b> ą“
ą“®ąµ¼ą“¤ąµą“¤ąµą“", + "mwe-embedplayer-do_not_warn_again": "ą“ą“¾ą“µą“æą“Æą“æąµ½ ą“ ą“øą“Øąµą“¦ąµą“¶ą“ ą“ą“¾ą“£ą“æą“ąµą“ąµą“£ąµą“ą“¤ą“æą“²ąµą“²", + "mwe-embedplayer-playerSelect": "ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øąµą“Ŗą“¾ą“§ą“æą“ąµ¾", + "mwe-embedplayer-read_before_embed": "ą“ąµ¾ą“Ŗąµą“Ŗąµą“ąµą“¤ąµą“¤ąµą“Øąµą“Øą“¤ą“æą“Øąµ ą“®ąµą“®ąµą“Ŗąµ <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ą“ą“¤ąµ ą“µą“¾ą“Æą“æą“ąµą“ąµą“</a>.", + "mwe-embedplayer-embed_site_or_blog": "ą“ą“°ąµ ą“¤ą“¾ą“³ą“æąµ½ ą“ąµ¾ą“Ŗąµą“Ŗąµą“ąµą“¤ąµą“¤ąµą“", + "mwe-embedplayer-embed_wiki": "ą“ą“°ąµ ą“µą“æą“ąµą“ą“æą“Æą“æąµ½ ą“ąµ¾ą“Ŗąµą“Ŗąµą“ąµą“¤ąµą“¤ąµą“", + "mwe-embedplayer-related_videos": "ą“¬ą“Øąµą“§ą“Ŗąµą“Ŗąµą“ąµą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ąµą“ąµ¾", + "mwe-embedplayer-seeking": "ą“Øąµą“ąµą“ąµą“Øąµą“Øąµ", + "mwe-embedplayer-buffering": "ą“¬ą“«ą“±ą“æą“ąµ", + "mwe-embedplayer-video-h264": "ą“ą“ąµą“ąµ.264 ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“", + "mwe-embedplayer-video-webm": "ą“µąµą“¬ąµāą“ą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“", + "mwe-embedplayer-video-flv": "ą“«ąµą“²ą“¾ą“·ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“", + "mwe-embedplayer-video-ogg": "ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“", + "mwe-embedplayer-video-audio": "ą“ą“ąµ ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“", + "mwe-embedplayer-audio-mpeg": "ą“ą“ą“Ŗąµą“ąµ ą“¶ą“¬ąµą“¦ą“", + "mwe-embedplayer-video-3gp": "3ą“ą“æ.ą“Ŗą“æ. ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“", + "mwe-embedplayer-video-mpeg": "ą“ą“ą“Ŗąµą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“", + "mwe-embedplayer-video-msvideo": "ą“.ą“µą“æ.ą“. ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“", + "mwe-embedplayer-missing-source": "ą“øąµą“°ąµą“¤ą“øąµą“øąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ ą“ą“£ąµą“ąµą“¤ąµą“¤ą“¾ą“Øą“¾ą“Æą“æą“²ąµą“²", + "mwe-embedplayer-vlcapp-intro": "ą“ ą“øąµą“±ąµą“±ą“æąµ½ ą“Øą“æą“Øąµą“Øąµą“®ąµą“³ąµą“³ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ąµą“ąµ¾ ą“ą“«ąµą“£ą“æą“²ąµ ą“ą“Ŗą“¾ą“”ą“æą“²ąµ ą“ą“¾ą“£ąµą“Øąµą“Øą“¤ą“æą“Øą“¾ą“Æą“æ ą“øąµą“ą“Øąµą“Æ $1 ą“ą“µą“¶ąµą“Æą“®ą“¾ą“£ąµ.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "ą“µą“æ.ą“ąµ½.ą“øą“æ. ą“ą“Ŗąµ", + "mwe-embedplayer-vlcapp-downloadapp": "ą“ą“Ŗąµ ą“øąµą“±ąµą“±ąµą“±ą“æąµ½ ą“Øą“æą“Øąµą“Øąµą“ ą“µą“æ.ą“ąµ½.ą“øą“æ. ą“ą“Ŗąµ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“", + "mwe-embedplayer-vlcapp-openvideo": "ą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ ą“µą“æ.ą“ąµ½.ą“øą“æ. ą“ą“Ŗą“æąµ½ ą“¤ąµą“±ą“ąµą“ąµą“", + "mwe-embedplayer-vlcapp-downloadvideo": "ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“", + "mwe-embedplayer-vlcapp-vlcapppopup": "ą“ ą“øąµą“±ąµą“±ą“æąµ½ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ąµą“ąµ¾ ą“Ŗąµą“°ą“¦ąµ¼ą“¶ą“æą“Ŗąµą“Ŗą“æą“ąµą“ą“¾ąµ», ą“øąµą“ą“Øąµą“Æ ą“µą“æ.ą“ąµ½.ą“øą“æ. ą“ą“Ŗąµ ą“ą“µą“¶ąµą“Æą“®ą“¾ą“£ąµ. ą“ąµ»ą“øąµą“±ąµą“±ąµąµ¾ ą“ąµą“Æąµą“Æą“£ąµ?", + "mwe-embedplayer-iewebmprompt-intro": "ą“
ą“Æąµą“Æąµ! ą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“ąµą“ąµą“Øąµą“Øą“¤ą“æą“Øąµ ą“®ąµą“®ąµą“Ŗąµ ą“ąµą“Æąµą“Æąµą“£ąµą“ ą“ą“°ąµ ą“ą“¾ą“°ąµą“Æą“ ą“ąµą“ą“æ...", + "mwe-embedplayer-iewebmprompt-linktext": "ą“ą“Øąµą“±ąµ¼ą“Øąµą“±ąµą“±ąµ ą“ą“ąµą“øąµą“Ŗąµą“²ąµą“±ą“±ą“æą“Øąµą“³ąµą“³ ą“µąµą“¬ąµą“ą“ ą“®ąµą“”ą“æą“Æ ą“ą“¾ą“ą“ąµą“ąµ¾ ą“ąµ»ą“øąµą“±ąµą“±ąµąµ¾ ą“ąµą“Æąµą“Æąµą“", + "mwe-embedplayer-iewebmprompt-outro": "ą“ąµ»ą“øąµą“±ąµą“±ąµąµ¾ ą“ąµą“Æąµą“¤ ą“¶ąµą“·ą“ ą“ ą“¤ą“¾ąµ¾ ą“µąµą“£ąµą“ąµą“®ąµą“ąµą“ąµą“ąµą“." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ms.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ms.json new file mode 100644 index 00000000..f19d2f22 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ms.json @@ -0,0 +1,82 @@ +{ + "@metadata": { + "authors": [ + "Anakmalaysia" + ] + }, + "mwe-embedplayer-credit-title": "Tajuk: $1", + "mwe-embedplayer-credit-date": "Tarikh: $1", + "mwe-embedplayer-credit-author": "Pengarang: $1", + "mwe-embedplayer-nocredits": "Tidak terdapat kredit", + "mwe-embedplayer-loading_plugin": "Plugin sedang dimuatkan...", + "mwe-embedplayer-select_playback": "Tetapan tayangan video", + "mwe-embedplayer-link_back": "Paut balik", + "mwe-embedplayer-error_swap_vid": "Ralat: mwEmbed tidak dapat menukar teg video untuk antaramuka mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Tambah pada hujung urutan", + "mwe-embedplayer-missing_video_stream": "Fail video untuk strim ini tidak dijumpai", + "mwe-embedplayer-play_clip": "Putarkan klip", + "mwe-embedplayer-pause_clip": "Hentikan klip sejenak", + "mwe-embedplayer-volume_control": "Kawalan kelantangan bunyi", + "mwe-embedplayer-player_options": "Pilihan pemain", + "mwe-embedplayer-timed_text": "Teks bermasa", + "mwe-embedplayer-player_fullscreen": "Skrin penuh", + "mwe-embedplayer-next_clip_msg": "Putarkan klip seterusnya", + "mwe-embedplayer-prev_clip_msg": "Putarkan klip sebelumnya", + "mwe-embedplayer-current_clip_msg": "Sambung putarkan klip ini", + "mwe-embedplayer-seek_to": "Cari $1", + "mwe-embedplayer-paused": "dihentikan sejenak", + "mwe-embedplayer-download_segment": "Muat turun pilihan:", + "mwe-embedplayer-download_full": "Muat turun fail video selengkapnya:", + "mwe-embedplayer-download_right_click": "Untuk memuat turun, klik kanan dan pilih <i>Save link as...</i>", + "mwe-embedplayer-download_clip": "Muat turun video", + "mwe-embedplayer-download_text": "Muat turun teks", + "mwe-embedplayer-download": "Muat turun", + "mwe-embedplayer-share": "Kongsi", + "mwe-embedplayer-credits": "Kredit", + "mwe-embedplayer-about-library": "Tentang pemain Kaltura", + "mwe-embedplayer-about-library-desc": "Pustaka media HTML5 Kaltura kini membolehkan anda untuk memanfaatkan teg-teg HTML5 <video> dan <audio> dengan antaramuka pemain yang konsisten di semua pelayar utama.\n\n[$1 Maklumat lanjut tentang pustaka Kaltura].", + "mwe-embedplayer-clip_linkback": "Halaman sumber klip", + "mwe-embedplayer-choose_player": "Pilih pemain video", + "mwe-embedplayer-no-player": "Tidak terdapat pemain untuk $1", + "mwe-embedplayer-share_this_video": "Kongsi video ini", + "mwe-embedplayer-video_credits": "Kredit video", + "mwe-embedplayer-no-video_credits": "Tidak terdapat kredit", + "mwe-embedplayer-kaltura-platform-title": "Platform video sumber terbuka Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Tutup", + "mwe-embedplayer-ogg-player-vlc-player": "Pemain VLC", + "mwe-embedplayer-ogg-player-oggNative": "Pemain Ogg HTML5", + "mwe-embedplayer-ogg-player-mp3Native": "Pemain MP3 HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Pemain AAC HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Pemain H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Pemain WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Plugin Ogg am", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Plugin QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura", + "mwe-embedplayer-ogg-player-selected": "(dipilih)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Untuk tontonan video yang lebih baik, kami mencadangkan <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">pelayar video HTML5</a>.", + "mwe-embedplayer-download-warn": "Tiada pemain dalam pelayar serasi yang dikesan: untuk menayangkan video dalam pelayar, sila muat turun [$1 Firefox terbaru]", + "mwe-embedplayer-fullscreen-tip": "Tekan <b>F11</b> untuk menogol <i>pelayar web</i> ke skrin penuh", + "mwe-embedplayer-fullscreen-tip-osx": "Tekan <b>shift ā F</b> untuk ke skrin penuh", + "mwe-embedplayer-do_not_warn_again": "Jangan paparkan mesej ini lagi", + "mwe-embedplayer-playerSelect": "Pemain", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Baca ini</a> sebelum menyiratkan video.", + "mwe-embedplayer-embed_site_or_blog": "Siratkan pada halaman", + "mwe-embedplayer-embed_wiki": "Siratkan pada wiki", + "mwe-embedplayer-related_videos": "Video-video berkaitan", + "mwe-embedplayer-seeking": "mencari", + "mwe-embedplayer-buffering": "menimbal", + "mwe-embedplayer-video-h264": "video H.264", + "mwe-embedplayer-video-webm": "video WebM", + "mwe-embedplayer-video-flv": "video Flash", + "mwe-embedplayer-video-ogg": "video Ogg", + "mwe-embedplayer-video-audio": "audio Ogg", + "mwe-embedplayer-audio-mpeg": "audio MPEG", + "mwe-embedplayer-video-3gp": "video 3GP", + "mwe-embedplayer-video-mpeg": "video MPEG", + "mwe-embedplayer-video-msvideo": "video AVI", + "mwe-embedplayer-missing-source": "Video sumber tidak dijumpai" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/mt.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/mt.json new file mode 100644 index 00000000..9414549e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/mt.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Chrisportelli" + ] + }, + "mwe-embedplayer-close_btn": "Agħlaq", + "mwe-embedplayer-ogg-player-selected": "(magħżul)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-do_not_warn_again": "Fil-futur, turix dan il-messaĔĔ", + "mwe-embedplayer-playerSelect": "Plejers", + "mwe-embedplayer-related_videos": "Vidjows relatati", + "mwe-embedplayer-video-h264": "Vidjow H.264", + "mwe-embedplayer-video-webm": "Vidjow WebM", + "mwe-embedplayer-video-flv": "Vidjow Flash", + "mwe-embedplayer-video-ogg": "Vidjow Ogg", + "mwe-embedplayer-video-audio": "Awdjo Ogg", + "mwe-embedplayer-audio-mpeg": "Awdjo MPEG", + "mwe-embedplayer-video-3gp": "Vidjow 3GP", + "mwe-embedplayer-video-mpeg": "Vidjow MPEG", + "mwe-embedplayer-video-msvideo": "Vidjow AVI", + "mwe-embedplayer-missing-source": "L-ebda sors ta' vidjow ma nstab" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nb.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nb.json new file mode 100644 index 00000000..00a6c126 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nb.json @@ -0,0 +1,92 @@ +{ + "@metadata": { + "authors": [ + "Danmichaelo", + "Nghtwlkr" + ] + }, + "mwe-embedplayer-credit-title": "Tittel: $1", + "mwe-embedplayer-credit-date": "Dato: $1", + "mwe-embedplayer-credit-author": "Opphavsperson: $1", + "mwe-embedplayer-nocredits": "Ingen kreditering tilgjengelig", + "mwe-embedplayer-loading_plugin": "Laster utvidelse ...", + "mwe-embedplayer-select_playback": "Angi avspillingsinnstillinger", + "mwe-embedplayer-link_back": "Lenk tilbake", + "mwe-embedplayer-error_swap_vid": "Feil: mwEmbed kunne ikke bytte ut videoelementet for mwEmbed-grensesnittet", + "mwe-embedplayer-add_to_end_of_sequence": "Legg til pĆ„ slutten av sekvensen", + "mwe-embedplayer-missing_video_stream": "Videofilen for denne strĆømmen mangler", + "mwe-embedplayer-play_clip": "Spill av klipp", + "mwe-embedplayer-pause_clip": "Pause klipp", + "mwe-embedplayer-volume_control": "Volumkontroll", + "mwe-embedplayer-player_options": "Avspillerinnstillinger", + "mwe-embedplayer-timed_text": "Tidsbestemt tekst", + "mwe-embedplayer-player_fullscreen": "Fullskjerm", + "mwe-embedplayer-next_clip_msg": "Spill av neste klipp", + "mwe-embedplayer-prev_clip_msg": "Spill av forrige klipp", + "mwe-embedplayer-current_clip_msg": "Fortsett Ć„ spille av dette klippet", + "mwe-embedplayer-seek_to": "SĆøk $1", + "mwe-embedplayer-paused": "pauset", + "mwe-embedplayer-download_segment": "Last ned utvalg:", + "mwe-embedplayer-download_full_video": "Last ned hele videofilen:", + "mwe-embedplayer-download_full_audio": "Last ned hele lydfilen:", + "mwe-embedplayer-download_right_click": "For Ć„ laste ned, hĆøyreklikk og velg <i>Lagre lenke som...</i>", + "mwe-embedplayer-download_clip": "Last ned video", + "mwe-embedplayer-download_text": "Last ned tekst", + "mwe-embedplayer-download": "Last ned", + "mwe-embedplayer-share": "Del", + "mwe-embedplayer-credits": "Info", + "mwe-embedplayer-about-library": "Om Kaltura-avspilleren", + "mwe-embedplayer-about-library-desc": "Kaltura HTML5-biblioteket gir muligheten til Ć„ ta i bruk HTML5-taggene <video> og <audio> i dag med et konsistent avspillingsgrensesnitt pĆ„ tvers av alle de viktigste nettleserne.\n\n[$1 Mer om Kaltura avspillingsbiblioteket].", + "mwe-embedplayer-clip_linkback": "Kildesiden for klippet", + "mwe-embedplayer-choose_player": "Velg videospiller", + "mwe-embedplayer-no-player": "Ingen spiller tilgjengelig for $1", + "mwe-embedplayer-share_this_video": "Del denne videoen", + "mwe-embedplayer-share_this_audio": "Del denne lydfilen", + "mwe-embedplayer-video_credits": "Kreditering", + "mwe-embedplayer-no-video_credits": "Ingen kreditering tilgjengelig", + "mwe-embedplayer-kaltura-platform-title": "Kaltura Ć„pen kildekode-videoplattform", + "mwe-embedplayer-menu_btn": "Meny", + "mwe-embedplayer-close_btn": "Lukk", + "mwe-embedplayer-ogg-player-vlc-player": "VLC-spiller", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg-spiller", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3-spiller", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC-spiller", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264-spiller", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM-avspiller", + "mwe-embedplayer-ogg-player-oggPlugin": "Generisk Ogg-utvidelse", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "appen VLC for iOS", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-utvidelse", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura-spiller", + "mwe-embedplayer-ogg-player-selected": "(valgt)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "For en bedre avspillingsopplevelse anbefaler vi en <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5-videofremviser</a>.", + "mwe-embedplayer-download-warn": "Ingen kompatibel mediespiller for nettleseren ble funnet: for avspilling i nettleseren kan du laste ned [$1 nyeste utgave av Firefox]", + "mwe-embedplayer-fullscreen-tip": "Trykk <b>F11</b> for Ć„ sette <i>nettleseren</i> i fullskjermmodus", + "mwe-embedplayer-fullscreen-tip-osx": "Trykk <b>shift ā F</b> for Ć„ vise i fullskjerm", + "mwe-embedplayer-do_not_warn_again": "Ikke vis denne meldingen i fremtiden", + "mwe-embedplayer-playerSelect": "Spillere", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Les dette</a> fĆør du bygger inn.", + "mwe-embedplayer-embed_site_or_blog": "Bygg inn pĆ„ en side", + "mwe-embedplayer-embed_wiki": "Bygg inn pĆ„ en wiki", + "mwe-embedplayer-related_videos": "Relaterte videoer", + "mwe-embedplayer-seeking": "sĆøker", + "mwe-embedplayer-buffering": "mellomlagrer", + "mwe-embedplayer-video-h264": "H.264-video", + "mwe-embedplayer-video-webm": "WebM-video", + "mwe-embedplayer-video-flv": "Flash-video", + "mwe-embedplayer-video-ogg": "Ogg-video", + "mwe-embedplayer-video-audio": "Ogg-audio", + "mwe-embedplayer-audio-mpeg": "MPEG-lyd", + "mwe-embedplayer-video-3gp": "3GP-video", + "mwe-embedplayer-video-mpeg": "MPEG-video", + "mwe-embedplayer-video-msvideo": "AVI-video", + "mwe-embedplayer-missing-source": "Ingen kildevideo ble funnet", + "mwe-embedplayer-vlcapp-intro": "For Ć„ spille av videoer fra dette nettstedet pĆ„ en iPhone eller iPad, trenger du $1 (gratis).", + "mwe-embedplayer-vlcapp-vlcapplinktext": "appen VLC", + "mwe-embedplayer-vlcapp-downloadapp": "Last ned appen VLC fra App Store", + "mwe-embedplayer-vlcapp-openvideo": "Ć
pne denne videoen i VLC-appen", + "mwe-embedplayer-vlcapp-downloadvideo": "Last ned denne videoen", + "mwe-embedplayer-vlcapp-vlcapppopup": "For Ć„ spille av videoer pĆ„ dette nettstedet, trenger du appen VLC (gratis). Vil du installere nĆ„?" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nds-nl.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nds-nl.json new file mode 100644 index 00000000..36e62cdb --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nds-nl.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Servien" + ] + }, + "mwe-embedplayer-play_clip": "Klip aofspeulen" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nl.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nl.json new file mode 100644 index 00000000..66fef83a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nl.json @@ -0,0 +1,85 @@ +{ + "@metadata": { + "authors": [ + "Arent", + "Siebrand", + "Southparkfan" + ] + }, + "mwe-embedplayer-credit-title": "Naam: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Auteur: $1", + "mwe-embedplayer-nocredits": "Geen auteursgegevens beschikbaar", + "mwe-embedplayer-loading_plugin": "Bezig met het laden van de uitbreiding...", + "mwe-embedplayer-select_playback": "Afspeelinstellingen instellen", + "mwe-embedplayer-link_back": "Terugverwijzen", + "mwe-embedplayer-error_swap_vid": "Fout: mvEmbed kon de videotag voor de mwEmbed-interface niet wisselen", + "mwe-embedplayer-add_to_end_of_sequence": "Aan het einde van de reeks toevoegen", + "mwe-embedplayer-missing_video_stream": "Het videobestand voor deze stream is niet aanwezig", + "mwe-embedplayer-play_clip": "Clip afspelen", + "mwe-embedplayer-pause_clip": "Clip pauzeren", + "mwe-embedplayer-volume_control": "Volumebeheer", + "mwe-embedplayer-player_options": "Mediaspelerinstellingen", + "mwe-embedplayer-timed_text": "Ondertitels", + "mwe-embedplayer-player_fullscreen": "Volledig scherm", + "mwe-embedplayer-next_clip_msg": "Volgende clip afspelen", + "mwe-embedplayer-prev_clip_msg": "Vorige clip afspelen", + "mwe-embedplayer-current_clip_msg": "Doorgaan met het afspelen van deze clip", + "mwe-embedplayer-seek_to": "Zoeken naar $1", + "mwe-embedplayer-paused": "gepauzeerd", + "mwe-embedplayer-download_segment": "Selectie downloaden:", + "mwe-embedplayer-download_full": "Volledig videobestand downloaden:", + "mwe-embedplayer-download_right_click": "Klik rechts en selecteer <i>Koppeling opslaan als...</i> om het bestand te downloaden", + "mwe-embedplayer-download_clip": "Video downloaden", + "mwe-embedplayer-download_text": "Tekst downloaden", + "mwe-embedplayer-download": "Downloaden", + "mwe-embedplayer-share": "Delen", + "mwe-embedplayer-credits": "Vermeldingen", + "mwe-embedplayer-about-library": "Over de Kalturaspeler", + "mwe-embedplayer-about-library-desc": "De HTML5-bibliotheek van Kaltura zorgt dat u nu kunt profiteren van de HTML5-labels <nowiki><video></nowiki> en <nowiki><audio></nowiki> met een consistent uiterlijk van de speler in alle veelgebruikte browsers.\n\n[$1 Meer over de bibliotheek van de Kaltura-speler].", + "mwe-embedplayer-clip_linkback": "Bronpagina van de clip", + "mwe-embedplayer-choose_player": "Mediaspeler kiezen", + "mwe-embedplayer-no-player": "Geen speler beschikbaar voor $1", + "mwe-embedplayer-share_this_video": "Deze video delen", + "mwe-embedplayer-video_credits": "Naamsvermeldingen video", + "mwe-embedplayer-no-video_credits": "Geen auteursinformatie beschikbaar", + "mwe-embedplayer-kaltura-platform-title": "Kaltura open source videoplatform", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Sluiten", + "mwe-embedplayer-ogg-player-vlc-player": "VLC-mediaspeler", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg-speler", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3-speler", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC-speler", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264-speler", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM-speler", + "mwe-embedplayer-ogg-player-oggPlugin": "Algemene Ogg-plugin", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-plugin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura mediaspeler", + "mwe-embedplayer-ogg-player-selected": "(geselecteerd)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Voor een betere kwaliteitsbeleving adviseren we een <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5 videobrowser</a>.", + "mwe-embedplayer-download-warn": "Er is geen compatibele speler in de browser aangetroffen. Download de [$1 meest recente versie van Firefox] om dit bestand in de browser af te kunnen spelen.", + "mwe-embedplayer-fullscreen-tip": "Druk op <b>F11</b> om de <i>web browser</i> in het volledige scherm weer te geven", + "mwe-embedplayer-fullscreen-tip-osx": "Typ <b>SHIRT+ā+F</b> voor volledig scherm of terug", + "mwe-embedplayer-do_not_warn_again": "Dit bericht niet meer weergeven.", + "mwe-embedplayer-playerSelect": "Spelers", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Lees dit</a> voordat u gaat embedden (Engels)!", + "mwe-embedplayer-embed_site_or_blog": "Toevoegen aan een pagina", + "mwe-embedplayer-embed_wiki": "Toevoegen aan een pagina", + "mwe-embedplayer-related_videos": "Gerelateerde video's", + "mwe-embedplayer-seeking": "bezig met zoeken", + "mwe-embedplayer-buffering": "bufferen", + "mwe-embedplayer-video-h264": "H.264-video", + "mwe-embedplayer-video-webm": "WebM video", + "mwe-embedplayer-video-flv": "Flash-video", + "mwe-embedplayer-video-ogg": "Ogg-video", + "mwe-embedplayer-video-audio": "Ogg-audio", + "mwe-embedplayer-audio-mpeg": "MPEG-audio", + "mwe-embedplayer-video-3gp": "3GP-video", + "mwe-embedplayer-video-mpeg": "MPEG-video", + "mwe-embedplayer-video-msvideo": "AVI-video", + "mwe-embedplayer-missing-source": "Er is geen bronvideo gevonden." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nn.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nn.json new file mode 100644 index 00000000..c96be9d4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/nn.json @@ -0,0 +1,84 @@ +{ + "@metadata": { + "authors": [ + "Nghtwlkr", + "Njardarlogar", + "Gaute", + "Ranveig" + ] + }, + "mwe-embedplayer-credit-title": "Tittel: $1", + "mwe-embedplayer-credit-date": "Dato: $1", + "mwe-embedplayer-credit-author": "Forfattar: $1", + "mwe-embedplayer-nocredits": "Inga godskriving tilgjengeleg", + "mwe-embedplayer-loading_plugin": "Lastar inn utviding ā¦", + "mwe-embedplayer-select_playback": "Set avspelingsinnstillingar", + "mwe-embedplayer-link_back": "Lenkja attende", + "mwe-embedplayer-error_swap_vid": "Feil: mwEmbed kunne ikkje byta videomerket for mwEmbed-grensesnittet", + "mwe-embedplayer-add_to_end_of_sequence": "Legg til ved enden av sekvensen", + "mwe-embedplayer-missing_video_stream": "Videofila for strĆøyminga manglar", + "mwe-embedplayer-play_clip": "Spel av klipp", + "mwe-embedplayer-pause_clip": "Stogg klipp", + "mwe-embedplayer-volume_control": "Volumstyring", + "mwe-embedplayer-player_options": "Spelarval", + "mwe-embedplayer-timed_text": "Tidbunden tekst", + "mwe-embedplayer-player_fullscreen": "Fullskjerm", + "mwe-embedplayer-next_clip_msg": "Spel av neste klippet", + "mwe-embedplayer-prev_clip_msg": "Spel av fĆørre klippet", + "mwe-embedplayer-current_clip_msg": "Haldt fram med Ć„ spela av klippet", + "mwe-embedplayer-seek_to": "SĆøk $1", + "mwe-embedplayer-paused": "stogga", + "mwe-embedplayer-download_segment": "Last ned utval:", + "mwe-embedplayer-download_full_video": "Last ned heile videofila:", + "mwe-embedplayer-download_full_audio": "Last ned heile lydfila:", + "mwe-embedplayer-download_right_click": "For Ć„ lasta ned, hĆøgreklikk og vel <i>Lagra lenkje som...</i>", + "mwe-embedplayer-download_clip": "Last ned video", + "mwe-embedplayer-download_text": "Last ned tekst", + "mwe-embedplayer-download": "Last ned", + "mwe-embedplayer-share": "Del", + "mwe-embedplayer-credits": "Godskriving", + "mwe-embedplayer-about-library": "Om Kaltura-spelaren", + "mwe-embedplayer-about-library-desc": "HTML5-mediebiblioteket i Kaltura tillĆØt deg Ć„ utnytta fĆøremonene til HTML5-merka <video> og <audio> i dag med eit konsistent spelargrensesnitt gjennom alle dei stĆørrre nettlesarane.\n\n[$1 Meir om spelarbiblioteket Kaltura]", + "mwe-embedplayer-clip_linkback": "Kjeldesida til klippet", + "mwe-embedplayer-choose_player": "Vel videospelar", + "mwe-embedplayer-no-player": "Ingen spelar tilgjengeleg for $1", + "mwe-embedplayer-share_this_video": "Del videoen", + "mwe-embedplayer-share_this_audio": "Del denne lydfila", + "mwe-embedplayer-video_credits": "Videogodskriving", + "mwe-embedplayer-no-video_credits": "Inga godskriving tilgjengeleg", + "mwe-embedplayer-kaltura-platform-title": "Kaltura, videoplattform med open kjeldekode", + "mwe-embedplayer-menu_btn": "Meny", + "mwe-embedplayer-close_btn": "Lat att", + "mwe-embedplayer-ogg-player-vlc-player": "VLC-spelar", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg-spelar", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264-spelar", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM-spelar", + "mwe-embedplayer-ogg-player-oggPlugin": "Generisk Ogg-utviding", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-utviding", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura-spelar", + "mwe-embedplayer-ogg-player-selected": "(vald)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "For ei betre videoavspelingsoppleving tilrĆ„r me ein <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">html5-videolesar</a>.", + "mwe-embedplayer-download-warn": "Det vart ikkje funne nokon kompatibel spelar i nettlesaren; for Ć„ spela av i nettlesaren bĆør du lasta ned [$1 siste utgĆ„va av Firefox]", + "mwe-embedplayer-fullscreen-tip": "Trykk <b>F11</b> for Ć„ slĆ„ pĆ„ fullskjermen til <i>nettlesaren</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Trykk pĆ„ <b>shift ā F</b> for Ć„ slĆ„ pĆ„ fullskjerm", + "mwe-embedplayer-do_not_warn_again": "Ikkje vis meldinga i framtida.", + "mwe-embedplayer-playerSelect": "Avspelarar", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Les dette</a> fĆør du byggjer inn.", + "mwe-embedplayer-embed_site_or_blog": "Bygg inn i ei side", + "mwe-embedplayer-related_videos": "Skylde videoar", + "mwe-embedplayer-seeking": "sĆøkjer", + "mwe-embedplayer-buffering": "buffrar", + "mwe-embedplayer-video-h264": "H.264-video", + "mwe-embedplayer-video-webm": "WebM-video", + "mwe-embedplayer-video-flv": "Flash-video", + "mwe-embedplayer-video-ogg": "Ogg-video", + "mwe-embedplayer-video-audio": "Ogg-ljod", + "mwe-embedplayer-audio-mpeg": "MPEG-ljod", + "mwe-embedplayer-video-3gp": "3GP-video", + "mwe-embedplayer-video-mpeg": "MPEG-video", + "mwe-embedplayer-video-msvideo": "AVI-video", + "mwe-embedplayer-missing-source": "Ingen kjeldevideo vart funnen" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/oc.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/oc.json new file mode 100644 index 00000000..c481affa --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/oc.json @@ -0,0 +1,50 @@ +{ + "@metadata": { + "authors": [ + "Cedric31" + ] + }, + "mwe-embedplayer-loading_plugin": "cargament del plugin ...", + "mwe-embedplayer-select_playback": "Definir las preferĆ©ncias de lectura", + "mwe-embedplayer-link_back": "Ligam retorn", + "mwe-embedplayer-error_swap_vid": "Erreur : mv_embed a pas capitat d'escambiar l'atribut de la vidĆØo per l'interfĆ cia mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "Apondre a la fin de la sequĆ©ncia", + "mwe-embedplayer-missing_video_stream": "Lo fichiĆØr vidĆØo per aqueste flus es mancant", + "mwe-embedplayer-play_clip": "Legir lo clip", + "mwe-embedplayer-pause_clip": "Metre lo clip en pausa", + "mwe-embedplayer-volume_control": "ContrarĆ²tle del volum", + "mwe-embedplayer-player_options": "Opcions del lector", + "mwe-embedplayer-player_fullscreen": "Ecran plen", + "mwe-embedplayer-next_clip_msg": "Legir lo clip seguent", + "mwe-embedplayer-prev_clip_msg": "Legir lo clip precedent", + "mwe-embedplayer-current_clip_msg": "Perseguir la lectura d'aqueste clip", + "mwe-embedplayer-seek_to": "AtĆ©nher $1", + "mwe-embedplayer-paused": "en pausa", + "mwe-embedplayer-download_segment": "Telecargar la seleccion :", + "mwe-embedplayer-download_full": "Telecargar lo fichiĆØr de la vidĆØo completa :", + "mwe-embedplayer-download_right_click": "Per telecargar, clicatz-drech e seleccionatz <i>Enregistrar la cibla del ligam jos...</i>", + "mwe-embedplayer-download_clip": "Telecargar la vidĆØo", + "mwe-embedplayer-download_text": "Telecargar lo tĆØxte", + "mwe-embedplayer-download": "Telecargar", + "mwe-embedplayer-share": "Partejar", + "mwe-embedplayer-credits": "Credits", + "mwe-embedplayer-clip_linkback": "Pagina font del clip", + "mwe-embedplayer-choose_player": "Causir lo lector vidĆØo", + "mwe-embedplayer-share_this_video": "Partejar aquesta vidĆØo", + "mwe-embedplayer-video_credits": "Credits de la vidĆØo", + "mwe-embedplayer-menu_btn": "MenĆŗ", + "mwe-embedplayer-close_btn": "Tampar", + "mwe-embedplayer-ogg-player-oggPlugin": "Modul generic Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Modul QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-selected": "(seleccionat)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Per un melhor visionatge recomandam un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navigador vidĆØo HTML5</a>.", + "mwe-embedplayer-do_not_warn_again": "Afichar pas mai aqueste messatge a l'avenir", + "mwe-embedplayer-read_before_embed": "LegissĆØtz <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">aquĆ²</a> abans de procedir !", + "mwe-embedplayer-embed_site_or_blog": "Integrar dins una pagina", + "mwe-embedplayer-related_videos": "VidĆØos associadas", + "mwe-embedplayer-seeking": "recĆØrca" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pam.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pam.json new file mode 100644 index 00000000..bb3f6794 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pam.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Leeheonjin" + ] + }, + "mwe-embedplayer-iewebmprompt-intro": "Ui! Atin pang metung a bage bayu me pa i-play ing video a ini..." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pdc.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pdc.json new file mode 100644 index 00000000..b78c9b0a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pdc.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Xqt" + ] + }, + "mwe-embedplayer-credit-title": "Titel: $1", + "mwe-embedplayer-seek_to": "Guck uff $1" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pl.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pl.json new file mode 100644 index 00000000..97e49986 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pl.json @@ -0,0 +1,81 @@ +{ + "@metadata": { + "authors": [ + "BeginaFelicysym", + "Sp5uhe" + ] + }, + "mwe-embedplayer-credit-title": "TytuÅ ā $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "Informacja o twĆ³rcach nie jest dostÄpna", + "mwe-embedplayer-loading_plugin": "trwa Åadowanie wtyczki...", + "mwe-embedplayer-select_playback": "Ustaw preferencje odtwarzania", + "mwe-embedplayer-link_back": "Link powrotny", + "mwe-embedplayer-error_swap_vid": "BÅÄ
d ā mv_embed nie byÅ w stanie zamieniaÄ znacznika filmu dla interfejsu mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "Dodaj na koniec sekwencji", + "mwe-embedplayer-missing_video_stream": "Brak pliku z filmem dla tego strumienia", + "mwe-embedplayer-play_clip": "OdtwĆ³rz klip", + "mwe-embedplayer-pause_clip": "Wstrzymaj odtwarzanie klipu", + "mwe-embedplayer-volume_control": "Regulacja gÅoÅnoÅci", + "mwe-embedplayer-player_options": "Opcje odtwarzacza", + "mwe-embedplayer-timed_text": "Lista dialogowa", + "mwe-embedplayer-player_fullscreen": "PeÅny ekran", + "mwe-embedplayer-next_clip_msg": "OdtwĆ³rz nastÄpny klip", + "mwe-embedplayer-prev_clip_msg": "OdtwĆ³rz poprzedni klip", + "mwe-embedplayer-current_clip_msg": "Kontynuuj odtwarzanie tego klipu", + "mwe-embedplayer-seek_to": "PrzewiÅ $1", + "mwe-embedplayer-paused": "wstrzymane", + "mwe-embedplayer-download_segment": "WybĆ³r pobierania", + "mwe-embedplayer-download_full": "Pobierz peÅny plik z filmem", + "mwe-embedplayer-download_right_click": "Aby pobraÄ, kliknij prawym przyciskiem myszy i wybierz <i>Zapisz link jako...</i>", + "mwe-embedplayer-download_clip": "Pobierz film", + "mwe-embedplayer-download_text": "Pobierz tekst", + "mwe-embedplayer-download": "Pobierz", + "mwe-embedplayer-share": "UdostÄpnij", + "mwe-embedplayer-credits": "TwĆ³rcy", + "mwe-embedplayer-about-library": "O odtwarzaczu Kaltura", + "mwe-embedplayer-about-library-desc": "Biblioteka Kaltura obsÅugi mediĆ³w dla HTML5 pozwala na użycie znacznikĆ³w HTML5 <code><nowiki><video></nowiki></code> i <code><nowiki><audio></nowiki></code> ze spĆ³jnym interfejsem odtwarzacza we wszystkich najpopularniejszych przeglÄ
darkach.\n\n[$1 WiÄcej na temat biblioteki odtwarzacza Kaltura].", + "mwe-embedplayer-clip_linkback": "Strona ÅŗrĆ³dÅowa klipu", + "mwe-embedplayer-choose_player": "Wybierz odtwarzacz wideo", + "mwe-embedplayer-no-player": "Brak dostÄpnych odtwarzaczy dla $1", + "mwe-embedplayer-share_this_video": "UdostÄpnij ten film", + "mwe-embedplayer-video_credits": "TwĆ³rcy filmu", + "mwe-embedplayer-no-video_credits": "Informacja o twĆ³rcach nie jest dostÄpna", + "mwe-embedplayer-kaltura-platform-title": "Kaltura ā platforma filmĆ³w z otwartym kodem", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Zamknij", + "mwe-embedplayer-ogg-player-vlc-player": "Odtwarzacz VLC", + "mwe-embedplayer-ogg-player-oggNative": "Odtwarzacz HTML5 Ogg", + "mwe-embedplayer-ogg-player-h264Native": "Odtwarzacz HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "Odtwarzacz HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "Pierwotna wtyczka Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Wtyczka QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Cortado w Java", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Odtwarzacz Kaltura", + "mwe-embedplayer-ogg-player-selected": "(zaznaczone)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Dla lepszego odtwarzania filmĆ³w polecamy [przeglÄ
darkÄ video html5 $1</a>.", + "mwe-embedplayer-download-warn": "Nie odnaleziono zgodnego odtwarzacza dla przeglÄ
darki, aby odtworzyÄ tÄ
zawartoÅÄ w przeglÄ
darce należy pobraÄ [$1 najnowszÄ
wersjÄFirefox]", + "mwe-embedplayer-fullscreen-tip": "NaciÅnij klawisz <b>F11</b> by przeÅÄ
czyÄ <i>przeglÄ
darkÄ</i> w tryb peÅnoekranowy", + "mwe-embedplayer-fullscreen-tip-osx": "NaciÅnij klawisze <b>shift ā f</b> aby przeÅÄ
czyÄ w tryb peÅnoekranowy", + "mwe-embedplayer-do_not_warn_again": "W przyszÅoÅci nie pokazuj tego komunikatu", + "mwe-embedplayer-playerSelect": "Odtwarzacze", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Przeczytaj to</a> przed wstawieniem.", + "mwe-embedplayer-embed_site_or_blog": "UmieÅÄ na swojej stronie lub blogu", + "mwe-embedplayer-related_videos": "Podobne filmy", + "mwe-embedplayer-seeking": "przewijanie", + "mwe-embedplayer-buffering": "buforowanie", + "mwe-embedplayer-video-h264": "Wideo w H.264", + "mwe-embedplayer-video-webm": "Wideo WebM", + "mwe-embedplayer-video-flv": "Wideo we Flash", + "mwe-embedplayer-video-ogg": "Wideo w Ogg", + "mwe-embedplayer-video-audio": "DÅŗwiÄk w Ogg", + "mwe-embedplayer-audio-mpeg": "Wideo MPEG", + "mwe-embedplayer-video-3gp": "Wideo 3GP", + "mwe-embedplayer-video-mpeg": "Wideo MPEG", + "mwe-embedplayer-video-msvideo": "Wideo AVI", + "mwe-embedplayer-missing-source": "Nie ustalono ÅŗrĆ³dÅa obrazu." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pms.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pms.json new file mode 100644 index 00000000..b667b89e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pms.json @@ -0,0 +1,80 @@ +{ + "@metadata": { + "authors": [ + "BorichĆØt", + "DragonĆ²t" + ] + }, + "mwe-embedplayer-credit-title": "TƬtol: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "Gnun arconossiment Ć«d paternitĆ disponƬbil", + "mwe-embedplayer-loading_plugin": "CariĆ© plugin...", + "mwe-embedplayer-select_playback": "AmpostĆ© gust Ć«d letura", + "mwe-embedplayer-link_back": "Anliura andrĆ©", + "mwe-embedplayer-error_swap_vid": "Eror: mwEmbed a l'Ć© pa stĆ it bon a cangĆ© la tichĆ«tta dĆ«l filmĆ pĆ«r l'antĆ«rfacia mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "GiontĆ© a la fin Ć«d la sequensa", + "mwe-embedplayer-missing_video_stream": "L'archivi dĆ«l filmĆ pr'Ć«s fluss a manca", + "mwe-embedplayer-play_clip": "FĆ parte Ć«l curtmetragi", + "mwe-embedplayer-pause_clip": "Ferma Ć«l curtmetragi", + "mwe-embedplayer-volume_control": "ContrĆ²l dĆ«l volum", + "mwe-embedplayer-player_options": "Opsion dĆ«l letor", + "mwe-embedplayer-timed_text": "Test sincronisĆ ", + "mwe-embedplayer-player_fullscreen": "A scren pien", + "mwe-embedplayer-next_clip_msg": "FĆ parte Ć«l curtmetragi ch'a ven", + "mwe-embedplayer-prev_clip_msg": "FĆ parte Ć«l curtmetragi prima", + "mwe-embedplayer-current_clip_msg": "Continua a fĆ© girĆ© sto curtmetragi", + "mwe-embedplayer-seek_to": "Serca $1", + "mwe-embedplayer-paused": "an pĆ usa", + "mwe-embedplayer-download_segment": "DĆ«scariĆ© la selession:", + "mwe-embedplayer-download_full": "DĆ«scariĆ© l'archivi antregh dĆ«l filmĆ :", + "mwe-embedplayer-download_right_click": "PĆ«r dĆ«scariĆ©, sgnaca con Ć«l tast drit dĆ«l rat e selession-a <i>Salva Ć«l colegament com...</i>", + "mwe-embedplayer-download_clip": "DĆ«scariĆ© Ć«l filmĆ ", + "mwe-embedplayer-download_text": "DĆ«scariĆ© Ć«l test", + "mwe-embedplayer-download": "DĆ«scaria", + "mwe-embedplayer-share": "Condivid", + "mwe-embedplayer-credits": "Arconossiment", + "mwe-embedplayer-about-library": "A propĆ²sit dĆ«l riprodutor Kaltura", + "mwe-embedplayer-about-library-desc": "La librarƬa dĆ«l mojen HTML5 Ć«d Kaltura a lo abƬlita a sfrutĆ© ancheuj le tichĆ«tte HTML5 <code><nowiki><video></nowiki></code> e <code><nowiki><audio></nowiki></code> con n'antĆ«rfacia Ć«d riprodussion coerenta con tĆ¹it ij navigador prinsipaj.\n\n[$1 PĆ«r savĆØjne Ć«d pi a propĆ²sit Ć«d la librarƬa dĆ«l riprodutor Kaltura]", + "mwe-embedplayer-clip_linkback": "PĆ gina sorgiss dĆ«l curt-metragi", + "mwe-embedplayer-choose_player": "Serne Ć«l letor dij filmĆ ", + "mwe-embedplayer-no-player": "Pa gnun letor disponƬbij pĆ«r $1", + "mwe-embedplayer-share_this_video": "PartagĆ© Ć«s filmĆ ", + "mwe-embedplayer-video_credits": "Arconossiment dĆ«l filmĆ ", + "mwe-embedplayer-no-video_credits": "Pa gnun crĆ©dit disponƬbij", + "mwe-embedplayer-kaltura-platform-title": "Piataforma pĆ«r filmĆ a sorgiss duverta Kaltura", + "mwe-embedplayer-menu_btn": "Lista", + "mwe-embedplayer-close_btn": "Sara", + "mwe-embedplayer-ogg-player-vlc-player": "Letor VLC", + "mwe-embedplayer-ogg-player-oggNative": "Letor HTML5 Ogg", + "mwe-embedplayer-ogg-player-h264Native": "Letor HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "Letor HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "Plugin Generic Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Plugin QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Letor Kaltura", + "mwe-embedplayer-ogg-player-selected": "(selessionĆ )", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Per n'esperiensa Ć«d vision pi bon-a i arcomandoma un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navigador adat ai filmĆ html5</a>.", + "mwe-embedplayer-download-warn": "A l'Ć© trovasse che Ć«l navigador a l'Ć© nen compatƬbil, pĆ«r na letura ant Ć«l navigador, pĆ«r piasƬ ch'a dĆ«scaria l'[$1 Ć¹ltim Firefox]", + "mwe-embedplayer-fullscreen-tip": "SgnachĆ© <b>F11</b> pĆ«r passĆ© al <i>navigador dl'aragnĆ </i> a scren antregh", + "mwe-embedplayer-fullscreen-tip-osx": "Ch'a sgnaca <b>majĆ¹scole ā F</b> pĆ«r passĆ© a scren antregh", + "mwe-embedplayer-do_not_warn_again": "Ant l'avnƬ, mostrĆ© pa pi Ć«s mĆ«ssagi", + "mwe-embedplayer-playerSelect": "Letor", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Les sossƬ</a> prima d'ancorporĆ©.", + "mwe-embedplayer-embed_site_or_blog": "AncorporĆ© an sna pĆ gina", + "mwe-embedplayer-related_videos": "FilmĆ assossiĆ ", + "mwe-embedplayer-seeking": "arserca", + "mwe-embedplayer-buffering": "an camin a butĆ© ant la memĆ²ria tampon", + "mwe-embedplayer-video-h264": "filmĆ H.264", + "mwe-embedplayer-video-webm": "FilmĆ WebM", + "mwe-embedplayer-video-flv": "filmĆ Flash", + "mwe-embedplayer-video-ogg": "filmĆ Ogg", + "mwe-embedplayer-video-audio": "Ćudio Ogg", + "mwe-embedplayer-audio-mpeg": "Sonor MPEG", + "mwe-embedplayer-video-3gp": "FilmĆ 3GP", + "mwe-embedplayer-video-mpeg": "FilmĆ MPEG", + "mwe-embedplayer-video-msvideo": "FilmĆ AVI", + "mwe-embedplayer-missing-source": "Gnun filmĆ sorgiss a l'Ć© stĆ it trovĆ ." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ps.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ps.json new file mode 100644 index 00000000..7bb42723 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ps.json @@ -0,0 +1,21 @@ +{ + "@metadata": { + "authors": [ + "Ahmed-Najib-Biabani-Ibrahimkhel" + ] + }, + "mwe-embedplayer-credit-title": "Ų³Ų±ŁŁŚ©: $1", + "mwe-embedplayer-credit-date": "ŁŪŁ¼Ł: $1", + "mwe-embedplayer-credit-author": "ŁŁŚ©ŁŲ§Ł: $1", + "mwe-embedplayer-download_clip": "ŁŁŚŁŁ ŚŚ©ŲŖŁ Ś©ŁŁ", + "mwe-embedplayer-download_text": "Ł
ŲŖŁ ŚŚ©ŲŖŁ Ś©ŁŁ", + "mwe-embedplayer-download": "ŚŚ©ŲŖŁ Ś©ŁŁ", + "mwe-embedplayer-share": "Ų“Ų±ŁŚ©ŁŁ", + "mwe-embedplayer-close_btn": "ŲŖŚŁ", + "mwe-embedplayer-ogg-player-selected": "(Ł¼Ų§Ś©Ł Ų“ŁŪ)", + "mwe-embedplayer-playerSelect": "ŲŗŚŁŁŚ©Ł", + "mwe-embedplayer-audio-mpeg": "MPEG ŲŗŚ", + "mwe-embedplayer-video-3gp": "3GP ŁŁŚŁŁ", + "mwe-embedplayer-video-mpeg": "MPEG ŁŁŚŁŁ", + "mwe-embedplayer-video-msvideo": "AVI ŁŁŚŁŁ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pt-br.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pt-br.json new file mode 100644 index 00000000..830e4dce --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pt-br.json @@ -0,0 +1,86 @@ +{ + "@metadata": { + "authors": [ + "Cainamarques", + "Dianakc", + "Giro720", + "Luckas", + "Luckas Blade" + ] + }, + "mwe-embedplayer-credit-title": "TĆtulo: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "CrĆ©ditos nĆ£o disponĆveis", + "mwe-embedplayer-loading_plugin": "Carregando plugin ...", + "mwe-embedplayer-select_playback": "Definir preferĆŖncias de reproduĆ§Ć£o", + "mwe-embedplayer-link_back": "Criar link de volta", + "mwe-embedplayer-error_swap_vid": "Erro: o mv_embed nĆ£o conseguiu trocar o elemento de vĆdeo pela interface mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "Adicionar ao fim da sequĆŖncia", + "mwe-embedplayer-missing_video_stream": "O arquivo de vĆdeo para esta transmissĆ£o estĆ” em falta", + "mwe-embedplayer-play_clip": "Tocar videoclipe", + "mwe-embedplayer-pause_clip": "Pausar clipe", + "mwe-embedplayer-volume_control": "Controle de volume", + "mwe-embedplayer-player_options": "OpƧƵes do tocador", + "mwe-embedplayer-timed_text": "Legendas", + "mwe-embedplayer-player_fullscreen": "Tela inteira", + "mwe-embedplayer-next_clip_msg": "Tocar o clipe seguinte", + "mwe-embedplayer-prev_clip_msg": "Tocar o clipe anteiror", + "mwe-embedplayer-current_clip_msg": "Continue a tocar este clipe", + "mwe-embedplayer-seek_to": "Procurar $1", + "mwe-embedplayer-paused": "pausado", + "mwe-embedplayer-download_segment": "Download da seleĆ§Ć£o:", + "mwe-embedplayer-download_full": "Donwload do arquivo completo:", + "mwe-embedplayer-download_right_click": "Para fazer donwload, clique com o botĆ£o direito e selecione <i>Salvar link como...</i>", + "mwe-embedplayer-download_clip": "Download de vĆdeo", + "mwe-embedplayer-download_text": "Download do texto", + "mwe-embedplayer-download": "Download", + "mwe-embedplayer-share": "Compartilhar", + "mwe-embedplayer-credits": "CrĆ©ditos", + "mwe-embedplayer-about-library": "Sobre o reprodutor Kaltura", + "mwe-embedplayer-about-library-desc": "A biblioteca de mĆdia HTML5 da Kaltura permite que vocĆŖ tira vantagem hoje das marcaƧƵes HTML5 <code><nowiki><video></nowiki></code> e <code><nowiki><audio></nowiki></code> com uma interface de reprodutor consistente em todos os principais navegadores.\n\n[$1 Mais sobre a biblioteca de reproduĆ§Ć£o Kaltura].\n\nenables you to take advantage of the HTML5 <code><nowiki><video></nowiki></code> and <code><nowiki><audio></nowiki></code> tags today with a consistent player interface across all major browsers.\n\t\n[$1 More about the Kaltura player library].", + "mwe-embedplayer-clip_linkback": "PĆ”gina da fonte do clipe", + "mwe-embedplayer-choose_player": "Escolher leitor de vĆdeo", + "mwe-embedplayer-no-player": "NĆ£o hĆ” nenhum leitor disponĆvel para $1", + "mwe-embedplayer-share_this_video": "Compartilhar este vĆdeo", + "mwe-embedplayer-video_credits": "CrĆ©ditos do vĆdeo", + "mwe-embedplayer-no-video_credits": "CrĆ©ditos nĆ£o disponĆveis", + "mwe-embedplayer-kaltura-platform-title": "Plataforma de vĆdeo em cĆ³digo aberto Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Fechar", + "mwe-embedplayer-ogg-player-vlc-player": "Leitor VLC", + "mwe-embedplayer-ogg-player-oggNative": "Leitor Ogg HTML5", + "mwe-embedplayer-ogg-player-mp3Native": "Tocador de MP3 em HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Tocador de ACC em HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Tocador de H.264 em HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Tocador WebM em HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Plugin Ogg genĆ©rico", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Plugin QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Tocador Kaltura", + "mwe-embedplayer-ogg-player-selected": "(selecionado)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Para uma melhor experiĆŖncia de reproduĆ§Ć£o de vĆdeo recomendamos um <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navegador que suporta HTML5</a>.", + "mwe-embedplayer-download-warn": "NĆ£o foi detetado nenhum leitor compatĆvel integrado ao browser: para reproduzir pelo browser, faƧa o download da [$1 Ćŗltima versĆ£o do Firefox]", + "mwe-embedplayer-fullscreen-tip": "Aperte <b>F11</b> para ativar ou desativar o modo de tela inteira no <i>browser</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Aperte <b>shift ā F</b> para ativar ou desativar o modo de tela inteira", + "mwe-embedplayer-do_not_warn_again": "No futuro, nĆ£o mostrar esta mensagem", + "mwe-embedplayer-playerSelect": "Tocadores", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Leia isto</a> antes de incorporar.", + "mwe-embedplayer-embed_site_or_blog": "Incorporar em uma pĆ”gina", + "mwe-embedplayer-embed_wiki": "Incorporar em uma wiki", + "mwe-embedplayer-related_videos": "VĆdeos relacionados", + "mwe-embedplayer-seeking": "procurando", + "mwe-embedplayer-buffering": "criando buffer", + "mwe-embedplayer-video-h264": "VĆdeo H.264", + "mwe-embedplayer-video-webm": "VĆdeo WebM", + "mwe-embedplayer-video-flv": "VĆdeo Flash", + "mwe-embedplayer-video-ogg": "VĆdeo Ogg", + "mwe-embedplayer-video-audio": "Ćudio Ogg", + "mwe-embedplayer-audio-mpeg": "Ćudio MPEG", + "mwe-embedplayer-video-3gp": "VĆdeo 3GP", + "mwe-embedplayer-video-mpeg": "VĆdeo MPEG", + "mwe-embedplayer-video-msvideo": "VĆdeo AVI", + "mwe-embedplayer-missing-source": "Nenhum vĆdeo foi encontrado" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pt.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pt.json new file mode 100644 index 00000000..b5b83814 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/pt.json @@ -0,0 +1,101 @@ +{ + "@metadata": { + "authors": [ + "Cainamarques", + "Hamilton Abreu", + "Imperadeiro98", + "Luckas", + "Malafaya", + "SandroHc", + "Vitorvicentevalente", + "Waldir" + ] + }, + "mwe-embedplayer-credit-title": "TĆtulo: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "Sem crĆ©ditos disponĆveis", + "mwe-embedplayer-loading_plugin": "A carregar o ''plugin'' ...", + "mwe-embedplayer-select_playback": "Definir a preferĆŖncia de reproduĆ§Ć£o", + "mwe-embedplayer-link_back": "Ligar atrĆ”s", + "mwe-embedplayer-error_swap_vid": "Erro: o mv_embed nĆ£o conseguiu trocar o elemento de vĆdeo pela interface mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "Adicionar ao fim da sequĆŖncia", + "mwe-embedplayer-missing_video_stream": "O ficheiro vĆdeo para esta transmissĆ£o estĆ” em falta", + "mwe-embedplayer-play_clip": "Reproduzir clipe", + "mwe-embedplayer-pause_clip": "Pausar clipe", + "mwe-embedplayer-volume_control": "Controlo de volume", + "mwe-embedplayer-player_options": "OpƧƵes do leitor", + "mwe-embedplayer-timed_text": "Legendas", + "mwe-embedplayer-player_fullscreen": "EcrĆ£ inteiro", + "mwe-embedplayer-next_clip_msg": "Reproduzir clipe seguinte", + "mwe-embedplayer-prev_clip_msg": "Reproduzir clipe anterior", + "mwe-embedplayer-current_clip_msg": "Continuar a reproduzir este clipe", + "mwe-embedplayer-seek_to": "Procurar $1", + "mwe-embedplayer-paused": "em pausa", + "mwe-embedplayer-download_segment": "Descarga da selecĆ§Ć£o:", + "mwe-embedplayer-download_full_video": "Descarga do ficheiro vĆdeo completo:", + "mwe-embedplayer-download_full_audio": "Descarregar ficheiro de Ć”udio completo:", + "mwe-embedplayer-download_right_click": "Para descarregar, clique no botĆ£o direito do rato e seleccione <i>Guardar ligaĆ§Ć£o como...</i>", + "mwe-embedplayer-download_clip": "Descarga do vĆdeo", + "mwe-embedplayer-download_text": "Descarga do texto", + "mwe-embedplayer-download": "Descarga", + "mwe-embedplayer-share": "Partilhar", + "mwe-embedplayer-credits": "CrĆ©ditos", + "mwe-embedplayer-about-library": "Sobre o leitor Kaltura", + "mwe-embedplayer-about-library-desc": "A biblioteca multimĆ©dia HTML5 do Kaltura permite-lhe utilizar jĆ” hoje os elementos <code><nowiki><video></nowiki></code> e <code><nowiki><audio></nowiki></code> do HTML5 com uma interface consistente do leitor em todos os navegadores principais.\n\t\n[$1 Mais sobre a biblioteca do leitor Kaltura].", + "mwe-embedplayer-clip_linkback": "PĆ”gina fonte do clipe", + "mwe-embedplayer-choose_player": "Escolher leitor de vĆdeo", + "mwe-embedplayer-no-player": "NĆ£o hĆ” nenhum leitor disponĆvel para $1", + "mwe-embedplayer-share_this_video": "Partilhar este vĆdeo", + "mwe-embedplayer-share_this_audio": "Partilhar ficheiro de Ć”udio", + "mwe-embedplayer-video_credits": "CrĆ©ditos do vĆdeo", + "mwe-embedplayer-no-video_credits": "Sem crĆ©ditos disponĆveis", + "mwe-embedplayer-kaltura-platform-title": "Plataforma de vĆdeo em cĆ³digo aberto Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Fechar", + "mwe-embedplayer-ogg-player-vlc-player": "Leitor VLC", + "mwe-embedplayer-ogg-player-oggNative": "Leitor Ogg HTML5", + "mwe-embedplayer-ogg-player-mp3Native": "Leitor MP3 HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Leitor AAC HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Leitor H.264 HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Leitor WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "''Plugin'' Ogg genĆ©rico", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC para aplicaĆ§Ć£o iOS", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "''Plugin'' QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Leitor Kaltura", + "mwe-embedplayer-ogg-player-selected": "(seleccionado)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Para uma melhor experiĆŖncia de reproduĆ§Ć£o de vĆdeo recomendamos um <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navegador de vĆdeo HTML5</a>.", + "mwe-embedplayer-download-warn": "NĆ£o foi detectado nenhum leitor compatĆvel integrado no navegador: para reproduzir no navegador, faƧa a descarga da [$1 Ćŗltima versĆ£o do Firefox]", + "mwe-embedplayer-fullscreen-tip": "Carregue em <b>F11</b> para activar ou desactivar o modo de ecrĆ£ inteiro no navegador", + "mwe-embedplayer-fullscreen-tip-osx": "Carregue em <b>shift ā F</b> para activar ou dcesativar o modo de ecrĆ£ inteiro", + "mwe-embedplayer-do_not_warn_again": "No futuro, nĆ£o mostrar esta mensagem", + "mwe-embedplayer-playerSelect": "Leitores", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Leia isto</a> antes de incorporar.", + "mwe-embedplayer-embed_site_or_blog": "Incorporar numa pĆ”gina", + "mwe-embedplayer-embed_wiki": "Incorporar numa wiki", + "mwe-embedplayer-related_videos": "VĆdeos relacionados", + "mwe-embedplayer-seeking": "a procurar", + "mwe-embedplayer-buffering": "a carregar", + "mwe-embedplayer-video-h264": "VĆdeo H.264", + "mwe-embedplayer-video-webm": "VĆdeo WebM", + "mwe-embedplayer-video-flv": "VĆdeo Flash", + "mwe-embedplayer-video-ogg": "VĆdeo Ogg", + "mwe-embedplayer-video-audio": "Ćudio Ogg", + "mwe-embedplayer-audio-mpeg": "Ćudio MPEG", + "mwe-embedplayer-video-3gp": "VĆdeo 3GP", + "mwe-embedplayer-video-mpeg": "VĆdeo MPEG", + "mwe-embedplayer-video-msvideo": "VĆdeo AVI", + "mwe-embedplayer-missing-source": "NĆ£o foi encontrado nenhum vĆdeo.", + "mwe-embedplayer-vlcapp-intro": "Para conseguir ver vĆdeos a partir deste sĆtio num iPhone ou iPad, precisa da gratuita $1.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "AplicaĆ§Ć£o VLC", + "mwe-embedplayer-vlcapp-downloadapp": "Descarregar a aplicaĆ§Ć£o VLC a partir da App Store", + "mwe-embedplayer-vlcapp-openvideo": "Abrir este vĆdeo na aplicaĆ§Ć£o VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "Descarregar este vĆdeo", + "mwe-embedplayer-vlcapp-vlcapppopup": "Para reproduzir vĆdeos neste sĆtio, precisa da aplicaĆ§Ć£o gratuita VLC. Instalar agora?", + "mwe-embedplayer-iewebmprompt-intro": "Ops! SĆ³ mais uma coisa antes de poder ver o vĆdeo...", + "mwe-embedplayer-iewebmprompt-outro": "Recarregar esta pĆ”gina apĆ³s a instalaĆ§Ć£o." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/qqq.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/qqq.json new file mode 100644 index 00000000..7d0939c3 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/qqq.json @@ -0,0 +1,50 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "EugeneZelenko", + "Shirayuki", + "Umherirrender" + ] + }, + "mwe-embedplayer-credit-title": "Used as a part of the credit. Parameters:\n* $1 - title\nThis message is followed by the following messages:\n* {{msg-mw|mwe-embedplayer-credit-author}}\n* {{msg-mw|mwe-embedplayer-credit-date}}", + "mwe-embedplayer-credit-date": "Parameters:\n* $1 - date\n{{Identical|Date}}", + "mwe-embedplayer-credit-author": "Parameters:\n* $1 - author\n{{Identical|Author}}", + "mwe-embedplayer-player_fullscreen": "{{Identical|Full screen}}", + "mwe-embedplayer-seek_to": "Used as the Player status string. Parameters:\n* $1 - a time in the NPT format. NPT (Normal play time) is defined in [//www.ietf.org/rfc/rfc2326.txt RFC 2326].", + "mwe-embedplayer-paused": "{{Identical|Paused}}", + "mwe-embedplayer-download_full_video": "Header for the Download tab in the menu, when it's a video file.", + "mwe-embedplayer-download_full_audio": "Header for the Download tab in the menu, when it's an audio file.", + "mwe-embedplayer-download": "{{Identical|Download}}", + "mwe-embedplayer-share": "{{Identical|Share}}", + "mwe-embedplayer-credits": "{{Identical|Credit}}", + "mwe-embedplayer-about-library-desc": "Parameters:\n* $1 - URL", + "mwe-embedplayer-no-player": "This message means that there are no available players to play $1.\n* $1 - source media title", + "mwe-embedplayer-share_this_video": "Header for the Share tab in the menu, when it's a video file.", + "mwe-embedplayer-share_this_audio": "Header for the Share tab in the menu, when it's an audio file.", + "mwe-embedplayer-menu_btn": "{{Identical|Menu}}", + "mwe-embedplayer-close_btn": "{{Identical|Close}}", + "mwe-embedplayer-ogg-player-mp3Native": "name of mp3 player in configuration screen", + "mwe-embedplayer-ogg-player-aacNative": "name of AAC player in configuration screen", + "mwe-embedplayer-ogg-player-webmNative": "name of WebM player in configuration screen", + "mwe-embedplayer-ogg-player-vp9Native": "name of VP9 player in configuration screen", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "name of IE WebM plugin installer helper in configuration screen", + "mwe-embedplayer-ogg-player-selected": "{{Identical|Selected}}", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "name of IE WebM plugin installer helper in configuration screen", + "mwe-embedplayer-ogg-player-ogvJsPlayer": "name of ogv.js Ogg JavaScript player in configuration screen", + "mwe-embedplayer-for_best_experience": "Shown when user's browser doesn't support playing videos. Parameters:\n* $1 - An empty <a> tag. Don't use this parameter.", + "mwe-embedplayer-download-warn": "Parameters:\n* $1 - URL", + "mwe-embedplayer-do_not_warn_again": "Standard message for disabling\nfuture identical warnings messages", + "mwe-embedplayer-playerSelect": "{{Identical|Player}}", + "mwe-embedplayer-embed_site_or_blog": "title for iframe embed code in share dialog", + "mwe-embedplayer-embed_wiki": "title for wiki embed code in share dialog", + "mwe-embedplayer-vlcapp-intro": "Shown where a video would be on the page, on iPhones/iPads. Parameter $1 is a link to the App store page for the vlc app, with the text contianed in the mwe-embedplayer-vlcapp-vlcapplinktext message. This message is followed by a bulleted list of links consisting of the messages: mwe-embedplayer-vlcapp-downloadapp, mwe-embedplayer-vlcapp-openvideo, mwe-embedplayer-vlcapp-openvideo. See also the related mwe-embedplayer-vlcapp-vlcapppopup message.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "Text of the $1 parameter of mwe-embedplayer-vlcapp-intro. Will be linked to https://itunes.apple.com/us/app/vlc-for-ios/id650377962?mt=8 (the download page for the vlc app).", + "mwe-embedplayer-vlcapp-downloadapp": "First bullet point after the mwe-embedplayer-vlcapp-intro. Links to the download page for installing the vlc app ( https://itunes.apple.com/us/app/vlc-for-ios/id650377962?mt=8 ).", + "mwe-embedplayer-vlcapp-openvideo": "Second bullet point after the mwe-embedplayer-vlcapp-intro. Link will open the video in the VLC app, if the app is installed", + "mwe-embedplayer-vlcapp-downloadvideo": "Third bullet point after the mwe-embedplayer-vlcapp-intro. Linked directly to the video file", + "mwe-embedplayer-vlcapp-vlcapppopup": "Popup dialog box shown to user if they do not have the VLC app installed when trying to play a video on iPhone/iPad. Box will be presented with this message and two buttons (OK and cancel. Actual text of buttons may vary.) If user presses ok, they are redirected to https://itunes.apple.com/us/app/vlc-for-ios/id650377962?mt=8.", + "mwe-embedplayer-iewebmprompt-intro": "Shown where a video would be on the page, on IE with no WebM or Ogg support. Followed by mwe-embedplayer-iewebmprompt-linktext", + "mwe-embedplayer-iewebmprompt-linktext": "Shown where a video would be on the page, on IE with no WebM or Ogg support. When clicked links to https://tools.google.com/dlpage/webmmf/", + "mwe-embedplayer-iewebmprompt-outro": "Shown where a video would be on the page, on IE with no WebM or Ogg support. Follows mwe-embedplayer-iewebmprompt-linktext" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/qu.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/qu.json new file mode 100644 index 00000000..6f0d1346 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/qu.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "AlimanRuna" + ] + }, + "mwe-embedplayer-credit-date": "P'unchaw: $1" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ro.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ro.json new file mode 100644 index 00000000..1742edd2 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ro.json @@ -0,0 +1,83 @@ +{ + "@metadata": { + "authors": [ + "Minisarm", + "Stelistcristi" + ] + }, + "mwe-embedplayer-credit-title": "Titlu: $1", + "mwe-embedplayer-credit-date": "Data: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-nocredits": "Niciun credit disponibil", + "mwe-embedplayer-loading_plugin": "Se Ć®ncarcÄ modulul...", + "mwe-embedplayer-select_playback": "SeteazÄ preferinČele de redare", + "mwe-embedplayer-link_back": "LegÄturÄ cÄtre Ć®napoi", + "mwe-embedplayer-error_swap_vid": "Eroare: mwEmbed nu a putut schimba eticheta videoului pentru interfaČa mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "AdaugÄ la sfĆ¢rČitul secvenČei", + "mwe-embedplayer-missing_video_stream": "FiČierul video pentru acest flux lipseČte", + "mwe-embedplayer-play_clip": "RedÄ clipul", + "mwe-embedplayer-pause_clip": "PauzÄ", + "mwe-embedplayer-volume_control": "Control de volum", + "mwe-embedplayer-player_options": "OpČiunile playerului", + "mwe-embedplayer-timed_text": "Subtitrare sincronizatÄ", + "mwe-embedplayer-player_fullscreen": "Ecran complet", + "mwe-embedplayer-next_clip_msg": "RedÄ clipul urmÄtor", + "mwe-embedplayer-prev_clip_msg": "RedÄ clip precedent", + "mwe-embedplayer-current_clip_msg": "ContinuÄ redarea acestui clip", + "mwe-embedplayer-seek_to": "DeruleazÄ la $1", + "mwe-embedplayer-paused": "Ć®n pauzÄ", + "mwe-embedplayer-download_segment": "DescarcÄ selecČia:", + "mwe-embedplayer-download_full": "DescÄrcare videoclip Ć®ntreg:", + "mwe-embedplayer-download_right_click": "Pentru a descÄrca, faceČi clic dreapta Či selectaČi <i>SalveazÄ legÄtura ca...</i>", + "mwe-embedplayer-download_clip": "DescarcÄ videoclipul", + "mwe-embedplayer-download_text": "DescÄrcare subtitrare", + "mwe-embedplayer-download": "DescÄrcare", + "mwe-embedplayer-share": "Distribuire", + "mwe-embedplayer-credits": "Credite", + "mwe-embedplayer-about-library": "Despre playerul Kaltura", + "mwe-embedplayer-about-library-desc": "Biblioteca HTML5 de la Kaltura vÄ ajutÄ sÄ profitaČi de avantajele atributelor <video> Či <audio> prezente astÄzi Ć®n HTML5 cu o interfaČÄ de player consistentÄ Či compatibilÄ cu cele mai populare navigatoare.\n\n[$1 Mai multe despre biblioteca playerului Kaltura].", + "mwe-embedplayer-clip_linkback": "Pagina sursÄ a clipului", + "mwe-embedplayer-choose_player": "Alegere player video", + "mwe-embedplayer-no-player": "Niciun player disponibil pentru $1", + "mwe-embedplayer-share_this_video": "Distribuire videoclip", + "mwe-embedplayer-video_credits": "Creditele videoclipului", + "mwe-embedplayer-no-video_credits": "Niciun credit disponibil", + "mwe-embedplayer-kaltura-platform-title": "Platforma video cu sursÄ deschisÄ de la Kaltura", + "mwe-embedplayer-menu_btn": "Meniu", + "mwe-embedplayer-close_btn": "Ćnchide", + "mwe-embedplayer-ogg-player-vlc-player": "Player VLC", + "mwe-embedplayer-ogg-player-oggNative": "Player HTML5 Ogg", + "mwe-embedplayer-ogg-player-mp3Native": "Player MP3 HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Player AAC HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Player HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "Player HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "Modul generic Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Modul QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX QuickTime", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Player Kaltura", + "mwe-embedplayer-ogg-player-selected": "(selectat)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Pentru o vizionare mai bunÄ a videoclipului vÄ recomandÄm un <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">navigator compatibil cu modulul video din HTML5</a>.", + "mwe-embedplayer-download-warn": "Nu s-a detectat niciun player integrat Ć®n navigator compatibil: pentru a reda Ć®n navigator, vÄ rugÄm sÄ descÄrcaČi [$1 ultima versiune de Firefox].", + "mwe-embedplayer-fullscreen-tip": "ApÄsaČi <b>F11</b> pentru a comuta <i>navigatorul</i> Ć®n modul ecran complet", + "mwe-embedplayer-fullscreen-tip-osx": "ApÄsaČi <b>shift ā F</b> pentru a comuta Ć®n modul ecran complet", + "mwe-embedplayer-do_not_warn_again": "Nu mai afiČa acest mesaj Ć®n viitor", + "mwe-embedplayer-playerSelect": "Playere", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">CitiČi aici</a> Ć®nainte de a Ć®ncorpora.", + "mwe-embedplayer-embed_site_or_blog": "Ćncorporare pe o paginÄ", + "mwe-embedplayer-embed_wiki": "Ćncorporare pe un wiki", + "mwe-embedplayer-related_videos": "Videoclipuri similare", + "mwe-embedplayer-seeking": "derulare", + "mwe-embedplayer-buffering": "Ć®ncÄrcare Ć®n memoria tampon", + "mwe-embedplayer-video-h264": "Video H.264", + "mwe-embedplayer-video-webm": "Video WebM", + "mwe-embedplayer-video-flv": "Video Flash", + "mwe-embedplayer-video-ogg": "Video Ogg", + "mwe-embedplayer-video-audio": "Audio Ogg", + "mwe-embedplayer-audio-mpeg": "Audio MPEG", + "mwe-embedplayer-video-3gp": "Video 3GP", + "mwe-embedplayer-video-mpeg": "Video MPEG", + "mwe-embedplayer-video-msvideo": "Video AVI", + "mwe-embedplayer-missing-source": "Nu s-a gÄsit niciun videoclip sursÄ." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/roa-tara.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/roa-tara.json new file mode 100644 index 00000000..698f8860 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/roa-tara.json @@ -0,0 +1,33 @@ +{ + "@metadata": { + "authors": [ + "Joetaras" + ] + }, + "mwe-embedplayer-credit-title": "Titole: $1", + "mwe-embedplayer-credit-date": "Date: $1", + "mwe-embedplayer-credit-author": "Autore: $1", + "mwe-embedplayer-download_clip": "Scareche 'u video", + "mwe-embedplayer-download_text": "Scareche 'u teste", + "mwe-embedplayer-download": "Scareche", + "mwe-embedplayer-share": "Condivide", + "mwe-embedplayer-credits": "Credite", + "mwe-embedplayer-menu_btn": "MenĆ¹", + "mwe-embedplayer-close_btn": "Chiude", + "mwe-embedplayer-ogg-player-vlc-player": "Visualizzatore VLC", + "mwe-embedplayer-ogg-player-oggNative": "Visualizzatore Ogg de HTML5", + "mwe-embedplayer-ogg-player-mp3Native": "Visualizzatore MP3 de HTML5", + "mwe-embedplayer-ogg-player-aacNative": "Visualizzatore AAC de HTML5", + "mwe-embedplayer-ogg-player-h264Native": "Visualizzatore H.264 de HTML5", + "mwe-embedplayer-ogg-player-webmNative": "Visualizzatore WebM de HTML5", + "mwe-embedplayer-ogg-player-selected": "(scacchiate)", + "mwe-embedplayer-video-h264": "Video H.264", + "mwe-embedplayer-video-webm": "Video WebM", + "mwe-embedplayer-video-flv": "Video Flash", + "mwe-embedplayer-video-ogg": "Video Ogg", + "mwe-embedplayer-video-audio": "Audio Ogg", + "mwe-embedplayer-audio-mpeg": "Audio MPEG", + "mwe-embedplayer-video-3gp": "Video 3GP", + "mwe-embedplayer-video-mpeg": "Video MPEG", + "mwe-embedplayer-video-msvideo": "Video AVI" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ru.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ru.json new file mode 100644 index 00000000..899217a0 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ru.json @@ -0,0 +1,100 @@ +{ + "@metadata": { + "authors": [ + "Eleferen", + "MaxSem", + "Okras", + "ŠŠ»ŠµŠŗŃŠ°Š½Š“Ń Š”ŠøŠ³Š°ŃŃŠ²", + "Kaganer" + ] + }, + "mwe-embedplayer-credit-title": "ŠŠ°Š·Š²Š°Š½ŠøŠµ: $1", + "mwe-embedplayer-credit-date": "ŠŠ°ŃŠ°: $1", + "mwe-embedplayer-credit-author": "ŠŠ²ŃŠ¾Ń: $1", + "mwe-embedplayer-nocredits": "ŠŠµŃ ŃŠ²ŠµŠ“ŠµŠ½ŠøŠ¹ Š¾ ŃŠ¾Š·Š“Š°ŃŠµŠ»ŃŃ
", + "mwe-embedplayer-loading_plugin": "Š·Š°Š³ŃŃŠ·ŠŗŠ° ŠæŠ»Š°Š³ŠøŠ½Š° ...", + "mwe-embedplayer-select_playback": "Š£ŃŃŠ°Š½Š¾Š²ŠøŃŃ Š½Š°ŃŃŃŠ¾Š¹ŠŗŠø Š²Š¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½ŠøŃ", + "mwe-embedplayer-link_back": "ŠŠ±ŃŠ°ŃŠ½Š°Ń ŃŃŃŠ»ŠŗŠ°", + "mwe-embedplayer-error_swap_vid": "ŠŃŠøŠ±ŠŗŠ°: mv_embed Š½Šµ Š¼Š¾Š¶ŠµŃ ŠæŠ¾Š¼ŠµŠ½ŃŃŃ ŃŠµŠ³ Š²ŠøŠ“ŠµŠ¾ Š“Š»Ń ŠøŠ½ŃŠµŃŃŠµŠ¹ŃŠ° mv_embed", + "mwe-embedplayer-add_to_end_of_sequence": "ŠŠ¾Š±Š°Š²ŠøŃŃ Š² ŠŗŠ¾Š½ŠµŃ ŠæŠ¾ŃŠ»ŠµŠ“Š¾Š²Š°ŃŠµŠ»ŃŠ½Š¾ŃŃŠø", + "mwe-embedplayer-missing_video_stream": "ŠŠøŠ“ŠµŠ¾ŃŠ°Š¹Š» Š“Š»Ń ŃŃŠ¾Š³Š¾ ŠæŠ¾ŃŠ¾ŠŗŠ° Š¾ŃŃŃŃŃŃŠ²ŃŠµŃ", + "mwe-embedplayer-play_clip": "ŠŠ¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŃŃŠø ŠŗŠ»ŠøŠæ", + "mwe-embedplayer-pause_clip": "ŠŃŠøŠ¾ŃŃŠ°Š½Š¾Š²ŠøŃŃ ŠŗŠ»ŠøŠæ", + "mwe-embedplayer-volume_control": "Š ŠµŠ³ŃŠ»ŠøŃŠ¾Š²ŠŗŠ° Š³ŃŠ¾Š¼ŠŗŠ¾ŃŃŠø", + "mwe-embedplayer-player_options": "ŠŠ°ŃŃŃŠ¾Š¹ŠŗŠø ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń", + "mwe-embedplayer-timed_text": "Š”ŠøŠ½Ń
ŃŠ¾Š½ŠøŠ·ŠøŃŠ¾Š²Š°Š½Š½ŃŠ¹ ŃŠµŠŗŃŃ", + "mwe-embedplayer-player_fullscreen": "ŠŠ° Š²ŠµŃŃ ŃŠŗŃŠ°Š½", + "mwe-embedplayer-next_clip_msg": "ŠŠ¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŃŃŠø ŃŠ»ŠµŠ“ŃŃŃŠøŠ¹ ŠŗŠ»ŠøŠæ", + "mwe-embedplayer-prev_clip_msg": "ŠŠ¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŃŃŠø ŠæŃŠµŠ“ŃŠ“ŃŃŠøŠ¹ ŠŗŠ»ŠøŠæ", + "mwe-embedplayer-current_clip_msg": "ŠŃŠ¾Š“Š¾Š»Š¶ŠøŃŃ Š²Š¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½ŠøŠµ ŃŃŠ¾Š³Š¾ ŠŗŠ»ŠøŠæŠ°", + "mwe-embedplayer-seek_to": "ŠŠµŃŠµŠ¹ŃŠø Šŗ $1", + "mwe-embedplayer-paused": "ŠæŠ°ŃŠ·Š°", + "mwe-embedplayer-download_segment": "ŠŃŠ±Š¾Ń Š·Š°Š³ŃŃŠ·ŠŗŠø:", + "mwe-embedplayer-download_full_video": "ŠŠ°Š³ŃŃŠ·ŠøŃŃ ŠæŠ¾Š»Š½ŃŠ¹ Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š»:", + "mwe-embedplayer-download_full_audio": "ŠŠ°Š³ŃŃŠ·ŠøŃŃ ŠæŠ¾Š»Š½ŃŠ¹ Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š»:", + "mwe-embedplayer-download_right_click": "Š§ŃŠ¾Š±Ń Š·Š°Š³ŃŃŠ·ŠøŃŃ, Š½Š°Š¶Š¼ŠøŃŠµ ŠæŃŠ°Š²ŃŃ ŠŗŠ½Š¾ŠæŠŗŃ Šø Š²ŃŠ±ŠµŃŠøŃŠµ Ā«Š”Š¾Ń
ŃŠ°Š½ŠøŃŃ Š¾Š±ŃŠµŠŗŃ ŠŗŠ°Šŗā¦Ā»", + "mwe-embedplayer-download_clip": "ŠŠ°Š³ŃŃŠ·ŠøŃŃ Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-download_text": "ŠŠ°Š³ŃŃŠ·ŠøŃŃ ŃŠµŠŗŃŃ", + "mwe-embedplayer-download": "Š”ŠŗŠ°ŃŠ°ŃŃ", + "mwe-embedplayer-share": "ŠŠ¾Š“ŠµŠ»ŠøŃŃŃŃ", + "mwe-embedplayer-credits": "Š”Š¾Š·Š“Š°ŃŠµŠ»Šø", + "mwe-embedplayer-about-library": "Š ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Šµ Kaltura", + "mwe-embedplayer-about-library-desc": "HTML5 Š¼ŠµŠ“ŠøŠ°-Š±ŠøŠ±Š»ŠøŠ¾ŃŠµŠŗŠ° Kaltura ŠæŠ¾Š·Š²Š¾Š»ŃŠµŃ Š²Š°Š¼ ŃŠ¶Šµ ŃŠµŠ¹ŃŠ°Ń ŠæŠ¾Š»ŃŠ·Š¾Š²Š°ŃŃŃŃ ŃŠµŠ³Š°Š¼Šø HTML5 <code><nowiki><video></nowiki></code> Šø <code><nowiki><audio></nowiki></code> ŃŠ¾ ŃŃŠ°Š½Š“Š°ŃŃŠ½ŃŠ¼ ŠøŠ½ŃŠµŃŃŠµŠ¹ŃŠ¾Š¼ Š²Š¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½ŠøŃ Š²Š¾ Š²ŃŠµŃ
Š¾ŃŠ½Š¾Š²Š½ŃŃ
Š±ŃŠ°ŃŠ·ŠµŃŠ°Ń
.\n\n[$1 ŠŠ¾Š“ŃŠ¾Š±Š½ŠµŠµ Š¾ Š±ŠøŠ±Š»ŠøŠ¾ŃŠµŠŗŠµ ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń Kaltura].", + "mwe-embedplayer-clip_linkback": "ŠŃŃ
Š¾Š“Š½Š°Ń ŃŃŃŠ°Š½ŠøŃŠ° ŠŗŠ»ŠøŠæŠ°", + "mwe-embedplayer-choose_player": "ŠŃŠ±Š¾Ń ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń", + "mwe-embedplayer-no-player": "ŠŠµŃ ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń Š“Š»Ń $1", + "mwe-embedplayer-share_this_video": "ŠŠ¾Š“ŠµŠ»ŠøŃŃŃŃ ŃŃŠøŠ¼ Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-share_this_audio": "ŠŠ¾Š“ŠµŠ»ŠøŃŃŃŃ ŃŃŠøŠ¼ Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š»Š¾Š¼", + "mwe-embedplayer-video_credits": "Š ŃŠ¾Š·Š“Š°ŃŠµŠ»ŃŃ
Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-no-video_credits": "ŠŠµŃ ŃŠ²ŠµŠ“ŠµŠ½ŠøŠ¹ Š¾ ŃŠ¾Š·Š“Š°ŃŠµŠ»ŃŃ
", + "mwe-embedplayer-kaltura-platform-title": "ŠŠøŠ“ŠµŠ¾-ŠæŠ»Š°ŃŃŠ¾ŃŠ¼Š° Ń Š¾ŃŠŗŃŃŃŃŠ¼ ŠøŃŃ
Š¾Š“Š½ŃŠ¼ ŠŗŠ¾Š“Š¾Š¼ Kaltura", + "mwe-embedplayer-menu_btn": "ŠŠµŠ½Ń", + "mwe-embedplayer-close_btn": "ŠŠ°ŠŗŃŃŃŃ", + "mwe-embedplayer-ogg-player-vlc-player": "ŠŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń VLC", + "mwe-embedplayer-ogg-player-oggNative": "ŠŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń HTML5 Ogg", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3-ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC-ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń", + "mwe-embedplayer-ogg-player-h264Native": "ŠŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "ŠŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "ŠŠ±ŃŠøŠ¹ ŠæŠ»Š°Š³ŠøŠ½ Ogg", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "ŠŃŠøŠ»Š¾Š¶ŠµŠ½ŠøŠµ VLC Š“Š»Ń iOS", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "ŠŠ°Š³ŃŃŠ·ŃŠøŠŗ ŠæŠ»Š°Š³ŠøŠ½Š° IE WebM", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "ŠŠ»Š°Š³ŠøŠ½ QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "ŠŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń Kaltura", + "mwe-embedplayer-ogg-player-selected": "(Š²ŃŠ±ŃŠ°Š½Š¾)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "ŠŠ»Ń Š»ŃŃŃŠµŠ³Š¾ Š²Š¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½ŠøŃ Š²ŠøŠ“ŠµŠ¾ Š¼Ń ŃŠµŠŗŠ¾Š¼ŠµŠ½Š“ŃŠµŠ¼ <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Š±ŃŠ°ŃŠ·ŠµŃ, ŠæŠ¾Š“Š“ŠµŃŠ¶ŠøŠ²Š°ŃŃŠøŠ¹ HTML5</a>.", + "mwe-embedplayer-download-warn": "ŠŠµ Š½Š°Š¹Š“ŠµŠ½Š¾ Š²ŃŃŃŠ¾ŠµŠ½Š½Š¾Š³Š¾ Š² Š±ŃŠ°ŃŠ·ŠµŃ ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń, Š“Š»Ń Š²Š¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½ŠøŠø Š² Š±ŃŠ°ŃŠ·ŠµŃŠµ Š·Š°Š³ŃŃŠ·ŠøŃŠµ [$1 ŠæŠ¾ŃŠ»ŠµŠ“Š½ŠøŠ¹ Firefox]", + "mwe-embedplayer-fullscreen-tip": "ŠŠ»Š°Š²ŠøŃŠ° <b>F11</b> ŠæŠµŃŠµŠ²Š¾Š“ŠøŃ <i>Š²ŠµŠ±-Š±ŃŠ°ŃŠ·ŠµŃ</i> Š² ŠæŠ¾Š»Š½Š¾ŃŠŗŃŠ°Š½Š½ŃŠ¹ ŃŠµŠ¶ŠøŠ¼", + "mwe-embedplayer-fullscreen-tip-osx": "ŠŠ°Š¶Š¼ŠøŃŠµ <b>shift ā F</b> Š“Š»Ń ŠæŠµŃŠµŃ
Š¾Š“Š° Š² ŠæŠ¾Š»Š½Š¾ŃŠŗŃŠ°Š½Š½ŃŠ¹ ŃŠµŠ¶ŠøŠ¼", + "mwe-embedplayer-do_not_warn_again": "ŠŠµ ŠæŠ¾ŠŗŠ°Š·ŃŠ²Š°ŃŃ ŃŃŠ¾ ŃŠ¾Š¾Š±ŃŠµŠ½ŠøŠµ Š² Š±ŃŠ“ŃŃŠµŠ¼", + "mwe-embedplayer-playerSelect": "ŠŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Šø", + "mwe-embedplayer-read_before_embed": "ŠŠ¾Š¶Š°Š»ŃŠ¹ŃŃŠ°, <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ŠæŃŠ¾ŃŃŠøŃŠµ ŃŃŠ¾</a> ŠæŠµŃŠµŠ“ Š²ŃŃŃŠ°ŠøŠ²Š°Š½ŠøŠµŠ¼!", + "mwe-embedplayer-embed_site_or_blog": "ŠŃŃŠ°Š²ŠøŃŃ Š½Š° ŃŃŃŠ°Š½ŠøŃŃ", + "mwe-embedplayer-embed_wiki": "ŠŠ½ŠµŠ“ŃŃŠ½ Š² Š²ŠøŠŗŠø", + "mwe-embedplayer-related_videos": "Š”Š²ŃŠ·Š°Š½Š½ŃŠµ Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-seeking": "ŠæŠ¾ŠøŃŠŗ", + "mwe-embedplayer-buffering": "Š±ŃŃŠµŃŠøŠ·Š°ŃŠøŃ", + "mwe-embedplayer-video-h264": "ŠŠøŠ“ŠµŠ¾ H.264", + "mwe-embedplayer-video-webm": "ŠŠøŠ“ŠµŠ¾ WebM", + "mwe-embedplayer-video-flv": "Flash-Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-ogg": "Ogg-Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-audio": "Ogg-Š°ŃŠ“ŠøŠ¾", + "mwe-embedplayer-audio-mpeg": "MPEG-Š°ŃŠ“ŠøŠ¾", + "mwe-embedplayer-video-3gp": "3GP-Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-mpeg": "MPEG-Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-msvideo": "AVI-Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-missing-source": "ŠŠµ Š½Š°Š¹Š“ŠµŠ½ ŠøŃŃŠ¾ŃŠ½ŠøŠŗ Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-vlcapp-intro": "ŠŠ»Ń ŠæŃŠ¾ŃŠ¼Š¾ŃŃŠ° Š²ŠøŠ“ŠµŠ¾ Ń ŃŃŠ¾Š³Š¾ ŃŠ°Š¹ŃŠ° Š½Š° iPhone ŠøŠ»Šø iPad Š²Š°Š¼ Š½ŃŠ¶Š½Š¾ Š±ŠµŃŠæŠ»Š°ŃŠ½Š¾Šµ ŠæŃŠøŠ»Š¾Š¶ŠµŠ½ŠøŠµ $1.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "ŠŃŠøŠ»Š¾Š¶ŠµŠ½ŠøŠµ VLC", + "mwe-embedplayer-vlcapp-downloadapp": "ŠŠ°Š³ŃŃŠ·ŠøŃŃ ŠæŃŠøŠ»Š¾Š¶ŠµŠ½ŠøŠµ VLC ŠøŠ· App Store", + "mwe-embedplayer-vlcapp-openvideo": "ŠŃŠŗŃŃŃŃ ŃŃŠ¾ Š²ŠøŠ“ŠµŠ¾ Š² ŠæŃŠøŠ»Š¾Š¶ŠµŠ½ŠøŠø VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "Š”ŠŗŠ°ŃŠ°ŃŃ ŃŃŠ¾ Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-vlcapp-vlcapppopup": "ŠŠ»Ń Š²Š¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½ŠøŃ Š²ŠøŠ“ŠµŠ¾ Š½Š° ŃŃŠ¾Š¼ ŃŠ°Š¹ŃŠµ Š²Š°Š¼ Š½ŠµŠ¾Š±Ń
Š¾Š“ŠøŠ¼Š¾ Š±ŠµŃŠæŠ»Š°ŃŠ½Š¾Šµ ŠæŃŠøŠ»Š¾Š¶ŠµŠ½ŠøŠµ VLC. Š£ŃŃŠ°Š½Š¾Š²ŠøŃŃ ŃŠµŠ¹ŃŠ°Ń?", + "mwe-embedplayer-iewebmprompt-intro": "Š£ŠæŃ! ŠŃŃ ŠŗŠ¾Šµ-ŃŃŠ¾, ŠæŃŠµŠ¶Š“Šµ ŃŠµŠ¼ Š²Ń ŃŠ¼Š¾Š¶ŠµŃŠµ ŠæŃŠ¾ŃŠ¼Š¾ŃŃŠµŃŃ ŃŃŠ¾ Š²ŠøŠ“ŠµŠ¾ā¦", + "mwe-embedplayer-iewebmprompt-linktext": "Š£ŃŃŠ°Š½Š¾Š²ŠøŃŠµ Š¼ŠµŠ“ŠøŠ°-ŠŗŠ¾Š¼ŠæŠ¾Š½ŠµŠ½ŃŃ WebM Š“Š»Ń Microsoft Internet Explorer", + "mwe-embedplayer-iewebmprompt-outro": "ŠŠ¾ŃŠ»Šµ ŃŃŃŠ°Š½Š¾Š²ŠŗŠø ŠæŠµŃŠµŠ·Š°Š³ŃŃŠ·ŠøŃŠµ ŃŃŃ ŃŃŃŠ°Š½ŠøŃŃ." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/rue.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/rue.json new file mode 100644 index 00000000..86c2c343 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/rue.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Gazeb" + ] + }, + "mwe-embedplayer-close_btn": "ŠŠ°ŠæŠµŃŃŠø", + "mwe-embedplayer-ogg-player-vlc-player": "ŠŠµŃŠµŠ³ŃŠ°Š²Š°Ń VLC" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/si.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/si.json new file mode 100644 index 00000000..76991f4a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/si.json @@ -0,0 +1,78 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ", + "Susith Chandira Gts" + ] + }, + "mwe-embedplayer-credit-title": "ą¶øą·ą¶ą·ą¶ą·ą·: $1", + "mwe-embedplayer-credit-date": "ą¶Æą·ą¶±ą¶ŗ: $1", + "mwe-embedplayer-credit-author": "ą¶ą¶ą·: $1", + "mwe-embedplayer-nocredits": "ą·ą·ą¶ą·ą¶ą· ą¶ą·ą·ą·ą·ą¶ą· ą¶½ą¶¶ą· ą¶ą¶ ą¶±ą·ą·ą·ą¶", + "mwe-embedplayer-loading_plugin": "ą¶“ą·ą¶½ą¶ą·ą¶±ą¶ŗ ą¶“ą·ą¶»ą¶«ą¶ŗ ą·ą·ą¶øą·ą¶±ą· ...", + "mwe-embedplayer-select_playback": "ą¶“ą·ą·
ą·ą·ą·ą¶ŗą·ą¶øą· ą¶
ą¶·ą·ą¶»ą·ą¶ ą·ą¶ŗ ą·ą¶ą·ą¶±ą·ą¶±", + "mwe-embedplayer-link_back": "ą¶±ą·ą·ą¶ ą·ą¶øą·ą¶¶ą¶±ą·ą¶° ą¶ą¶»ą¶±ą·ą¶±", + "mwe-embedplayer-add_to_end_of_sequence": "ą¶
ą¶±ą·ą¶ą·āą¶»ą¶øą¶ŗą· ą¶
ą·ą·ą·ą¶±ą¶ŗą¶§ ą¶ą¶ą· ą¶ą¶»ą¶±ą·ą¶±", + "mwe-embedplayer-missing_video_stream": "ą¶øą·ą¶ø ą¶“ą·āą¶»ą·ą·ą·ą¶ŗ ą·ą¶³ą·ą· ą·ą·ą¶©ą·ą¶ŗą· ą¶ą·ą¶±ą·ą· ą¶Æą¶ą·ą¶±ą¶§ ą¶±ą·ą¶øą·ą¶", + "mwe-embedplayer-play_clip": "ą¶ą·ą¶½ą·ą¶“ą¶ŗ ą·ą¶ŗą¶±ą·ą¶±", + "mwe-embedplayer-pause_clip": "ą¶ą·ą¶½ą·ą¶“ą¶ŗ ą·ą·ą¶»ą·ą¶øą¶ą¶ ą¶ą¶»ą¶±ą·ą¶±", + "mwe-embedplayer-volume_control": "ą·ą¶¶ą·ą¶Æ ą¶“ą·āą¶»ą¶øą·ą¶« ą¶“ą·ą¶½ą¶ą¶ŗ", + "mwe-embedplayer-player_options": "ą·ą·ą¶Æą¶ ą·ą·ą¶ą¶½ą·ą¶“ą¶ŗą¶±ą·", + "mwe-embedplayer-timed_text": "ą¶ą·ą¶½ą·ą¶ ą¶“ą·ą·
", + "mwe-embedplayer-player_fullscreen": "ą¶“ą·ą¶»ą·ą¶« ą¶ą·ą¶»ą¶ŗ", + "mwe-embedplayer-next_clip_msg": "ą¶øą·ą·
ą¶ ą¶ą·ą¶½ą·ą¶“ą¶ŗ ą·ą¶ŗą¶±ą·ą¶±", + "mwe-embedplayer-prev_clip_msg": "ą¶“ą·ą¶» ą¶ą·ą¶½ą·ą¶“ą¶ŗ ą·ą¶ŗą¶±ą·ą¶±", + "mwe-embedplayer-current_clip_msg": "ą¶øą·ą¶ø ą¶ą·ą¶½ą·ą¶“ą¶ŗ ą¶Æą·ą¶ą¶§ą¶ø ą·ą¶ŗą¶±ą·ą¶±", + "mwe-embedplayer-seek_to": "$1 ą¶ą¶½ą·ą¶ŗą¶±ą·ą¶±", + "mwe-embedplayer-paused": "ą·ą·ą¶»ą·ą¶øą¶ą¶ą¶ŗą·", + "mwe-embedplayer-download_segment": "ą¶ą·ą¶»ą·ą¶ø ą¶¶ą·ą¶ą¶±ą·ą¶±:", + "mwe-embedplayer-download_full_video": "ą·ą¶øą·ą¶“ą·ą¶»ą·ą¶« ą·ą·ą¶©ą·ą¶ŗą· ą¶ą·ą¶±ą·ą· ą¶¶ą·ą¶ą¶±ą·ą¶±:", + "mwe-embedplayer-download_full_audio": "ą¶“ą·ą¶»ą·ą¶« ą·ą¶ą¶ą·ą¶ ą¶ą·ą¶±ą·ą· ą¶¶ą·ą¶ą¶±ą·ą¶±:", + "mwe-embedplayer-download_right_click": "ą¶¶ą·ą¶ą¶ ą¶ą·ą¶»ą·ą¶ø ą·ą¶³ą·ą·, ą¶Æą¶ą·ą¶« ą¶ą·ą¶½ą·ą¶ą· ą¶ą¶» <i>Save link as...</i> ą¶ą·ą¶»ą¶±ą·ą¶±", + "mwe-embedplayer-download_clip": "ą·ą·ą¶©ą·ą¶ŗą·ą· ą¶¶ą·ą¶ą¶±ą·ą¶±", + "mwe-embedplayer-download_text": "ą¶“ą·ą¶Øą¶ŗ ą¶¶ą·ą¶ą¶±ą·ą¶±", + "mwe-embedplayer-download": "ą¶¶ą·ą¶ą¶±ą·ą¶±", + "mwe-embedplayer-share": "ą·ą·ą·ą¶øą·ą¶»ą· ą¶ą¶»ą¶±ą·ą¶±", + "mwe-embedplayer-credits": "ą·ą·ą¶ą·ą¶ą·ą¶ŗ", + "mwe-embedplayer-about-library": "Kaltura ą·ą·ą¶Æą¶ą¶ŗ ą¶“ą·ą·
ą·ą¶¶ą¶³", + "mwe-embedplayer-clip_linkback": "ą¶ą·ą¶½ą·ą¶“ą¶ŗą· ą¶øą·ą¶½ą·ą·ą·āą¶» ą¶“ą·ą¶§ą·ą·", + "mwe-embedplayer-choose_player": "ą·ą·ą¶©ą·ą¶ŗą· ą·ą·ą¶Æą¶ą¶ŗ ą¶ą·ą¶»ą¶±ą·ą¶±", + "mwe-embedplayer-no-player": "$1 ą·ą¶³ą·ą· ą·ą·ą¶Æą¶ą¶ŗą¶ą· ą¶½ą¶¶ą· ą¶ą¶ ą¶±ą·ą·ą·ą¶", + "mwe-embedplayer-share_this_video": "ą¶øą·ą¶ø ą·ą·ą¶©ą·ą¶ŗą·ą· ą·ą·ą·ą¶øą·ą¶»ą· ą¶ą¶»ą¶±ą·ą¶±", + "mwe-embedplayer-share_this_audio": "ą¶øą·ą¶ø ą·ą¶ą¶ą·ą¶ ą¶ą·ą¶±ą·ą· ą·ą·ą·ą¶øą·ą¶»ą· ą¶ą¶»ą¶±ą·ą¶±", + "mwe-embedplayer-video_credits": "ą·ą·ą¶©ą·ą¶ŗą· ą·ą·ą¶ą·ą¶ą·ą¶ŗ", + "mwe-embedplayer-no-video_credits": "ą·ą·ą¶ą·ą¶ą·ą¶ŗ ą¶½ą¶¶ą· ą¶ą¶ ą¶±ą·ą·ą·ą¶", + "mwe-embedplayer-kaltura-platform-title": "Kaltura ą·ą·ą·ą·ą¶ ą¶øą·ą¶½ą·ą·ą·āą¶» ą·ą·ą¶Æą·ą·ą·āą¶ŗ ą¶ą¶»ą·
ą·ą¶ŗ", + "mwe-embedplayer-menu_btn": "ą¶øą·ą¶±ą·ą·", + "mwe-embedplayer-close_btn": "ą·ą·ą¶±ą·ą¶±", + "mwe-embedplayer-ogg-player-vlc-player": "VLC ą·ą·ą¶Æą¶ą¶ŗ", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg ą·ą·ą¶Æą¶ą¶ŗ", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 ą·ą·ą¶Æą¶ą¶ŗ", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM ą·ą·ą¶Æą¶ą¶ŗ", + "mwe-embedplayer-ogg-player-oggPlugin": "ą¶“ą·āą¶»ą¶¢ą·ą¶ą·ą¶ŗ Ogg ą¶“ą·ą¶½ą¶ą·ą¶±ą¶ŗ", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime ą¶“ą·ą¶½ą¶ą·ą¶±ą¶ŗ", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "ą·ą·ą¶½ą·ą·ą·ą·ą·ą¶Æą¶ą¶ŗ", + "mwe-embedplayer-ogg-player-kplayer": "ą¶ą¶½ą·ą¶ą·ą¶»ą· ą·ą·ą¶Æą¶ą¶ŗ", + "mwe-embedplayer-ogg-player-selected": "(ą¶ą·ą¶»ą·ą¶ą¶ą·)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK ą·ą·ą¶½ą·ą·ą· Vorbis", + "mwe-embedplayer-fullscreen-tip": "ą¶§ą·ą¶ą¶½ <i>ą·ą·ą¶¶ą· ą¶ą·ą·ą·ą¶</i> ą¶“ą·ą¶»ą·ą¶« ą¶ą·ą¶»ą¶ŗ ą·ą¶³ą·ą· <b>F11</b> ą¶ą¶¶ą¶±ą·ą¶±", + "mwe-embedplayer-fullscreen-tip-osx": "ą¶§ą·ą¶ą¶½ ą¶“ą·ą¶»ą·ą¶« ą¶ą·ą¶»ą¶ŗ ą·ą¶³ą·ą· <b>shift ā F</b> ą¶ą¶¶ą¶±ą·ą¶±", + "mwe-embedplayer-do_not_warn_again": "ą¶ą¶Æą·ą¶»ą·ą¶ŗą·ą¶Æą·, ą¶øą·ą¶ø ą¶“ą¶«ą·ą·ą·ą¶©ą¶ŗ ą¶“ą·ą¶±ą·ą·ą¶±ą·ą¶± ą¶ą¶“ą·", + "mwe-embedplayer-playerSelect": "ą·ą·ą¶Æą¶", + "mwe-embedplayer-read_before_embed": "ą¶ą¶¶ą·ą¶¶ą·ą¶ø ą¶“ą·ą¶» <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ą¶øą·ą¶ŗ ą¶ą·ą¶ŗą·ą¶±ą·ą¶±</a>.", + "mwe-embedplayer-embed_site_or_blog": "ą¶“ą·ą¶§ą·ą·ą¶ ą¶ą¶¶ą·ą¶¶ą·ą¶±ą·ą¶±", + "mwe-embedplayer-related_videos": "ą¶ą·ą·āą¶»ą·ą¶ ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-seeking": "ą¶ą¶½ą·ą¶ŗą¶øą·ą¶±ą·", + "mwe-embedplayer-buffering": "ą¶
ą·ą¶»ą·ą¶°ą·ą¶ą¶»ą¶«ą¶ŗ ą¶ą¶»ą¶øą·ą¶±ą·", + "mwe-embedplayer-video-h264": "H.264 ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-video-webm": "ą·ą·ą¶¶ą·ą¶ą¶øą· ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-video-flv": "ą·ą·ą¶½ą·ą·ą· ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-video-ogg": "Ogg ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-video-audio": "Ogg ą·ą·āą¶»ą·ą·āą¶ŗ", + "mwe-embedplayer-audio-mpeg": "MPEG ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-video-3gp": "3GP ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-video-mpeg": "MPEG ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-video-msvideo": "AVI ą·ą·ą¶©ą·ą¶ŗą·", + "mwe-embedplayer-missing-source": "ą¶øą·ą¶½ą·ą·ą·āą¶» ą·ą·ą¶©ą·ą¶ŗą·ą·ą¶ą· ą·ą¶øą· ą¶±ą·ą·ą·ą¶«ą·" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sk.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sk.json new file mode 100644 index 00000000..fee61f56 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sk.json @@ -0,0 +1,6 @@ +{ + "@metadata": [], + "mwe-embedplayer-download": "StiahnuÅ„", + "mwe-embedplayer-close_btn": "ZavrieÅ„", + "mwe-embedplayer-do_not_warn_again": "Nateraz nezobrazovaÅ„" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sr-ec.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sr-ec.json new file mode 100644 index 00000000..fa893c4a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sr-ec.json @@ -0,0 +1,78 @@ +{ + "@metadata": { + "authors": [ + "Milicevic01", + "Rancher", + "ŠŠøŃ
Š°ŃŠ»Š¾ ŠŠ½ŃŠµŠ»ŠŗŠ¾Š²ŠøŃ" + ] + }, + "mwe-embedplayer-credit-title": "ŠŠ°ŃŠ»Š¾Š²: $1", + "mwe-embedplayer-credit-date": "ŠŠ°ŃŃŠ¼: $1", + "mwe-embedplayer-credit-author": "ŠŃŃŠ¾Ń: $1", + "mwe-embedplayer-loading_plugin": "Š£ŃŠøŃŠ°Š²Š°Š¼ Š“Š¾Š“Š°ŃŠ°Šŗā¦", + "mwe-embedplayer-select_playback": "ŠŠ¾ŃŃŠ°Š²Šø ŠæŠ¾Š“ŠµŃŠ°Š²Š°ŃŠ° Š·Š° ŠøŠ·Š²Š¾ŃŠµŃŠµ", + "mwe-embedplayer-link_back": "ŠŠ±ŃŠ½ŃŃŠ° Š²ŠµŠ·Š°", + "mwe-embedplayer-error_swap_vid": "ŠŃŠµŃŠŗŠ°: mwEmbed Š½Šµ Š¼Š¾Š¶Šµ Š“Š° Š·Š°Š¼ŠµŠ½Šø Š²ŠøŠ“ŠµŠ¾-Š¾Š·Š½Š°ŠŗŃ Š·Š° Š¾ŠŗŃŃŠ¶ŠµŃŠµ mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "ŠŠ¾Š“Š°Ń Š½Š° ŠŗŃŠ°Ń Š½ŠøŠ·Š°", + "mwe-embedplayer-missing_video_stream": "ŠŠµŠ“Š¾ŃŃŠ°ŃŠµ Š²ŠøŠ“ŠµŠ¾-ŃŠ½ŠøŠ¼Š°Šŗ Š·Š° Š¾Š²Š°Ń ŃŠ¾Šŗ", + "mwe-embedplayer-play_clip": "ŠŃŃŃŠø ŠŗŠ»ŠøŠæ", + "mwe-embedplayer-pause_clip": "ŠŠ°ŃŠ·ŠøŃŠ°Ń ŠŗŠ»ŠøŠæ", + "mwe-embedplayer-volume_control": "ŠŠ¾Š½ŃŃŠ¾Š»Š° ŃŠ°ŃŠøŠ½Šµ Š·Š²ŃŠŗŠ°", + "mwe-embedplayer-player_options": "ŠŠ¾ŃŃŠ°Š²ŠŗŠµ ŠøŠ·Š²Š¾ŃŠ°ŃŠ°", + "mwe-embedplayer-timed_text": "Š£ŃŠŗŠ»Š°ŃŠµŠ½ ŃŠµŠŗŃŃ", + "mwe-embedplayer-player_fullscreen": "Š¦ŠµŠ¾ ŠµŠŗŃŠ°Š½", + "mwe-embedplayer-next_clip_msg": "ŠŃŃŃŠø ŃŠ»ŠµŠ“ŠµŃŠø ŠŗŠ»ŠøŠæ", + "mwe-embedplayer-prev_clip_msg": "ŠŃŃŃŠø ŠæŃŠµŃŃ
Š¾Š“Š½Šø ŠŗŠ»ŠøŠæ", + "mwe-embedplayer-current_clip_msg": "ŠŠ°ŃŃŠ°Š²Šø Ń ŠøŠ·Š²Š¾ŃŠµŃŠµŠ¼ Š¾Š²Š¾Š³ ŃŠ½ŠøŠ¼ŠŗŠ°", + "mwe-embedplayer-seek_to": "Š”ŠŗŠ¾ŃŠø Š½Š° $1", + "mwe-embedplayer-paused": "ŠæŠ°ŃŠ·ŠøŃŠ°Š½Š¾", + "mwe-embedplayer-download_segment": "ŠŠ·Š±Š¾Ń Š·Š° ŠæŃŠµŃŠ·ŠøŠ¼Š°ŃŠµ:", + "mwe-embedplayer-download_full": "ŠŃŠµŃŠ·Š¼ŠøŃŠµ ŃŠµŠ¾ Š²ŠøŠ“ŠµŠ¾-ŃŠ½ŠøŠ¼Š°Šŗ:", + "mwe-embedplayer-download_right_click": "ŠŠ° ŠæŃŠµŃŠ·ŠøŠ¼Š°ŃŠµ, ŠæŃŠøŃŠøŃŠ½ŠøŃŠµ Š“ŠµŃŠ½Šø ŠŗŠ»ŠøŠŗ Šø ŠøŠ·Š°Š±ŠµŃŠøŃŠµ <i>Š”Š°ŃŃŠ²Š°Ń Š²ŠµŠ·Ń ŠŗŠ°Š¾ā¦</i>", + "mwe-embedplayer-download_clip": "ŠŃŠµŃŠ·Š¼Šø Š²ŠøŠ“ŠµŠ¾-ŃŠ½ŠøŠ¼Š°Šŗ", + "mwe-embedplayer-download_text": "ŠŃŠµŃŠ·Š¼Šø ŃŠµŠŗŃŃ", + "mwe-embedplayer-download": "ŠŃŠµŃŠ·Š¼Šø", + "mwe-embedplayer-share": "ŠŠµŠ»Šø", + "mwe-embedplayer-credits": "ŠŠ°ŃŠ»ŃŠ³Šµ", + "mwe-embedplayer-about-library": "Š ŠøŠ·Š²Š¾ŃŠ°ŃŃ ŠŠ°Š»ŃŃŃŠ°", + "mwe-embedplayer-about-library-desc": "ŠŠ°Š»ŃŃŃŠøŠ½Š° Š¼ŃŠ»ŃŠøŠ¼ŠµŠ“ŠøŃŠ°Š»Š½Š° Š±ŠøŠ±Š»ŠøŠ¾ŃŠµŠŗŠ° HTML5 Š²Š°Š¼ Š¾Š¼Š¾Š³ŃŃŠ°Š²Š° Š“Š° ŠŗŠ¾ŃŠøŃŃŠøŃŠµ HTML5 Š¾Š·Š½Š°ŠŗŠµ <video> Šø <audio> ŃŠ° ŃŃŠ°Š½Š“Š°ŃŠ“Š½ŠøŠ¼ ŃŃŃŠµŃŠµŠ¼ Š·Š° ŠøŠ·Š²Š¾ŃŠµŃŠµ ŠæŃŠµŠŗŠ¾ Š½Š°ŃŠ·Š°ŃŃŃŠæŃŠµŠ½ŠøŃŠøŃ
ŠæŃŠµŠ³Š»ŠµŠ“Š°ŃŠ°.\n\n[$1 ŠŠøŃŠµ Š¾ ŠŠ°Š»ŃŃŃŠøŠ½Š¾Ń Š±ŠøŠ±Š»ŠøŠ¾ŃŠµŃŠø Š·Š° ŠøŠ·Š²Š¾ŃŠµŃŠµ].", + "mwe-embedplayer-clip_linkback": "ŠŠ·Š²Š¾ŃŠ½Š° ŃŃŃŠ°Š½ŠøŃŠ° ŃŠ½ŠøŠ¼ŠŗŠ°", + "mwe-embedplayer-choose_player": "ŠŠ·Š°Š±ŠµŃŠøŃŠµ Š²ŠøŠ“ŠµŠ¾-ŠæŠ»ŠµŃŠµŃ", + "mwe-embedplayer-no-player": "ŠŠµŠ¼Š° Š“Š¾ŃŃŃŠæŠ½ŠøŃ
ŠøŠ·Š²Š¾ŃŠ°ŃŠ° Š·Š° $1", + "mwe-embedplayer-share_this_video": "ŠŠµŠ»Šø Š¾Š²Š°Ń ŃŠ½ŠøŠ¼Š°Šŗ", + "mwe-embedplayer-video_credits": "ŠŃŃŠ¾ŃŠø ŃŠ½ŠøŠ¼ŠŗŠ°", + "mwe-embedplayer-no-video_credits": "ŠŠµŠ¼Š° Š°ŃŃŠ¾ŃŃŠŗŠøŃ
ŠæŠ¾Š“Š°ŃŠ°ŠŗŠ°", + "mwe-embedplayer-kaltura-platform-title": "ŠŠ°Š»ŃŃŃŠøŠ½Š° Š¾ŃŠ²Š¾ŃŠµŠ½Š° Š²ŠøŠ“ŠµŠ¾-ŠæŠ»Š°ŃŃŠ¾ŃŠ¼Š°", + "mwe-embedplayer-menu_btn": "ŠŠµŠ½Šø", + "mwe-embedplayer-close_btn": "ŠŠ°ŃŠ²Š¾ŃŠø", + "mwe-embedplayer-ogg-player-vlc-player": "VLC ŠæŠ»ŠµŃŠµŃ", + "mwe-embedplayer-ogg-player-oggNative": "ŠŠ·Š²Š¾ŃŠ°Ń .ogg (HTML5)", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 ŠæŠ»ŠµŃŠµŃ", + "mwe-embedplayer-ogg-player-webmNative": "ŠŠ·Š²Š¾ŃŠ°Ń WebM (HTML5)", + "mwe-embedplayer-ogg-player-oggPlugin": "ŠŠµŠ½ŠµŃŠøŃŠŗŠø Ogg ŠæŠ»Š°Š³ŠøŠ½", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime ŠæŠ»Š°Š³ŠøŠ½", + "mwe-embedplayer-ogg-player-quicktime-activex": "ŠŠ²ŠøŠŗŃŠ°ŃŠ¼ (ŠŠŗŃŠøŠ²ŠøŠŗŃ)", + "mwe-embedplayer-ogg-player-cortado": "ŠŠ¾ŃŃŠ°Š“Š¾ (ŠŠ°Š²Š°)", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "ŠŠ·Š²Š¾ŃŠ°Ń ŠŠ°Š»ŃŃŃŠ°", + "mwe-embedplayer-ogg-player-selected": "(ŠøŠ·Š°Š±ŃŠ°Š½Š¾)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "ŠŠ° ŠŗŠ²Š°Š»ŠøŃŠµŃŠ½ŠøŃŠµ ŠæŃŠµŠ³Š»ŠµŠ“Š°ŃŠµ ŃŠ½ŠøŠ¼Š°ŠŗŠ°, ŠæŃŠµŠæŠ¾ŃŃŃŃŃŠµŠ¼Š¾ Š²Š°Š¼ <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5 Š²ŠøŠ“ŠµŠ¾ ŠæŃŠµŠ³Š»ŠµŠ“Š°Ń</a>.", + "mwe-embedplayer-download-warn": "ŠŠøŃŠµ ŠæŃŠ¾Š½Š°ŃŠµŠ½ ŠæŃŠøŠŗŠ»Š°Š“Š°Š½ ŠøŠ·Š²Š¾ŃŠ°Ń Š·Š° ŠæŃŃŃŠ°ŃŠµ ŠæŃŠµŠŗŠ¾ ŠæŃŠµŠ³Š»ŠµŠ“Š°ŃŠ°. ŠŃŠµŃŠ·Š¼ŠøŃŠµ [$1 Š½Š°ŃŠ½Š¾Š²ŠøŃŠø Š¤Š°ŃŠµŃŃŠ¾ŠŗŃ]", + "mwe-embedplayer-fullscreen-tip": "ŠŃŠøŃŠøŃŠ½ŠøŃŠµ <b>F11</b> Š“Š° ŠæŃŠµŠ±Š°ŃŠøŃŠµ <i>ŠæŃŠµŠ³Š»ŠµŠ“Š°Ń</i> Š½Š° ŃŠµŠ¾ ŠµŠŗŃŠ°Š½", + "mwe-embedplayer-fullscreen-tip-osx": "ŠŃŠøŃŠøŃŠ½ŠøŃŠµ <b>Shift ā F</b> Š·Š° ŠæŃŠµŠ±Š°ŃŠøŠ²Š°ŃŠµ Š½Š° ŃŠµŠ¾ ŠµŠŗŃŠ°Š½", + "mwe-embedplayer-do_not_warn_again": "ŠŠµ ŠæŃŠøŠŗŠ°Š·ŃŃ Š¾Š²Ń ŠæŠ¾ŃŃŠŗŃ ŠæŠ¾Š½Š¾Š²Š¾", + "mwe-embedplayer-playerSelect": "ŠŠ·Š²Š¾ŃŠ°ŃŠø", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ŠŃŠ¾ŃŠøŃŠ°ŃŃŠµ Š¾Š²Š¾</a> ŠæŃŠµ ŃŠ³ŃŠ°ŃŠøŠ²Š°ŃŠ°.", + "mwe-embedplayer-embed_site_or_blog": "Š£Š³ŃŠ°Š“Šø Ń ŃŃŃŠ°Š½ŠøŃŃ", + "mwe-embedplayer-related_videos": "Š”ŃŠ¾Š“Š½Šø Š²ŠøŠ“ŠµŠ¾-ŃŠ½ŠøŠ¼ŃŠø", + "mwe-embedplayer-seeking": "ŃŃŠ°Š¶ŠøŠ¼", + "mwe-embedplayer-buffering": "ŃŃŠøŃŠ°Š²Š°Š¼", + "mwe-embedplayer-video-h264": "H.264 Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-webm": "WebM Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-flv": "Š¤Š»ŠµŃ Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-ogg": "Ogg Š²ŠøŠ“ŠµŠ¾", + "mwe-embedplayer-video-audio": "Ogg Š°ŃŠ“ŠøŠ¾", + "mwe-embedplayer-missing-source": "ŠŠøŃŠµ ŠæŃŠ¾Š½Š°ŃŠµŠ½ ŠøŠ·Š²Š¾Ń ŃŠ½ŠøŠ¼ŠŗŠ°.", + "mwe-embedplayer-vlcapp-downloadvideo": "ŠŃŠµŃŠ·Š¼Šø Š¾Š²Š°Ń Š²ŠøŠ“ŠµŠ¾" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sr-el.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sr-el.json new file mode 100644 index 00000000..84f4cb21 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sr-el.json @@ -0,0 +1,77 @@ +{ + "@metadata": { + "authors": [ + "Rancher", + "Milicevic01" + ] + }, + "mwe-embedplayer-credit-title": "Naslov: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Autor: $1", + "mwe-embedplayer-loading_plugin": "UÄitavam dodatakā¦", + "mwe-embedplayer-select_playback": "Postavi podeÅ”avanja za izvoÄenje", + "mwe-embedplayer-link_back": "Obrnuta veza", + "mwe-embedplayer-error_swap_vid": "GreÅ”ka: mwEmbed ne može da zameni video-oznaku za suÄelje mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Dodaj na kraj niza", + "mwe-embedplayer-missing_video_stream": "Nedostaje video-snimak za ovaj tok", + "mwe-embedplayer-play_clip": "Pusti klip", + "mwe-embedplayer-pause_clip": "Pauziraj klip", + "mwe-embedplayer-volume_control": "Kontrola jaÄine zvuka", + "mwe-embedplayer-player_options": "Postavke izvoÄaÄa", + "mwe-embedplayer-timed_text": "UsklaÄen tekst", + "mwe-embedplayer-player_fullscreen": "Ceo ekran", + "mwe-embedplayer-next_clip_msg": "Pusti sledeÄi klip", + "mwe-embedplayer-prev_clip_msg": "Pusti prethodni klip", + "mwe-embedplayer-current_clip_msg": "Nastavi s izvoÄenjem ovog snimka", + "mwe-embedplayer-seek_to": "SkoÄi na $1", + "mwe-embedplayer-paused": "pauzirano", + "mwe-embedplayer-download_segment": "Izbor za preuzimanje:", + "mwe-embedplayer-download_full": "Preuzmite ceo video-snimak:", + "mwe-embedplayer-download_right_click": "Za preuzimanje, pritisnite desni klik i izaberite <i>SaÄuvaj vezu kaoā¦</i>", + "mwe-embedplayer-download_clip": "Preuzmi video-snimak", + "mwe-embedplayer-download_text": "Preuzmi tekst", + "mwe-embedplayer-download": "Preuzmi", + "mwe-embedplayer-share": "Deli", + "mwe-embedplayer-credits": "Zasluge", + "mwe-embedplayer-about-library": "O izvoÄaÄu Kaltura", + "mwe-embedplayer-about-library-desc": "Kalturina multimedijalna biblioteka HTML5 vam omoguÄava da koristite HTML5 oznake <video> i <audio> sa standardnim suÄeljem za izvoÄenje preko najzastupljenijih pregledaÄa.\n\n[$1 ViÅ”e o Kalturinoj biblioteci za izvoÄenje].", + "mwe-embedplayer-clip_linkback": "Izvorna stranica snimka", + "mwe-embedplayer-choose_player": "Izaberite video-plejer", + "mwe-embedplayer-no-player": "Nema dostupnih izvoÄaÄa za $1", + "mwe-embedplayer-share_this_video": "Deli ovaj snimak", + "mwe-embedplayer-video_credits": "Autori snimka", + "mwe-embedplayer-no-video_credits": "Nema autorskih podataka", + "mwe-embedplayer-kaltura-platform-title": "Kalturina otvorena video-platforma", + "mwe-embedplayer-menu_btn": "Meni", + "mwe-embedplayer-close_btn": "Zatvori", + "mwe-embedplayer-ogg-player-vlc-player": "VLC plejer", + "mwe-embedplayer-ogg-player-oggNative": "IzvoÄaÄ .ogg (HTML5)", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 plejer", + "mwe-embedplayer-ogg-player-webmNative": "IzvoÄaÄ WebM (HTML5)", + "mwe-embedplayer-ogg-player-oggPlugin": "GeneriÄki Ogg plagin", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime plagin", + "mwe-embedplayer-ogg-player-quicktime-activex": "Kviktajm (Aktiviks)", + "mwe-embedplayer-ogg-player-cortado": "Kortado (Java)", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "IzvoÄaÄ Kaltura", + "mwe-embedplayer-ogg-player-selected": "(izabrano)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Za kvalitetnije pregledanje snimaka, preporuÄujemo vam <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">najnoviji Fajerfoks</a>.", + "mwe-embedplayer-download-warn": "Nije pronaÄen prikladan izvoÄaÄ za puÅ”tanje preko pregledaÄa. Preuzmite [$1 najnoviji Fajerfoks]", + "mwe-embedplayer-fullscreen-tip": "Pritisnite <b>F11</b> da prebacite <i>pregledaÄ</i> na ceo ekran", + "mwe-embedplayer-fullscreen-tip-osx": "Pritisnite <b>Shift ā F</b> za prebacivanje na ceo ekran", + "mwe-embedplayer-do_not_warn_again": "Ne prikazuj ovu poruku ponovo", + "mwe-embedplayer-playerSelect": "IzvoÄaÄi", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ProÄitajte ovo</a> pre ugraÄivanja.", + "mwe-embedplayer-embed_site_or_blog": "Ugradi u stranicu", + "mwe-embedplayer-related_videos": "Srodni video-snimci", + "mwe-embedplayer-seeking": "tražim", + "mwe-embedplayer-buffering": "uÄitavam", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-webm": "WebM video", + "mwe-embedplayer-video-flv": "FleÅ” video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg audio", + "mwe-embedplayer-missing-source": "Nije pronaÄen izvor snimka.", + "mwe-embedplayer-vlcapp-downloadvideo": "Preuzmi ovaj video" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sv.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sv.json new file mode 100644 index 00000000..d34d25d2 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/sv.json @@ -0,0 +1,96 @@ +{ + "@metadata": { + "authors": [ + "Ainali", + "Dafer45", + "Lokal Profil", + "WikiPhoenix", + "Jenniesarina" + ] + }, + "mwe-embedplayer-credit-title": "Titel: $1", + "mwe-embedplayer-credit-date": "Datum: $1", + "mwe-embedplayer-credit-author": "Fƶrfattare: $1", + "mwe-embedplayer-nocredits": "Inga erkƤnnanden tillgƤngliga", + "mwe-embedplayer-loading_plugin": "laddar insticksmodul...", + "mwe-embedplayer-select_playback": "Ange uppspelningsinstƤllningar", + "mwe-embedplayer-link_back": "LƤnka tillbaka", + "mwe-embedplayer-error_swap_vid": "Fel: mwEmbed kunde inte att byta videoetiketten fƶr mwEmbed-grƤnssnittet", + "mwe-embedplayer-add_to_end_of_sequence": "LƤgg till i slutet av sekvens", + "mwe-embedplayer-missing_video_stream": "Videofil fƶr den hƤr datastrƶmmen saknas", + "mwe-embedplayer-play_clip": "Spela klipp", + "mwe-embedplayer-pause_clip": "Pausa klipp", + "mwe-embedplayer-volume_control": "Volymkontroll", + "mwe-embedplayer-player_options": "Spelaralternativ", + "mwe-embedplayer-timed_text": "TidsbestƤmd text", + "mwe-embedplayer-player_fullscreen": "FullskƤrm", + "mwe-embedplayer-next_clip_msg": "Spela nƤsta klipp", + "mwe-embedplayer-prev_clip_msg": "Spela fƶregĆ„ende klipp", + "mwe-embedplayer-current_clip_msg": "FortsƤtt spela detta klipp", + "mwe-embedplayer-seek_to": "Sƶk $1", + "mwe-embedplayer-paused": "pausad", + "mwe-embedplayer-download_segment": "HƤmta urval:", + "mwe-embedplayer-download_full_video": "Ladda ner den fullstƤndiga videofilen:", + "mwe-embedplayer-download_full_audio": "Ladda ned fullstƤndig ljudfil:", + "mwe-embedplayer-download_right_click": "Fƶr att ladda ner, hƶgerklicka och vƤlj <i>Spara lƤnk som ...</i>", + "mwe-embedplayer-download_clip": "Ladda ner video", + "mwe-embedplayer-download_text": "Ladda ner text", + "mwe-embedplayer-download": "Ladda ner", + "mwe-embedplayer-share": "Dela", + "mwe-embedplayer-credits": "ErkƤnnanden", + "mwe-embedplayer-about-library": "Om Kaltura player", + "mwe-embedplayer-about-library-desc": "Kaltura's HTML5 mediabibliotek ger dig mƶjlighet att utnyttja HTML5 <video> och <audio> taggar idag med ett konsekvent spelargrƤnssnitt ƶver alla stƶrre webblƤsare.\n\n[$1 Mer om Kaltura spelarbiblioteket].", + "mwe-embedplayer-clip_linkback": "KlippkƤllsidan", + "mwe-embedplayer-choose_player": "VƤlj videouppspelare", + "mwe-embedplayer-no-player": "Ingen spelare tillgƤnglig fƶr $1", + "mwe-embedplayer-share_this_video": "Dela denna video", + "mwe-embedplayer-share_this_audio": "Dela denna ljudfil", + "mwe-embedplayer-video_credits": "VideoerkƤnnanden", + "mwe-embedplayer-no-video_credits": "Inga erkƤnnanden tillgƤngliga", + "mwe-embedplayer-kaltura-platform-title": "Kaltura ƶppen kƤllkod videoplattform", + "mwe-embedplayer-menu_btn": "Meny", + "mwe-embedplayer-close_btn": "StƤng", + "mwe-embedplayer-ogg-player-vlc-player": "VLC spelare", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg spelare", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3-spelare", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC-spelare", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 spelare", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM spelare", + "mwe-embedplayer-ogg-player-oggPlugin": "Generiella Ogg-tillƤgg", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "VLC fƶr iOS-app", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-insticksmodul", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura spelare", + "mwe-embedplayer-ogg-player-selected": "(vald)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Fƶr en bƤttre videouppspelningsupplevelse rekommenderar vi en <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5 videowebblƤsare</a>.", + "mwe-embedplayer-download-warn": "Ingen kompatibel mediaspelare i webblƤsaren upptƤcktes: fƶr webblƤsaruppspelning, hƤmta [$1 senaste Firefox]", + "mwe-embedplayer-fullscreen-tip": "Tryck pĆ„ <b>F11</b> fƶr att vƤxla <i>webblƤsaren</i> till helskƤrm", + "mwe-embedplayer-fullscreen-tip-osx": "Tryck pĆ„ <b>SKIFT ā f</b> fƶr att vƤxla till helskƤrm", + "mwe-embedplayer-do_not_warn_again": "Visa inte detta meddelande fortsƤttningsvis", + "mwe-embedplayer-playerSelect": "Spelare", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">LƤs detta</a> innan inbƤddning.", + "mwe-embedplayer-embed_site_or_blog": "BƤdda in pĆ„ en sida", + "mwe-embedplayer-embed_wiki": "BƤdda in pĆ„ en wiki", + "mwe-embedplayer-related_videos": "Relaterade videos", + "mwe-embedplayer-seeking": "sƶker", + "mwe-embedplayer-buffering": "buffring", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-webm": "WebM video", + "mwe-embedplayer-video-flv": "Flash-video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg ljud", + "mwe-embedplayer-audio-mpeg": "MPEG audio", + "mwe-embedplayer-video-3gp": "3GP video", + "mwe-embedplayer-video-mpeg": "MPEG video", + "mwe-embedplayer-video-msvideo": "AVI video", + "mwe-embedplayer-missing-source": "Ingen kƤllvideo hittades", + "mwe-embedplayer-vlcapp-intro": "I fƶr att visa video frĆ„n denna webbplats pĆ„ en iPhone eller iPad, behƶver du den kostnadsfria $1.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "VLC-app", + "mwe-embedplayer-vlcapp-downloadapp": "Ladda ner VLC-appen frĆ„n App Store", + "mwe-embedplayer-vlcapp-openvideo": "Ćppna denna video i VLC-appen", + "mwe-embedplayer-vlcapp-downloadvideo": "Ladda ner denna video", + "mwe-embedplayer-vlcapp-vlcapppopup": "Fƶr att spela upp video pĆ„ denna webbplats, behƶver du den kostnadsfria VLC-appen. Installera nu?", + "mwe-embedplayer-iewebmprompt-intro": "Oops! En sak till innan du kan spela denna video..." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ta.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ta.json new file mode 100644 index 00000000..5e8d84a9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ta.json @@ -0,0 +1,40 @@ +{ + "@metadata": { + "authors": [ + "Karthi.dr", + "Shanmugamp7", + "ą®®ą®¤ą®©ą®¾ą®¹ą®°ą®©ąÆ" + ] + }, + "mwe-embedplayer-credit-title": "ą®¤ą®²ąÆą®ŖąÆą®ŖąÆ: $1", + "mwe-embedplayer-credit-date": "ą®¤ąÆą®¤ą®æ: $1", + "mwe-embedplayer-credit-author": "ą®ą®ąÆą®ąÆą®©ą®°ąÆ: $1", + "mwe-embedplayer-play_clip": "ą®¤ąÆą®£ąÆą®ąÆ ą®ą®Æą®ąÆą®ąÆ", + "mwe-embedplayer-player_fullscreen": "ą®®ąÆą®“ąÆą®¤ąÆą®¤ą®æą®°ąÆ", + "mwe-embedplayer-next_clip_msg": "ą®
ą®ąÆą®¤ąÆą®¤ ą®¤ąÆą®£ąÆą®ąÆ ą®ą®Æą®ąÆą®ąÆ", + "mwe-embedplayer-prev_clip_msg": "ą®®ąÆą®ØąÆą®¤ąÆą®Æ ą®¤ąÆą®£ąÆą®ąÆ ą®ą®Æą®ąÆą®ąÆ", + "mwe-embedplayer-current_clip_msg": "ą®ą®¤ąÆą®¤ąÆą®£ąÆą®ąÆ ą®ą®Æą®ąÆą®ąÆą®µą®¤ąÆą®¤ąÆ ą®¤ąÆą®ą®°ąÆ", + "mwe-embedplayer-paused": "ą®ą®ąÆą®Øą®æą®±ąÆą®¤ąÆą®¤ą®ŖąÆą®Ŗą®ąÆą®ą®¤ąÆ", + "mwe-embedplayer-download_segment": "ą®¤ąÆą®°ą®æą®µąÆą®¤ąÆ ą®¤ą®°ą®µą®æą®±ą®ąÆą®ąÆ:", + "mwe-embedplayer-download_full": "ą®®ąÆą®“ąÆą®ąÆ ą®ą®¾ą®£ąÆą®³ą®æą®ąÆ ą®ąÆą®ŖąÆą®ŖąÆą®¤ąÆ ą®¤ą®°ą®µą®æą®±ą®ąÆą®ąÆ:", + "mwe-embedplayer-download_clip": "ą®ą®¾ą®£ąÆą®³ą®æą®ÆąÆą®¤ąÆ ą®¤ą®°ą®µą®æą®±ą®ąÆą®ąÆ", + "mwe-embedplayer-download_text": "ą®ą®°ąÆą®ÆąÆą®¤ąÆ ą®¤ą®°ą®µą®æą®±ą®ąÆą®ąÆ", + "mwe-embedplayer-download": "ą®Ŗą®¤ą®æą®µą®æą®±ą®ąÆą®ą®®ąÆ ą®ąÆą®ÆąÆ", + "mwe-embedplayer-share": "ą®Ŗą®ą®æą®°ąÆ", + "mwe-embedplayer-choose_player": "ą®ą®¾ą®£ąÆą®³ą®æ ą®ą®Æą®ąÆą®ą®æą®ÆąÆą®¤ąÆ ą®¤ąÆą®°ą®æ", + "mwe-embedplayer-share_this_video": "ą®ą®ąÆ ą®ą®¾ą®£ąÆą®³ą®æą®ÆąÆą®ŖąÆ ą®Ŗą®ą®æą®°ąÆą®", + "mwe-embedplayer-menu_btn": "ą®Ŗą®ąÆą®ą®æ", + "mwe-embedplayer-close_btn": "ą®®ąÆą®ąÆ", + "mwe-embedplayer-ogg-player-vlc-player": "VLC ą®ą®ą® ą®ą®Æą®ąÆą®ą®æ", + "mwe-embedplayer-do_not_warn_again": "ą®µą®°ąÆą®ąÆą®ą®¾ą®²ą®¤ąÆą®¤ą®æą®²ąÆ ą®ą®ąÆą®ąÆą®ÆąÆą®¤ą®æą®ÆąÆą®ąÆ ą®ą®¾ą®ąÆą® ą®µąÆą®£ąÆą®ą®¾ą®®ąÆ", + "mwe-embedplayer-playerSelect": "ą®ą®Æą®ąÆą®ą®æą®ą®³ąÆ", + "mwe-embedplayer-related_videos": "ą®¤ąÆą®ą®°ąÆą®ŖąÆą®³ąÆą®³ ą®ą®¾ą®£ąÆą®³ą®æą®ą®³ąÆ", + "mwe-embedplayer-video-h264": "H.264 ą®ą®¾ą®£ąÆą®³ą®æ", + "mwe-embedplayer-video-webm": "WebM ą®ą®¾ą®£ąÆą®³ą®æ", + "mwe-embedplayer-video-flv": "ą®Ŗą®æą®³ą®¾ą®·ąÆ ą®ą®¾ą®£ąÆą®³ą®æ", + "mwe-embedplayer-video-ogg": "Ogg ą®ą®¾ą®£ąÆą®³ą®æ", + "mwe-embedplayer-video-3gp": "3GP ą®ą®¾ą®£ąÆą®³ą®æ", + "mwe-embedplayer-video-mpeg": "MPEG ą®ą®¾ą®£ąÆą®³ą®æ", + "mwe-embedplayer-video-msvideo": "AVI ą®ą®¾ą®£ąÆą®³ą®æ", + "mwe-embedplayer-missing-source": "ą®®ąÆą®²ą®ąÆ ą®ą®¾ą®£ąÆą®³ą®æą®ÆąÆą®¤ąÆą®®ąÆ ą®ą®£ąÆą®ąÆą®Ŗą®æą®ą®æą®ąÆą®ą®ŖąÆą®Ŗą®ą®µą®æą®²ąÆą®²ąÆ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/te.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/te.json new file mode 100644 index 00000000..3c69d4f7 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/te.json @@ -0,0 +1,17 @@ +{ + "@metadata": { + "authors": [ + "Veeven" + ] + }, + "mwe-embedplayer-credit-title": "ą°¶ą±ą°°ą±ą°·ą°æą°: $1", + "mwe-embedplayer-credit-date": "ą°¤ą±ą°¦ą±: $1", + "mwe-embedplayer-player_fullscreen": "ą°Øą°æą°ą°”ą±ą°¤ą±ą°°", + "mwe-embedplayer-download": "ą°¦ą°æą°ą°Ŗą±ą°ą±ą°²ą±", + "mwe-embedplayer-share": "ą°Ŗą°ą°ą±ą°ą±ą°ą°”ą°æ", + "mwe-embedplayer-share_this_video": "ą° ą°µą±ą°”ą°æą°Æą±ą°Øą°æ ą°Ŗą°ą°ą±ą°ą±ą°ą°”ą°æ", + "mwe-embedplayer-menu_btn": "ą°®ą±ą°Øą±", + "mwe-embedplayer-close_btn": "ą°®ą±ą°øą°æą°µą±ą°Æą°æ", + "mwe-embedplayer-ogg-player-selected": "(ą°ą°ą°ą±ą°ą±ą°Øą±ą°Øą°¾ą°°ą±)", + "mwe-embedplayer-related_videos": "ą°øą°ą°¬ą°ą°§ą°æą°¤ ą°¦ą±ą°¶ą±ą°Æą°ą°¾ą°²ą±" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tet.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tet.json new file mode 100644 index 00000000..3e73c4ed --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tet.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "MF-Warburg" + ] + }, + "mwe-embedplayer-credit-author": "AutĆ³r: $1" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tl.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tl.json new file mode 100644 index 00000000..78eb2b06 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tl.json @@ -0,0 +1,83 @@ +{ + "@metadata": { + "authors": [ + "AnakngAraw", + "Sky Harbor", + "Leeheonjin" + ] + }, + "mwe-embedplayer-credit-title": "Pamagat: $1", + "mwe-embedplayer-credit-date": "Petsa: $1", + "mwe-embedplayer-credit-author": "May-akda: $1", + "mwe-embedplayer-nocredits": "Walang makuhang mga pagbanggit", + "mwe-embedplayer-loading_plugin": "Ikinakarga ang pampasak ...", + "mwe-embedplayer-select_playback": "Itakda ang nais sa pagpapaandar", + "mwe-embedplayer-link_back": "Ikawing pabalik", + "mwe-embedplayer-error_swap_vid": "Kamalian: hindi nagawang pagpalitin ng mwEmbed ang tatak ng bidyo para sa hangganang-mukha ng mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "Idagdag sa huli ng sunuran", + "mwe-embedplayer-missing_video_stream": "Nawawala ang talaksan ng biyo para sa daloy na ito", + "mwe-embedplayer-play_clip": "Palaruin ang klip", + "mwe-embedplayer-pause_clip": "Pahintuin ang klip", + "mwe-embedplayer-volume_control": "Pangtaban ng lakas ng tunog", + "mwe-embedplayer-player_options": "Pagpipiliang pangpampaandar", + "mwe-embedplayer-timed_text": "Tekstong inoorasan", + "mwe-embedplayer-player_fullscreen": "Buong panooran", + "mwe-embedplayer-next_clip_msg": "Paandarin ang susunod na putol", + "mwe-embedplayer-prev_clip_msg": "Paandarin ang nakaraang putol", + "mwe-embedplayer-current_clip_msg": "Ipagpatuloy ang pagpapaandar ng putol na ito", + "mwe-embedplayer-seek_to": "Hanapin ang $1", + "mwe-embedplayer-paused": "hininto", + "mwe-embedplayer-download_segment": "Ikargang pababa ang napili:", + "mwe-embedplayer-download_full_video": "Ikargang pababa ang buong talaksan ng bidyo:", + "mwe-embedplayer-download_right_click": "Upang maikargang paibaba, pindutin ang kanan at piliin ang <i>Sagipin ang kawing bilang...</i>", + "mwe-embedplayer-download_clip": "Ikargang pababa ang bidyo", + "mwe-embedplayer-download_text": "Ikargang paibaba ang teksto", + "mwe-embedplayer-download": "Ikargang pababa", + "mwe-embedplayer-share": "Ipamahagi", + "mwe-embedplayer-credits": "Mga banggit-pagkilala", + "mwe-embedplayer-about-library": "Tungkol sa pampaandar na Kaltura", + "mwe-embedplayer-about-library-desc": "Ang aklatan ng midyang HTML5 ng Kaltura ay nagpapahintulot sa iyong samantalahin ang mga tatak na <code><nowiki><bidyo></nowiki></code> na HTML5 at <code><nowiki><audio></nowiki></code> ngayon ng isang ugnayang-mukha ng palagiang pampaandar sa kahabaan ng lahat ng pangunahing mga pantingin-tingin.\n\n[$1 Marami pang hinggil sa aklatan ng pampaandar ng Kaltura].", + "mwe-embedplayer-clip_linkback": "Pahinang batayan ng klip", + "mwe-embedplayer-choose_player": "Piliin ang pampaandar ng bidyo", + "mwe-embedplayer-no-player": "Walang makuhang pampaandar para sa $1", + "mwe-embedplayer-share_this_video": "Ipamahagi ang bidyong ito", + "mwe-embedplayer-video_credits": "Mga banggit-pagkilala ng bidyo", + "mwe-embedplayer-no-video_credits": "Walang makuhang mga pagbanggit", + "mwe-embedplayer-kaltura-platform-title": "Plataporma ng bukas na pinagmulan ng bidyo ng Kaltura", + "mwe-embedplayer-menu_btn": "Menu", + "mwe-embedplayer-close_btn": "Isara", + "mwe-embedplayer-ogg-player-vlc-player": "Pampaandar ng VLC", + "mwe-embedplayer-ogg-player-oggNative": "Pampaandar ng HTML5 Ogg", + "mwe-embedplayer-ogg-player-h264Native": "Pampaandar ng HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "Pampaandar ng HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "Panlahatang pamasak ng Ogg", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Pampasak ng QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "ActiveX ng QuickTime", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Pampaandar na Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Pampaandar ng Kaltura", + "mwe-embedplayer-ogg-player-selected": "(napili na)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Para sa mas mainam na karanasan ng pagpapaandar ng bidyo iminumungkahi namin ang <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">pantingin-tingin ng bidyo na html5</a>.", + "mwe-embedplayer-download-warn": "Walang napansin na kaugmang pampaandar ng pantingin-tingin, para sa pag-uulit ng pagpapaandar ng pantingin-tingin ikargang paibaba ang [$1 pinakahuling Firefox]", + "mwe-embedplayer-fullscreen-tip": "Pindutin ang <b>F11</b> pampalit-lipat ng <i>pantingin-tingin sa web</i> na buo ang panooran", + "mwe-embedplayer-fullscreen-tip-osx": "Pindutin ang <b>shift ā F</b> upang mapalitan at malipatan ang buong panooran", + "mwe-embedplayer-do_not_warn_again": "Sa hinaharap, huwag ipakita ang mensaheng ito", + "mwe-embedplayer-playerSelect": "Mga pampaandar", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">Basahin ito</a> bago ibaon.", + "mwe-embedplayer-embed_site_or_blog": "Ibaon sa isang pahina", + "mwe-embedplayer-related_videos": "Kaugnay na mga bidyo", + "mwe-embedplayer-seeking": "hinahanap", + "mwe-embedplayer-buffering": "pinapakinis", + "mwe-embedplayer-video-h264": "Bidyong H.264", + "mwe-embedplayer-video-webm": "Bidyong WebM", + "mwe-embedplayer-video-flv": "Bidyong Flash", + "mwe-embedplayer-video-ogg": "Bidyong Ogg", + "mwe-embedplayer-video-audio": "Tunog na Ogg", + "mwe-embedplayer-audio-mpeg": "Tunog na MPEG", + "mwe-embedplayer-video-3gp": "Bidyong 3GP", + "mwe-embedplayer-video-mpeg": "Bidyong MPEG", + "mwe-embedplayer-video-msvideo": "Bidyong AVI", + "mwe-embedplayer-missing-source": "Walang natagpuang batayang bidyo", + "mwe-embedplayer-iewebmprompt-intro": "Ui! Isa pang bagay bago mo i-play itong video..." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tr.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tr.json new file mode 100644 index 00000000..e76ebff4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tr.json @@ -0,0 +1,85 @@ +{ + "@metadata": { + "authors": [ + "Emperyan", + "Sayginer" + ] + }, + "mwe-embedplayer-credit-title": "BaÅlık: $1", + "mwe-embedplayer-credit-date": "Tarih: $1", + "mwe-embedplayer-credit-author": "Yazar: $1", + "mwe-embedplayer-loading_plugin": "Eklenti yĆ¼kleniyor ...", + "mwe-embedplayer-select_playback": "Tekrar oynatma tercihini ayarla", + "mwe-embedplayer-link_back": "Geri baÄlantı ver", + "mwe-embedplayer-error_swap_vid": "Hata: mwEmbed, mwEmbed arayĆ¼zĆ¼ iƧin video etiketini deÄiÅ tokuÅ yapamıyor", + "mwe-embedplayer-add_to_end_of_sequence": "Sıranın sonuna ekle", + "mwe-embedplayer-missing_video_stream": "Bu akıŠiƧin video dosyası kayıp", + "mwe-embedplayer-play_clip": "Klibi oynat", + "mwe-embedplayer-pause_clip": "Klibi durdur", + "mwe-embedplayer-volume_control": "Ses denetimi", + "mwe-embedplayer-player_options": "Oynatıcı seƧenekleri", + "mwe-embedplayer-timed_text": "ZamanlanmıŠmetin", + "mwe-embedplayer-player_fullscreen": "Tam ekran", + "mwe-embedplayer-next_clip_msg": "Sonraki klibi oynat", + "mwe-embedplayer-prev_clip_msg": "Ćnceki klibi oynat", + "mwe-embedplayer-current_clip_msg": "Bu klibi oynatmaya devam et", + "mwe-embedplayer-seek_to": "$1 sĆ¼resine git", + "mwe-embedplayer-paused": "durduruldu", + "mwe-embedplayer-download_segment": "SeƧimi indir:", + "mwe-embedplayer-download_full_video": "Tam video dosyasını indir:", + "mwe-embedplayer-download_full_audio": "Ses dosyasının tamamını indir:", + "mwe-embedplayer-download_right_click": "Ä°ndirmek iƧin, saÄ tıklayın ve <i>BaÄlantıyı farklı kaydet...</i>'i seƧin", + "mwe-embedplayer-download_clip": "Videoyu indir", + "mwe-embedplayer-download_text": "Metni indir", + "mwe-embedplayer-download": "Ä°ndir", + "mwe-embedplayer-share": "PaylaÅ", + "mwe-embedplayer-credits": "Katkıda bulunanlar", + "mwe-embedplayer-about-library": "Kaltura oynatıcısı hakkında", + "mwe-embedplayer-clip_linkback": "Klip kaynak sayfası", + "mwe-embedplayer-choose_player": "Video oynatıcı seƧ", + "mwe-embedplayer-no-player": "$1 iƧin oynatıcı mevcut deÄil", + "mwe-embedplayer-share_this_video": "Bu videoyu paylaÅ", + "mwe-embedplayer-share_this_audio": "Bu ses dosyasını paylaÅ", + "mwe-embedplayer-video_credits": "Videoya katkıda bulunanlar", + "mwe-embedplayer-kaltura-platform-title": "Kaltura aƧık kaynak kodlu video platformu", + "mwe-embedplayer-menu_btn": "MenĆ¼", + "mwe-embedplayer-close_btn": "Kapat", + "mwe-embedplayer-ogg-player-vlc-player": "VLC player", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg oynatıcı", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3 oynatıcı", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC oynatıcı", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 oynatıcı", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebM oynatıcı", + "mwe-embedplayer-ogg-player-oggPlugin": "Jenerik Ogg eklentisi", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime eklentisi", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kaltura oynatıcısı", + "mwe-embedplayer-ogg-player-selected": "(seƧili)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "Daha iyi bir video oynatma deneyimi iƧin ƶnerimiz:<br /><a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">Firefox 3.5</a>.", + "mwe-embedplayer-do_not_warn_again": "Gelecekte bu iletiyi gƶsterme", + "mwe-embedplayer-playerSelect": "Oynatıcılar", + "mwe-embedplayer-read_before_embed": "LĆ¼tfen gerƧekten gƶmmeden <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">uzaktan gƶmme hakkındaki gĆ¼venlik notlarını</a> okuyun!", + "mwe-embedplayer-embed_site_or_blog": "Bir sayfaya gƶmĆ¼n", + "mwe-embedplayer-embed_wiki": "Bir viki Ć¼zerinde gƶm", + "mwe-embedplayer-related_videos": "Ä°lgili videolar", + "mwe-embedplayer-seeking": "aranıyor", + "mwe-embedplayer-buffering": "ara belleÄe alınıyor", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-webm": "WebM video", + "mwe-embedplayer-video-flv": "Flash, video", + "mwe-embedplayer-video-ogg": "Ogg video", + "mwe-embedplayer-video-audio": "Ogg ses", + "mwe-embedplayer-audio-mpeg": "MPEG ses", + "mwe-embedplayer-video-3gp": "3GP video", + "mwe-embedplayer-video-mpeg": "MPEG video", + "mwe-embedplayer-video-msvideo": "AVI video", + "mwe-embedplayer-missing-source": "Video kaynaÄı bulunamadı", + "mwe-embedplayer-vlcapp-vlcapplinktext": "VLC uygulaması", + "mwe-embedplayer-vlcapp-downloadapp": "VLC uygulamasını App Store'dan indir", + "mwe-embedplayer-vlcapp-openvideo": "Bu videoyu VLC uygulamasıyla aƧ", + "mwe-embedplayer-vlcapp-downloadvideo": "Bu videoyu indir", + "mwe-embedplayer-vlcapp-vlcapppopup": "Bu sitedeki videoları oynatmak iƧin, Ć¼cretsiz olan VLC uygulaması gerekiyor. Åimdi yĆ¼klensin mi?" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tzm.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tzm.json new file mode 100644 index 00000000..8a49fbb4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/tzm.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Tifinaghes" + ] + }, + "mwe-embedplayer-share": "ā“¼āµā“»āµ", + "mwe-embedplayer-video-h264": "H.264 video", + "mwe-embedplayer-video-flv": "ā“¼āµā“°āµ video", + "mwe-embedplayer-video-ogg": "Ogg video" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/uk.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/uk.json new file mode 100644 index 00000000..5089e774 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/uk.json @@ -0,0 +1,92 @@ +{ + "@metadata": { + "authors": [ + "Andriykopanytsia", + "Base", + "ŠŃŠ°", + "Š¢ŠµŃŃ" + ] + }, + "mwe-embedplayer-credit-title": "ŠŠ°Š·Š²Š°: $1", + "mwe-embedplayer-credit-date": "ŠŠ°ŃŠ°: $1", + "mwe-embedplayer-credit-author": "ŠŠ²ŃŠ¾Ń: $1", + "mwe-embedplayer-nocredits": "ŠŠµŠ¼Š° Š²ŃŠ“Š¾Š¼Š¾ŃŃŠµŠ¹ ŠæŃŠ¾ Š°Š²ŃŠ¾ŃŠ°", + "mwe-embedplayer-loading_plugin": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠµŠ½Š½Ń Š“Š¾Š“Š°ŃŠŗŠ° ...", + "mwe-embedplayer-select_playback": "ŠŃŃŠ°Š½Š¾Š²ŠøŃŠø Š½Š°Š»Š°ŃŃŃŠ²Š°Š½Š½Ń Š²ŃŠ“ŃŠ²Š¾ŃŠµŠ½Š½Ń", + "mwe-embedplayer-link_back": "ŠŠ²Š¾ŃŠ¾ŃŠ½Ń ŠæŠ¾ŃŠøŠ»Š°Š½Š½Ń", + "mwe-embedplayer-error_swap_vid": "ŠŠ¾Š¼ŠøŠ»ŠŗŠ°: mwEmbed Š½Šµ Š²Š“Š°Š»Š¾ŃŃ Š·Š°Š¼ŃŠ½ŠøŃŠø ŃŠµŠ³ Š²ŃŠ“ŠµŠ¾ Š“Š»Ń ŃŠ½ŃŠµŃŃŠµŠ¹ŃŃ mwEmbed", + "mwe-embedplayer-add_to_end_of_sequence": "ŠŠ¾Š“Š°ŃŠø Ń ŠŗŃŠ½ŠµŃŃ ŠæŠ¾ŃŠ»ŃŠ“Š¾Š²Š½Š¾ŃŃŃ", + "mwe-embedplayer-missing_video_stream": "ŠŃŠ“ŠµŠ¾ŃŠ°Š¹Š» Š“Š»Ń ŃŃŠ¾Š³Š¾ ŠæŠ¾ŃŠ¾ŠŗŃ Š²ŃŠ“ŃŃŃŠ½ŃŠ¹", + "mwe-embedplayer-play_clip": "ŠŃŠ“ŃŠ²Š¾ŃŠøŃŠø ŠŗŠ»ŃŠæ", + "mwe-embedplayer-pause_clip": "ŠŃŠøŠ·ŃŠæŠøŠ½ŠøŃŠø ŠŗŠ»ŃŠæ", + "mwe-embedplayer-volume_control": "Š ŠµŠ³ŃŠ»ŃŠ²Š°Š½Š½Ń Š³ŃŃŠ½Š¾ŃŃŃ", + "mwe-embedplayer-player_options": "ŠŠ°Š»Š°ŃŃŃŠ²Š°Š½Š½Ń ŠæŃŠ¾Š³ŃŠ°Š²Š°ŃŠ°", + "mwe-embedplayer-timed_text": "Š”ŃŠ±ŃŠøŃŃŠø", + "mwe-embedplayer-player_fullscreen": "ŠŠ° Š²ŠµŃŃ ŠµŠŗŃŠ°Š½", + "mwe-embedplayer-next_clip_msg": "ŠŃŠ“ŃŠ²Š¾ŃŠøŃŠø Š½Š°ŃŃŃŠæŠ½ŠøŠ¹ ŠŗŠ»ŃŠæ", + "mwe-embedplayer-prev_clip_msg": "ŠŃŠ“ŃŠ²Š¾ŃŠøŃŠø ŠæŠ¾ŠæŠµŃŠµŠ“Š½ŃŠ¹ ŠŗŠ»ŃŠæ", + "mwe-embedplayer-current_clip_msg": "ŠŃŠ¾Š“Š¾Š²Š¶ŠøŃŠø Š²ŃŠ“ŃŠ²Š¾ŃŠµŠ½Š½Ń ŃŃŠ¾Š³Š¾ ŠŗŠ»ŃŠæŃ", + "mwe-embedplayer-seek_to": "ŠŠµŃŠµŠ¹ŃŠø Š“Š¾ $1", + "mwe-embedplayer-paused": "ŠæŠ°ŃŠ·Š°", + "mwe-embedplayer-download_segment": "ŠŠøŠ±ŃŃ Š·Š°Š²Š°Š½ŃŠ°Š¶ŠµŠ½Š½Ń:", + "mwe-embedplayer-download_full": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø Š²ŠµŃŃ Š²ŃŠ“ŠµŠ¾-ŃŠ°Š¹Š»:", + "mwe-embedplayer-download_right_click": "ŠŠ»Ń Š·Š°Š²Š°Š½ŃŠ°Š¶ŠµŠ½Š½Ń, Š½Š°ŃŠøŃŠ½ŃŃŃ ŠæŃŠ°Š²Ń ŠŗŠ½Š¾ŠæŠŗŃ Š¼ŠøŃŃ Ń Š¾Š±ŠµŃŃŃŃ Ā«ŠŠ±ŠµŃŠµŠ³ŃŠø Š¾Š±'ŃŠŗŃ ŃŠŗā¦Ā»", + "mwe-embedplayer-download_clip": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-download_text": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø ŃŠµŠŗŃŃ", + "mwe-embedplayer-download": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø", + "mwe-embedplayer-share": "ŠŠ¾Š“ŃŠ»ŠøŃŠøŃŃ", + "mwe-embedplayer-credits": "Š”ŃŠ²Š¾ŃŃŠ²Š°ŃŃ", + "mwe-embedplayer-about-library": "ŠŃŠ¾ ŠæŃŠ¾Š³ŃŠ°Š²Š°Ń Kaltura", + "mwe-embedplayer-about-library-desc": "HTML5 Š¼ŠµŠ“ŃŠ°-Š±ŃŠ±Š»ŃŠ¾ŃŠµŠŗŠ° Kaltura Š“Š¾Š·Š²Š¾Š»ŃŃ ŠŠ°Š¼ ŠŗŠ¾ŃŠøŃŃŃŠ²Š°ŃŠøŃŃ HTML5 ŃŠµŠ³Š°Š¼Šø <Š²ŃŠ“ŠµŠ¾> ŃŠ° <Š°ŃŠ“ŃŠ¾> Š²Š¶Šµ ŃŃŠ¾Š³Š¾Š“Š½Ń Š·Ń ŃŃŠ°Š½Š“Š°ŃŃŠ½ŠøŠ¼ ŃŠ½ŃŠµŃŃŠµŠ¹ŃŠ¾Š¼ Š²ŃŠ“ŃŠ²Š¾ŃŠµŠ½Š½Ń Ń ŃŃŠ·Š½ŠøŃ
Š±ŃŠ°ŃŠ·ŠµŃŠ°Ń
.\n\n[$1 ŠŃŠ»ŃŃŠµ ŠæŃŠ¾ Š±ŃŠ±Š»ŃŠ¾ŃŠµŠŗŃ ŠæŃŠ¾Š³ŃŠ°Š²Š°ŃŠ° Kaltura].", + "mwe-embedplayer-clip_linkback": "ŠŠøŃ
ŃŠ“Š½Š° ŃŃŠ¾ŃŃŠ½ŠŗŠ° ŠŗŠ»ŃŠæŃ", + "mwe-embedplayer-choose_player": "ŠŠøŠ±ŠµŃŃŃŃ Š²ŃŠ“ŠµŠ¾ ŠæŠ»ŠµŃŃ", + "mwe-embedplayer-no-player": "ŠŠµŠ¼Š° ŠæŃŠ¾Š³ŃŠ°Š²Š°ŃŠ° Š“Š»Ń $1", + "mwe-embedplayer-share_this_video": "ŠŠ¾Š“ŃŠ»ŠøŃŠøŃŃ ŃŠøŠ¼ Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-video_credits": "ŠŃŠ¾ ŃŃŠ²Š¾ŃŃŠ²Š°ŃŃŠ² Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-no-video_credits": "ŠŠµŠ¼Š° Š²ŃŠ“Š¾Š¼Š¾ŃŃŠµŠ¹ ŠæŃŠ¾ Š°Š²ŃŠ¾ŃŠ°", + "mwe-embedplayer-kaltura-platform-title": "ŠŃŠ“ŠµŠ¾-ŠæŠ»Š°ŃŃŠ¾ŃŠ¼Š° Š· Š²ŃŠ“ŠŗŃŠøŃŠøŠ¼ ŠŗŠ¾Š“Š¾Š¼ Kaltura", + "mwe-embedplayer-menu_btn": "ŠŠµŠ½Ń", + "mwe-embedplayer-close_btn": "ŠŠ°ŠŗŃŠøŃŠø", + "mwe-embedplayer-ogg-player-vlc-player": "VLC ŠæŃŠ¾Š³ŃŠ°Š²Š°Ń", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Ogg ŠæŃŠ¾Š³ŃŠ°Š²Š°Ń", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3-ŠæŃŠ¾Š³ŃŠ°Š²Š°Ń", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC-ŠæŃŠ¾Š³ŃŠ°Š²Š°Ń", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264 ŠæŃŠ¾Š³ŃŠ°Š²Š°Ń", + "mwe-embedplayer-ogg-player-webmNative": "ŠŃŠ¾Š³ŃŠ°Š²Š°Ń HTML5 WebM", + "mwe-embedplayer-ogg-player-oggPlugin": "ŠŠ°Š³Š°Š»ŃŠ½ŠøŠ¹ ŠæŠ»Š°ŅŃŠ½ Ogg", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "ŠŃŠ¾Š³ŃŠ°Š¼Š° VLC Š“Š»Ń iOS", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "ŠŠ¾Š“Š°ŃŠ¾Šŗ QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "ŠŃŠ¾Š³ŃŠ°Š²Š°Ń Kaltura", + "mwe-embedplayer-ogg-player-selected": "(Š¾Š±ŃŠ°Š½Š¾)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "ŠŠ»Ń ŠŗŃŠ°ŃŠ¾Š³Š¾ Š²ŃŠ“ŃŠ²Š¾ŃŠµŠ½Š½Ń Š²ŃŠ“ŠµŠ¾ ŃŠµŠŗŠ¾Š¼ŠµŠ½Š“ŃŃŠ¼Š¾ <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">html5 Š²ŃŠ“ŠµŠ¾ Š±ŃŠ°ŃŠ·ŠµŃ</a>.", + "mwe-embedplayer-download-warn": "ŠŠµ Š·Š½Š°Š¹Š“ŠµŠ½Š¾ Š²Š±ŃŠ“Š¾Š²Š°Š½Š¾Š³Š¾ ŠæŃŠ¾Š³ŃŠ°Š²Š°ŃŠ° Š“Š»Ń Š±ŃŠ°ŃŠ·ŠµŃŠ°, Š“Š»Ń Š²ŃŠ“ŃŠ²Š¾ŃŠµŠ½Š½Ń Š² Š±ŃŠ°ŃŠ·ŠµŃŃ Š·Š°Š²Š°Š½ŃŠ°Š¶ŃŠµ, Š±ŃŠ“Ń Š»Š°ŃŠŗŠ°, [$1 Š¾ŃŃŠ°Š½Š½ŃŠ¹ Firefox]", + "mwe-embedplayer-fullscreen-tip": "ŠŠ°ŃŠøŃŠ½ŃŃŃ ŠŗŠ½Š¾ŠæŠŗŃ <b>F11</b> Š“Š»Ń ŠæŠµŃŠµŠ¼ŠøŠŗŠ°Š½Š½Ń <i>Š²ŠµŠ±-Š±ŃŠ°ŃŠ·ŠµŃŃ</i> Ń ŠæŠ¾Š²Š½Š¾ŠµŠŗŃŠ°Š½Š½ŠøŠ¹ ŃŠµŠ¶ŠøŠ¼", + "mwe-embedplayer-fullscreen-tip-osx": "ŠŠ°ŃŠøŃŠ½ŃŃŃ ŠŗŠ½Š¾ŠæŠŗŃ <b>shift ā F</b> Š“Š»Ń ŠæŠµŃŠµŃ
Š¾Š“Ń Ń ŠæŠ¾Š²Š½Š¾ŠµŠŗŃŠ°Š½Š½ŠøŠ¹ ŃŠµŠ¶ŠøŠ¼", + "mwe-embedplayer-do_not_warn_again": "ŠŠµ ŠæŠ¾ŠŗŠ°Š·ŃŠ²Š°ŃŠø ŃŠµ ŠæŠ¾Š²ŃŠ“Š¾Š¼Š»ŠµŠ½Š½Ń Ń Š¼Š°Š¹Š±ŃŃŠ½ŃŠ¾Š¼Ń", + "mwe-embedplayer-playerSelect": "ŠŃŠ¾Š³ŃŠ°Š²Š°ŃŃ", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">ŠŃŠ¾ŃŠøŃŠ°Š¹ŃŠµ ŃŠµ</a> ŠæŠµŃŠµŠ“ Š²ŠŗŠ»ŃŃŠµŠ½Š½ŃŠ¼.", + "mwe-embedplayer-embed_site_or_blog": "ŠŠŗŠ»ŃŃŠøŃŠø Š½Š° ŃŃŠ¾ŃŃŠ½ŠŗŃ", + "mwe-embedplayer-embed_wiki": "ŠŠ±ŃŠ“Š¾Š²Š°Š½ŠøŠ¹ Ń Š²ŃŠŗŃ", + "mwe-embedplayer-related_videos": "ŠŠ¾Š²'ŃŠ·Š°Š½Ń Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-seeking": "ŠæŠ¾ŃŃŠŗ", + "mwe-embedplayer-buffering": "Š±ŃŃŠµŃŠøŠ·Š°ŃŃŃ", + "mwe-embedplayer-video-h264": "H.264 Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-video-webm": "ŠŃŠ“ŠµŠ¾ WebM", + "mwe-embedplayer-video-flv": "Š¤Š»ŠµŃ Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-video-ogg": "Ogg Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-video-audio": "Ogg Š°ŃŠ“ŃŠ¾", + "mwe-embedplayer-audio-mpeg": "MPEG-Š°ŃŠ“ŃŠ¾", + "mwe-embedplayer-video-3gp": "3GP-Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-video-mpeg": "MPEG-Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-video-msvideo": "AVI-Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-missing-source": "ŠŠµ Š·Š½Š°Š¹Š“ŠµŠ½Š¾ Š“Š¶ŠµŃŠµŠ»Š¾ Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-vlcapp-intro": "ŠŠ»Ń ŠæŠµŃŠµŠ³Š»ŃŠ“Ń Š²ŃŠ“ŠµŠ¾ Š· ŃŃŠ¾Š³Š¾ ŃŠ°Š¹ŃŃ Š½Š° iPhone Š°Š±Š¾ iPad Š²Š°Š¼ ŠæŠ¾ŃŃŃŠ±Š½Š° Š±ŠµŠ·ŠŗŠ¾ŃŃŠ¾Š²Š½Š° ŠæŃŠ¾Š³ŃŠ°Š¼Š° $1.", + "mwe-embedplayer-vlcapp-vlcapplinktext": "ŠŃŠ¾Š³ŃŠ°Š¼Š° VLC", + "mwe-embedplayer-vlcapp-downloadapp": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø ŠæŃŠ¾Š³ŃŠ°Š¼Ń VLC ŃŠ· App Store", + "mwe-embedplayer-vlcapp-openvideo": "ŠŃŠ“ŠŗŃŠøŃŠø ŃŠµ Š²ŃŠ“ŠµŠ¾ Ń ŠæŃŠ¾Š³ŃŠ°Š¼Ń VLC", + "mwe-embedplayer-vlcapp-downloadvideo": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø ŃŠµ Š²ŃŠ“ŠµŠ¾", + "mwe-embedplayer-vlcapp-vlcapppopup": "ŠŠ»Ń Š²ŃŠ“ŃŠ²Š¾ŃŠµŠ½Š½Ń Š²ŃŠ“ŠµŠ¾ Š½Š° ŃŃŠ¾Š¼Ń ŃŠ°Š¹ŃŃ ŠæŠ¾ŃŃŃŠ±Š½Š° Š±ŠµŠ·ŠŗŠ¾ŃŃŠ¾Š²Š½Š° ŠæŃŠ¾Š³ŃŠ°Š¼Š° VLC. ŠŃŃŠ°Š½Š¾Š²ŠøŃŠø Š·Š°ŃŠ°Š·?" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ur.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ur.json new file mode 100644 index 00000000..2136b2ba --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/ur.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "mwe-embedplayer-download": "ŚŲ§Ų¤Ł ŁŁŚ Ų Ų§ŲŖŲ§Ų±ŁŲ§", + "mwe-embedplayer-share": "ŲŲµŪ", + "mwe-embedplayer-credits": "Ś©Ų±ŪŚŁ¹", + "mwe-embedplayer-menu_btn": "Ł
ŪŁŁ", + "mwe-embedplayer-close_btn": "ŲØŁŲÆ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vec.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vec.json new file mode 100644 index 00000000..6c166455 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vec.json @@ -0,0 +1,38 @@ +{ + "@metadata": [], + "mwe-embedplayer-credit-title": "Titolo: $1", + "mwe-embedplayer-loading_plugin": "so' drio cargar el plugin...", + "mwe-embedplayer-link_back": "ColĆØga indrƬo", + "mwe-embedplayer-add_to_end_of_sequence": "Taca in fondo a la sequensa", + "mwe-embedplayer-play_clip": "Riprodusi", + "mwe-embedplayer-pause_clip": "Meti in pausa", + "mwe-embedplayer-volume_control": "Controlo volume", + "mwe-embedplayer-player_fullscreen": "Schermo intiero", + "mwe-embedplayer-seek_to": "Serca $1", + "mwe-embedplayer-paused": "en pausa", + "mwe-embedplayer-download_segment": "Descarga la selession:", + "mwe-embedplayer-download_full": "Descarga tuto el file video:", + "mwe-embedplayer-download_right_click": "Par descargar, struca el boton destro e selessiona <i>Salva colegamento come...</i>", + "mwe-embedplayer-download_clip": "Descarga el video", + "mwe-embedplayer-download": "Descarga", + "mwe-embedplayer-share": "Spartissi", + "mwe-embedplayer-credits": "Riconossimenti", + "mwe-embedplayer-choose_player": "Siegli el letor multimedial", + "mwe-embedplayer-share_this_video": "Condividi sto video", + "mwe-embedplayer-video_credits": "Riconossimenti del video", + "mwe-embedplayer-menu_btn": "MenĆ¹", + "mwe-embedplayer-close_btn": "Sara", + "mwe-embedplayer-ogg-player-vlc-player": "Letor VLC", + "mwe-embedplayer-ogg-player-oggPlugin": "Plugin Ogg generico", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Plugin QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Letor Kaltura", + "mwe-embedplayer-ogg-player-selected": "(selessionĆ )", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-read_before_embed": "<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">LĆØzi qua</a> prima de 'ndar vanti.", + "mwe-embedplayer-embed_site_or_blog": "Inserissi drento na pagina", + "mwe-embedplayer-related_videos": "Video ligĆ a sto qua", + "mwe-embedplayer-seeking": "so' drio sercar" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vep.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vep.json new file mode 100644 index 00000000..c90787dd --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vep.json @@ -0,0 +1,12 @@ +{ + "@metadata": [], + "mwe-embedplayer-link_back": "Kosketuz tagaze", + "mwe-embedplayer-play_clip": "VƤta klip", + "mwe-embedplayer-credits": "Tegijad", + "mwe-embedplayer-menu_btn": "MenĆ¼", + "mwe-embedplayer-close_btn": "Saubata", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTime-plagin", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-selected": "(valitud)" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vi.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vi.json new file mode 100644 index 00000000..a88dd46d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/vi.json @@ -0,0 +1,77 @@ +{ + "@metadata": { + "authors": [ + "Minh Nguyen" + ] + }, + "mwe-embedplayer-credit-title": "Tį»±a: $1", + "mwe-embedplayer-credit-date": "NgĆ y: $1", + "mwe-embedplayer-credit-author": "TĆ”c giįŗ£: $1", + "mwe-embedplayer-nocredits": "KhĆ“ng cĆ³ sįŗµn lį»i ghi cĆ“ng", + "mwe-embedplayer-loading_plugin": "Äang tįŗ£i phįŗ§n bį» trį»£ ā¦", + "mwe-embedplayer-select_playback": "Cįŗ„u hƬnh phĆ”t lįŗ”i", + "mwe-embedplayer-missing_video_stream": "Tįŗp tin video cį»§a luį»ng nĆ y bį» mįŗ„t", + "mwe-embedplayer-play_clip": "ChĘ”i clip", + "mwe-embedplayer-pause_clip": "Tįŗ”m ngį»«ng clip", + "mwe-embedplayer-volume_control": "Äiį»u khiį»n Ć¢m lĘ°į»£ng", + "mwe-embedplayer-player_options": "TĆ¹y chį»n trƬnh chĘ”i", + "mwe-embedplayer-timed_text": "VÄn bįŗ£n Äį»ng bį»", + "mwe-embedplayer-player_fullscreen": "ToĆ n mĆ n hƬnh", + "mwe-embedplayer-next_clip_msg": "ChĘ”i clip sau", + "mwe-embedplayer-prev_clip_msg": "ChĘ”i clip trĘ°į»c", + "mwe-embedplayer-current_clip_msg": "ChĘ”i clip nĆ y tiįŗæp", + "mwe-embedplayer-seek_to": "Nhįŗ£y tį»i $1", + "mwe-embedplayer-paused": "Äang tįŗ”m ngį»«ng", + "mwe-embedplayer-download_segment": "Tįŗ£i vį» lį»±a chį»n:", + "mwe-embedplayer-download_full": "Tįŗ£i vį» cįŗ£ tįŗp tin video:", + "mwe-embedplayer-download_right_click": "Äį» tįŗ£i vį», hĆ£y nhįŗ„n chuį»t phįŗ£i vĆ chį»n <i>LĘ°u LiĆŖn Kįŗæt dĘ°į»i dįŗ”ngā¦</i> (<i>Save Link Asā¦</i>)", + "mwe-embedplayer-download_clip": "Tįŗ£i vį» video", + "mwe-embedplayer-download_text": "Tįŗ£i vį» vÄn bįŗ£n", + "mwe-embedplayer-download": "Tįŗ£i vį»", + "mwe-embedplayer-share": "Chia sįŗ»", + "mwe-embedplayer-credits": "Ghi cĆ“ng", + "mwe-embedplayer-about-library": "Giį»i thiį»u trƬnh chĘ”i Kaltura", + "mwe-embedplayer-clip_linkback": "Trang nguį»n clip", + "mwe-embedplayer-choose_player": "Chį»n trƬnh chĘ”i video", + "mwe-embedplayer-no-player": "KhĆ“ng cĆ³ sįŗµn trƬnh chĘ”i cho $1", + "mwe-embedplayer-share_this_video": "Chia sįŗ» video nĆ y", + "mwe-embedplayer-video_credits": "Ghi cĆ“ng vį» video", + "mwe-embedplayer-no-video_credits": "KhĆ“ng cĆ³ sįŗµn lį»i ghi cĆ“ng", + "mwe-embedplayer-kaltura-platform-title": "Nį»n tįŗ£ng video nguį»n mį» Kaltura", + "mwe-embedplayer-menu_btn": "TrƬnh ÄĘ”n", + "mwe-embedplayer-close_btn": "ÄĆ³ng", + "mwe-embedplayer-ogg-player-vlc-player": "TrƬnh chĘ”i VLC", + "mwe-embedplayer-ogg-player-oggNative": "TrƬnh chĘ”i Ogg HTML5", + "mwe-embedplayer-ogg-player-mp3Native": "TrƬnh chĘ”i MP3 HTML5", + "mwe-embedplayer-ogg-player-aacNative": "TrƬnh chĘ”i AAC HTML5", + "mwe-embedplayer-ogg-player-h264Native": "TrƬnh chĘ”i HTML5 H.264", + "mwe-embedplayer-ogg-player-webmNative": "TrƬnh chĘ”i WebM HTML5", + "mwe-embedplayer-ogg-player-oggPlugin": "Phįŗ§n bį» trį»£ Ogg thĘ°į»ng", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "Phįŗ§n bį» trį»£ QuickTime", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-cortado": "Java Cortado", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "TrƬnh chĘ”i Kaltura", + "mwe-embedplayer-ogg-player-selected": "(ÄĘ°į»£c chį»n)", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-fullscreen-tip": "Bįŗ„m <b>F11</b> Äį» bįŗt/tįŗÆt chįŗæ Äį» toĆ n mĆ n hƬnh <i>cį»§a trƬnh duyį»t</i>", + "mwe-embedplayer-fullscreen-tip-osx": "Bįŗ„m tį» hį»£p <b>ā§āF</b> Äį» bįŗt/tįŗÆt chįŗæ Äį» toĆ n mĆ n hƬnh", + "mwe-embedplayer-do_not_warn_again": "Tį»« nay khĆ“ng hiį»n thį» thĆ“ng bĆ”o nĆ y", + "mwe-embedplayer-playerSelect": "TrƬnh chĘ”i", + "mwe-embedplayer-read_before_embed": "HĆ£y <a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding?uselang=vi\" target=\"new\">Äį»c cįŗ£nh bĆ”o</a> trĘ°į»c khi nhĆŗng.", + "mwe-embedplayer-embed_site_or_blog": "NhĆŗng vĆ o trang", + "mwe-embedplayer-embed_wiki": "NhĆŗng vĆ o trang wiki", + "mwe-embedplayer-related_videos": "Video liĆŖn quan", + "mwe-embedplayer-seeking": "Äang nhįŗ£y", + "mwe-embedplayer-buffering": "Äang Äį»m", + "mwe-embedplayer-video-h264": "Video H.264", + "mwe-embedplayer-video-webm": "Video WebM", + "mwe-embedplayer-video-flv": "Video Flash", + "mwe-embedplayer-video-ogg": "Video Ogg", + "mwe-embedplayer-video-audio": "Ćm thanh Ogg", + "mwe-embedplayer-audio-mpeg": "Ćm thanh MPEG", + "mwe-embedplayer-video-3gp": "Video 3GP", + "mwe-embedplayer-video-mpeg": "Video MPEG", + "mwe-embedplayer-video-msvideo": "Video AVI", + "mwe-embedplayer-missing-source": "KhĆ“ng tƬm thįŗ„y video gį»c" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/yi.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/yi.json new file mode 100644 index 00000000..ce1af5d6 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/yi.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "פ××××שע×Ø", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "mwe-embedplayer-credit-date": "××Ö·××¢: $1", + "mwe-embedplayer-close_btn": "ש×××”×" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/zh-hans.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/zh-hans.json new file mode 100644 index 00000000..debfbc6e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/zh-hans.json @@ -0,0 +1,102 @@ +{ + "@metadata": { + "authors": [ + "Hydra", + "Shizhao", + "Xiaomingyan", + "Yfdyh000", + "ä¹ęč·Øę°Ŗ", + "NigelSoft", + "Liuxinyu970226", + "Duolaimi" + ] + }, + "mwe-embedplayer-credit-title": "ę é¢ļ¼$1", + "mwe-embedplayer-credit-date": "ę„ęļ¼$1", + "mwe-embedplayer-credit-author": "ä½č
ļ¼$1", + "mwe-embedplayer-nocredits": "ę²”ęå¶ä½äŗŗååå", + "mwe-embedplayer-loading_plugin": "ę£åØč½½å
„ę件...", + "mwe-embedplayer-select_playback": "č®¾ē½®ęę¾å儽", + "mwe-embedplayer-link_back": "é¾ę„å", + "mwe-embedplayer-error_swap_vid": "åŗéļ¼mwEmbedę ę³å°č§é¢ę ē¾č½¬ę¢äøŗmwEmbedēé¢", + "mwe-embedplayer-add_to_end_of_sequence": "ę·»å č³éåę«å°¾", + "mwe-embedplayer-missing_video_stream": "čÆ„č§é¢ęµēč§é¢ę件äø¢å¤±", + "mwe-embedplayer-play_clip": "ęę¾ēꮵ", + "mwe-embedplayer-pause_clip": "ęåēꮵ", + "mwe-embedplayer-volume_control": "č°ę“é³é", + "mwe-embedplayer-player_options": "ęę¾åØé锹", + "mwe-embedplayer-timed_text": "åå¹", + "mwe-embedplayer-player_fullscreen": "å
Øå±", + "mwe-embedplayer-next_clip_msg": "ęę¾äøäøēꮵ", + "mwe-embedplayer-prev_clip_msg": "ęę¾äøäøēꮵ", + "mwe-embedplayer-current_clip_msg": "ē»§ē»ęę¾ę¬ēꮵ", + "mwe-embedplayer-seek_to": "åÆ»ę¾$1", + "mwe-embedplayer-paused": "å·²ęå", + "mwe-embedplayer-download_segment": "äøč½½čéēꮵļ¼", + "mwe-embedplayer-download_full_video": "äøč½½å®ę“č§é¢ę件ļ¼", + "mwe-embedplayer-download_full_audio": "äøč½½å®ę“é³é¢ę件ļ¼", + "mwe-embedplayer-download_right_click": "äøč½½čÆ·åå»é¼ ę å³é®å¹¶éę©āé¾ę„å¦åäøŗ...ā", + "mwe-embedplayer-download_clip": "äøč½½č§é¢", + "mwe-embedplayer-download_text": "äøč½½åå¹", + "mwe-embedplayer-download": "äøč½½", + "mwe-embedplayer-share": "åäŗ«", + "mwe-embedplayer-credits": "å¶ä½äŗŗå", + "mwe-embedplayer-about-library": "å
³äŗKalturaęę¾åØ", + "mwe-embedplayer-about-library-desc": "KalturaēHTML5åŖä½åŗåÆä»„č®©ä½ åØęęēäø»ęµęµč§åØä½æēØäøč“ēęę¾åØēé¢äŗ«åHTML5<video>å<audio>ę ē¾ēä¾æå©ć\n\n[$1 ę“å¤å
³äŗKalturaęę¾åØåŗēäæ”ęÆ]ć", + "mwe-embedplayer-clip_linkback": "ēꮵęŗ锵é¢", + "mwe-embedplayer-choose_player": "éę©č§é¢ęę¾åØ", + "mwe-embedplayer-no-player": "ę²”ęéēØäŗ$1ēęę¾åØ", + "mwe-embedplayer-share_this_video": "åäŗ«čÆ„č§é¢", + "mwe-embedplayer-share_this_audio": "åäŗ«čæäøŖé³é¢ę件", + "mwe-embedplayer-video_credits": "č§é¢å¶ä½äŗŗå", + "mwe-embedplayer-no-video_credits": "ę²”ęå¶ä½äŗŗååå", + "mwe-embedplayer-kaltura-platform-title": "Kalturaå¼ęŗč§é¢å¹³å°", + "mwe-embedplayer-menu_btn": "čå", + "mwe-embedplayer-close_btn": "å
³é", + "mwe-embedplayer-ogg-player-vlc-player": "VLCęę¾åØ", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Oggęę¾åØ", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3ęę¾åØ", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AACęę¾åØ", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264ęę¾åØ", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebMęę¾åØ", + "mwe-embedplayer-ogg-player-oggPlugin": "éēØOggę件", + "mwe-embedplayer-ogg-player-vlcAppPlayer": "ēØäŗiOSēVLCåŗēØēØåŗ", + "mwe-embedplayer-ogg-player-IEWebMPrompt": "IE WebMę件äøč½½åØ", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTimeę件", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kalturaęę¾åØ", + "mwe-embedplayer-ogg-player-selected": "ļ¼å·²éļ¼", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "äøŗäŗå¾å°ę“儽ēč§é¢ęę¾ä½éŖļ¼ę们ęØč<a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5č§é¢ęµč§åØ</a>ć", + "mwe-embedplayer-download-warn": "ę£ęµå°ęę¾åØåęµč§åØäøå
¼å®¹ļ¼äøŗäŗč½åØęµč§åØäøęę¾ļ¼čÆ·äøč½½[$1 ęę°Firefox]", + "mwe-embedplayer-fullscreen-tip": "ę<b>F11</b>åę¢ęµč§åØč³å
Øå±", + "mwe-embedplayer-fullscreen-tip-osx": "ę<b>Shift ā F</b>åę¢č³å
Øå±", + "mwe-embedplayer-do_not_warn_again": "仄åäøåę¾ē¤ŗčÆ„äæ”ęÆ", + "mwe-embedplayer-playerSelect": "ęę¾åØ", + "mwe-embedplayer-read_before_embed": "åµå
„åčÆ·<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">é
čÆ»ę¬ę</a>ć", + "mwe-embedplayer-embed_site_or_blog": "åµå
„锵é¢", + "mwe-embedplayer-embed_wiki": "åµå
„wiki", + "mwe-embedplayer-related_videos": "ēøå
³č§é¢", + "mwe-embedplayer-seeking": "ę£åØåÆ»ę¾", + "mwe-embedplayer-buffering": "ę£åØē¼å²", + "mwe-embedplayer-video-h264": "H.264č§é¢", + "mwe-embedplayer-video-webm": "WebMč§é¢", + "mwe-embedplayer-video-flv": "Flashč§é¢", + "mwe-embedplayer-video-ogg": "Oggč§é¢", + "mwe-embedplayer-video-audio": "Oggé³é¢", + "mwe-embedplayer-audio-mpeg": "MPEGé³é¢", + "mwe-embedplayer-video-3gp": "3GPč§é¢", + "mwe-embedplayer-video-mpeg": "MPEGč§é¢", + "mwe-embedplayer-video-msvideo": "AVIč§é¢", + "mwe-embedplayer-missing-source": "ęŖę¾å°ęŗč§é¢", + "mwe-embedplayer-vlcapp-intro": "äøŗäŗåØiPhoneęiPadäøč§ēę¤ē«ēč§é¢ļ¼ęØéč¦å
č“¹ē$1ć", + "mwe-embedplayer-vlcapp-vlcapplinktext": "VLCåŗēØēØåŗ", + "mwe-embedplayer-vlcapp-downloadapp": "ä»App Storeäøč½½VLCåŗēØēØåŗ", + "mwe-embedplayer-vlcapp-openvideo": "ä½æēØVLCåŗēØēØåŗęå¼ę¤č§é¢", + "mwe-embedplayer-vlcapp-downloadvideo": "äøč½½čæäøŖč§é¢", + "mwe-embedplayer-vlcapp-vlcapppopup": "č¦åØčÆ„ē½ē«ęę¾č§é¢ļ¼ęØéč¦å
č“¹ēVLCåŗēØēØåŗćē°åØå®č£
ļ¼", + "mwe-embedplayer-iewebmprompt-intro": "ååļ¼åØęØåÆ仄ęę¾čÆ„č§é¢åęØčæéč¦åäø件äŗā¦ā¦", + "mwe-embedplayer-iewebmprompt-linktext": "äøŗMicrosoft Internet Explorerå®č£
WebMåŖä½ē»ä»¶", + "mwe-embedplayer-iewebmprompt-outro": "åØå®č£
åéę°å č½½ę¤é”µé¢ć" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/zh-hant.json b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/zh-hant.json new file mode 100644 index 00000000..5dceb76e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/i18n/zh-hant.json @@ -0,0 +1,86 @@ +{ + "@metadata": { + "authors": [ + "Justincheng12345", + "Mark85296341", + "Simon Shek", + "StephDC", + "LNDDYL" + ] + }, + "mwe-embedplayer-credit-title": "ęØé”ļ¼$1", + "mwe-embedplayer-credit-date": "ę„ęļ¼$1", + "mwe-embedplayer-credit-author": "ä½č
ļ¼$1", + "mwe-embedplayer-nocredits": "ęŖē½²å", + "mwe-embedplayer-loading_plugin": "ę£åØč¼å
„å¤ęēØå¼...", + "mwe-embedplayer-select_playback": "čØå®åę¾å儽", + "mwe-embedplayer-link_back": "åé£", + "mwe-embedplayer-error_swap_vid": "éÆčŖ¤ļ¼mwEmbedē”ę³č½ęēØę¼mwEmbedä»é¢ēå½±ēęØē±¤", + "mwe-embedplayer-add_to_end_of_sequence": "ę·»å č³åŗåę«å°¾", + "mwe-embedplayer-missing_video_stream": "ę¤äø²ęµēå½±ēęŖę”å·²éŗ失", + "mwe-embedplayer-play_clip": "ęę¾åŖč¼Æ", + "mwe-embedplayer-pause_clip": "ę«ååŖč¼Æ", + "mwe-embedplayer-volume_control": "é³éę§å¶", + "mwe-embedplayer-player_options": "ęę¾åØéøé
", + "mwe-embedplayer-timed_text": "åå¹", + "mwe-embedplayer-player_fullscreen": "å
Øč¢å¹", + "mwe-embedplayer-next_clip_msg": "ęę¾äøäøåŖč¼Æ", + "mwe-embedplayer-prev_clip_msg": "ęę¾åäøåŖč¼Æ", + "mwe-embedplayer-current_clip_msg": "ē¹¼ēŗęę¾ę¤åŖč¼Æ", + "mwe-embedplayer-seek_to": "å°ę¾$1", + "mwe-embedplayer-paused": "ę«å", + "mwe-embedplayer-download_segment": "äøč¼éøꮵļ¼", + "mwe-embedplayer-download_full": "äøč¼å®ę“ēå½±ēęŖļ¼", + "mwe-embedplayer-download_right_click": "äøč¼č«ęå³éµäø¦éøę<i>é£ēµå¦åēŗ...</i>", + "mwe-embedplayer-download_clip": "äøč¼å½±ē", + "mwe-embedplayer-download_text": "äøč¼åå¹", + "mwe-embedplayer-download": "äøč¼", + "mwe-embedplayer-share": "åäŗ«", + "mwe-embedplayer-credits": "ē½²å", + "mwe-embedplayer-about-library": "éę¼Kalturaęę¾åØ", + "mwe-embedplayer-about-library-desc": "KalturaēHTML5åŖé«ę«č®ęØåØē¶ä»č½č·Øč¶ęęäø»ęµēč¦½åØå
åå°å©ēØHTML5å½±ēåé³čØęØē±¤ć\n\n[$1 ę“å¤éę¼Kalturaęę¾åØę«ēč³čØ]ć", + "mwe-embedplayer-clip_linkback": "åŖč¼Æęŗé é¢", + "mwe-embedplayer-choose_player": "éøęå½±ēęę¾åØ", + "mwe-embedplayer-no-player": "$1ę²ęåÆēØęę¾åØ", + "mwe-embedplayer-share_this_video": "åäŗ«č©²å½±ē", + "mwe-embedplayer-video_credits": "å½±ēē½²å", + "mwe-embedplayer-no-video_credits": "ē”ē½²å", + "mwe-embedplayer-kaltura-platform-title": "Kalturaéę¾åå§ē¢¼å½±ēå¹³å°", + "mwe-embedplayer-menu_btn": "éøå®", + "mwe-embedplayer-close_btn": "éé", + "mwe-embedplayer-ogg-player-vlc-player": "VLCęę¾åØ", + "mwe-embedplayer-ogg-player-oggNative": "HTML5 Oggęę¾åØ", + "mwe-embedplayer-ogg-player-mp3Native": "HTML5 MP3 ęę¾ę©", + "mwe-embedplayer-ogg-player-aacNative": "HTML5 AAC ęę¾ę©", + "mwe-embedplayer-ogg-player-h264Native": "HTML5 H.264ęę¾åØ", + "mwe-embedplayer-ogg-player-webmNative": "HTML5 WebMęę¾åØ", + "mwe-embedplayer-ogg-player-oggPlugin": "ęŖę³ØåOggę件", + "mwe-embedplayer-ogg-player-quicktime-mozilla": "QuickTimeå¤ęēØå¼", + "mwe-embedplayer-ogg-player-quicktime-activex": "QuickTime ActiveX", + "mwe-embedplayer-ogg-player-flowplayer": "Flowplayer", + "mwe-embedplayer-ogg-player-kplayer": "Kalturaęę¾åØ", + "mwe-embedplayer-ogg-player-selected": "ļ¼å·²éøåļ¼", + "mwe-embedplayer-ogg-player-omtkplayer": "OMTK Flash Vorbis", + "mwe-embedplayer-for_best_experience": "ēŗåå¾ę“儽影ēęę¾é«é©ļ¼ęåęØč¦<a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\" target=\"_blank\">HTML5å½±ēēč¦½åØ</a>ć", + "mwe-embedplayer-download-warn": "ęŖ¢ęø¬å°ęę¾åØčēč¦½åØäøēø容ļ¼å¦åøęę¼ēč¦½åØäøęę¾č«äøč¼[$1 ęę°ēę¬Firefoxēč¦½åØ]", + "mwe-embedplayer-fullscreen-tip": "ę<b>F11</b>ęēč¦½åØčØēŗå
Øč¢å¹", + "mwe-embedplayer-fullscreen-tip-osx": "ę<b>Shift ā F</b>čØēŗå
Øč¢å¹", + "mwe-embedplayer-do_not_warn_again": "仄å¾äøåé”Æē¤ŗę¤čØęÆ", + "mwe-embedplayer-playerSelect": "ęę¾åØ", + "mwe-embedplayer-read_before_embed": "åµå
„åč«å
<a href=\"https://www.mediawiki.org/wiki/Security_Notes_on_Remote_Embedding\" target=\"new\">é±č®ę¬ę</a>ć", + "mwe-embedplayer-embed_site_or_blog": "åµå
„é é¢", + "mwe-embedplayer-embed_wiki": "åØ wiki äøåµå
„", + "mwe-embedplayer-related_videos": "ēøéå½±ē", + "mwe-embedplayer-seeking": "ę£åØęå°", + "mwe-embedplayer-buffering": "ē·©č”äø", + "mwe-embedplayer-video-h264": "H.264å½±ē", + "mwe-embedplayer-video-webm": "WebMå½±ē", + "mwe-embedplayer-video-flv": "Flashå½±ē", + "mwe-embedplayer-video-ogg": "Oggå½±ē", + "mwe-embedplayer-video-audio": "Oggé³čØ", + "mwe-embedplayer-audio-mpeg": "MPEGé³čØ", + "mwe-embedplayer-video-3gp": "3GPå½±ē", + "mwe-embedplayer-video-mpeg": "MPEGå½±ē", + "mwe-embedplayer-video-msvideo": "AVIå½±ē", + "mwe-embedplayer-missing-source": "ęŖę¾å°åå§å½±ē" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/blackvideo.mp4 b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/blackvideo.mp4 Binary files differnew file mode 100644 index 00000000..cf86d1a8 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/blackvideo.mp4 diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js new file mode 100644 index 00000000..131302a2 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayer.js @@ -0,0 +1,2760 @@ +/** +* embedPlayer is the base class for html5 video tag javascript abstraction library +* embedPlayer include a few subclasses: +* +* mediaPlayer Media player embed system ie: java, vlc or native. +* mediaElement Represents source media elements +* mw.PlayerControlBuilder Handles skinning of the player controls +*/ +( function( mw, $ ) {"use strict"; + /** + * Merge in the default video attributes supported by embedPlayer: + */ + mw.mergeConfig('EmbedPlayer.Attributes', { + /* + * Base html element attributes: + */ + + // id: Auto-populated if unset + "id" : null, + + // Width: alternate to "style" to set player width + "width" : null, + + // Height: alternative to "style" to set player height + "height" : null, + + /* + * Base html5 video element attributes / states also see: + * http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html + */ + + // Media src URI, can be relative or absolute URI + "src" : null, + + // Poster attribute for displaying a place holder image before loading + // or playing the video + "poster" : null, + + // Autoplay if the media should start playing + "autoplay" : false, + + // Loop attribute if the media should repeat on complete + "loop" : false, + + // If the player controls should be displayed + "controls" : true, + + // Video starts "paused" + "paused" : true, + + // ReadyState an attribute informs clients of video loading state: + // see: http://www.whatwg.org/specs/web-apps/current-work/#readystate + "readyState" : 0, + + // Loading state of the video element + "networkState" : 0, + + // Current playback position + "currentTime" : 0, + + // Previous player set time + // Lets javascript use $('#videoId')[0].currentTime = newTime; + "previousTime" : 0, + + // Previous player set volume + // Lets javascript use $('#videoId')[0].volume = newVolume; + "previousVolume" : 1, + + // Initial player volume: + "volume" : 0.75, + + // Caches the volume before a mute toggle + "preMuteVolume" : 0.75, + + // Media duration: Value is populated via + // custom data-durationhint attribute or via the media file once its played + "duration" : null, + + // A hint to the duration of the media file so that duration + // can be displayed in the player without loading the media file + 'data-durationhint': null, + + // to disable menu or timedText for a given embed + 'data-disablecontrols': null, + + // Also support direct durationHint attribute ( backwards compatibly ) + // @deprecated please use data-durationhint instead. + 'durationHint' : null, + + // Mute state + "muted" : false, + + /** + * Custom attributes for embedPlayer player: (not part of the html5 + * video spec) + */ + + // Default video aspect ratio + 'videoAspect' : '4:3', + + // Start time of the clip + "start" : 0, + + // End time of the clip + "end" : null, + + // If the player controls should be overlaid + // ( Global default via config EmbedPlayer.OverlayControls in module + // loader.js) + "overlaycontrols" : true, + + // Attribute to use 'native' controls + "usenativecontrols" : false, + + // If the player should include an attribution button: + 'attributionbutton' : true, + + // A player error object (Includes title and message) + // * Used to display an error instead of a play button + // * The full player api available + 'playerError' : {}, + + // A flag to hide the player gui and disable autoplay + // * Used for empty players or a player where you want to dynamically set sources, then play. + // * The player API remains active. + 'data-blockPlayerDisplay': null, + + // If serving an ogg_chop segment use this to offset the presentation time + // ( for some plugins that use ogg page time rather than presentation time ) + "startOffset" : 0, + + // If the download link should be shown + "downloadLink" : true, + + // Content type of the media + "type" : null + + } ); + + + /** + * The base source attribute checks also see: + * http://dev.w3.org/html5/spec/Overview.html#the-source-element + */ + mw.mergeConfig( 'EmbedPlayer.SourceAttributes', [ + // source id + 'id', + + // media url + 'src', + + // Title string for the source asset + 'title', + + // The html5 spec uses label instead of 'title' for naming sources + 'label', + + // boolean if we support temporal url requests on the source media + 'URLTimeEncoding', + + // Media has a startOffset ( used for plugins that + // display ogg page time rather than presentation time + 'startOffset', + + // Media start time + 'start', + + // Media end time + 'end', + + // If the source is the default source + 'default', + + // Title of the source + 'title', + + // titleKey ( used for api lookups TODO move into mediaWiki specific support + 'titleKey' + ] ); + + + /** + * Base embedPlayer object + * + * @param {Element} + * element, the element used for initialization. + * @constructor + */ + mw.EmbedPlayer = function( element ) { + return this.init( element ); + }; + + mw.EmbedPlayer.prototype = { + + // The mediaElement object containing all mediaSource objects + 'mediaElement' : null, + + // Object that describes the supported feature set of the underling plugin / + // Support list is described in PlayerControlBuilder components + 'supports': { }, + + // If the player is done loading ( does not guarantee playability ) + // for example if there is an error playerReadyFlag is still set to true once + // no more loading is to be done + 'playerReadyFlag' : false, + + // Stores the loading errors + 'loadError' : false, + + // Thumbnail updating flag ( to avoid rewriting an thumbnail thats already + // being updated) + 'thumbnailUpdatingFlag' : false, + + // Stopped state flag + 'stopped' : true, + + // Local variable to hold CMML meeta data about the current clip + // for more on CMML see: http://wiki.xiph.org/CMML + 'cmmlData': null, + + // Stores the seek time request, Updated by the seek function + 'serverSeekTime' : 0, + + // If the embedPlayer is current 'seeking' + 'seeking' : false, + + // Percent of the clip buffered: + 'bufferedPercent' : 0, + + // Holds the timer interval function + 'monitorTimerId' : null, + + // Buffer flags + 'bufferStartFlag' : false, + 'bufferEndFlag' : false, + + // For supporting media fragments stores the play end time + 'pauseTime' : null, + + // On done playing + 'donePlayingCount' : 0 + , + // if player events should be Propagated + '_propagateEvents': true, + + // If the onDone interface should be displayed + 'onDoneInterfaceFlag': true, + + // if we should check for a loading spinner in the monitor function: + '_checkHideSpinner' : false, + + // If pause play controls click controls should be active: + '_playContorls' : true, + + // If player should be displayed (in some caused like audio, we don't need the player to be visible + 'displayPlayer': true, + + // Widget loaded should only fire once + 'widgetLoaded': false, + + /** + * embedPlayer + * + * @constructor + * + * @param {Element} + * element DOM element that we are building the player interface for. + */ + init: function( element ) { + var _this = this; + mw.log('EmbedPlayer: initEmbedPlayer: ' + $(element).width() ); + + var playerAttributes = mw.config.get( 'EmbedPlayer.Attributes' ); + + // Store the rewrite element tag type + this.rewriteElementTagName = element.tagName.toLowerCase(); + + this.noPlayerFallbackHTML = $( element ).html(); + + // Setup the player Interface from supported attributes: + for ( var attr in playerAttributes ) { + // We can't use $(element).attr( attr ) because we have to check for boolean attributes: + if ( element.getAttribute( attr ) != null ) { + // boolean attributes + if( element.getAttribute( attr ) == '' ){ + this[ attr ] = true; + } else { + this[ attr ] = element.getAttribute( attr ); + } + } else { + this[attr] = playerAttributes[attr]; + } + // string -> boolean + if( this[ attr ] == "false" ) this[attr] = false; + if( this[ attr ] == "true" ) this[attr] = true; + } + + // Hide "controls" if using native player controls: + if( this.useNativePlayerControls() ){ + _this.controls = true; + } + // Set the skin name from the class + var sn = $(element).attr( 'class' ); + + if ( sn && sn != '' ) { + var skinList = mw.config.get('EmbedPlayer.SkinList'); + for ( var n = 0; n < skinList.length; n++ ) { + if ( sn.indexOf( skinList[n].toLowerCase() ) !== -1 ) { + this.skinName = skinList[ n ]; + } + } + } + // Set the default skin if unset: + if ( !this.skinName ) { + this.skinName = mw.config.get( 'EmbedPlayer.DefaultSkin' ); + } + + // Support custom monitorRate Attribute ( if not use default ) + if( !this.monitorRate ){ + this.monitorRate = mw.config.get( 'EmbedPlayer.MonitorRate' ); + } + + // Make sure startOffset is cast as an float: + if ( this.startOffset && this.startOffset.split( ':' ).length >= 2 ) { + this.startOffset = parseFloat( mw.npt2seconds( this.startOffset ) ); + } + + // Make sure offset is in float: + this.startOffset = parseFloat( this.startOffset ); + + // Set the source duration + if ( $( element ).attr( 'duration' ) ) { + _this.duration = $( element ).attr( 'duration' ); + } + // Add durationHint property form data-durationhint: + if( _this['data-durationhint']){ + _this.durationHint = _this['data-durationhint']; + } + // Update duration from provided durationHint + if ( _this.durationHint && ! _this.duration){ + _this.duration = mw.npt2seconds( _this.durationHint ); + } + + // Make sure duration is a float: + this.duration = parseFloat( this.duration ); + mw.log( 'EmbedPlayer::init:' + this.id + " duration is: " + this.duration ); + + // Add disablecontrols property form data-disablecontrols: + if( _this['data-disablecontrols'] ){ + _this.disablecontrols = _this['data-disablecontrols']; + } + + // Set the playerElementId id + this.pid = 'pid_' + this.id; + + // Add the mediaElement object with the elements sources: + this.mediaElement = new mw.MediaElement( element ); + + this.bindHelper( 'updateLayout', function() { + _this.updateLayout(); + }); + }, + /** + * Bind helpers to help iOS retain bind context + * + * Yes, iOS will fail when you run $( embedPlayer ).bind() + * but "work" when you run embedPlayer.bind() if the script urls are from diffrent "resources" + */ + bindHelper: function( name, callback ){ + $( this ).bind( name, callback ); + return this; + }, + unbindHelper: function( bindName ){ + if( bindName ) { + $( this ).unbind( bindName ); + } + return this; + }, + triggerQueueCallback: function( name, callback ){ + $( this ).triggerQueueCallback( name, callback ); + }, + triggerHelper: function( name, obj ){ + try{ + $( this ).trigger( name, obj ); + } catch( e ){ + // ignore try catch calls + // mw.log( "EmbedPlayer:: possible error in trgger: " + name + " " + e.toString() ); + } + }, + /** + * Stop events from Propagation and blocks interface updates and trigger events. + * @return + */ + stopEventPropagation: function(){ + mw.log("EmbedPlayer:: stopEventPropagation"); + this.stopMonitor(); + this._propagateEvents = false; + }, + + /** + * Restores event propagation + * @return + */ + restoreEventPropagation: function(){ + mw.log("EmbedPlayer:: restoreEventPropagation"); + this._propagateEvents = true; + this.startMonitor(); + }, + + /** + * Enables the play controls ( for example when an ad is done ) + */ + enablePlayControls: function(){ + mw.log("EmbedPlayer:: enablePlayControls" ); + if( this.useNativePlayerControls() ){ + return ; + } + this._playContorls = true; + // re-enable hover: + this.getInterface().find( '.play-btn' ) + .buttonHover() + .css('cursor', 'pointer' ); + + this.controlBuilder.enableSeekBar(); + /* + * We should pass an array with enabled components, and the controlBuilder will listen + * to this event and handle the layout changes. we should not call to this.controlBuilder inside embedPlayer. + * [ 'playButton', 'seekBar' ] + */ + $( this ).trigger( 'onEnableInterfaceComponents'); + }, + + /** + * Disables play controls, for example when an ad is playing back + */ + disablePlayControls: function(){ + if( this.useNativePlayerControls() ){ + return ; + } + this._playContorls = false; + // turn off hover: + this.getInterface().find( '.play-btn' ) + .unbind('mouseenter mouseleave') + .css('cursor', 'default' ); + + this.controlBuilder.disableSeekBar(); + /** + * We should pass an array with disabled components, and the controlBuilder will listen + * to this event and handle the layout changes. we should not call to this.controlBuilder inside embedPlayer. + * [ 'playButton', 'seekBar' ] + */ + $( this ).trigger( 'onDisableInterfaceComponents'); + }, + + /** + * For plugin-players to update supported features + */ + updateFeatureSupport: function(){ + $( this ).trigger('updateFeatureSupportEvent', this.supports ); + return ; + }, + /** + * Apply Intrinsic Aspect ratio of a given image to a poster image layout + */ + applyIntrinsicAspect: function(){ + var $this = $( this ); + // Check if a image thumbnail is present: + if( this.getInterface().find('.playerPoster').length ){ + var img = this.getInterface().find('.playerPoster')[0]; + var pHeight = $this.height(); + // Check for intrinsic width and maintain aspect ratio + if( img.naturalWidth && img.naturalHeight ){ + var pWidth = parseInt( img.naturalWidth / img.naturalHeight * pHeight); + if( pWidth > $this.width() ){ + pWidth = $this.width(); + pHeight = parseInt( img.naturalHeight / img.naturalWidth * pWidth ); + } + $( img ).css({ + 'height' : pHeight + 'px', + 'width': pWidth + 'px', + 'left': ( ( $this.width() - pWidth ) * .5 ) + 'px', + 'top': ( ( $this.height() - pHeight ) * .5 ) + 'px', + 'position' : 'absolute' + }); + } + } + }, + /** + * Set the width & height from css style attribute, element attribute, or by + * default value if no css or attribute is provided set a callback to + * resize. + * + * Updates this.width & this.height + * + * @param {Element} + * element Source element to grab size from + */ + loadPlayerSize: function( element ) { + // check for direct element attribute: + this.height = element.height > 0 ? element.height + '' : $(element).css( 'height' ); + this.width = element.width > 0 ? element.width + '' : $(element).css( 'width' ); + + // Special check for chrome 100% with re-mapping to 32px + // Video embed at 32x32 will have to wait for intrinsic video size later on + if( this.height == '32px' || this.height =='32px' ){ + this.width = '100%'; + this.height = '100%'; + } + mw.log('EmbedPlayer::loadPlayerSize: css size:' + this.width + ' h: ' + this.height); + + // Set to parent size ( resize events will cause player size updates) + if( this.height.indexOf('100%') != -1 || this.width.indexOf('100%') != -1 ){ + var $relativeParent = $(element).parents().filter(function() { + // reduce to only relative position or "body" elements + return $( this ).is('body') || $( this ).css('position') == 'relative'; + }).slice(0,1); // grab only the "first" + this.width = $relativeParent.width(); + this.height = $relativeParent.height(); + } + // Make sure height and width are a number + this.height = parseInt( this.height ); + this.width = parseInt( this.width ); + + // Set via attribute if CSS is zero or NaN and we have an attribute value: + this.height = ( this.height==0 || isNaN( this.height ) + && $(element).attr( 'height' ) ) ? + parseInt( $(element).attr( 'height' ) ): this.height; + this.width = ( this.width == 0 || isNaN( this.width ) + && $(element).attr( 'width' ) )? + parseInt( $(element).attr( 'width' ) ): this.width; + + + // Special case for audio + + // Firefox sets audio height to "0px" while webkit uses 32px .. force zero: + if( this.isAudio() && this.height == '32' ) { + this.height = 20; + } + + // Use default aspect ration to get height or width ( if rewriting a non-audio player ) + if( this.isAudio() && this.videoAspect ) { + var aspect = this.videoAspect.split( ':' ); + if( this.height && !this.width ) { + this.width = parseInt( this.height * ( aspect[0] / aspect[1] ) ); + } + if( this.width && !this.height ) { + var apectRatio = ( aspect[1] / aspect[0] ); + this.height = parseInt( this.width * ( aspect[1] / aspect[0] ) ); + } + } + + // On load sometimes attr is temporally -1 as we don't have video metadata yet. + // or in IE we get NaN for width height + // + // NOTE: browsers that do support height width should set "waitForMeta" flag in addElement + if( ( isNaN( this.height )|| isNaN( this.width ) ) || + ( this.height == -1 || this.width == -1 ) || + // Check for firefox defaults + // Note: ideally firefox would not do random guesses at css + // values + ( (this.height == 150 || this.height == 64 ) && this.width == 300 ) + ) { + var defaultSize = mw.config.get( 'EmbedPlayer.DefaultSize' ).split( 'x' ); + if( isNaN( this.width ) ){ + this.width = defaultSize[0]; + } + + // Special height default for audio tag ( if not set ) + if( this.isAudio() ) { + this.height = 20; + }else{ + this.height = defaultSize[1]; + } + } + }, + + /** + * Get the player pixel width not including controls + * + * @return {Number} pixel height of the video + */ + getPlayerWidth: function() { + var profile = $.client.profile(); + + if ( profile.name === 'firefox' && profile.versionNumber < 2 ) { + return ( $( this ).parent().parent().width() ); + } + return $( this ).width(); + }, + + /** + * Get the player pixel height not including controls + * + * @return {Number} pixel height of the video + */ + getPlayerHeight: function() { + return $( this ).height(); + }, + + /** + * Check player for sources. If we need to get media sources form an + * external file that request is issued here + */ + checkPlayerSources: function() { + mw.log( 'EmbedPlayer::checkPlayerSources: ' + this.id ); + var _this = this; + // Allow plugins to listen to a preCheckPlayerSources ( for registering the source loading point ) + $( _this ).trigger( 'preCheckPlayerSources' ); + + // Allow plugins to block on sources lookup ( cases where we just have an api key for example ) + $( _this ).triggerQueueCallback( 'checkPlayerSourcesEvent', function(){ + _this.setupSourcePlayer(); + }); + }, + + /** + * Get text tracks from the mediaElement + */ + getTextTracks: function(){ + if( !this.mediaElement ){ + return []; + } + return this.mediaElement.getTextTracks(); + }, + /** + * Empty the player sources + */ + emptySources: function(){ + if( this.mediaElement ){ + this.mediaElement.sources = []; + this.mediaElement.selectedSource = null; + } + // setup pointer to old source: + this.prevPlayer = this.selectedPlayer; + // don't null out the selected player on empty sources + //this.selectedPlayer =null; + }, + + /** + * Switch and play a video source + * + * Checks if the target source is the same playback mode and does player switch if needed. + * and calls playerSwitchSource + */ + switchPlaySource: function( source, switchCallback, doneCallback ){ + var _this = this; + var targetPlayer = mw.EmbedTypes.getMediaPlayers().defaultPlayer( source.mimeType ) ; + if( targetPlayer.library != this.selectedPlayer.library ){ + this.selectedPlayer = targetPlayer; + this.updatePlaybackInterface( function(){ + _this.playerSwitchSource( source, switchCallback, doneCallback ); + }); + } else { + // Call the player switch directly: + _this.playerSwitchSource( source, switchCallback, doneCallback ); + } + }, + /** + * abstract function player interface must support actual source switch + */ + playerSwitchSource: function( source, switchCallback, doneCallback ){ + mw.log( "Error player interface must support actual source switch"); + }, + + /** + * Set up the select source player + * + * issues autoSelectSource call + * + * Sets load error if no source is playable + */ + setupSourcePlayer: function() { + var _this = this; + mw.log("EmbedPlayer::setupSourcePlayer: " + this.id + ' sources: ' + this.mediaElement.sources.length ); + + // Check for source replace configuration: + if( mw.config.get('EmbedPlayer.ReplaceSources' ) ){ + this.emptySources(); + $.each( mw.config.get('EmbedPlayer.ReplaceSources' ), function( inx, source ){ + _this.mediaElement.tryAddSource( source ); + }); + } + + // Autoseletct the media source + this.mediaElement.autoSelectSource(); + + // Auto select player based on default order + if( this.mediaElement.selectedSource ){ + this.selectedPlayer = mw.EmbedTypes.getMediaPlayers().defaultPlayer( this.mediaElement.selectedSource.mimeType ); + // Check if we need to switch player rendering libraries: + if ( this.selectedPlayer && ( !this.prevPlayer || this.prevPlayer.library != this.selectedPlayer.library ) ) { + // Inherit the playback system of the selected player: + this.updatePlaybackInterface(); + return ; + } + } + + // Check if no player is selected + if( !this.selectedPlayer || !this.mediaElement.selectedSource ){ + this.showPlayerError(); + mw.log( "EmbedPlayer:: setupSourcePlayer > player ready ( but with errors ) "); + } else { + // Trigger layout ready event + $( this ).trigger( 'layoutReady' ); + // Show the interface: + this.getInterface().find( '.control-bar').show(); + this.addLargePlayBtn(); + } + // We still do the playerReady sequence on errors to provide an api + // and player error events + this.playerReadyFlag = true; + // trigger the player ready event; + $( this ).trigger( 'playerReady' ); + this.triggerWidgetLoaded(); + }, + + /** + * Updates the player interface + * + * Loads and inherit methods from the selected player interface. + * + * @param {Function} + * callback Function to be called once playback-system has been + * inherited + */ + updatePlaybackInterface: function( callback ) { + var _this = this; + mw.log( "EmbedPlayer::updatePlaybackInterface: duration is: " + this.getDuration() + ' playerId: ' + this.id ); + // Clear out any non-base embedObj methods: + if ( this.instanceOf ) { + // Update the prev instance var used for swiching interfaces to know the previous instance. + $( this ).data( 'previousInstanceOf', this.instanceOf ); + var tmpObj = window['mw.EmbedPlayer' + this.instanceOf ]; + for ( var i in tmpObj ) { + // Restore parent into local location + if ( typeof this[ 'parent_' + i ] != 'undefined' ) { + this[i] = this[ 'parent_' + i]; + } else { + this[i] = null; + } + } + } + // Set up the new embedObj + mw.log( 'EmbedPlayer::updatePlaybackInterface: embedding with ' + this.selectedPlayer.library ); + this.selectedPlayer.load( function() { + _this.updateLoadedPlayerInterface( callback ); + }); + }, + /** + * Update a loaded player interface by setting local methods to the + * updated player prototype methods + * + * @parma {function} + * callback function called once player has been loaded + */ + updateLoadedPlayerInterface: function( callback ){ + var _this = this; + mw.log( 'EmbedPlayer::updateLoadedPlayerInterface ' + _this.selectedPlayer.library + " player loaded for " + _this.id ); + + // Get embed library player Interface + var playerInterface = mw[ 'EmbedPlayer' + _this.selectedPlayer.library ]; + + // Build the player interface ( if the interface includes an init ) + if( playerInterface.init ){ + playerInterface.init(); + } + + for ( var method in playerInterface ) { + if ( typeof _this[method] != 'undefined' && !_this['parent_' + method] ) { + _this['parent_' + method] = _this[method]; + } + _this[ method ] = playerInterface[ method ]; + } + // Update feature support + _this.updateFeatureSupport(); + // Update duration + _this.getDuration(); + // show player inline + _this.showPlayer(); + // Run the callback if provided + if ( callback && $.isFunction( callback ) ){ + callback(); + } + }, + + /** + * Select a player playback system + * + * @param {Object} + * player Player playback system to be selected player playback + * system include vlc, native, java etc. + */ + selectPlayer: function( player ) { + mw.log("EmbedPlayer:: selectPlayer " + player.id ); + var _this = this; + if ( this.selectedPlayer.id != player.id ) { + this.selectedPlayer = player; + this.updatePlaybackInterface( function(){ + // Hide / remove track container + _this.getInterface().find( '.track' ).remove(); + // We have to re-bind hoverIntent ( has to happen in this scope ) + if( !_this.useNativePlayerControls() && _this.controls && _this.controlBuilder.isOverlayControls() ){ + _this.controlBuilder.showControlBar(); + _this.getInterface().hoverIntent({ + 'sensitivity': 4, + 'timeout' : 2000, + 'over' : function(){ + _this.controlBuilder.showControlBar(); + }, + 'out' : function(){ + _this.controlBuilder.hideControlBar(); + } + }); + } + }); + } + }, + + /** + * Get a time range from the media start and end time + * + * @return startNpt and endNpt time if present + */ + getTimeRange: function() { + var end_time = ( this.controlBuilder.longTimeDisp )? '/' + mw.seconds2npt( this.getDuration() ) : ''; + var defaultTimeRange = '0:00' + end_time; + if ( !this.mediaElement ){ + return defaultTimeRange; + } + if ( !this.mediaElement.selectedSource ){ + return defaultTimeRange; + } + if ( !this.mediaElement.selectedSource.endNpt ){ + return defaultTimeRange; + } + return this.mediaElement.selectedSource.startNpt + this.mediaElement.selectedSource.endNpt; + }, + + /** + * Get the duration of the embed player + */ + getDuration: function() { + if ( isNaN(this.duration) && this.mediaElement && this.mediaElement.selectedSource && + typeof this.mediaElement.selectedSource.durationHint != 'undefined' ){ + this.duration = this.mediaElement.selectedSource.durationHint; + } + return this.duration; + }, + + /** + * Get the player height + */ + getHeight: function() { + return this.getInterface().height(); + }, + + /** + * Get the player width + */ + getWidth: function(){ + return this.getInterface().width(); + }, + + /** + * Check if the selected source is an audio element: + */ + isAudio: function(){ + return ( this.rewriteElementTagName == 'audio' + || + ( this.mediaElement && this.mediaElement.selectedSource && this.mediaElement.selectedSource.mimeType.indexOf('audio/') !== -1 ) + ); + }, + + /** + * Get the plugin embed html ( should be implemented by embed player interface ) + */ + embedPlayerHTML: function() { + return 'Error: function embedPlayerHTML should be implemented by embed player interface '; + }, + + /** + * Seek function ( should be implemented by embedPlayer interface + * playerNative, playerKplayer etc. ) embedPlayer seek only handles URL + * time seeks + * @param {Float} + * percent of the video total length to seek to + */ + seek: function( percent ) { + var _this = this; + this.seeking = true; + // Trigger preSeek event for plugins that want to store pre seek conditions. + $( this ).trigger( 'preSeek', percent ); + + // Do argument checking: + if( percent < 0 ){ + percent = 0; + } + + if( percent > 1 ){ + percent = 1; + } + // set the playhead to the target position + this.updatePlayHead( percent ); + + // See if we should do a server side seek ( player independent ) + if ( this.supportsURLTimeEncoding() ) { + mw.log( 'EmbedPlayer::seek:: updated serverSeekTime: ' + mw.seconds2npt ( this.serverSeekTime ) + + ' currentTime: ' + _this.currentTime ); + // make sure we need to seek: + if( _this.currentTime == _this.serverSeekTime ){ + return ; + } + + this.stop(); + this.didSeekJump = true; + // Make sure this.serverSeekTime is up-to-date: + this.serverSeekTime = mw.npt2seconds( this.startNpt ) + parseFloat( percent * this.getDuration() ); + } + // Run the onSeeking interface update + // NOTE controlBuilder should really bind to html5 events rather + // than explicitly calling it or inheriting stuff. + this.controlBuilder.onSeek(); + }, + + /** + * Seeks to the requested time and issues a callback when ready (should be + * overwritten by client that supports frame serving) + */ + setCurrentTime: function( time, callback ) { + mw.log( 'Error: EmbedPlayer, setCurrentTime not overriden' ); + if( $.isFunction( callback ) ){ + callback(); + } + }, + + /** + * On clip done action. Called once a clip is done playing + * TODO clean up end sequence flow + */ + triggeredEndDone: false, + postSequence: false, + onClipDone: function() { + var _this = this; + // Don't run onclipdone if _propagateEvents is off + if( !_this._propagateEvents ){ + return ; + } + mw.log( 'EmbedPlayer::onClipDone: propagate:' + _this._propagateEvents + ' id:' + this.id + ' doneCount:' + this.donePlayingCount + ' stop state:' +this.isStopped() ); + // Only run stopped once: + if( !this.isStopped() ){ + // set the "stopped" flag: + this.stopped = true; + + // Show the control bar: + this.controlBuilder.showControlBar(); + + // TOOD we should improve the end event flow + // First end event for ads or current clip ended bindings + if( ! this.onDoneInterfaceFlag ){ + this.stopEventPropagation(); + } + + mw.log("EmbedPlayer:: trigger: ended ( inteface continue pre-check: " + this.onDoneInterfaceFlag + ' )' ); + $( this ).trigger( 'ended' ); + mw.log("EmbedPlayer::onClipDone:Trigged ended, continue? " + this.onDoneInterfaceFlag); + + + if( ! this.onDoneInterfaceFlag ){ + // Restore events if we are not running the interface done actions + this.restoreEventPropagation(); + return ; + } + + // A secondary end event for playlist and clip sequence endings + if( this.onDoneInterfaceFlag ){ + // We trigger two end events to match KDP and ensure playbackComplete always comes before playerPlayEnd + // in content ends. + mw.log("EmbedPlayer:: trigger: playbackComplete"); + $( this ).trigger( 'playbackComplete' ); + // now trigger postEnd for( playerPlayEnd ) + mw.log("EmbedPlayer:: trigger: postEnded"); + $( this ).trigger( 'postEnded' ); + } + // if the ended event did not trigger more timeline actions run the actual stop: + if( this.onDoneInterfaceFlag ){ + mw.log("EmbedPlayer::onDoneInterfaceFlag=true do interface done"); + // Prevent the native "onPlay" event from propagating that happens when we rewind: + this.stopEventPropagation(); + + // Update the clip done playing count ( for keeping track of replays ) + _this.donePlayingCount ++; + + // Rewind the player to the start: + // NOTE: Setting to 0 causes lags on iPad when replaying, thus setting to 0.01 + this.setCurrentTime(0.01, function(){ + + // Set to stopped state: + _this.stop(); + + // Restore events after we rewind the player + _this.restoreEventPropagation(); + + // Check if we have the "loop" property set + if( _this.loop ) { + _this.stopped = false; + _this.play(); + return; + } else { + // make sure we are in a paused state. + _this.pause(); + } + // Check if have a force display of the large play button + if( mw.config.get('EmbedPlayer.ForceLargeReplayButton') === true ){ + _this.addLargePlayBtn(); + } else{ + // Check if we should hide the large play button on end: + if( $( _this ).data( 'hideEndPlayButton' ) || !_this.useLargePlayBtn() ){ + _this.hideLargePlayBtn(); + } else { + _this.addLargePlayBtn(); + } + } + // An event for once the all ended events are done. + mw.log("EmbedPlayer:: trigger: onEndedDone"); + if ( !_this.triggeredEndDone ){ + _this.triggeredEndDone = true; + $( _this ).trigger( 'onEndedDone', [_this.id] ); + } + }) + } + } + }, + + + /** + * Shows the video Thumbnail, updates pause state + */ + showThumbnail: function() { + var _this = this; + mw.log( 'EmbedPlayer::showThumbnail::' + this.stopped ); + + // Close Menu Overlay: + this.controlBuilder.closeMenuOverlay(); + + // update the thumbnail html: + this.updatePosterHTML(); + + this.paused = true; + this.stopped = true; + + // Once the thumbnail is shown run the mediaReady trigger (if not using native controls) + if( !this.useNativePlayerControls() ){ + mw.log("mediaLoaded"); + $( this ).trigger( 'mediaLoaded' ); + } + }, + + /** + * Show the player + */ + showPlayer: function () { + mw.log( 'EmbedPlayer:: showPlayer: ' + this.id + ' interface: w:' + this.width + ' h:' + this.height ); + var _this = this; + + // Remove the player loader spinner if it exists + this.hideSpinnerAndPlayBtn(); + // If a isPersistentNativePlayer ( overlay the controls ) + if( !this.useNativePlayerControls() && this.isPersistentNativePlayer() ){ + $( this ).show(); + } + // Add controls if enabled: + if ( this.controls ) { + if( this.useNativePlayerControls() ){ + if( this.getPlayerElement() ){ + $( this.getPlayerElement() ).attr('controls', "true"); + } + } else { + this.controlBuilder.addControls(); + } + } + + // Update Thumbnail for the "player" + this.updatePosterHTML(); + + // Update temporal url if present + this.updateTemporalUrl(); + + // Do we need to show the player? + if( this.displayPlayer === false ) { + _this.getVideoHolder().hide(); + _this.getInterface().height( _this.getComponentsHeight() ); + _this.triggerHelper('updateLayout'); + } + + // Update layout + this.updateLayout(); + + // Make sure we have a play btn: + this.addLargePlayBtn(); + + // Update the playerReady flag + this.playerReadyFlag = true; + mw.log("EmbedPlayer:: Trigger: playerReady"); + // trigger the player ready event; + $( this ).trigger( 'playerReady' ); + this.triggerWidgetLoaded(); + + // Check if we want to block the player display + if( this['data-blockPlayerDisplay'] ){ + this.blockPlayerDisplay(); + return ; + } + + // Check if there are any errors to be displayed: + if( this.getError() ){ + this.showErrorMsg( this.getError() ); + return ; + } + // Auto play stopped ( no playerReady has already started playback ) and if not on an iPad with iOS > 3 + if ( this.isStopped() && this.autoplay && (!mw.isIOS() || mw.isIpad3() ) ) { + mw.log( 'EmbedPlayer::showPlayer::Do autoPlay' ); + _this.play(); + } + }, + + getComponentsHeight: function() { + var height = 0; + + // Go over all playerContainer direct children with .block class + this.getInterface().find('.block').each(function() { + height += $( this ).outerHeight( true ); + }); + + // FIXME embedPlayer should know nothing about playlist layout + /* If we're in vertical playlist mode, and not in fullscreen add playlist height + if( $('#container').hasClass('vertical') && ! this.controlBuilder.isInFullScreen() && this.displayPlayer ) { + height += $('#playlistContainer').outerHeight( true ); + } + */ + + // + var offset = (mw.isIOS()) ? 5 : 0; + + return height + offset; + }, + updateLayout: function() { + // update image layout: + this.applyIntrinsicAspect(); + if( !mw.config.get('EmbedPlayer.IsIframeServer' ) ){ + // Use intrensic container size + return ; + } + // Set window height if in iframe: + var windowHeight; + if( mw.isIOS() && ! this.controlBuilder.isInFullScreen() ) { + windowHeight = $( window.parent.document.getElementById( this.id ) ).height(); + } else { + windowHeight = window.innerHeight; + } + + var newHeight = windowHeight - this.getComponentsHeight(); + var currentHeight = this.getVideoHolder().height(); + // Always update videoHolder height + if( currentHeight !== newHeight ) { + mw.log('EmbedPlayer: updateLayout:: window: ' + windowHeight + ', components: ' + this.getComponentsHeight() + ', videoHolder old height: ' + currentHeight + ', new height: ' + newHeight ); + this.getVideoHolder().height( newHeight ); + } + }, + /** + * Gets a refrence to the main player interface, builds if not avaliable + */ + getInterface: function(){ + if( !this.$interface ){ + // init the control builder + this.controlBuilder = new mw.PlayerControlBuilder( this ); + + // build the interface wrapper + this.$interface = $( this ).wrap( + $('<div />') + .addClass( 'mwPlayerContainer ' + this.controlBuilder.playerClass ) + .append( + $('<div />').addClass( 'videoHolder' ) + ) + ).parent().parent(); + + // pass along any inhereted style: + if( this.style.cssText ){ + this.$interface[0].style.cssText = this.style.cssText; + } + // clear out base style + this.style.cssText = ''; + + // if not displayiung a play button, ( pass through to native player ) + if( ! this.useLargePlayBtn() ){ + this.$interface.css('pointer-events', 'none'); + } + } + return this.$interface; + }, + + /** + * Media fragments handler based on: + * http://www.w3.org/2008/WebVideo/Fragments/WD-media-fragments-spec/#fragment-dimensions + * + * We support seconds and npt ( normal play time ) + * + * Updates the player per fragment url info if present + * + */ + updateTemporalUrl: function(){ + var sourceHash = /[^\#]+$/.exec( this.getSrc() ).toString(); + if( sourceHash.indexOf('t=') === 0 ){ + // parse the times + var times = sourceHash.substr(2).split(','); + if( times[0] ){ + // update the current time + this.currentTime = mw.npt2seconds( times[0].toString() ); + } + if( times[1] ){ + this.pauseTime = mw.npt2seconds( times[1].toString() ); + // ignore invalid ranges: + if( this.pauseTime < this.currentTime ){ + this.pauseTime = null; + } + } + // Update the play head + this.updatePlayHead( this.currentTime / this.duration ); + // Update status: + this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) ); + } + }, + /** + * Sets an error message on the player + * + * @param {string} + * errorMsg + */ + setError: function( errorObj ){ + var _this = this; + if ( typeof errorObj == 'string' ) { + this.playerError = { + 'title' : _this.getKalturaMsg( 'ks-GENERIC_ERROR_TITLE' ), + 'message' : errorObj + } + return ; + + } + this.playerError = errorObj; + }, + /** + * Gets the current player error + */ + getError: function() { + if ( !$.isEmptyObject( this.playerError ) ) { + return this.playerError; + } + return null; + }, + + /** + * Show an error message on the player + * + * @param {object} + * errorObj + */ + showErrorMsg: function( errorObj ){ + // Remove a loading spinner + this.hideSpinnerAndPlayBtn(); + if( this.controlBuilder ) { + if( mw.config.get("EmbedPlayer.ShowPlayerAlerts") ) { + var alertObj = $.extend( errorObj, { + 'isModal': true, + 'keepOverlay': true, + 'noButtons': true, + 'isError': true + } ); + this.controlBuilder.displayAlert( alertObj ); + } + } + return ; + }, + + /** + * Blocks the player display by invoking an empty error msg + */ + blockPlayerDisplay: function(){ + this.showErrorMsg(); + this.getInterface().find( '.error' ).hide(); + }, + + /** + * Get missing plugin html (check for user included code) + * + * @param {String} + * [misssingType] missing type mime + */ + showPlayerError: function( ) { + var _this = this; + var $this = $( this ); + mw.log("EmbedPlayer::showPlayerError"); + // Hide loader + this.hideSpinnerAndPlayBtn(); + + // Error in loading media ( trigger the mediaLoadError ) + $this.trigger( 'mediaLoadError' ); + + // We don't distiguish between mediaError and mediaLoadError right now + // TODO fire mediaError only on failed to recive audio/video data. + $this.trigger( 'mediaError' ); + + // Check if we want to block the player display ( no error displayed ) + if( this['data-blockPlayerDisplay'] ){ + this.blockPlayerDisplay(); + return ; + } + + // Check if there is a more specific error: + if( this.getError() ){ + this.showErrorMsg( this.getError() ); + return ; + } + + // If no error is given assume missing sources: + this.showNoInlinePlabackSupport(); + }, + + /** + * Show player missing sources method + */ + showNoInlinePlabackSupport: function(){ + var _this = this; + var $this = $( this); + + // Check if any sources are avaliable: + if( this.mediaElement.sources.length == 0 + || + !mw.config.get('EmbedPlayer.NotPlayableDownloadLink') ) + { + return ; + } + // Set the isLink player flag: + this.isLinkPlayer= true; + // Update the poster and html: + this.updatePosterHTML(); + + // Make sure we have a play btn: + this.addLargePlayBtn(); + + // By default set the direct download url to the first source. + var downloadUrl = this.mediaElement.sources[0].getSrc(); + // Allow plugins to update the download url ( to point to server side tools to select + // stream based on user agent ( i.e IE8 h.264 file, blackberry 3gp file etc ) + this.triggerHelper( 'directDownloadLink', function( dlUrl ){ + if( dlUrl ){ + downloadUrl = dlUrl; + } + }); + // Set the play button to the first available source: + var $pBtn = this.getInterface().find('.play-btn-large') + .attr( 'title', mw.msg('mwe-embedplayer-play_clip') ) + .show() + .unbind( 'click' ) + .click( function() { + _this.triggerHelper( 'firstPlay', [ _this.id ] ); // To send stats event for play + _this.triggerHelper( 'playing' ); + return true; + }); + if( !$pBtn.parent('a').length ){ + $pBtn.wrap( $( '<a />' ).attr("target", "_blank" ) ); + } + $pBtn.parent('a').attr( "href", downloadUrl ); + + $( this ).trigger( 'showInlineDownloadLink' ); + }, + /** + * Update the video time request via a time request string + * + * @param {String} + * timeRequest video time to be updated + */ + updateVideoTimeReq: function( timeRequest ) { + mw.log( 'EmbedPlayer::updateVideoTimeReq:' + timeRequest ); + var timeParts = timeRequest.split( '/' ); + this.updateVideoTime( timeParts[0], timeParts[1] ); + }, + + /** + * Update Video time from provided startNpt and endNpt values + * + * @param {String} + * startNpt the new start time in npt format ( hh:mm:ss.ms ) + * @param {String} + * endNpt the new end time in npt format ( hh:mm:ss.ms ) + */ + updateVideoTime: function( startNpt, endNpt ) { + // update media + this.mediaElement.updateSourceTimes( startNpt, endNpt ); + + // update time + this.controlBuilder.setStatus( startNpt + '/' + endNpt ); + + // reset slider + this.updatePlayHead( 0 ); + + // Reset the serverSeekTime if urlTimeEncoding is enabled + if ( this.supportsURLTimeEncoding() ) { + this.serverSeekTime = 0; + } else { + this.serverSeekTime = mw.npt2seconds( startNpt ); + } + }, + + + /** + * Update Thumb time with npt formated time + * + * @param {String} + * time NPT formated time to update thumbnail + */ + updateThumbTimeNPT: function( time ) { + this.updateThumbTime( mw.npt2seconds( time ) - parseInt( this.startOffset ) ); + }, + + /** + * Update the thumb with a new time + * + * @param {Float} + * floatSeconds Time to update the thumb to + */ + updateThumbTime:function( floatSeconds ) { + // mw.log('updateThumbTime:'+floatSeconds); + var _this = this; + if ( typeof this.orgThumSrc == 'undefined' ) { + this.orgThumSrc = this.poster; + } + if ( this.orgThumSrc.indexOf( 't=' ) !== -1 ) { + this.lastThumbUrl = mw.replaceUrlParams( this.orgThumSrc, + { + 't' : mw.seconds2npt( floatSeconds + parseInt( this.startOffset ) ) + } + ); + if ( !this.thumbnailUpdatingFlag ) { + this.updatePoster( this.lastThumbUrl , false ); + this.lastThumbUrl = null; + } + } + }, + + /** + * Updates the displayed thumbnail via percent of the stream + * + * @param {Float} + * percent Percent of duration to update thumb + */ + updateThumbPerc:function( percent ) { + return this.updateThumbTime( ( this.getDuration() * percent ) ); + }, + + /** + * Update the poster source + * @param {String} + * posterSrc Poster src url + */ + updatePosterSrc: function( posterSrc ){ + if( ! posterSrc ) { + posterSrc = mw.config.get( 'EmbedPlayer.BlackPixel' ); + } + this.poster = posterSrc; + this.updatePosterHTML(); + this.applyIntrinsicAspect(); + }, + + /** + * Called after sources are updated, and your ready for the player to change media + * @return + */ + changeMedia: function( callback ){ + var _this = this; + var $this = $( this ); + mw.log( 'EmbedPlayer:: changeMedia '); + // Empty out embedPlayer object sources + this.emptySources(); + + // onChangeMedia triggered at the start of the change media commands + $this.trigger( 'onChangeMedia' ); + + // Reset first play to true, to count that play event + this.firstPlay = true; + // reset donePlaying count on change media. + this.donePlayingCount = 0; + this.triggeredEndDone = false; + this.preSequence = false; + this.postSequence = false; + + this.setCurrentTime( 0.01 ); + // Reset the playhead + this.updatePlayHead( 0 ); + // update the status: + this.controlBuilder.setStatus( this.getTimeRange() ); + + // Add a loader to the embed player: + this.pauseLoading(); + + // Clear out any player error ( both via attr and object property ): + this.setError( null ); + + // Clear out any player display blocks + this['data-blockPlayerDisplay'] = null + $this.attr( 'data-blockPlayerDisplay', ''); + + // Clear out the player error div: + this.getInterface().find('.error').remove(); + this.controlBuilder.closeAlert(); + this.controlBuilder.closeMenuOverlay(); + + // Restore the control bar: + this.getInterface().find('.control-bar').show(); + // Hide the play btn + this.hideLargePlayBtn(); + + //If we are change playing media add a ready binding: + var bindName = 'playerReady.changeMedia'; + $this.unbind( bindName ).bind( bindName, function(){ + mw.log('EmbedPlayer::changeMedia playerReady callback'); + // hide the loading spinner: + _this.hideSpinnerAndPlayBtn(); + // check for an erro on change media: + if( _this.getError() ){ + _this.showErrorMsg( _this.getError() ); + return ; + } + // Always show the control bar on switch: + if( _this.controlBuilder ){ + _this.controlBuilder.showControlBar(); + } + // Make sure the play button reflects the original play state + if( _this.autoplay ){ + _this.hideLargePlayBtn(); + } else { + _this.addLargePlayBtn(); + } + var source = _this.getSource(); + if( (_this.isPersistentNativePlayer() || _this.useNativePlayerControls()) && source ){ + // If switching a Persistent native player update the source: + // ( stop and play won't refresh the source ) + _this.switchPlaySource( source, function(){ + _this.changeMediaStarted = false; + $this.trigger( 'onChangeMediaDone' ); + if( _this.autoplay ){ + _this.play(); + } else { + // pause is need to keep pause sate, while + // switch source calls .play() that some browsers require. + // to reflect source swiches. + _this.pause(); + _this.addLargePlayBtn(); + } + if( callback ){ + callback() + } + }); + // we are handling trigger and callback asynchronously return here. + return ; + } + + // Reset changeMediaStarted flag + _this.changeMediaStarted = false; + + // Stop should unload the native player + _this.stop(); + + // reload the player + if( _this.autoplay ){ + _this.play(); + } else { + _this.addLargePlayBtn(); + } + + $this.trigger( 'onChangeMediaDone' ); + if( callback ) { + callback(); + } + }); + + // Load new sources per the entry id via the checkPlayerSourcesEvent hook: + $this.triggerQueueCallback( 'checkPlayerSourcesEvent', function(){ + // Start player events leading to playerReady + _this.setupSourcePlayer(); + }); + }, + /** + * Checks if the current player / configuration is an image play screen: + */ + isImagePlayScreen:function(){ + return ( this.useNativePlayerControls() && + !this.isLinkPlayer && + mw.isIphone() && + mw.config.get( 'EmbedPlayer.iPhoneShowHTMLPlayScreen') + ); + }, + /** + * Triggers widgetLoaded event - Needs to be triggered only once, at the first time playerReady is trigerred + */ + triggerWidgetLoaded: function() { + if ( !this.widgetLoaded ) { + this.widgetLoaded = true; + mw.log( "EmbedPlayer:: Trigger: widgetLoaded"); + this.triggerHelper( 'widgetLoaded' ); + } + }, + + /** + * Updates the poster HTML + */ + updatePosterHTML: function () { + mw.log( 'EmbedPlayer:updatePosterHTML::' + this.id ); + + var _this = this, + thumb_html = '', + class_atr = '', + style_atr = '', + profile = $.client.profile(); + + if( this.isImagePlayScreen() ){ + this.addPlayScreenWithNativeOffScreen(); + return ; + } + + // Set by default thumb value if not found + var posterSrc = ( this.poster ) ? this.poster : + mw.config.get( 'EmbedPlayer.BlackPixel' ); + + // Update PersistentNativePlayer poster: + if( this.isPersistentNativePlayer() ){ + var $vid = $( '#' + this.pid ).show(); + $vid.attr( 'poster', posterSrc ); + // Add a quick timeout hide / show ( firefox 4x bug with native poster updates ) + if ( profile.name === 'firefox' ){ + $vid.hide(); + setTimeout( function () { + $vid.show(); + }, 0); + } + } else { + // hide the pid if present: + $( '#' + this.pid ).hide(); + // Poster support is not very consistent in browsers use a jpg poster image: + $( this ) + .html( + $( '<img />' ) + .css({ + 'position': 'absolute', + 'top': 0, + 'left': 0, + 'right': 0, + 'bottom': 0 + }) + .attr({ + 'src' : posterSrc + }) + .addClass( 'playerPoster' ) + .load(function(){ + _this.applyIntrinsicAspect(); + }) + ).show(); + } + if ( this.useLargePlayBtn() && this.controlBuilder + && + this.height > this.controlBuilder.getComponentHeight( 'playButtonLarge' ) + ) { + this.addLargePlayBtn(); + } + }, + /** + * Abstract method, must be set by player inteface + */ + addPlayScreenWithNativeOffScreen: function(){ + mw.log( "Error: EmbedPlayer, Must override 'addPlayScreenWithNativeOffScreen' with player inteface" ); + return ; + }, + /** + * Checks if a large play button should be displayed on the + * otherwise native player + */ + useLargePlayBtn: function(){ + if( this.isPersistantPlayBtn() ){ + return true; + } + // If we are using native controls return false: + return !this.useNativePlayerControls(); + }, + /** + * Checks if the play button should stay on screen during playback, + * cases where a native player is dipalyed such as iPhone. + */ + isPersistantPlayBtn: function(){ + return mw.isAndroid2() || + ( mw.isIphone() && mw.config.get( 'EmbedPlayer.iPhoneShowHTMLPlayScreen' ) ); + }, + /** + * Checks if native controls should be used + * + * @returns boolean true if the mwEmbed player interface should be used + * false if the mwEmbed player interface should not be used + */ + useNativePlayerControls: function() { + if( this.usenativecontrols === true ){ + return true; + } + + if( mw.config.get('EmbedPlayer.NativeControls') === true ) { + return true; + } + + // Check for special webkit property that allows inline iPhone playback: + if( mw.config.get('EmbedPlayer.WebKitPlaysInline') === true && mw.isIphone() ) { + return false; + } + + // Do some device detection devices that don't support overlays + // and go into full screen once play is clicked: + if( mw.isAndroid2() || mw.isIpod() || mw.isIphone() ){ + return true; + } + + // iPad can use html controls if its a persistantPlayer in the dom before loading ) + // else it needs to use native controls: + if( mw.isIpad() ){ + if( mw.config.get('EmbedPlayer.EnableIpadHTMLControls') === true){ + return false; + } else { + // Set warning that your trying to do iPad controls without + // persistent native player: + return true; + } + } + return false; + }, + /** + * Checks if the native player is persistent in the dom since the intial page build out. + */ + isPersistentNativePlayer: function(){ + if( this.isLinkPlayer ){ + return false; + } + // Since we check this early on sometimes the player + // has not yet been updated to the pid location + if( $('#' + this.pid ).length == 0 ){ + return $('#' + this.id ).hasClass('persistentNativePlayer'); + } + return $('#' + this.pid ).hasClass('persistentNativePlayer'); + }, + // + isTouchDevice: function(){ + return mw.isIpad() + || + mw.isAndroid40() + || + mw.isMobileChrome(); + }, + /** + * Hides the large play button + * TODO move to player controls + */ + hideLargePlayBtn: function(){ + if( this.getInterface() ){ + this.getInterface().find( '.play-btn-large' ).hide(); + } + }, + /** + * Add a play button (if not already there ) + */ + addLargePlayBtn: function(){ + // check if we are pauseLoading ( i.e switching media, seeking, etc. and don't display play btn: + if( this.isPauseLoading ){ + mw.log("EmbedPlayer:: addLargePlayBtn ( skip play button, during load )"); + return; + } + // if using native controls make sure we can click the big play button by restoring + // interface click events: + if( this.useNativePlayerControls() ){ + this.getInterface().css('pointer-events', 'auto'); + } + + // iPhone in WebKitPlaysInline mode does not support clickable overlays as of iOS 5.0 + if( mw.config.get( 'EmbedPlayer.WebKitPlaysInline') && mw.isIphone() ) { + return ; + } + if( this.getInterface().find( '.play-btn-large' ).length ){ + this.getInterface().find( '.play-btn-large' ).show(); + } else { + this.getVideoHolder().append( + this.controlBuilder.getComponent( 'playButtonLarge' ) + ); + } + }, + + getVideoHolder: function() { + return this.getInterface().find('.videoHolder'); + }, + + /** + * Abstract method, + * Get native player html ( should be set by mw.EmbedPlayerNative ) + */ + getNativePlayerHtml: function(){ + return $('<div />' ) + .css( 'width', this.getWidth() ) + .html( 'Error: Trying to get native html5 player without native support for codec' ); + }, + + /** + * Should be set via native embed support + */ + applyMediaElementBindings: function(){ + mw.log("Warning applyMediaElementBindings should be implemented by player interface" ); + return ; + }, + + /** + * Gets code to embed the player remotely for "share" this player links + */ + getSharingEmbedCode: function() { + switch( mw.config.get( 'EmbedPlayer.ShareEmbedMode' ) ){ + case 'iframe': + return this.getShareIframeObject(); + break; + case 'videojs': + return this.getShareEmbedVideoJs(); + break; + } + }, + + /** + * Gets code to embed the player in a wiki + */ + getWikiEmbedCode: function() { + if( this.apiTitleKey) { + return '[[File:' + this.apiTitleKey + ']]'; + } else { + return false; + } + }, + + /** + * Get the iframe share code: + */ + getShareIframeObject: function(){ + // TODO move to getShareIframeSrc + var iframeUrl = this.getIframeSourceUrl(); + + // Set up embedFrame src path + var embedCode = '<iframe src="' + mw.html.escape( iframeUrl ) + '" '; + + // Set width / height of embed object + embedCode += 'width="' + this.getPlayerWidth() +'" '; + embedCode += 'height="' + this.getPlayerHeight() + '" '; + embedCode += 'frameborder="0" '; + embedCode += 'webkitAllowFullScreen mozallowfullscreen allowFullScreen'; + + // Close up the embedCode tag: + embedCode+='></iframe>'; + + // Return the embed code + return embedCode; + }, + /** + * Gets the iframe source url + */ + getIframeSourceUrl: function(){ + var iframeUrl = false; + this.triggerHelper( 'getShareIframeSrc', [ function( localIframeSrc ){ + if( iframeUrl){ + mw.log("Error multiple modules binding getShareIframeSrc" ); + } + iframeUrl = localIframeSrc; + }, this.id ]); + if( iframeUrl ){ + return iframeUrl; + } + // old style embed: + var iframeUrl = mw.getMwEmbedPath() + 'mwEmbedFrame.php?'; + var params = {'src[]' : []}; + + // Output all the video sources: + for( var i=0; i < this.mediaElement.sources.length; i++ ){ + var source = this.mediaElement.sources[i]; + if( source.src ) { + params['src[]'].push(mw.absoluteUrl( source.src )); + } + } + // Output the poster attr + if( this.poster ){ + params.poster = this.poster; + } + + // Set the skin if set to something other than default + if( this.skinName ){ + params.skin = this.skinName; + } + + if( this.duration ) { + params.durationHint = parseFloat( this.duration ); + } + iframeUrl += $.param( params ); + return iframeUrl; + }, + /** + * Get the share embed Video tag html to share the embed code. + */ + getShareEmbedVideoJs: function(){ + + // Set the embed tag type: + var embedtag = ( this.isAudio() )? 'audio': 'video'; + + // Set up the mwEmbed js include: + var embedCode = '<script type="text/javascript" ' + + 'src="' + + mw.html.escape( + mw.absoluteUrl( + mw.getMwEmbedSrc() + ) + ) + '"></script>' + + '<' + embedtag + ' '; + + if( this.poster ) { + embedCode += 'poster="' + + mw.html.escape( mw.absoluteUrl( this.poster ) ) + + '" '; + } + + // Set the skin if set to something other than default + if( this.skinName ){ + embedCode += 'class="' + + mw.html.escape( this.skinName ) + + '" '; + } + + if( this.duration ) { + embedCode +='durationHint="' + parseFloat( this.duration ) + '" '; + } + + if( this.width || this.height ){ + embedCode += 'style="'; + embedCode += ( this.width )? 'width:' + this.width +'px;': ''; + embedCode += ( this.height )? 'height:' + this.height +'px;': ''; + embedCode += '" '; + } + + // Close the video attr + embedCode += '>'; + + // Output all the video sources: + for( var i=0; i < this.mediaElement.sources.length; i++ ){ + var source = this.mediaElement.sources[i]; + if( source.src ) { + embedCode +='<source src="' + + mw.absoluteUrl( source.src ) + + '" ></source>'; + } + } + // Close the video tag + embedCode += '</video>'; + + return embedCode; + }, + + + + /** + * Base Embed Controls + */ + + /** + * The Play Action + * + * Handles play requests, updates relevant states: + * seeking =false + * paused =false + * + * Triggers the play event + * + * Updates pause button Starts the "monitor" + */ + firstPlay : true, + preSequence: false, + inPreSequence: false, + replayEventCount : 0, + play: function() { + var _this = this; + var $this = $( this ); + // Store the absolute play time ( to track native events that should not invoke interface updates ) + mw.log( "EmbedPlayer:: play: " + this._propagateEvents + ' poster: ' + this.stopped ); + + this.absoluteStartPlayTime = new Date().getTime(); + + // Check if thumbnail is being displayed and embed html + if ( _this.isStopped() && (_this.preSequence == false || (_this.sequenceProxy && _this.sequenceProxy.isInSequence == false) )) { + if ( !_this.selectedPlayer ) { + _this.showPlayerError(); + return false; + } else { + _this.embedPlayerHTML(); + } + } + // playing, exit stopped state: + _this.stopped = false; + + if( !this.preSequence ) { + this.preSequence = true; + mw.log( "EmbedPlayer:: trigger preSequence " ); + this.triggerHelper( 'preSequence' ); + this.playInterfaceUpdate(); + // if we entered into ad loading return + if( _this.sequenceProxy && _this.sequenceProxy.isInSequence ){ + mw.log("EmbedPlayer:: isInSequence, do NOT play content"); + return false; + } + } + + // We need first play event for analytics purpose + if( this.firstPlay && this._propagateEvents) { + this.firstPlay = false; + this.triggerHelper( 'firstPlay', [ _this.id ] ); + } + + if( this.paused === true ){ + this.paused = false; + // Check if we should Trigger the play event + mw.log("EmbedPlayer:: trigger play event::" + !this.paused + ' events:' + this._propagateEvents ); + // trigger the actual play event: + if( this._propagateEvents ) { + this.triggerHelper( 'onplay' ); + } + } + + // If we previously finished playing this clip run the "replay hook" + if( this.donePlayingCount > 0 && !this.paused && this._propagateEvents ) { + this.replayEventCount++; + // Trigger end done on replay + this.triggeredEndDone = false; + if( this.replayEventCount <= this.donePlayingCount){ + mw.log("EmbedPlayer::play> trigger replayEvent"); + this.triggerHelper( 'replayEvent' ); + } + } + + // If we have start time defined, start playing from that point + if( this.currentTime < this.startTime ) { + $this.bind('playing.startTime', function(){ + $this.unbind('playing.startTime'); + if( !mw.isIOS() ){ + _this.setCurrentTime( _this.startTime ); + _this.startTime = 0; + } else { + // iPad seeking on syncronus play event sucks + setTimeout( function(){ + _this.setCurrentTime( _this.startTime, function(){ + _this.play(); + }); + _this.startTime = 0; + }, 500 ) + } + _this.startTime = 0; + }); + } + + this.playInterfaceUpdate(); + // If play controls are enabled continue to video content element playback: + if( _this._playContorls ){ + return true; + } else { + // return false ( Mock play event, or handled elsewhere ) + return false; + } + }, + /** + * Update the player inteface for playback + * TODO move to controlBuilder + */ + playInterfaceUpdate: function(){ + var _this = this; + mw.log( 'EmbedPlayer:: playInterfaceUpdate' ); + // Hide any overlay: + if( this.controlBuilder ){ + this.controlBuilder.closeMenuOverlay(); + } + // Hide any buttons or errors if present: + this.getInterface().find( '.error' ).remove(); + this.hideLargePlayBtn(); + + this.getInterface().find('.play-btn span') + .removeClass( 'ui-icon-play' ) + .addClass( 'ui-icon-pause' ); + + this.hideSpinnerOncePlaying(); + + this.getInterface().find( '.play-btn' ) + .unbind('click') + .click( function( ) { + if( _this._playContorls ){ + _this.pause(); + } + } ) + .attr( 'title', mw.msg( 'mwe-embedplayer-pause_clip' ) ); + }, + /** + * Pause player, and display a loading animation + * @return + */ + pauseLoading: function(){ + this.pause(); + this.addPlayerSpinner(); + this.isPauseLoading = true; + }, + /** + * Adds a loading spinner to the player. + */ + addPlayerSpinner: function(){ + var sId = 'loadingSpinner_' + this.id; + // remove any old spinner + $( '#' + sId ).remove(); + // hide the play btn if present + this.hideLargePlayBtn(); + // re add an absolute positioned spinner: + $( this ).show().getAbsoluteOverlaySpinner() + .attr( 'id', sId ); + }, + hideSpinner: function(){ + // remove the spinner + $( '#loadingSpinner_' + this.id + ',.loadingSpinner' ).remove(); + }, + /** + * Hides the loading spinner + */ + hideSpinnerAndPlayBtn: function(){ + this.isPauseLoading = false; + this.hideSpinner(); + // hide the play btn + this.hideLargePlayBtn(); + }, + /** + * Hides the loading spinner once playing. + */ + hideSpinnerOncePlaying: function(){ + this._checkHideSpinner = true; + }, + /** + * Base embed pause Updates the play/pause button state. + * + * There is no general way to pause the video must be overwritten by embed + * object to support this functionality. + * + * @param {Boolean} if the event was triggered by user action or propagated by js. + */ + pause: function() { + var _this = this; + // Trigger the pause event if not already paused and using native controls: + if( this.paused === false ){ + this.paused = true; + if( this._propagateEvents ){ + mw.log( 'EmbedPlayer:trigger pause:' + this.paused ); + // we only trigger "onpause" to avoid event propagation to the native object method + // i.e in jQuery ( this ).trigger('pause') also calls: this.pause(); + $( this ).trigger( 'onpause' ); + } + } + _this.pauseInterfaceUpdate(); + }, + /** + * Sets the player interface to paused mode. + */ + pauseInterfaceUpdate: function(){ + var _this =this; + mw.log("EmbedPlayer::pauseInterfaceUpdate"); + // Update the ctrl "paused state" + this.getInterface().find('.play-btn span' ) + .removeClass( 'ui-icon-pause' ) + .addClass( 'ui-icon-play' ); + + this.getInterface().find( '.play-btn' ) + .unbind('click') + .click( function() { + if( _this._playContorls ){ + _this.play(); + } + } ) + .attr( 'title', mw.msg( 'mwe-embedplayer-play_clip' ) ); + }, + /** + * Maps the html5 load request. There is no general way to "load" clips so + * underling plugin-player libs should override. + */ + load: function() { + // should be done by child (no base way to pre-buffer video) + mw.log( 'Waring:: the load method should be overided by player interface' ); + }, + + + /** + * Base embed stop + * + * Updates the player to the stop state. + * + * Shows Thumbnail + * Resets Buffer + * Resets Playhead slider + * Resets Status + * + * Trigger the "doStop" event + */ + stop: function() { + var _this = this; + mw.log( 'EmbedPlayer::stop:' + this.id ); + // update the player to stopped state: + this.stopped = true; + + // Rest the prequecne flag: + this.preSequence = false; + + // Trigger the stop event: + $( this ).trigger( 'doStop' ); + + // no longer seeking: + this.didSeekJump = false; + + // Reset current time and prev time and seek offset + this.currentTime = this.previousTime = this.serverSeekTime = 0; + + this.stopMonitor(); + + // pause playback ( if playing ) + if( !this.paused ){ + this.pause(); + } + // Restore the play button ( if not native controls or is android ) + if( this.useLargePlayBtn() ){ + this.addLargePlayBtn(); + this.pauseInterfaceUpdate(); + } + + // Native player controls: + if( !this.isPersistentNativePlayer() ){ + // Rewrite the html to thumbnail disp + this.showThumbnail(); + this.bufferedPercent = 0; // reset buffer state + this.controlBuilder.setStatus( this.getTimeRange() ); + } + // Reset the playhead + this.updatePlayHead( 0 ); + // update the status: + this.controlBuilder.setStatus( this.getTimeRange() ); + // reset buffer indicator: + this.bufferedPercent = 0; + this.updateBufferStatus(); + }, + + /** + * Base Embed mute + * + * Handles interface updates for toggling mute. Plug-in / player interface + * must handle the actual media player action + */ + toggleMute: function( userAction ) { + mw.log( 'EmbedPlayer::toggleMute> (old state:) ' + this.muted ); + if ( this.muted ) { + this.muted = false; + var percent = this.preMuteVolume; + } else { + this.muted = true; + this.preMuteVolume = this.volume; + var percent = 0; + } + // Change the volume and trigger the volume change so that other plugins can listen. + this.setVolume( percent, true ); + // Update the interface + this.setInterfaceVolume( percent ); + // trigger the onToggleMute event + $( this ).trigger('onToggleMute'); + }, + + /** + * Update volume function ( called from interface updates ) + * + * @param {float} + * percent Percent of full volume + * @param {triggerChange} + * boolean change if the event should be triggered + */ + setVolume: function( percent, triggerChange ) { + var _this = this; + // ignore NaN percent: + if( isNaN( percent ) ){ + return ; + } + // Set the local volume attribute + this.previousVolume = this.volume; + + this.volume = percent; + + // Un-mute if setting positive volume + if( percent != 0 ){ + this.muted = false; + } + + // Update the playerElement volume + this.setPlayerElementVolume( percent ); + //mw.log("EmbedPlayer:: setVolume:: " + percent + ' trigger volumeChanged: ' + triggerChange ); + if( triggerChange ){ + $( _this ).trigger('volumeChanged', percent ); + } + }, + + /** + * Updates the interface volume + * + * TODO should move to controlBuilder + * + * @param {float} + * percent Percentage volume to update interface + */ + setInterfaceVolume: function( percent ) { + if( this.supports[ 'volumeControl' ] && + this.getInterface().find( '.volume-slider' ).length + ) { + this.getInterface().find( '.volume-slider' ).slider( 'value', percent * 100 ); + } + }, + + /** + * Abstract method Update volume Method must be override by plug-in / player interface + * + * @param {float} + * percent Percentage volume to update + */ + setPlayerElementVolume: function( percent ) { + mw.log('Error player does not support volume adjustment' ); + }, + + /** + * Abstract method get volume Method must be override by plug-in / player interface + * (if player does not override we return the abstract player value ) + */ + getPlayerElementVolume: function(){ + // mw.log(' error player does not support getting volume property' ); + return this.volume; + }, + + /** + * Abstract method get volume muted property must be overwritten by plug-in / + * player interface (if player does not override we return the abstract + * player value ) + */ + getPlayerElementMuted: function(){ + // mw.log(' error player does not support getting mute property' ); + return this.muted; + }, + + /** + * Passes a fullscreen request to the controlBuilder interface + */ + fullscreen: function() { + this.controlBuilder.toggleFullscreen(); + }, + + /** + * Abstract method to be run post embedding the player Generally should be + * overwritten by the plug-in / player + */ + postEmbedActions:function() { + return ; + }, + + /** + * Checks the player state based on thumbnail display & paused state + * + * @return {Boolean} true if playing false if not playing + */ + isPlaying : function() { + if ( this.stopped ) { + // in stopped state + return false; + } else if ( this.paused ) { + // paused state + return false; + } else { + return true; + } + }, + + /** + * Get Stopped state + * + * @return {Boolean} true if stopped false if playing + */ + isStopped: function() { + return this.stopped; + }, + /** + * Stop the play state monitor + */ + stopMonitor: function(){ + clearInterval( this.monitorInterval ); + this.monitorInterval = 0; + }, + /** + * Start the play state monitor + */ + startMonitor: function(){ + this.monitor(); + }, + + /** + * Monitor playback and update interface components. underling player classes + * are responsible for updating currentTime + */ + monitor: function() { + var _this = this; + + // Check for current time update outside of embed player + _this.syncCurrentTime(); + + // mw.log( "monitor:: " + this.currentTime + ' propagateEvents: ' + _this._propagateEvents ); + + // update player status + _this.updatePlayheadStatus(); + + // Keep volume proprties set outside of the embed player in sync + _this.syncVolume(); + + // Make sure the monitor continues to run as long as the video is not stoped + _this.syncMonitor() + + if( _this._propagateEvents ){ + + // mw.log('trigger:monitor:: ' + this.currentTime ); + $( _this ).trigger( 'monitorEvent', [ _this.id ] ); + + // Trigger the "progress" event per HTML5 api support + if( _this.progressEventData ) { + $( _this ).trigger( 'progress', _this.progressEventData ); + } + } + }, + /** + * Sync the monitor function + */ + syncMonitor: function(){ + var _this = this; + // Call monitor at this.monitorRate interval. + // ( use setInterval to avoid stacking monitor requests ) + if( ! this.isStopped() ) { + if( !this.monitorInterval ){ + this.monitorInterval = setInterval( function(){ + if( _this.monitor ) + _this.monitor(); + }, this.monitorRate ); + } + } else { + // If stopped "stop" monitor: + this.stopMonitor(); + } + }, + + /** + * Sync the video volume + */ + syncVolume: function(){ + var _this = this; + // Check if volume was set outside of embed player function + // mw.log( ' this.volume: ' + _this.volume + ' prev Volume:: ' + _this.previousVolume ); + if( Math.round( _this.volume * 100 ) != Math.round( _this.previousVolume * 100 ) ) { + _this.setInterfaceVolume( _this.volume ); + } + // Update the previous volume + _this.previousVolume = _this.volume; + + // Update the volume from the player element + _this.volume = this.getPlayerElementVolume(); + + // update the mute state from the player element + if( _this.muted != _this.getPlayerElementMuted() && ! _this.isStopped() ){ + mw.log( "EmbedPlayer::syncVolume: muted does not mach embed player" ); + _this.toggleMute(); + // Make sure they match: + _this.muted = _this.getPlayerElementMuted(); + } + }, + + /** + * Checks if the currentTime was updated outside of the getPlayerElementTime function + */ + syncCurrentTime: function(){ + var _this = this; + + // Hide the spinner once we have time update: + if( _this._checkHideSpinner && _this.currentTime != _this.getPlayerElementTime() ){ + _this._checkHideSpinner = false; + _this.hideSpinnerAndPlayBtn(); + + if( _this.isPersistantPlayBtn() ){ + // add the play button likely iphone or native player that needs the play button on + // non-event "exit native html5 player" + _this.addLargePlayBtn(); + } else{ + // also hide the play button ( in case it was there somehow ) + _this.hideLargePlayBtn(); + } + } + + // Check if a javascript currentTime change based seek has occurred + if( parseInt( _this.previousTime ) != parseInt( _this.currentTime ) && + !this.userSlide && + !this.seeking && + !this.isStopped() + ){ + // If the time has been updated and is in range issue a seek + if( _this.getDuration() && _this.currentTime <= _this.getDuration() ){ + var seekPercent = _this.currentTime / _this.getDuration(); + mw.log("EmbedPlayer::syncCurrentTime::" + _this.previousTime + ' != ' + + _this.currentTime + " javascript based currentTime update to " + + seekPercent + ' == ' + _this.currentTime ); + _this.previousTime = _this.currentTime; + this.seek( seekPercent ); + } + } + + // Update currentTime via embedPlayer + _this.currentTime = _this.getPlayerElementTime(); + + // Update any offsets from server seek + if( _this.serverSeekTime && _this.supportsURLTimeEncoding() ){ + _this.currentTime = parseInt( _this.serverSeekTime ) + parseInt( _this.getPlayerElementTime() ); + } + + // Update the previousTime ( so we can know if the user-javascript changed currentTime ) + _this.previousTime = _this.currentTime; + + // Check for a pauseTime to stop playback in temporal media fragments + if( _this.pauseTime && _this.currentTime > _this.pauseTime ){ + _this.pause(); + _this.pauseTime = null; + } + }, + /** + * Updates the player time and playhead position based on currentTime + */ + updatePlayheadStatus: function(){ + var _this = this; + if ( this.currentTime >= 0 && this.duration ) { + if ( !this.userSlide && !this.seeking ) { + if ( parseInt( this.startOffset ) != 0 ) { + this.updatePlayHead( ( this.currentTime - this.startOffset ) / this.duration ); + var et = ( this.controlBuilder.longTimeDisp ) ? '/' + mw.seconds2npt( parseFloat( this.startOffset ) + parseFloat( this.duration ) ) : ''; + this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) + et ); + } else { + // use raw currentTIme for playhead updates + var ct = ( this.getPlayerElement() ) ? this.getPlayerElement().currentTime || this.currentTime: this.currentTime; + this.updatePlayHead( ct / this.duration ); + // Only include the end time if longTimeDisp is enabled: + var et = ( this.controlBuilder.longTimeDisp ) ? '/' + mw.seconds2npt( this.duration ) : ''; + this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) + et ); + } + } + // Check if we are "done" + var endPresentationTime = ( this.startOffset ) ? ( this.startOffset + this.duration ) : this.duration; + if ( this.currentTime >= endPresentationTime && !this.isStopped() ) { + mw.log( "EmbedPlayer::updatePlayheadStatus > should run clip done :: " + this.currentTime + ' > ' + endPresentationTime ); + this.onClipDone(); + } + } else { + // Media lacks duration just show end time + if ( this.isStopped() ) { + this.controlBuilder.setStatus( this.getTimeRange() ); + } else if ( this.paused ) { + this.controlBuilder.setStatus( mw.msg( 'mwe-embedplayer-paused' ) ); + } else if ( this.isPlaying() ) { + if ( this.currentTime && ! this.duration ) + this.controlBuilder.setStatus( mw.seconds2npt( this.currentTime ) + ' /' ); + else + this.controlBuilder.setStatus( " - - - " ); + } else { + this.controlBuilder.setStatus( this.getTimeRange() ); + } + } + }, + + /** + * Abstract getPlayerElementTime function + */ + getPlayerElementTime: function(){ + mw.log("Error: getPlayerElementTime should be implemented by embed library"); + }, + + /** + * Abstract getPlayerElementTime function + */ + getPlayerElement: function(){ + mw.log("Error: getPlayerElement should be implemented by embed library, or you may be calling this event too soon"); + }, + + /** + * Update the Buffer status based on the local bufferedPercent var + */ + updateBufferStatus: function() { + // Get the buffer target based for playlist vs clip + var $buffer = this.getInterface().find( '.mw_buffer' ); + // Update the buffer progress bar (if available ) + if ( this.bufferedPercent != 0 ) { + // mw.log('Update buffer css: ' + ( this.bufferedPercent * 100 ) + + // '% ' + $buffer.length ); + if ( this.bufferedPercent > 1 ){ + this.bufferedPercent = 1; + } + $buffer.css({ + "width" : ( this.bufferedPercent * 100 ) + '%' + }); + $( this ).trigger( 'updateBufferPercent', this.bufferedPercent ); + } else { + $buffer.css( "width", '0px' ); + } + + // if we have not already run the buffer start hook + if( this.bufferedPercent > 0 && !this.bufferStartFlag ) { + this.bufferStartFlag = true; + mw.log("EmbedPlayer::bufferStart"); + $( this ).trigger( 'bufferStartEvent' ); + } + + // if we have not already run the buffer end hook + if( this.bufferedPercent == 1 && !this.bufferEndFlag){ + this.bufferEndFlag = true; + $( this ).trigger( 'bufferEndEvent' ); + } + }, + + /** + * Update the player playhead + * + * @param {Float} + * perc Value between 0 and 1 for position of playhead + */ + updatePlayHead: function( perc ) { + //mw.log( 'EmbedPlayer: updatePlayHead: '+ perc); + if( this.getInterface() ){ + var $playHead = this.getInterface().find( '.play_head' ); + if ( !this.useNativePlayerControls() && $playHead.length != 0 ) { + var val = parseInt( perc * 1000 ); + $playHead.slider( 'value', val ); + } + } + $( this ).trigger('updatePlayHeadPercent', perc); + }, + + + /** + * Helper Functions for selected source + */ + + /** + * Get the current selected media source or first source + * + * @param {Number} + * Requested time in seconds to be passed to the server if the + * server supports supportsURLTimeEncoding + * @return src url + */ + getSrc: function( serverSeekTime ) { + if( serverSeekTime ){ + this.serverSeekTime = serverSeekTime; + } + if( this.currentTime && !this.serverSeekTime){ + this.serverSeekTime = this.currentTime; + } + + // No media element we can't return src + if( !this.mediaElement ){ + return false; + } + + // If no source selected auto select the source: + if( !this.mediaElement.selectedSource ){ + this.mediaElement.autoSelectSource(); + }; + + // Return selected source: + if( this.mediaElement.selectedSource ){ + // See if we should pass the requested time to the source generator: + if( this.supportsURLTimeEncoding() ){ + // get the first source: + return this.mediaElement.selectedSource.getSrc( this.serverSeekTime ); + } else { + return this.mediaElement.selectedSource.getSrc(); + } + } + // No selected source return false: + return false; + }, + /** + * Return the currently selected source + */ + getSource: function(){ + // update the current selected source: + this.mediaElement.autoSelectSource(); + return this.mediaElement.selectedSource; + }, + /** + * Static helper to get media sources from a set of videoFiles + * + * Uses mediaElement select logic to chose a + * video file among a set of sources + * + * @param videoFiles + * @return + */ + getCompatibleSource: function( videoFiles ){ + // Convert videoFiles json into HTML element: + // TODO mediaElement should probably accept JSON + var $media = $('<video />'); + $.each(videoFiles, function( inx, source){ + $media.append( $('<source />').attr({ + 'src' : source.src, + 'type' : source.type + })); + mw.log("EmbedPlayer::getCompatibleSource: add " + source.src + ' of type:' + source.type ); + }); + var myMediaElement = new mw.MediaElement( $media[0] ); + var source = myMediaElement.autoSelectSource(); + if( source ){ + mw.log("EmbedPlayer::getCompatibleSource: " + source.getSrc()); + return source; + } + mw.log("Error:: could not find compatible source"); + return false; + }, + /** + * If the selected src supports URL time encoding + * + * @return {Boolean} true if the src supports url time requests false if the + * src does not support url time requests + */ + supportsURLTimeEncoding: function() { + var timeUrls = mw.config.get('EmbedPlayer.EnableURLTimeEncoding') ; + if( timeUrls == 'none' ){ + return false; + } else if( timeUrls == 'always' ){ + return this.mediaElement.selectedSource.URLTimeEncoding; + } else if( timeUrls == 'flash' ){ + if( this.mediaElement.selectedSource && this.mediaElement.selectedSource.URLTimeEncoding){ + // see if the current selected player is flash: + return ( this.instanceOf == 'Kplayer' ); + } + } else { + mw.log("Error:: invalid config value for EmbedPlayer.EnableURLTimeEncoding:: " + mw.config.get('EmbedPlayer.EnableURLTimeEncoding') ); + } + return false; + } + }; + +})( mw, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerGeneric.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerGeneric.js new file mode 100644 index 00000000..fc8dec55 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerGeneric.js @@ -0,0 +1,36 @@ +/* +* Simple embed object for unknown application/ogg plugin +*/ + +( function( mw, $ ) { "use strict"; + +mw.EmbedPlayerGeneric = { + // List of supported features of the generic plugin + supports: { + 'playHead':false, + 'pause':false, + 'stop':true, + 'fullscreen':false, + 'timeDisplay':false, + 'volumeControl':false + }, + + // Instance name: + instanceOf:'Generic', + + /* + * Generic embed html + * + * @return {String} + * embed code for generic ogg plugin + */ + embedPlayerHTML: function() { + $( this ).html( + '<object type="application/ogg" ' + + 'width="' + this.getWidth() + '" height="' + this.getHeight() + '" ' + + 'data="' + this.getSrc( this.seekTimeSec ) + '"></object>' + ); + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerIEWebMPrompt.css b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerIEWebMPrompt.css new file mode 100644 index 00000000..9cf7b490 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerIEWebMPrompt.css @@ -0,0 +1,18 @@ +.mwEmbedPlayer .iewebm-prompt { + position: absolute; + top: 100px; + bottom: 60px; + left: 20px; + right: 20px; + border-radius: 20px; + background-color: rgba(255, 255, 255, 0.75); + + width: auto !important; + height: auto !important; + + padding: 20px; +} + +.mwEmbedPlayer .iewebm-prompt div { + color: black; +}
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerIEWebMPrompt.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerIEWebMPrompt.js new file mode 100644 index 00000000..00694f81 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerIEWebMPrompt.js @@ -0,0 +1,46 @@ +/** + * Show a prompt to install WebM plugin for IE 9+ + */ + +( function( mw, $ ) { "use strict"; + +mw.EmbedPlayerIEWebMPrompt = { + // List of supported features (or lack thereof) + supports: { + 'playHead':false, /* The seek slider */ + 'pause':true, /* Play pause button in control bar */ + 'stop':true, /* Does this actually do anything?? */ + 'fullscreen':false, + 'timeDisplay':false, + 'volumeControl':false + }, + + // Instance name: + instanceOf:'IEWebMPrompt', + + /* + * Embed this "fake" player + * + * @return {String} + * embed code to link to WebM plugin download + */ + embedPlayerHTML: function() { + var pluginUrl = 'https://tools.google.com/dlpage/webmmf/', + $link; + + // Overlay the video placeholder with download plugin link. + $link = $( '<a></a>' ) + .attr( 'href', pluginUrl ) + .attr( 'target', '_blank' ) + .text( mw.msg( 'mwe-embedplayer-iewebmprompt-linktext' ) ); + $( this ).append( $( '<div class="iewebm-prompt"></div>' ) + .width( this.getWidth() ) + .height( this.getHeight() ) + .append( $( '<div></div>' ).text( mw.msg( 'mwe-embedplayer-iewebmprompt-intro' ) ) ) + .append( $link ) + .append( $( '<div></div>' ).text( mw.msg( 'mwe-embedplayer-iewebmprompt-outro' ) ) ) + ); + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js new file mode 100644 index 00000000..f6271621 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerImageOverlay.js @@ -0,0 +1,307 @@ +/** + * Used to Overlay images and take over player controls + * + * extends EmbedPlayerNative object image overlay support + */ + +mw.EmbedPlayerImageOverlay = { + + instanceOf: 'ImageOverlay', + + // If the player is "ready to play" + playerReady : true, + + // Pause time used to track player time between pauses + lastPauseTime: 0, + + // currentTime updated via internal clockStartTime var + currentTime:0, + + // StartOffset support seeking into the virtual player + startOffset:0, + + // The local clock used to emulate playback time + clockStartTime: 0, + + /** + * Build the player interface: + */ + init: function(){ + // Check if features are already updated: + if( this['native_instaceOf'] == 'Native' ){ + return ; + } + // inherit mw.EmbedPlayerNative ( + for( var i in mw.EmbedPlayerNative ){ + if( typeof mw.EmbedPlayerImageOverlay[ i ] != 'undefined' ){ + this['native_' + i ] = mw.EmbedPlayerNative[i]; + } else { + this[ i ] = mw.EmbedPlayerNative[i]; + } + } + }, + + /** + * When on playback method switch remove imageOverlay + * @param {function} callback + */ + updatePlaybackInterface: function( callback ){ + mw.log( 'EmbedPlayerImageOverlay:: updatePlaybackInterface remove imageOverlay: ' + $(this).siblings( '.imageOverlay' ).length ); + // Reset lastPauseTime + this.lastPauseTime = 0; + // Clear imageOverlay sibling: + $( this ).find( '.imageOverlay' ).remove(); + // Restore the video element on screen position: + $( this.getPlayerElement() ).css('left', 0 ); + // Call normal parent updatePlaybackInterface + this.parent_updatePlaybackInterface( callback ); + }, + + /** + * The method called to "show the player" + * For image overlay we want to: + * Set black video urls for player source + * Add an image overlay + */ + updatePosterHTML: function(){ + var vid = this.getPlayerElement(); + $( vid ).empty() + + // Provide modules the opportunity to supply black sources ( for registering event click ) + // this is need for iPad to capture the play click to auto continue after "playing an image" + // ( iOS requires a user gesture to initiate video playback ) + + // We don't just include the sources as part of core config, since it would result in + // a possible privacy leakage i.e hitting the kaltura servers when playing images. + this.triggerHelper( 'AddEmptyBlackSources', [ vid ] ); + + // embed the image: + this.embedPlayerHTML(); + + // add the play btn: + this.addLargePlayBtn(); + }, + + /** + * Play function starts the video playback + */ + play: function() { + mw.log( 'EmbedPlayerImageOverlay::play> lastPauseTime:' + this.lastPauseTime + ' ct: ' + this.currentTime ); + this.applyIntrinsicAspect(); + // Check for image duration + + // Reset playback if currentTime > duration: + if( this.currentTime > this.getDuration() ) { + this.currentTime = this.pauseTime = 0; + } + + // No longer in a stopped state: + this.stopped = false; + + // Capture the play event on the native player: ( should just be black silent sources ) + // This is needed so that if a playlist starts with image, it can continue to play the + // subsequent video without on iOS without requiring another click. + if( ! $( this ).data('previousInstanceOf') ){ + // Update the previousInstanceOf flag: + $( this ).data('previousInstanceOf', this.instanceOf ); + var vid = this.getPlayerElement(); + // populate the video with black video sources: + this.triggerHelper( 'AddEmptyBlackSources', [ vid ] ); + // run play: + vid.play(); + // inline pause + setTimeout(function(){ + vid.pause(); + },0); + // add another pause request after 500 ms ( iOS sometimes does not listen the first time ) + setTimeout(function(){ + vid.pause(); + }, mw.config.get( 'EmbedPlayer.MonitorRate' ) * 2 ); + } + // call the parent play ( to update interface and call respective triggers ) + this.parent_play(); + // make sure we are in play interface: + this.playInterfaceUpdate(); + + this.clockStartTime = new Date().getTime(); + // Start up monitor: + this.monitor(); + }, + getDuration: function(){ + if( this.duration ){ + return this.duration; + } + if( this.imageDuration ){ + this.duration = this.imageDuration ; + } else { + this.duration = mw.config.get( "EmbedPlayer.DefaultImageDuration" ); + } + // make sure duration has type float: + this.duration = parseFloat( this.duration ); + return this.duration; + }, + /** + * Stops the playback + */ + stop: function() { + this.currentTime = 0; + this.parent_stop(); + }, + _onpause: function(){ + // catch the native event ( and do nothing ) + }, + /** + * Preserves the pause time across for timed playback + */ + pause: function( ) { + this.lastPauseTime = this.currentTime; + mw.log( 'EmbedPlayerImageOverlay::pause, lastPauseTime: ' + this.lastPauseTime ); + // run parent pause; + this.parent_pause(); + this.stopMonitor(); + }, + + monitor: function(){ + if( this.duration == 0 ){ + this.disablePlayControls(); + return ; + } + $( this ).trigger( 'timeupdate' ); + + if ( this.currentTime >= this.duration ) { + $( this ).trigger( 'ended' ); + } else { + // Run the parent monitor: + this.parent_monitor(); + } + }, + /** + * Seeks to a given percent and updates the lastPauseTime + * + * @param {Float} seekPercent Percentage to seek into the virtual player + */ + seek: function( seekPercent ) { + this.lastPauseTime = seekPercent * this.getDuration(); + this.seeking = false; + // start seeking: + $( this ).trigger( 'seeking' ); + // Done seeking + $( this ).trigger( 'seeked' ); + this.play(); + }, + + /** + * Sets the current Time + * + * @param {Float} perc Percentage to seek into the virtual player + * @param {Function} callback Function called once time has been updated + */ + setCurrentTime: function( time, callback ) { + this.lastPauseTime = time; + // start seeking: + $( this ).trigger( 'seeking' ); + // Done seeking + $( this ).trigger( 'seeked' ); + if( callback ){ + callback(); + } + }, + /** + * Switch the image playback + */ + playerSwitchSource: function( source, switchCallback, doneCallback ){ + var _this = this; + this.selectedSource = source; + this.embedPlayerHTML(); + this.applyIntrinsicAspect(); + this.play(); + if( switchCallback ){ + switchCallback( this ); + } + // Wait for ended event to tr + $( this ).bind('ended.playerSwitchSource', function(){ + $( _this ).unbind('ended.playerSwitchSource'); + if( doneCallback ) { + doneCallback( this ); + } + }) + }, + /** + * Get the embed player time + */ + getPlayerElementTime: function() { + this.currentTime = ( ( new Date().getTime() - this.clockStartTime ) / 1000 ) + this.lastPauseTime; + return this.currentTime; + }, + /** + * Get the "embed" html for the html player + */ + embedPlayerHTML: function() { + var _this = this; + // remove any old imageOverlay: + this.$interface.find('.imageOverlay').remove(); + mw.log( 'EmbedPlayerImageOverlay :doEmbedHTML: ' + this.id ); + + var currentSoruceObj = this.selectedSource; + + if( !currentSoruceObj ){ + mw.log("Error:: EmbedPlayerImageOverlay:embedPlayerHTML> missing source" ); + return ; + } + var $image = + $( '<img />' ) + .css({ + 'position': 'relative', + 'width': '100%', + 'height': '100%' + }) + .attr({ + 'src' : currentSoruceObj.getSrc() + }) + .addClass( 'imageOverlay' ) + .load( function(){ + // reset clock time: + _this.clockStartTime = new Date().getTime(); + _this.monitor(); + }) + + // move the video element off screen: + $( this.getPlayerElement() ).css({ + 'left': this.getWidth()+50, + 'position' : 'absolute' + }); + + // Add the image before the video element or before the playerInterface + $( this ).html( $image ); + + this.applyIntrinsicAspect(); + }, + // wrap the parent rewize player to apply intensic apsect + resizePlayer: function( size , animate, callback){ + this.parent_resizePlayer( size , animate, callback ); + this.applyIntrinsicAspect(); + }, + applyIntrinsicAspect: function(){ + var $this = this.$interface; + // Check if a image thumbnail is present: + /*if( this.$interface && this.$interface.find('.imageOverlay').length ){ + var img = this.$interface.find('.imageOverlay')[0]; + var pHeight = $this.height(); + // Check for intrinsic width and maintain aspect ratio + if( img.naturalWidth && img.naturalHeight ){ + var pWidth = parseInt( img.naturalWidth / img.naturalHeight * pHeight); + if( pWidth > $this.width() ){ + pWidth = $this.width(); + pHeight = parseInt( img.naturalHeight / img.naturalWidth * pWidth ); + } + $( img ).css({ + 'height' : pHeight + 'px', + 'width': pWidth + 'px', + 'left': ( ( $this.width() - pWidth ) * .5 ) + 'px', + 'top': ( ( $this.height() - pHeight ) * .5 ) + 'px', + 'position' : 'absolute' + }); + } + }*/ + } +};
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js new file mode 100644 index 00000000..739a7769 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerKplayer.js @@ -0,0 +1,485 @@ +/* + * The "kaltura player" embedPlayer interface for fallback h.264 and flv video format support + */ +( function( mw, $ ) { "use strict"; + +// Called from the kdp.swf +window.jsInterfaceReadyFunc = function() { + return true; +} + +mw.EmbedPlayerKplayer = { + + // Instance name: + instanceOf : 'Kplayer', + + bindPostfix: '.kPlayer', + + // List of supported features: + supports : { + 'playHead' : true, + 'pause' : true, + 'stop' : true, + 'timeDisplay' : true, + 'volumeControl' : true, + 'overlays' : true, + 'fullscreen' : true + }, + + // Stores the current time as set from flash player + flashCurrentTime : 0, + + /* + * Write the Embed html to the target + */ + embedPlayerHTML : function() { + var _this = this; + + mw.log("EmbedPlayerKplayer:: embed src::" + _this.getSrc()); + var flashvars = {}; + flashvars.autoPlay = "true"; + flashvars.loop = "false"; + + var playerPath = mw.absoluteUrl( mw.getEmbedPlayerPath() + '/binPlayers/kaltura-player' ); + flashvars.entryId = mw.absoluteUrl( _this.getSrc() ); + + // Use a relative url if the protocol is file:// + if ( new mw.Uri( document.URL ).protocol == 'file' ) { + playerPath = mw.getRelativeMwEmbedPath() + 'modules/EmbedPlayer/binPlayers/kaltura-player'; + flashvars.entryId = _this.getSrc(); + } + + flashvars.debugMode = "false"; + flashvars.fileSystemMode = "true"; + flashvars.widgetId = "_7463"; + flashvars.partnerId = "7463"; + flashvars.pluginDomain = "kdp3/plugins/"; + flashvars.kml = "local"; + flashvars.kmlPath = playerPath + '/config.xml'; + flashvars.sourceType = "url"; + flashvars.jsInterfaceReadyFunc = "jsInterfaceReadyFunc"; + + // flashvars.host = "www.kaltura.com"; + flashvars.externalInterfaceDisabled = "false"; + flashvars.skinPath = playerPath + '/skin.swf'; + + flashvars["full.skinPath"] = playerPath + '/LightDoodleskin.swf'; + var flashVarParam = ''; + $.each( flashvars, function( fKey, fVal ){ + flashVarParam += '&' + fKey + '=' + encodeURIComponent( fVal ); + } ); + + var kdpPath = playerPath + "/kdp3.3.5.27.swf"; + + mw.log( "KPlayer:: embedPlayerHTML" ); + // remove any existing pid ( if present ) + $( '#' + this.pid ).remove(); + + var orgJsReadyCallback = window.jsCallbackReady; + window.jsCallbackReady = function( playerId ){ + _this.postEmbedActions(); + window.jsCallbackReady = orgJsReadyCallback; + }; + // attributes and params: + flashembed( $( this ).attr('id'), + { + id : this.pid, + src : kdpPath, + height : '100%', + width : '100%', + bgcolor : "#000000", + allowNetworking : "all", + version : [10,0], + wmode : "opaque" + }, + flashvars + ) + // Remove any old bindings: + $(_this).unbind( this.bindPostfix ); + + // Flash player loses its bindings once it changes sizes:: + $(_this).bind('onOpenFullScreen' + this.bindPostfix , function() { + _this.postEmbedActions(); + }); + $(_this).bind('onCloseFullScreen' + this.bindPostfix, function() { + _this.postEmbedActions(); + }); + }, + + // The number of times we have tried to bind the player + bindTryCount : 0, + + /** + * javascript run post player embedding + */ + postEmbedActions : function() { + var _this = this; + this.getPlayerElement(); + if ( this.playerElement && this.playerElement.addJsListener ) { + var bindEventMap = { + 'playerPaused' : 'onPause', + 'playerPlayed' : 'onPlay', + 'durationChange' : 'onDurationChange', + 'playerPlayEnd' : 'onClipDone', + 'playerUpdatePlayhead' : 'onUpdatePlayhead', + 'bytesTotalChange' : 'onBytesTotalChange', + 'bytesDownloadedChange' : 'onBytesDownloadedChange' + }; + + $.each( bindEventMap, function( bindName, localMethod ) { + _this.bindPlayerFunction(bindName, localMethod); + }); + this.bindTryCount = 0; + // Start the monitor + this.monitor(); + } else { + this.bindTryCount++; + // Keep trying to get the player element + if( this.bindTryCount > 500 ){ // 5 seconds + mw.log('Error:: KDP player never ready for bindings!'); + return ; + } + setTimeout(function() { + _this.postEmbedActions(); + }, 100); + } + }, + + /** + * Bind a Player Function, + * + * Build a global callback to bind to "this" player instance: + * + * @param {String} + * flash binding name + * @param {String} + * function callback name + */ + bindPlayerFunction : function(bindName, methodName) { + mw.log( 'EmbedPlayerKplayer:: bindPlayerFunction:' + bindName ); + // The kaltura kdp can only call a global function by given name + var gKdpCallbackName = 'kdp_' + methodName + '_cb_' + this.id.replace(/[^a-zA-Z 0-9]+/g,''); + + // Create an anonymous function with local player scope + var createGlobalCB = function(cName, embedPlayer) { + window[ cName ] = function(data) { + // Track all events ( except for playerUpdatePlayhead ) + if( bindName != 'playerUpdatePlayhead' ){ + mw.log("EmbedPlayerKplayer:: event: " + bindName); + } + if ( embedPlayer._propagateEvents ) { + embedPlayer[methodName](data); + } + }; + }(gKdpCallbackName, this); + // Remove the listener ( if it exists already ) + this.playerElement.removeJsListener( bindName, gKdpCallbackName ); + // Add the listener to the KDP flash player: + this.playerElement.addJsListener( bindName, gKdpCallbackName); + }, + + /** + * on Pause callback from the kaltura flash player calls parent_pause to + * update the interface + */ + onPause : function() { + this.parent_pause(); + }, + + /** + * onPlay function callback from the kaltura flash player directly call the + * parent_play + */ + onPlay : function() { + this.parent_play(); + }, + + onDurationChange : function(data, id) { + // Update the duration ( only if not in url time encoding mode: + if( !this.supportsURLTimeEncoding() ){ + this.duration = data.newValue; + this.triggerHelper('durationchange'); + } + }, + + /** + * play method calls parent_play to update the interface + */ + play: function() { + if ( this.playerElement && this.playerElement.sendNotification ) { + this.playerElement.sendNotification('doPlay'); + } + this.parent_play(); + }, + + /** + * pause method calls parent_pause to update the interface + */ + pause: function() { + if (this.playerElement && this.playerElement.sendNotification) { + this.playerElement.sendNotification('doPause'); + } + this.parent_pause(); + }, + /** + * playerSwitchSource switches the player source working around a few bugs in browsers + * + * @param {object} + * source Video Source object to switch to. + * @param {function} + * switchCallback Function to call once the source has been switched + * @param {function} + * doneCallback Function to call once the clip has completed playback + */ + playerSwitchSource: function( source, switchCallback, doneCallback ){ + var _this = this; + var waitCount = 0; + var src = source.getSrc(); + // Check if the source is already set to the target: + if( !src || src == this.getSrc() ){ + if( switchCallback ){ + switchCallback(); + } + setTimeout(function(){ + if( doneCallback ) + doneCallback(); + }, 100); + return ; + } + + var waitForJsListen = function( callback ){ + if( _this.getPlayerElement() && _this.getPlayerElement().addJsListener ){ + callback(); + } else { + // waited for 2 seconds fail + if( waitCount > 20 ){ + mw.log( "Error: Failed to swtich player source!"); + if( switchCallback ) + switchCallback(); + if( doneCallback ) + doneCallback(); + return; + } + + setTimeout(function(){ + waitCount++; + waitForJsListen( callback ); + },100) + } + }; + // wait for jslistener to be ready: + waitForJsListen( function(){ + var gPlayerReady = 'kdp_switch_' + _this.id + '_switchSrcReady'; + var gDoneName = 'kdp_switch_' + _this.id + '_switchSrcEnd'; + var gChangeMedia = 'kdp_switch_' + _this.id + '_changeMedia'; + window[ gPlayerReady ] = function(){ + mw.log("EmbedPlayerKplayer:: playerSwitchSource: " + src); + // remove the binding as soon as possible ( we only want this event once ) + _this.getPlayerElement().removeJsListener( 'playerReady', gPlayerReady ); + + _this.getPlayerElement().sendNotification("changeMedia", { 'entryId': src } ); + + window[ gChangeMedia ] = function (){ + mw.log("EmbedPlayerKplayer:: Media changed: " + src); + if( $.isFunction( switchCallback) ){ + switchCallback( _this ); + switchCallback = null + } + // restore monitor: + _this.monitor(); + } + // Add change media binding + _this.getPlayerElement().removeJsListener('changeMedia', gChangeMedia); + _this.getPlayerElement().addJsListener( 'changeMedia', gChangeMedia); + + window[ gDoneName ] = function(){ + if( $.isFunction( doneCallback ) ){ + doneCallback(); + doneCallback = null; + } + }; + _this.getPlayerElement().removeJsListener('playerPlayEnd', gDoneName); + _this.getPlayerElement().addJsListener( 'playerPlayEnd', gDoneName); + }; + // Remove then add the event: + _this.getPlayerElement().removeJsListener( 'playerReady', gPlayerReady ); + _this.getPlayerElement().addJsListener( 'playerReady', gPlayerReady ); + }); + }, + + /** + * Issues a seek to the playerElement + * + * @param {Float} + * percentage Percentage of total stream length to seek to + */ + seek : function(percentage) { + var _this = this; + var seekTime = percentage * this.getDuration(); + mw.log( 'EmbedPlayerKalturaKplayer:: seek: ' + percentage + ' time:' + seekTime ); + if (this.supportsURLTimeEncoding()) { + + // Make sure we could not do a local seek instead: + if (!(percentage < this.bufferedPercent + && this.playerElement.duration && !this.didSeekJump)) { + // We support URLTimeEncoding call parent seek: + this.parent_seek( percentage ); + return; + } + } + // Add a seeked callback event: + var seekedCallback = 'kdp_seek_' + this.id + '_' + new Date().getTime(); + window[ seekedCallback ] = function(){ + _this.seeking = false; + _this.triggerHelper( 'seeked' ); + if( seekInterval ) { + clearInterval( seekInterval ); + } + }; + this.playerElement.addJsListener('playerSeekEnd', seekedCallback ); + + if ( this.getPlayerElement() ) { + // trigger the html5 event: + _this.triggerHelper( 'seeking' ); + + // Issue the seek to the flash player: + this.playerElement.sendNotification('doSeek', seekTime); + + // Include a fallback seek timer: in case the kdp does not fire 'playerSeekEnd' + var orgTime = this.flashCurrentTime; + var seekInterval = setInterval( function(){ + if( _this.flashCurrentTime != orgTime ){ + _this.seeking = false; + clearInterval( seekInterval ); + this.triggerHelper( 'seeked' ); + } + }, mw.config.get( 'EmbedPlayer.MonitorRate' ) ); + + } else { + // try to do a play then seek: + this.doPlayThenSeek(percentage); + } + + // Run the onSeeking interface update + this.controlBuilder.onSeek(); + }, + + /** + * Seek in a existing stream + * + * @param {Float} + * percentage Percentage of the stream to seek to between 0 and 1 + */ + doPlayThenSeek : function(percentage) { + mw.log('EmbedPlayerKplayer::doPlayThenSeek::'); + var _this = this; + // issue the play request + this.play(); + + // let the player know we are seeking + _this.seeking = true; + this.triggerHelper( 'seeking' ); + + var getPlayerCount = 0; + var readyForSeek = function() { + _this.getPlayerElement(); + // if we have duration then we are ready to do the seek ( flash can't + // seek untill there is some buffer ) + if (_this.playerElement && _this.playerElement.sendNotification + && _this.getDuration() && _this.bufferedPercent) { + var seekTime = percentage * _this.getDuration(); + // Issue the seek to the flash player: + _this.playerElement.sendNotification('doSeek', seekTime); + } else { + // Try to get player for 20 seconds: + if (getPlayerCount < 400) { + setTimeout(readyForSeek, 50); + getPlayerCount++; + } else { + mw.log('Error: doPlayThenSeek failed'); + } + } + }; + readyForSeek(); + }, + + /** + * Issues a volume update to the playerElement + * + * @param {Float} + * percentage Percentage to update volume to + */ + setPlayerElementVolume : function(percentage) { + if ( this.getPlayerElement() && this.playerElement.sendNotification ) { + this.playerElement.sendNotification('changeVolume', percentage); + } + }, + + /** + * function called by flash at set interval to update the playhead. + */ + onUpdatePlayhead : function( playheadValue ) { + //mw.log('Update play head::' + playheadValue); + this.flashCurrentTime = playheadValue; + }, + + /** + * function called by flash when the total media size changes + */ + onBytesTotalChange : function(data, id) { + this.bytesTotal = data.newValue; + }, + + /** + * function called by flash applet when download bytes changes + */ + onBytesDownloadedChange : function(data, id) { + //mw.log('onBytesDownloadedChange'); + this.bytesLoaded = data.newValue; + this.bufferedPercent = this.bytesLoaded / this.bytesTotal; + + // Fire the parent html5 action + this.triggerHelper('progress', { + 'loaded' : this.bytesLoaded, + 'total' : this.bytesTotal + }); + }, + + /** + * Get the embed player time + */ + getPlayerElementTime : function() { + // update currentTime + return this.flashCurrentTime; + }, + + /** + * Get the embed fla object player Element + */ + getPlayerElement : function() { + this.playerElement = document.getElementById( this.pid ); + return this.playerElement; + } +}; + +} )( mediaWiki, jQuery ); + +/* + * jQuery Tools 1.2.5 - The missing UI library for the Web + * + * [toolbox.flashembed] + * + * NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE. + * + * http://flowplayer.org/tools/ + * + * File generated: Fri Oct 22 13:51:38 GMT 2010 + */ +(function(){function f(a,b){if(b)for(var c in b)if(b.hasOwnProperty(c))a[c]=b[c];return a}function l(a,b){var c=[];for(var d in a)if(a.hasOwnProperty(d))c[d]=b(a[d]);return c}function m(a,b,c){if(e.isSupported(b.version))a.innerHTML=e.getHTML(b,c);else if(b.expressInstall&&e.isSupported([6,65]))a.innerHTML=e.getHTML(f(b,{src:b.expressInstall}),{MMredirectURL:location.href,MMplayerType:"PlugIn",MMdoctitle:document.title});else{if(!a.innerHTML.replace(/\s/g,"")){a.innerHTML="<h2>Flash version "+b.version+ +" or greater is required</h2><h3>"+(g[0]>0?"Your version is "+g:"You have no flash plugin installed")+"</h3>"+(a.tagName=="A"?"<p>Click here to download latest version</p>":"<p>Download latest version from <a href='"+k+"'>here</a></p>");if(a.tagName=="A")a.onclick=function(){location.href=k}}if(b.onFail){var d=b.onFail.call(this);if(typeof d=="string")a.innerHTML=d}}if(i)window[b.id]=document.getElementById(b.id);f(this,{getRoot:function(){return a},getOptions:function(){return b},getConf:function(){return c}, +getApi:function(){return a.firstChild}})}var i=document.all,k="http://www.adobe.com/go/getflashplayer",n=typeof jQuery=="function",o=/(\d+)[^\d]+(\d+)[^\d]*(\d*)/,j={width:"100%",height:"100%",id:"_"+(""+Math.random()).slice(9),allowfullscreen:true,allowscriptaccess:"always",quality:"high",version:[3,0],onFail:null,expressInstall:null,w3c:false,cachebusting:false};window.attachEvent&&window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}}); +window.flashembed=function(a,b,c){if(typeof a=="string")a=document.getElementById(a.replace("#",""));if(a){if(typeof b=="string")b={src:b};return new m(a,f(f({},j),b),c)}};var e=f(window.flashembed,{conf:j,getVersion:function(){var a,b;try{b=navigator.plugins["Shockwave Flash"].description.slice(16)}catch(c){try{b=(a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"))&&a.GetVariable("$version")}catch(d){try{b=(a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"))&&a.GetVariable("$version")}catch(h){}}}return(b= +o.exec(b))?[b[1],b[3]]:[0,0]},asString:function(a){if(a===null||a===undefined)return null;var b=typeof a;if(b=="object"&&a.push)b="array";switch(b){case "string":a=a.replace(new RegExp('(["\\\\])',"g"),"\\$1");a=a.replace(/^\s?(\d+\.?\d+)%/,"$1pct");return'"'+a+'"';case "array":return"["+l(a,function(d){return e.asString(d)}).join(",")+"]";case "function":return'"function()"';case "object":b=[];for(var c in a)a.hasOwnProperty(c)&&b.push('"'+c+'":'+e.asString(a[c]));return"{"+b.join(",")+"}"}return String(a).replace(/\s/g, +" ").replace(/\'/g,'"')},getHTML:function(a,b){a=f({},a);var c='<object width="'+a.width+'" height="'+a.height+'" id="'+a.id+'" name="'+a.id+'"';if(a.cachebusting)a.src+=(a.src.indexOf("?")!=-1?"&":"?")+Math.random();c+=a.w3c||!i?' data="'+a.src+'" type="application/x-shockwave-flash"':' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';c+=">";if(a.w3c||i)c+='<param name="movie" value="'+a.src+'" />';a.width=a.height=a.id=a.w3c=a.src=null;a.onFail=a.version=a.expressInstall=null;for(var d in a)if(a[d])c+= +'<param name="'+d+'" value="'+a[d]+'" />';a="";if(b){for(var h in b)if(b[h]){d=b[h];a+=h+"="+(/function|object/.test(typeof d)?e.asString(d):d)+"&"}a=a.slice(0,-1);c+='<param name="flashvars" value=\''+a+"' />"}c+="</object>";return c},isSupported:function(a){return g[0]>a[0]||g[0]==a[0]&&g[1]>=a[1]}}),g=e.getVersion();if(n){jQuery.tools=jQuery.tools||{version:"1.2.5"};jQuery.tools.flashembed={conf:j};jQuery.fn.flashembed=function(a,b){return this.each(function(){$(this).data("flashembed",flashembed(this, +a,b))})}}})(); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerNative.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerNative.js new file mode 100644 index 00000000..8c514f70 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerNative.js @@ -0,0 +1,1088 @@ +/** +* Native embed library: +* +* Enables embedPlayer support for native html5 browser playback system +*/ +( function( mw, $ ) { "use strict"; + +mw.EmbedPlayerNative = { + + //Instance Name + instanceOf: 'Native', + + // Flag to only load the video ( not play it ) + onlyLoadFlag:false, + + //Callback fired once video is "loaded" + onLoadedCallback: null, + + // The previous "currentTime" to sniff seek actions + // NOTE the bug where onSeeked does not seem fire consistently may no longer be applicable + prevCurrentTime: -1, + + // Store the progress event ( updated during monitor ) + progressEventData: null, + + // If the media loaded event has been fired + mediaLoadedFlag: null, + + // A flag to keep the video tag offscreen. + keepPlayerOffScreenFlag: null, + + // A flag to designate the first play event, as to not propagate the native event in this case + isFirstEmbedPlay: null, + + // A local var to store the current seek target time: + currentSeekTargetTime: null, + + // All the native events per: + // http://www.w3.org/TR/html5/video.html#mediaevents + nativeEvents : [ + 'loadstart', + 'progress', + 'suspend', + 'abort', + 'error', + 'emptied', + 'stalled', + 'play', + 'pause', + 'loadedmetadata', + 'loadeddata', + 'waiting', + 'playing', + 'canplay', + 'canplaythrough', + 'seeking', + 'seeked', + 'timeupdate', + 'ended', + 'ratechange', + 'durationchange', + 'volumechange' + ], + + // Native player supported feature set + supports: { + 'playHead' : true, + 'pause' : true, + 'fullscreen' : true, + 'sourceSwitch': true, + 'timeDisplay' : true, + 'volumeControl' : true, + 'overlays' : true + }, + /** + * Updates the supported features given the "type of player" + */ + updateFeatureSupport: function(){ + // The native controls function checks for overly support + // especially the special case of iPad in-dom or not support + if( this.useNativePlayerControls() ) { + this.supports.overlays = false; + this.supports.volumeControl = false; + } + // iOS does not support volume control + if( mw.isIpad() ){ + this.supports.volumeControl = false; + } + // Check if we already have a selected source and a player in the page, + if( this.getPlayerElement() && this.getSrc() ){ + $( this.getPlayerElement() ).attr( 'src', this.getSrc() ); + } + // Check if we already have a video element an apply bindings ( for native interfaces ) + if( this.getPlayerElement() ){ + this.applyMediaElementBindings(); + } + + this.parent_updateFeatureSupport(); + }, + /** + * Adds an HTML screen and moves the video tag off screen, works around some iPhone bugs + */ + addPlayScreenWithNativeOffScreen: function(){ + var _this = this; + // Hide the player offscreen: + this.hidePlayerOffScreen(); + this.keepPlayerOffScreenFlag = true; + + // Add a play button on the native player: + this.addLargePlayBtn(); + + // Add a binding to show loader once clicked to show the loader + // bad ui to leave the play button displayed + this.$interface.find( '.play-btn-large' ).click( function(){ + _this.$interface.find( '.play-btn-large' ).hide(); + _this.addPlayerSpinner(); + _this.hideSpinnerOncePlaying(); + }); + + // Add an image poster: + var posterSrc = ( this.poster ) ? this.poster : + mw.config.get( 'EmbedPlayer.BlackPixel' ); + + // Check if the poster is already present: + if( $( this ).find( '.playerPoster' ).length ){ + $( this ).find( '.playerPoster' ).attr('src', posterSrc ); + } else { + $( this ).append( + $('<img />').css({ + 'margin' : '0', + 'width': '100%', + 'height': '100%' + }) + .attr( 'src', posterSrc) + .addClass('playerPoster') + ) + } + $( this ).show(); + }, + /** + * Return the embed code + */ + embedPlayerHTML : function () { + var _this = this; + var vid = _this.getPlayerElement(); + this.isFirstEmbedPlay = true; + + // Check if we should have a play button on the native player: + if( this.useLargePlayBtn() ){ + this.addLargePlayBtn(); + } + + if( vid && $( vid ).attr('src') == this.getSrc( this.currentTime ) ){ + _this.postEmbedActions(); + return ; + } + mw.log( "EmbedPlayerNative::embedPlayerHTML > play url:" + this.getSrc( this.currentTime ) + ' startOffset: ' + this.start_ntp + ' end: ' + this.end_ntp ); + + // Check if using native controls and already the "pid" is already in the DOM + if( this.isPersistentNativePlayer() && vid ) { + _this.postEmbedActions(); + return ; + } + // Reset some play state flags: + _this.bufferStartFlag = false; + _this.bufferEndFlag = false; + + $( this ).html( + _this.getNativePlayerHtml() + ); + + // Directly run postEmbedActions ( if playerElement is not available it will retry ) + _this.postEmbedActions(); + }, + + /** + * Get the native player embed code. + * + * @param {object} playerAttributes Attributes to be override in function call + * @return {object} cssSet css to apply to the player + */ + getNativePlayerHtml: function( playerAttributes, cssSet ){ + if( !playerAttributes) { + playerAttributes = {}; + } + // Update required attributes + if( !playerAttributes['id'] ){ + playerAttributes['id'] = this.pid; + } + if( !playerAttributes['src'] ){ + playerAttributes['src'] = this.getSrc( this.currentTime); + } + + // If autoplay pass along to attribute ( needed for iPad / iPod no js autoplay support + if( this.autoplay ) { + playerAttributes['autoplay'] = 'true'; + } + + if( !cssSet ){ + cssSet = {}; + } + + // Set default width height to 100% of parent container + if( !cssSet['width'] ) cssSet['width'] = '100%'; + if( !cssSet['height'] ) cssSet['height'] = '100%'; + + // Also need to set the loop param directly for iPad / iPod + if( this.loop ) { + playerAttributes['loop'] = 'true'; + } + + var tagName = this.isAudio() ? 'audio' : 'video'; + + return $( '<' + tagName + ' />' ) + // Add the special nativeEmbedPlayer to avoid any rewrites of of this video tag. + .addClass( 'nativeEmbedPlayerPid' ) + .attr( playerAttributes ) + .css( cssSet ) + }, + + /** + * Post element javascript, binds event listeners and starts monitor + */ + postEmbedActions: function() { + var _this = this; + // Setup local pointer: + var vid = this.getPlayerElement(); + if( !vid ){ + return ; + } + // Update the player source ( if needed ) + if( $( vid).attr( 'src' ) != this.getSrc( this.currentTime ) ){ + $( vid ).attr( 'src', this.getSrc( this.currentTime ) ); + } + // Update the WebKitPlaysInline value + if( mw.config.get( 'EmbedPlayer.WebKitPlaysInline') ){ + $( vid ).attr( 'webkit-playsinline', 1 ); + } + // Update the EmbedPlayer.WebKitAllowAirplay option: + if( mw.config.get( 'EmbedPlayer.WebKitAllowAirplay' ) ){ + $( vid ).attr( 'x-webkit-airplay', "allow" ); + } + // make sure to display native controls if enabled: + if( this.useNativePlayerControls() ){ + $( vid ).attr( 'controls', "true" ); + } + + // Apply media element bindings: + _this.applyMediaElementBindings(); + + // Make sure we start playing in the correct place: + if( this.currentTime != vid.currentTime ){ + var waitReadyStateCount = 0; + var checkReadyState = function(){ + if( vid.readyState > 0 ){ + vid.currentTime = this.currentTime; + return ; + } + if( waitReadyStateCount > 1000 ){ + mw.log("Error: EmbedPlayerNative: could not run native seek"); + return ; + } + waitReadyStateCount++; + setTimeout( function() { + checkReadyState(); + }, 10 ); + }; + } + // Some mobile devices ( iOS need a load call before play will work ) + if ( !_this.loop ) { + vid.load(); + } + }, + /** + * Apply media element bindings + */ + applyMediaElementBindings: function(){ + var _this = this; + mw.log("EmbedPlayerNative::MediaElementBindings"); + var vid = this.getPlayerElement(); + if( ! vid ){ + mw.log( " Error: applyMediaElementBindings without player elemnet"); + return ; + } + $.each( _this.nativeEvents, function( inx, eventName ){ + $( vid ).unbind( eventName + '.embedPlayerNative').bind( eventName + '.embedPlayerNative', function(){ + if( _this._propagateEvents ){ + var argArray = $.makeArray( arguments ); + // always pass the current ref id as the last argument + // helps check against some event trigger ref issues in jQuery + argArray.push( _this.id ); + // Check if there is local handler: + if( _this[ '_on' + eventName ] ){ + _this[ '_on' + eventName ].apply( _this, argArray); + } else { + // No local handler directly propagate the event to the abstract object: + $( _this ).trigger( eventName, argArray ); + } + } + }); + }); + }, + + // basic monitor function to update buffer + monitor: function(){ + var _this = this; + var vid = _this.getPlayerElement(); + + // Update the bufferedPercent + if( vid && vid.buffered && vid.buffered.end && vid.duration ) { + try{ + this.bufferedPercent = ( vid.buffered.end(0) / vid.duration ); + } catch ( e ){ + // opera does not have buffered.end zero index support ? + } + } + _this.parent_monitor(); + }, + + + /** + * Issue a seeking request. + * + * @param {Float} percent + * @param {bollean} stopAfterSeek if the player should stop after the seek + */ + seek: function( percent, stopAfterSeek ) { + // bounds check + if( percent < 0 ){ + percent = 0; + } + + if( percent > 1 ){ + percent = 1; + } + mw.log( 'EmbedPlayerNative::seek p: ' + percent + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seekTimeSec ); + + // Trigger preSeek event for plugins that want to store pre seek conditions. + this.triggerHelper( 'preSeek', percent ); + + this.seeking = true; + // Update the current time ( local property ) + this.currentTime = ( percent * this.duration ).toFixed( 2 ) ; + + // trigger the seeking event: + mw.log( 'EmbedPlayerNative::seek:trigger' ); + this.triggerHelper( 'seeking' ); + + // Run the onSeeking interface update + this.controlBuilder.onSeek(); + + // @@todo check if the clip is loaded here (if so we can do a local seek) + if ( this.supportsURLTimeEncoding() ) { + // Make sure we could not do a local seek instead: + if ( percent < this.bufferedPercent && this.playerElement.duration && !this.didSeekJump ) { + mw.log( "EmbedPlayerNative::seek local seek " + percent + ' is already buffered < ' + this.bufferedPercent ); + this.doNativeSeek( percent ); + } else { + // We support URLTimeEncoding call parent seek: + this.parent_seek( percent ); + } + } else { + // Try to do a play then seek: + this.doNativeSeek( percent ); + } + }, + + /** + * Do a native seek by updating the currentTime + * @param {float} percent + * Percent to seek to of full time + */ + doNativeSeek: function( percent, callback ) { + // If player already seeking, exit + var _this = this; + // chrome crashes with multiple seeks: + if( (navigator.userAgent.indexOf('Chrome') === -1) && _this.playerElement.seeking ) { + return ; + } + + mw.log( 'EmbedPlayerNative::doNativeSeek::' + percent ); + this.seeking = true; + + this.seekTimeSec = 0; + + // Hide iPad video off screen ( iOS shows quicktime logo during seek ) + if( mw.isIOS() ){ + this.hidePlayerOffScreen(); + } + + this.setCurrentTime( ( percent * this.duration ) , function(){ + // Update the current time ( so that there is not a monitor delay in reflecting "seeked time" ) + _this.currentTime = _this.getPlayerElement().currentTime; + // Done seeking ( should be a fallback trigger event ) : + if( _this.seeking ){ + _this.seeking = false; + $( _this ).trigger( 'seeked' ); + } + // restore iPad video position: + _this.restorePlayerOnScreen(); + + _this.monitor(); + // issue the callback: + if( callback ){ + callback(); + } + }); + }, + + /** + * Seek in a existing stream, we first play then seek to work around issues with iPad seeking. + * + * @param {Float} percent + * percent of the stream to seek to between 0 and 1 + */ + doPlayThenSeek: function( percent ) { + mw.log( 'EmbedPlayerNative::doPlayThenSeek::' + percent + ' isPaused ' + this.paused); + var _this = this; + var oldPauseState = this.paused; + this.play(); + var retryCount = 0; + var readyForSeek = function() { + _this.getPlayerElement(); + // If we have duration then we are ready to do the seek + if ( _this.playerElement && _this.playerElement.duration ) { + _this.doNativeSeek( percent, function(){ + // restore pause if paused: + if( oldPauseState ){ + _this.pause(); + } + } ); + } else { + // Try to get player for 30 seconds: + // (it would be nice if the onmetadata type callbacks where fired consistently) + if ( retryCount < 800 ) { + setTimeout( readyForSeek, 10 ); + retryCount++; + } else { + mw.log( 'EmbedPlayerNative:: Error: doPlayThenSeek failed :' + _this.playerElement.duration); + } + } + }; + readyForSeek(); + }, + + /** + * Set the current time with a callback + * + * @param {Float} position + * Seconds to set the time to + * @param {Function} callback + * Function called once time has been set. + */ + setCurrentTime: function( seekTime , callback, callbackCount ) { + var _this = this; + if( !callbackCount ){ + callbackCount = 0; + } + mw.log( "EmbedPlayerNative:: setCurrentTime seekTime:" + seekTime + ' count:' + callbackCount ); + + // Make sure all the timeouts don't seek to an expired target: + $( this ).data('currentSeekTarget', seekTime ); + + var vid = this.getPlayerElement(); + // add a callback handler to null out callback: + var callbackHandler = function(){ + if( $.isFunction( callback ) ){ + callback(); + callback = null; + } + } + if( !vid ) { + callbackHandler(); + _this.currentSeekTargetTime = seekTime.toFixed( 2 ); + return; + } + // Check if player is ready for seek: + if( vid.readyState < 1 ){ + // Try to seek for 4 seconds: + if( callbackCount >= 40 ){ + mw.log("Error:: EmbedPlayerNative: with seek request, media never in ready state"); + callbackHandler(); + return ; + } + setTimeout( function(){ + // Check that this seek did not expire: + if( $( _this ).data('currentSeekTarget') != seekTime ){ + mw.log("EmbedPlayerNative:: expired seek target"); + return ; + } + _this.setCurrentTime( seekTime, callback , callbackCount+1); + }, 100 ); + return ; + } + // Check if currentTime is already set to the seek target: + if( vid.currentTime.toFixed(2) == seekTime.toFixed(2) ){ + mw.log("EmbedPlayerNative:: setCurrentTime: current time matches seek target: " + + vid.currentTime.toFixed(2) + ' == ' + seekTime.toFixed(2) ); + callbackHandler(); + return; + } + // setup a namespaced seek bind: + var seekBind = 'seeked.nativeSeekBind'; + + // Remove any old listeners + $( vid ).unbind( seekBind ); + // Bind a seeked listener for the callback + $( vid ).bind( seekBind, function( event ) { + // Remove the listener: + $( vid ).unbind( seekBind ); + + // Check if seeking to zero: + if( seekTime == 0 && vid.currentTime == 0 ){ + callbackHandler(); + return ; + } + + // Check if we got a valid seek: + if( vid.currentTime > 0 ){ + callbackHandler(); + } else { + mw.log( "Error:: EmbedPlayerNative: seek callback without time updatet " + vid.currentTime ); + } + }); + setTimeout(function(){ + // Check that this seek did not expire: + if( $( _this ).data('currentSeekTarget') != seekTime ){ + mw.log("EmbedPlayerNative:: Expired seek target"); + return ; + } + + if( $.isFunction( callback ) ){ + // if seek is within 5 seconds of the target assume success. ( key frame intervals can mess with seek accuracy ) + // this only runs where the seek callback failed ( i.e broken html5 seek ? ) + if( Math.abs( vid.currentTime - seekTime ) < 5 ){ + mw.log( "EmbedPlayerNative:: Seek time is within 5 seconds of target, sucessfull seek"); + callback(); + } else { + mw.log( "Error:: EmbedPlayerNative: Seek still has not made a callback after 5 seconds, retry"); + _this.setCurrentTime( seekTime, callback , callbackCount++ ); + } + } + }, 5000); + + // Try to update the playerElement time: + try { + _this.currentSeekTargetTime = seekTime.toFixed( 2 ); + // use toFixed ( iOS issue with float seek times ) + vid.currentTime = _this.currentSeekTargetTime; + } catch ( e ) { + mw.log("Error:: EmbedPlayerNative: Could not set video tag seekTime"); + callbackHandler(); + return ; + } + + // Check for seeking state ( some player iOS / iPad can only seek while playing ) + if(! vid.seeking ){ + mw.log( "Error:: not entering seek state, play and wait for positive time" ); + vid.play(); + setTimeout(function(){ + _this.waitForPositiveCurrentTime( function(){ + mw.log("EmbedPlayerNative:: Got possitive time:" + vid.currentTime.toFixed(3) + ", trying to seek again"); + _this.setCurrentTime( seekTime , callback, callbackCount+1 ); + }); + }, mw.config.get( 'EmbedPlayer.MonitorRate' ) ); + } + }, + waitForPositiveCurrentTime: function( callback ){ + var _this = this; + var vid = this.getPlayerElement(); + this.waitForPositiveCurrentTimeCount++; + // Wait for playback for 10 seconds + if( vid.currentTime > 0 ){ + mw.log( 'EmbedPlayerNative:: waitForPositiveCurrentTime success' ); + callback(); + } else if( this.waitForPositiveCurrentTimeCount > 200 ){ + mw.log( "Error:: waitForPositiveCurrentTime failed to reach possitve time"); + callback(); + } else { + setTimeout(function(){ _this.waitForPositiveCurrentTime( callback ) }, 50 ) + } + }, + /** + * Get the embed player time + */ + getPlayerElementTime: function() { + var _this = this; + // Make sure we have .vid obj + this.getPlayerElement(); + if ( !this.playerElement ) { + mw.log( 'EmbedPlayerNative::getPlayerElementTime: ' + this.id + ' not in dom ( stop monitor)' ); + this.stop(); + return false; + } + var ct = this.playerElement.currentTime; + // Return 0 or a positive number: + if( ! ct || isNaN( ct ) || ct < 0 || ! isFinite( ct ) ){ + return 0; + } + // Return the playerElement currentTime + return this.playerElement.currentTime; + }, + + // Update the poster src ( updates the native object if in dom ) + updatePosterSrc: function( src ){ + if( this.getPlayerElement() ){ + $( this.getPlayerElement() ).attr('poster', src ); + } + // Also update the embedPlayer poster + this.parent_updatePosterSrc( src ); + }, + /** + * Empty player sources from the active video tag element + */ + emptySources: function(){ + // empty player source: + $( this.getPlayerElement() ).attr( 'src', null ); + // empty out generic sources: + this.parent_emptySources(); + }, + /** + * playerSwitchSource switches the player source working around a few bugs in browsers + * + * @param {Object} + * Source object to switch to. + * @param {function} + * switchCallback Function to call once the source has been switched + * @param {function} + * doneCallback Function to call once the clip has completed playback + */ + playerSwitchSource: function( source, switchCallback, doneCallback ){ + var _this = this; + var src = source.getSrc(); + var vid = this.getPlayerElement(); + var switchBindPostfix = '.playerSwitchSource'; + this.isPauseLoading = false; + // Make sure the switch source is different: + if( !src || src == vid.src ){ + if( $.isFunction( switchCallback ) ){ + switchCallback( vid ); + } + // Delay done callback to allow any non-blocking switch callback code to fully execute + if( $.isFunction( doneCallback ) ){ + doneCallback(); + } + return ; + } + + // only display switch msg if actually switching: + mw.log( 'EmbedPlayerNative:: playerSwitchSource: ' + src + ' native time: ' + vid.currentTime ); + + // Update some parent embedPlayer vars: + this.currentTime = 0; + this.previousTime = 0; + if ( vid ) { + try { + // Remove all switch player bindings + $( vid ).unbind( switchBindPostfix ); + + // pause before switching source + vid.pause(); + + var orginalControlsState = vid.controls; + // Hide controls ( to not display native play button while switching sources ) + vid.removeAttribute('controls'); + + // dissable seeking ( if we were in a seeking state before the switch ) + _this.seeking = false; + + // add a loading indicator: + _this.addPlayerSpinner(); + + // Do the actual source switch: + vid.src = src; + // load the updated src + vid.load(); + + // hide the player offscreen while we switch + _this.hidePlayerOffScreen(); + // restore position once we have metadata + $( vid ).bind( 'loadedmetadata' + switchBindPostfix, function(){ + $( vid ).unbind( 'loadedmetadata' + switchBindPostfix); + mw.log("EmbedPlayerNative:: playerSwitchSource> loadedmetadata callback for:" + src + ' switchCallback: ' + switchCallback ); + // Only update duration if we didn't get it server side + // Some browsers report bad duration (e.g. Android native browser) + // So avoid using the browser detected value if possible. + if ( !_this.duration && isFinite( vid.duration ) ) { + _this.duration = vid.duration; + } + // keep going towards playback! if switchCallback has not been called yet + // we need the "playing" event to trigger the switch callback + if ( $.isFunction( switchCallback ) ){ + vid.play(); + } + }); + + var handleSwitchCallback = function(){ + // restore video position ( now that we are playing with metadata size ) + _this.restorePlayerOnScreen(); + // play hide loading spinner: + _this.hideSpinnerAndPlayBtn(); + // Restore + vid.controls = orginalControlsState; + // check if we have a switch callback and issue it now: + if ( $.isFunction( switchCallback ) ){ + switchCallback( vid ); + switchCallback = null; + } + } + + // once playing issue callbacks: + $( vid ).bind( 'playing' + switchBindPostfix, function(){ + $( vid ).unbind( 'playing' + switchBindPostfix ); + mw.log("EmbedPlayerNative:: playerSwitchSource> playing callback"); + handleSwitchCallback(); + }); + + // Add the end binding if we have a post event: + if( $.isFunction( doneCallback ) ){ + $( vid ).bind( 'ended' + switchBindPostfix , function( event ) { + // remove end binding: + $( vid ).unbind( switchBindPostfix ); + // issue the doneCallback + doneCallback(); + + // Support loop for older iOS + // Temporarly disabled pending more testing or refactor into a better place. + //if ( _this.loop ) { + // vid.play(); + //} + return false; + }); + } + + // issue the play request: + vid.play(); + + // check if ready state is loading or doing anything ( iOS play restriction ) + // give iOS 5 seconds to ~start~ loading media + setTimeout(function(){ + // Check that the player got out of readyState 0 + if( vid.readyState === 0 && $.isFunction( switchCallback ) ){ + mw.log("EmbedPlayerNative:: possible iOS play without gesture failed, issue callback"); + // hand off to the swtich callback method. + handleSwitchCallback(); + // make sure we are in a pause state ( failed to change and play media ); + _this.pause(); + // show the big play button so the user can give us a user gesture: + if( ! _this.useLargePlayBtn() ){ + _this.addLargePlayBtn(); + } + } + }, 5000 ); + + + } catch (e) { + mw.log("Error: EmbedPlayerNative Error in switching source playback"); + } + } + }, + hidePlayerOffScreen:function( vid ){ + var vid = this.getPlayerElement(); + // Move the video offscreen while it switches ( hides quicktime logo only applies to iPad ) + $( vid ).css( { + 'position' : 'absolute', + 'left': '-4048px' + }); + }, + restorePlayerOnScreen: function( vid ){ + var vid = this.getPlayerElement(); + if( this.keepPlayerOffScreenFlag ){ + return ; + } + + // Remove any poster div ( that would overlay the player ) + $( this ).find( '.playerPoster' ).remove(); + // Restore video pos before calling sync syze + $( vid ).css( { + 'left': '0px' + }); + }, + /** + * Pause the video playback + * calls parent_pause to update the interface + */ + pause: function( ) { + this.getPlayerElement(); + this.parent_pause(); // update interface + if ( this.playerElement ) { // update player + this.playerElement.pause(); + } + }, + + /** + * Play back the video stream + * calls parent_play to update the interface + */ + play: function() { + var _this = this; + // if starting playback from stoped state and not in an ad or otherise blocked controls state: + // restore player: + if( this.isStopped() && this._playContorls ){ + this.restorePlayerOnScreen(); + } + // Run parent play: + if( _this.parent_play() ){ + if ( this.getPlayerElement() && this.getPlayerElement().play ) { + mw.log( "EmbedPlayerNative:: issue native play call" ); + // If in pauseloading state make sure the loading spinner is present: + if( this.isPauseLoading ){ + this.hideSpinnerOncePlaying(); + } + // issue a play request + this.getPlayerElement().play(); + // re-start the monitor: + this.monitor(); + } + } else { + mw.log( "EmbedPlayerNative:: parent play returned false, don't issue play on native element"); + } + }, + + /** + * Stop the player ( end all listeners ) + */ + stop: function(){ + var _this = this; + if( this.playerElement && this.playerElement.currentTime){ + this.playerElement.currentTime = 0; + this.playerElement.pause(); + } + this.parent_stop(); + }, + + /** + * Toggle the Mute + * calls parent_toggleMute to update the interface + */ + toggleMute: function() { + this.parent_toggleMute(); + this.getPlayerElement(); + if ( this.playerElement ) + this.playerElement.muted = this.muted; + }, + + /** + * Update Volume + * + * @param {Float} percent Value between 0 and 1 to set audio volume + */ + setPlayerElementVolume : function( percent ) { + if ( this.getPlayerElement() ) { + // Disable mute if positive volume + if( percent != 0 ) { + this.playerElement.muted = false; + } + this.playerElement.volume = percent; + } + }, + + /** + * get Volume + * + * @return {Float} + * Audio volume between 0 and 1. + */ + getPlayerElementVolume: function() { + if ( this.getPlayerElement() ) { + return this.playerElement.volume; + } + }, + /** + * get the native muted state + */ + getPlayerElementMuted: function(){ + if ( this.getPlayerElement() ) { + return this.playerElement.muted; + } + }, + + /** + * Get the native media duration + */ + getNativeDuration: function() { + if ( this.playerElement ) { + return this.playerElement.duration; + } + }, + + /** + * Load the video stream with a callback fired once the video is "loaded" + * + * @parma {Function} callbcak Function called once video is loaded + */ + load: function( callback ) { + this.getPlayerElement(); + if ( !this.playerElement ) { + // No vid loaded + mw.log( 'EmbedPlayerNative::load() ... doEmbed' ); + this.onlyLoadFlag = true; + this.embedPlayerHTML(); + this.onLoadedCallback = callback; + } else { + // Should not happen offten + this.playerElement.load(); + if( callback ){ + callback(); + } + } + }, + + /** + * Get /update the playerElement value + */ + getPlayerElement: function () { + this.playerElement = $( '#' + this.pid ).get( 0 ); + return this.playerElement; + }, + + /** + * Bindings for the Video Element Events + */ + + /** + * Local method for seeking event + * fired when "seeking" + */ + _onseeking: function() { + mw.log( "EmbedPlayerNative::onSeeking " + this.seeking + ' new time: ' + this.getPlayerElement().currentTime ); + if( this.seeking && Math.round( this.getPlayerElement().currentTime - this.currentSeekTargetTime ) > 2 ){ + mw.log( "Error:: EmbedPlayerNative Seek time missmatch: target:" + this.getPlayerElement().currentTime + + ' actual ' + this.currentSeekTargetTime + ', note apple HLS can only seek to 10 second targets'); + } + // Trigger the html5 seeking event + //( if not already set from interface ) + if( !this.seeking ) { + this.currentSeekTargetTime = this.getPlayerElement().currentTime; + this.seeking = true; + // Run the onSeeking interface update + this.controlBuilder.onSeek(); + + // Trigger the html5 "seeking" trigger + mw.log("EmbedPlayerNative::seeking:trigger:: " + this.seeking); + if( this._propagateEvents ){ + this.triggerHelper( 'seeking' ); + } + } + }, + + /** + * Local method for seeked event + * fired when done seeking + */ + _onseeked: function() { + mw.log("EmbedPlayerNative::onSeeked " + this.seeking + ' ct:' + this.playerElement.currentTime ); + // sync the seek checks so that we don't re-issue the seek request + this.previousTime = this.currentTime = this.playerElement.currentTime; + + // Trigger the html5 action on the parent + if( this.seeking ){ + + // HLS safari triggers onseek when its not even close to the target time, + // we don't want to trigger the seek event for these "fake" onseeked triggers + if( Math.abs( this.currentSeekTargetTime - this.getPlayerElement().currentTime ) > 2 ){ + mw.log( "Error:: EmbedPlayerNative:seeked triggred with time mismatch: target:" + + this.currentSeekTargetTime + + ' actual:' + this.getPlayerElement().currentTime ); + return ; + } + this.seeking = false; + if( this._propagateEvents ){ + mw.log( "EmbedPlayerNative:: trigger: seeked" ); + this.triggerHelper( 'seeked' ); + } + } + this.hideSpinner(); + // update the playhead status + if( this.isStopped() ){ + this.addLargePlayBtn(); + } + this.monitor(); + }, + + /** + * Handle the native paused event + */ + _onpause: function(){ + var _this = this; + var timeSincePlay = Math.abs( this.absoluteStartPlayTime - new Date().getTime() ); + mw.log( "EmbedPlayerNative:: OnPaused:: propagate:" + this._propagateEvents + ' time since play: ' + timeSincePlay + ' isNative=true' ); + // Only trigger parent pause if more than MonitorRate time has gone by. + // Some browsers trigger native pause events when they "play" or after a src switch + if( timeSincePlay > mw.config.get( 'EmbedPlayer.MonitorRate' ) ){ + _this.parent_pause(); + } else { + // continue playback: + this.getPlayerElement().play(); + } + }, + + /** + * Handle the native play event + */ + _onplay: function(){ + mw.log("EmbedPlayerNative:: OnPlay:: propogate:" + this._propagateEvents + ' paused: ' + this.paused); + // if using native controls make sure the inteface does not block the native controls interface: + if( this.useNativePlayerControls() ){ + this.$interface.css('pointer-events', 'none'); + } + + // Update the interface ( if paused ) + if( ! this.isFirstEmbedPlay && this._propagateEvents && this.paused ){ + this.parent_play(); + } else { + // make sure the interface reflects the current play state if not calling parent_play() + this.playInterfaceUpdate(); + } + // Set firstEmbedPlay state to false to avoid initial play invocation : + this.isFirstEmbedPlay = false; + }, + + /** + * Local method for metadata ready + * fired when metadata becomes available + * + * Used to update the media duration to + * accurately reflect the src duration + */ + _onloadedmetadata: function() { + this.getPlayerElement(); + + if ( this.playerElement && !isNaN( this.playerElement.duration ) && isFinite( this.playerElement.duration) ) { + mw.log( 'EmbedPlayerNative :onloadedmetadata metadata ready Update duration:' + this.playerElement.duration + ' old dur: ' + this.getDuration() ); + // Only update duration if we didn't get it server side + // Some browsers report bad duration (e.g. Android native browser) + // So avoid using the browser detected value if possible. + if( !this.duration && this.playerElement && isFinite( this.playerElement.duration ) ) { + this.duration = this.playerElement.duration; + } + } + + // Check if in "playing" state and we are _propagateEvents events and continue to playback: + if( !this.paused && this._propagateEvents ){ + this.getPlayerElement().play(); + } + + //Fire "onLoaded" flags if set + if( typeof this.onLoadedCallback == 'function' ) { + this.onLoadedCallback(); + } + + // Trigger "media loaded" + if( ! this.mediaLoadedFlag ){ + $( this ).trigger( 'mediaLoaded' ); + this.mediaLoadedFlag = true; + } + }, + + /** + * Local method for end of media event + */ + _onended: function( event ) { + var _this = this; + if( this.getPlayerElement() ){ + mw.log( 'EmbedPlayer:native: onended:' + this.playerElement.currentTime + ' real dur:' + this.getDuration() + ' ended ' + this._propagateEvents ); + if( this._propagateEvents ){ + this.onClipDone(); + } + } + }, + /** + * Local onClip done function for native player. + */ + onClipDone: function(){ + var _this = this; + // add clip done binding ( will only run on sequence complete ) + $(this).unbind('onEndedDone.onClipDone').bind( 'onEndedDone.onClipDone', function(){ + _this.addPlayScreenWithNativeOffScreen(); + // if not a legitmate play screen don't keep the player offscreen when playback starts: + if( !_this.isImagePlayScreen() ){ + _this.keepPlayerOffScreenFlag =false; + } + }); + this.parent_onClipDone(); + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvJs.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvJs.js new file mode 100644 index 00000000..791459f3 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerOgvJs.js @@ -0,0 +1,222 @@ +( function( mw, $ ) { "use strict"; + +var support = mw.OgvJsSupport; + +mw.EmbedPlayerOgvJs = { + + // Instance name: + instanceOf: 'OgvJs', + + // Supported feature set of the OGVPlayer widget: + supports: { + 'playHead' : true, + 'pause' : true, + 'stop' : true, + 'fullscreen' : true, + 'sourceSwitch': true, + 'timeDisplay' : true, + 'volumeControl' : false, + 'overlays': true, + 'timedText': true + }, + + /** + * Perform setup in response to a play start command. + * This means loading the code asynchronously if needed, + * and enabling web audio for iOS Safari inside the event + * handler. + * + * @return jQuery.Deferred + */ + _ogvJsPreInit: function() { + if( mw.isIOS() ) { + this._initializeAudioForiOS(); + } + return support.loadOgvJs(); + }, + + /** + * Actually initialize the player. + * + * @return OGVPlayer + */ + _ogvJsInit: function() { + var options = {}; + if ( this._iOSAudioContext ) { + // Reuse the audio context we opened earlier + options.audioContext = this._iOSAudioContext; + } + return new OGVPlayer( options ); + }, + + _iOSAudioContext: undefined, + + _initializeAudioForiOS: function() { + // iOS Safari Web Audio API must be initialized from an input event handler + if ( this._iOSAudioContext ) { + return; + } + this._iOSAudioContext = support.initAudioContext(); + }, + + /** + * Output the the embed html + */ + embedPlayerHTML: function (optionalCallback) { + + $( this ) + .empty() + .append( $.createSpinner( { + size: 'large', + type: 'block' + } ) ); + + var _this = this; + if( mw.isIOS() ) { + _this._initializeAudioForiOS(); + } + support.loadOgvJs().done( function() { + + var player = _this._ogvJsInit(); + player.id = _this.pid; + player.style.width = '100%'; + player.style.height = '100%'; + player.src = _this.getSrc(); + if ( _this.getDuration() ) { + player.durationHint = parseFloat( _this.getDuration() ); + } + player.addEventListener('ended', function() { + _this.onClipDone(); + }); + + // simulate timeupdate events, needed for subtitles + // @todo switch this to native timeupdate event when available upstream + var lastTime = 0, + timeupdateInterval = 0.25; + player.addEventListener( 'framecallback', function( event ) { + var player = _this.getPlayerElement(), + now = player ? player.currentTime : lastTime; + // Don't spam time updates on every frame + if ( Math.abs( now - lastTime ) >= timeupdateInterval ) { + lastTime = now; + $( _this ).trigger( 'timeupdate', [event, _this.id] ); + } + }); + + $( _this ).empty().append( player ); + player.play(); + + // Start the monitor: + _this.monitor(); + + if ( optionalCallback ) { + optionalCallback(); + } + }); + }, + + /** + * Get the embed player time + */ + getPlayerElementTime: function() { + this.getPlayerElement(); + var currentTime = 0; + if ( this.playerElement ) { + currentTime = this.playerElement.currentTime; + } else { + mw.log( "EmbedPlayerOgvJs:: Could not find playerElement" ); + } + return currentTime; + }, + + /** + * Update the playerElement instance with a pointer to the embed object + */ + getPlayerElement: function() { + // this.pid is in the form 'pid_mwe_player_<number>'; inherited from mw.EmbedPlayer.js + var $el = $( '#' + this.pid ); + if( !$el.length ) { + return false; + } + this.playerElement = $el.get( 0 ); + return this.playerElement; + }, + + /** + * Issue the doPlay request to the playerElement + * calls parent_play to update interface + */ + play: function() { + this.getPlayerElement(); + this.parent_play(); + if ( this.playerElement ) { + this.playerElement.play(); + // Restart the monitor if on second playthrough + this.monitor(); + } + }, + + /** + * Pause playback + * calls parent_pause to update interface + */ + pause: function() { + this.getPlayerElement(); + // Update the interface + this.parent_pause(); + // Call the pause function if it exists: + if ( this.playerElement ) { + this.playerElement.pause(); + } + }, + + /** + * Switch the source! + * For simplicity we just replace the player here. + */ + playerSwitchSource: function( source, switchCallback, doneCallback ){ + var _this = this; + var src = source.getSrc(); + var vid = this.getPlayerElement(); + if ( typeof vid.stop !== 'undefined' ) { + vid.stop(); + } + + switchCallback(); + + // Currently have to tear down the player and make a new one + this.embedPlayerHTML( doneCallback ); + }, + + /** + * Seek in the ogg stream + * @param {Float} percentage Percentage to seek into the stream + */ + seek: function( percentage ) { + this.setCurrentTime( percentage * parseFloat( this.getDuration() ) ); + }, + + setCurrentTime: function( time, callback ) { + this.getPlayerElement(); + + if ( this.playerElement ) { + this.playerElement.currentTime = time; + } + + this.currentTime = time; + this.previousTime = time; // prevent weird double-seek. MwEmbedPlyer is weird! + + // Run the onSeeking interface update + this.controlBuilder.onSeek(); + // @todo add proper events upstream + if( this.seeking ){ + this.seeking = false; + $( this ).trigger( 'seeked' ); + } + if ( $.isFunction( callback ) ) { + callback(); + } + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerVLCApp.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerVLCApp.js new file mode 100644 index 00000000..5fa6c6f8 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerVLCApp.js @@ -0,0 +1,101 @@ +/** + * Play the video using the vlc app on iOS + */ + +( function( mw, $ ) { "use strict"; + +mw.EmbedPlayerVLCApp = { + // List of supported features (or lack thereof) + supports: { + 'playHead':false, /* The seek slider */ + 'pause':true, /* Play pause button in control bar */ + 'stop':true, /* Does this actually do anything?? */ + 'fullscreen':false, + 'timeDisplay':false, + 'volumeControl':false + }, + + // Instance name: + instanceOf:'VLCApp', + + /* + * Embed this "fake" player + * + * @return {String} + * embed code to link to VLC app + */ + embedPlayerHTML: function() { + var fileUrl = this.getSrc( this.seekTimeSec ), + vlcUrl = 'vlc://' + (new mw.Uri( fileUrl )).toString(), + appStoreUrl = '//itunes.apple.com/us/app/vlc-for-ios/id650377962', + appInstalled = false, + promptInstallTimeout, + $link, + startTime; + + // Replace video with download in vlc link. + // the <span> ends up being not used as we get the html via .html() + $link = $( '<span></span>' ).append( $( '<a></a>' ).attr( 'href', appStoreUrl ).append( + mw.html.escape( mw.msg( 'mwe-embedplayer-vlcapp-vlcapplinktext' ) ) + ) ); + $( this ).html( $( '<div class="vlcapp-player"></div>' ) + .width( this.getWidth() ) + .height( this.getHeight() ) + .append( + // mw.msg doesn't have rawParams() equivalent. Lame. + mw.html.escape( + mw.msg( 'mwe-embedplayer-vlcapp-intro' ) + ).replace( /\$1/g, $link.html() ) + ).append( $( '<ul></ul>' ) + .append( $( '<li></li>' ).append( $( '<a></a>' ).attr( 'href', appStoreUrl ) + .text( mw.msg( 'mwe-embedplayer-vlcapp-downloadapp' ) ) ) + ).append( $( '<li></li>' ).append( $( '<a></a>' ).attr( 'href', vlcUrl ) + .text( mw.msg( 'mwe-embedplayer-vlcapp-openvideo' ) ) ) + ).append( $( '<li></li>' ).append( $( '<a></a>' ).attr( 'href', fileUrl ) + .text( mw.msg( 'mwe-embedplayer-vlcapp-downloadvideo' ) ) ) + ) + ) + ); + + // Try to auto-open in vlc. + // Based on http://stackoverflow.com/questions/627916/check-if-url-scheme-is-supported-in-javascript + + $( window ).one( 'pagehide', function() { + appInstalled = true; + if ( promptInstallTimeout ) { + window.clearTimeout( promptInstallTimeout ); + } + } ); + startTime = (new Date).getTime(); + try { + window.location = vlcUrl; + } catch( e ) { + // Just to be safe, ignore any exceptions + // However, it appears iOS doesn't throw any. Other browsers do. + } + promptInstallTimeout = window.setTimeout( function() { + var install; + if ( appInstalled ) { + return; + } + if ( document.hidden || document.webkitHidden ) { + // browser still running, but in background. + // probably means an App was opened up. + return; + } + if ( (new Date).getTime() - 15000 > startTime ) { + // We switched to VLC more than fifteen seconds ago. + // Probably we succesfully switched and the other detection + // methods failed. + return; + } + install = confirm( mw.msg( 'mwe-embedplayer-vlcapp-vlcapppopup' ) ); + if ( install ) { + window.location = appStoreUrl; + } + // Note about timeout: iPad air needs longer than an iPhone + }, 1000 ); + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerVlc.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerVlc.js new file mode 100644 index 00000000..c668cf40 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedPlayerVlc.js @@ -0,0 +1,358 @@ +/* +* VLC embed based on: http://people.videolan.org/~damienf/plugin-0.8.6.html +* javascript api: http://www.videolan.org/doc/play-howto/en/ch04.html +* assume version > 0.8.5.1 +*/ +( function( mw, $ ) { "use strict"; + +mw.EmbedPlayerVlc = { + + //Instance Name: + instanceOf : 'Vlc', + + //What the vlc player / plug-in supports: + supports : { + 'playHead':true, + 'pause':true, + 'stop':true, + 'fullscreen':true, + 'timeDisplay':true, + 'volumeControl':true, + + 'playlist_driver':true, // if the object supports playlist functions + 'overlay':false + }, + + // The previous state of the player instance + prevState : 0, + + // Counter for waiting for vlc embed to be ready + waitForVlcCount:0, + + // Store the current play time for vlc + vlcCurrentTime: 0, + + /** + * Get embed HTML + */ + embedPlayerHTML: function() { + var _this = this; + $( this ).html( + '<object classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921" ' + + 'codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab#Version=0,8,6,0" ' + + 'id="' + this.pid + '" events="True" height="' + this.getPlayerHeight() + '" width="' + this.getPlayerWidth() + '"' + + '>' + + '<param name="MRL" value="">' + + '<param name="ShowDisplay" value="True">' + + '<param name="AutoLoop" value="False">' + + '<param name="AutoPlay" value="False">' + + '<param name="Volume" value="50">' + + '<param name="StartTime" value="0">' + + '<embed pluginspage="http://www.videolan.org" type="application/x-vlc-plugin" ' + + 'progid="VideoLAN.VLCPlugin.2" name="' + this.pid + '" ' + + 'height="' + this.getHeight() + '" width="' + this.getWidth() + '" ' + + // Set the style for IE layout issues ) + 'style="width:' + this.getWidth() + 'px;height:' + this.getHeight() + 'px;" ' + + '>' + + '</object>' + ) + // Call postEmbedActions directly ( postEmbedJs will wait for player ready ) + _this.postEmbedActions(); + }, + + /** + * Javascript to run post vlc embedding + * Inserts the requested src to the embed instance + */ + postEmbedActions: function() { + var _this = this; + // Load a pointer to the vlc into the object (this.playerElement) + this.getPlayerElement(); + if ( this.playerElement && this.playerElement.playlist) { + // manipulate the dom object to make sure vlc has the correct size: + this.playerElement.style.width = this.getWidth(); + this.playerElement.style.height = this.getHeight(); + this.playerElement.playlist.items.clear(); + + // VLC likes absolute urls: + var src = mw.absoluteUrl( this.getSrc() ) ; + + mw.log( "EmbedPlayerVlc:: postEmbedActions play src:" + src ); + var itemId = this.playerElement.playlist.add( src ); + if ( itemId != -1 ) { + // Play + this.playerElement.playlist.playItem( itemId ); + } else { + mw.log( "Error:: EmbedPlayerVlc can not play" ); + } + setTimeout( function() { + _this.monitor(); + }, 100 ); + } else { + mw.log( 'EmbedPlayerVlc:: postEmbedActions: vlc not ready' ); + this.waitForVlcCount++; + if ( this.waitForVlcCount < 10 ) { + setTimeout( function() { + _this.postEmbedActions(); + }, 100 ); + } else { + mw.log( 'EmbedPlayerVlc:: vlc never ready' ); + } + } + }, + + /** + * Handles seek requests based on temporal media source type support + * + * @param {Float} percent Seek to this percent of the stream + */ + seek : function( percent ) { + this.getPlayerElement(); + // Use the parent (re) embed with new seek url method if urlTimeEncoding is supported. + if ( this.supportsURLTimeEncoding() ) { + this.parent_seek( percent ); + } else if ( this.playerElement ) { + this.seeking = true; + mw.log( "EmbedPlayerVlc:: seek to: " + percent ) + if ( ( this.playerElement.input.state == 3 ) && ( this.playerElement.input.position != percent ) ) + { + this.playerElement.input.position = percent; + this.controlBuilder.setStatus( mw.msg('mwe-embedplayer-seeking') ); + } + } else { + this.doPlayThenSeek( percent ); + } + this.parent_monitor(); + }, + + /** + * Issues a play request then seeks to a given time + * + * @param {Float} percent Seek to this percent of the stream after playing + */ + doPlayThenSeek:function( percent ) { + mw.log( 'EmbedPlayerVlc:: doPlayThenSeek' ); + var _this = this; + this.play(); + var seekCount = 0; + var readyForSeek = function() { + _this.getPlayerElement(); + var newState = _this.playerElement.input.state; + // If playing we are ready to do the seek + if ( newState == 3 ) { + _this.seek( percent ); + } else { + // Try to get player for 10 seconds: + if ( seekCount < 200 ) { + setTimeout( readyForSeek, 50 ); + rfsCount++; + } else { + mw.log( 'Error: EmbedPlayerVlc doPlayThenSeek failed' ); + } + } + } + readyForSeek(); + }, + + /** + * Updates the status time and player state + */ + monitor: function() { + this.getPlayerElement(); + if ( ! this.playerElement ){ + return ; + } + // Try to get relay vlc log messages to the console. + try{ + if ( this.playerElement.log.messages.count > 0 ) { + // there is one or more messages in the log + var iter = this.playerElement.log.messages.iterator(); + while ( iter.hasNext ) { + var msg = iter.next(); + var msgtype = msg.type.toString(); + if ( ( msg.severity == 1 ) && ( msgtype == "input" ) ) + { + mw.log( msg.message ); + } + } + // clear the log once finished to avoid clogging + this.playerElement.log.messages.clear(); + } + + var newState = this.playerElement.input.state; + if ( this.prevState != newState ) { + if ( newState == 0 ) + { + // current media has stopped + this.onStop(); + } + else if ( newState == 1 ) + { + // current media is opening/connecting + this.onOpen(); + } + else if ( newState == 2 ) + { + // current media is buffering data + this.onBuffer(); + } + else if ( newState == 3 ) + { + // current media is now playing + this.onPlay(); + } + else if ( this.playerElement.input.state == 4 ) { + // current media is now paused + this.onPause(); + } + this.prevState = newState; + } else if ( newState == 3 ) { + // current media is playing + this.onPlaying(); + } + } catch( e ){ + mw.log("EmbedPlayerVlc:: Monitor error"); + } + // Update the status and check timer via universal parent monitor + this.parent_monitor(); + }, + + /** + * Events: + */ + onOpen: function() { + // Open is considered equivalent to other players buffer status: + this.controlBuilder.setStatus( mw.msg('mwe-embedplayer-buffering') ); + }, + onBuffer: function() { + this.controlBuilder.setStatus( mw.msg('mwe-embedplayer-buffering') ); + }, + onPlay: function() { + this.onPlaying(); + }, + onPlaying: function() { + this.seeking = false; + // For now trust the duration from url over vlc input.length + if ( !this.getDuration() && this.playerElement.input.length > 0 ) + { + // mw.log('setting duration to ' + this.playerElement.input.length /1000); + this.duration = this.playerElement.input.length / 1000; + } + this.vlcCurrentTime = this.playerElement.input.time / 1000; + }, + + /** + * Get the embed player time + */ + getPlayerElementTime: function(){ + return this.vlcCurrentTime; + }, + + onPause: function() { + // Update the interface if paused via native plugin + this.parent_pause(); + }, + onStop: function() { + mw.log( 'EmbedPlayerVlc:: onStop' ); + if ( !this.seeking ){ + this.onClipDone(); + } + }, + + /** + * Handles play requests + */ + play: function() { + mw.log( 'EmbedPlayerVlc:: play' ); + // Update the interface + this.parent_play(); + if ( this.getPlayerElement() ) { + // plugin is already being present send play call: + // clear the message log and enable error logging + if ( this.playerElement.log ) { + this.playerElement.log.messages.clear(); + } + if ( this.playerElement.playlist && typeof this.playerElement.playlist.play == 'function') + this.playerElement.playlist.play(); + + if( typeof this.playerElement.play == 'function' ) + this.playerElement.play(); + + this.paused = false; + + // re-start the monitor: + this.monitor(); + } + }, + + /** + * Passes the Pause request to the plugin. + * calls parent "pause" to update interface + */ + pause: function() { + this.parent_pause(); // update the interface if paused via native control + if ( this.getPlayerElement() ) { + try{ + this.playerElement.playlist.togglePause(); + } catch( e ){ + mw.log("EmbedPlayerVlc:: Could not pause video " + e); + } + } + }, + + /** + * Mutes the video + * calls parent "toggleMute" to update interface + */ + toggleMute:function() { + this.parent_toggleMute(); + if ( this.getPlayerElement() ){ + this.playerElement.audio.toggleMute(); + } + }, + + /** + * Update the player volume + * @parm {Float} percent Percent of total volume + */ + setPlayerElementVolume: function ( percent ) { + if ( this.getPlayerElement() && this.playerElement.audio ) { + this.playerElement.audio.volume = percent * 100; + } + }, + + /** + * Gets the current volume + * @return {Float} percent percent of total volume + */ + getVolumen:function() { + if ( this.getPlayerElement() ){ + return this.playerElement.audio.volume / 100; + } + }, + + /** + * Passes fullscreen request to plugin + */ + fullscreen : function() { + if ( this.playerElement ) { + if ( this.playerElement.video ){ + try{ + this.playerElement.video.toggleFullscreen(); + } catch ( e ){ + mw.log("EmbedPlayerVlc:: toggle fullscreen : possible error: " + e); + } + } + } + }, + + /** + * Get the embed vlc object + */ + getPlayerElement : function() { + this.playerElement = $( '#' + this.pid )[0]; + return this.playerElement; + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedTypes.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedTypes.js new file mode 100644 index 00000000..21b2f452 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.EmbedTypes.js @@ -0,0 +1,360 @@ +/** + * mw.EmbedTypes object handles setting and getting of supported embed types: + * closely mirrors OggHandler so that its easier to share efforts in this area: + * http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/OggHandler/OggPlayer.js + */ +( function( mw, $ ) { "use strict"; + +/** + * Setup local players and supported mime types In an ideal world we would query the plugin + * to get what mime types it supports in practice not always reliable/available + * + * We can't cleanly store these values per library since player library is sometimes + * loaded post player detection + */ +// Flash based players: +var kplayer = new mw.MediaPlayer('kplayer', [ + 'video/x-flv', + 'video/h264', + 'video/mp4; codecs="avc1.42E01E"', + 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', + 'audio/mpeg' +], 'Kplayer'); + +// Native html5 players +var oggNativePlayer = new mw.MediaPlayer( 'oggNative', [ + 'video/ogg', + 'video/ogg; codecs="theora"', + 'video/ogg; codecs="theora, vorbis"', + 'audio/ogg', + 'audio/ogg; codecs="vorbis"', + 'application/ogg' +], 'Native' ); +// Native html5 players +var opusNativePlayer = new mw.MediaPlayer( 'opusNative', [ + 'audio/ogg; codecs="opus"', +], 'Native' ); +var h264NativePlayer = new mw.MediaPlayer( 'h264Native', [ + 'video/h264', + 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' +], 'Native' ); +var appleVdnPlayer = new mw.MediaPlayer( 'appleVdn', [ + 'application/vnd.apple.mpegurl', + 'application/vnd.apple.mpegurl; codecs="avc1.42E01E"' +], 'Native'); +var mp3NativePlayer = new mw.MediaPlayer( 'mp3Native', [ + 'audio/mpeg', + 'audio/mp3' +], 'Native' ); +var aacNativePlayer = new mw.MediaPlayer( 'aacNative', [ + 'audio/mp4', + 'audio/mp4; codecs="mp4a.40.5"' +], 'Native' ); +var webmNativePlayer = new mw.MediaPlayer( 'webmNative', [ + 'video/webm', + 'video/webm; codecs="vp8"', + 'video/webm; codecs="vp8, vorbis"', + 'audio/webm', + 'audio/webm; codecs="vorbis"' +], 'Native' ); +var vp9NativePlayer = new mw.MediaPlayer( 'vp9Native', [ + 'video/webm; codecs="vp9"', + 'video/webm; codecs="vp9, opus"', + 'video/webm; codecs="vp9, vorbis"', + 'audio/webm; codecs="opus"' +], 'Native' ); + +// Image Overlay player ( extends native ) +var imageOverlayPlayer = new mw.MediaPlayer( 'imageOverlay', [ + 'image/jpeg', + 'image/png' +], 'ImageOverlay' ); + +// VLC player +//var vlcMimeList = ['video/ogg', 'audio/ogg', 'audio/mpeg', 'application/ogg', 'video/x-flv', 'video/mp4', 'video/h264', 'video/x-msvideo', 'video/mpeg', 'video/3gp']; +//var vlcPlayer = new mw.MediaPlayer( 'vlc-player', vlcMimeList, 'Vlc' ); + +var vlcAppPlayer = new mw.MediaPlayer( 'vlcAppPlayer', [ + 'video/ogg', + 'video/ogg; codecs="theora"', + 'video/ogg; codecs="theora, vorbis"', + 'audio/ogg', + 'audio/ogg; codecs="vorbis"', + 'audio/ogg; codecs="opus"', + 'application/ogg', + 'video/webm', + 'video/webm; codecs="vp8"', + 'video/webm; codecs="vp8, vorbis"', +], 'VLCApp' ); + +var IEWebMPrompt = new mw.MediaPlayer( 'IEWebMPrompt', [ + 'video/webm', + 'video/webm; codecs="vp8"', + 'video/webm; codecs="vp8, vorbis"' +], 'IEWebMPrompt' ); + +var ogvJsPlayer = new mw.MediaPlayer( 'ogvJsPlayer', [ + 'video/ogg', + 'video/ogg; codecs="theora"', + 'video/ogg; codecs="theora, vorbis"', + 'video/ogg; codecs="theora, opus"', + 'audio/ogg', + 'audio/ogg; codecs="vorbis"', + 'audio/ogg; codecs="opus"', + 'application/ogg' +], 'OgvJs' ); + +// Generic plugin +//var oggPluginPlayer = new mw.MediaPlayer( 'oggPlugin', ['video/ogg', 'application/ogg'], 'Generic' ); + + +mw.EmbedTypes = { + + // MediaPlayers object ( supports methods for quering set of browser players ) + mediaPlayers: null, + + // Detect flag for completion + detect_done:false, + + /** + * Runs the detect method and update the detect_done flag + * + * @constructor + */ + init: function() { + // detect supported types + this.detect(); + this.detect_done = true; + }, + + getMediaPlayers: function(){ + if( this.mediaPlayers ){ + return this.mediaPlayers; + } + this.mediaPlayers = new mw.MediaPlayers(); + // detect available players + this.detectPlayers(); + return this.mediaPlayers; + }, + + /** + * If the browsers supports a given mimetype + * + * @param {String} + * mimeType Mime type for browser plug-in check + */ + supportedMimeType: function( mimeType ) { + for ( var i =0; i < navigator.plugins.length; i++ ) { + var plugin = navigator.plugins[i]; + if ( typeof plugin[ mimeType ] != "undefined" ){ + return true; + } + } + return false; + }, + addFlashPlayer: function(){ + if( !mw.config.get( 'EmbedPlayer.DisableHTML5FlashFallback' ) ){ + this.mediaPlayers.addPlayer( kplayer ); + } + }, + /** + * Detects what plug-ins the client supports + */ + detectPlayers: function() { + mw.log( "EmbedTypes::detectPlayers running detect" ); + + // All players support for playing "images" + this.mediaPlayers.addPlayer( imageOverlayPlayer ); + + // Some browsers filter out duplicate mime types, hiding some plugins + var uniqueMimesOnly = $.client.test( { opera: null, safari: null } ); + + // Use core mw.supportsFlash check: + if( mw.supportsFlash() ){ + this.addFlashPlayer(); + } + + // ActiveX plugins + if ( $.client.profile().name === 'msie' ) { + // VLC + //if ( this.testActiveX( 'VideoLAN.VLCPlugin.2' ) ) { + // this.mediaPlayers.addPlayer( vlcPlayer ); + //} + + // quicktime (currently off) + // if ( this.testActiveX( + // 'QuickTimeCheckObject.QuickTimeCheck.1' ) ) + // this.mediaPlayers.addPlayer(quicktimeActiveXPlayer); + } + // <video> element + if ( ! mw.config.get('EmbedPlayer.DisableVideoTagSupport' ) // to support testing limited / old browsers + && + ( + typeof HTMLVideoElement == 'object' // Firefox, Safari + || + typeof HTMLVideoElement == 'function' // Opera + ) + ){ + // Test what codecs the native player supports: + try { + var dummyvid = document.createElement( "video" ); + if( dummyvid.canPlayType ) { + // Add the webm player + if( dummyvid.canPlayType('video/webm; codecs="vp8, vorbis"') ){ + this.mediaPlayers.addPlayer( webmNativePlayer ); + } + if( dummyvid.canPlayType('video/webm; codecs="vp9, opus"') ){ + this.mediaPlayers.addPlayer( vp9NativePlayer ); + } + + // Test for MP3: + if ( this.supportedMimeType('audio/mpeg') ) { + this.mediaPlayers.addPlayer( mp3NativePlayer ); + } + + // Test for AAC: + if ( dummyvid.canPlayType( 'audio/mp4; codecs="mp4a.40.5"' ) ) { + this.mediaPlayers.addPlayer( aacNativePlayer ); + } + + // Test for h264: + if ( dummyvid.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"' ) ) { + this.mediaPlayers.addPlayer( h264NativePlayer ); + // Check for iOS for vdn player support ( apple adaptive ) or vdn canPlayType != '' ( ie maybe/probably ) + if( mw.isIOS() || dummyvid.canPlayType('application/vnd.apple.mpegurl; codecs="avc1.42E01E"' ) ){ + // Android 3x lies about HLS support ( only add if not Android 3.x ) + if( navigator.userAgent.indexOf( 'Android 3.') == -1 ){ + this.mediaPlayers.addPlayer( appleVdnPlayer ); + } + } + + } + // For now if Android assume we support h264Native (FIXME + // test on real devices ) + if ( mw.isAndroid2() ){ + this.mediaPlayers.addPlayer( h264NativePlayer ); + } + + // Test for ogg + if ( dummyvid.canPlayType( 'video/ogg; codecs="theora, vorbis"' ) || + dummyvid.canPlayType( 'audio/ogg; codecs="vorbis"' ) + ) { + this.mediaPlayers.addPlayer( oggNativePlayer ); + } + + // Test for opus + if ( dummyvid.canPlayType( 'audio/ogg; codecs="opus"' ).replace(/maybe/, '') ) { + this.mediaPlayers.addPlayer( opusNativePlayer ); + } + } + } catch ( e ) { + mw.log( 'could not run canPlayType ' + e ); + } + } + + // "navigator" plugins + if ( navigator.mimeTypes && navigator.mimeTypes.length > 0 ) { + for ( var i = 0; i < navigator.mimeTypes.length; i++ ) { + var type = navigator.mimeTypes[i].type; + var semicolonPos = type.indexOf( ';' ); + if ( semicolonPos > -1 ) { + type = type.substr( 0, semicolonPos ); + } + // mw.log( 'on type: ' + type ); + var pluginName = navigator.mimeTypes[i].enabledPlugin ? navigator.mimeTypes[i].enabledPlugin.name : ''; + if ( !pluginName ) { + // In case it is null or undefined + pluginName = ''; + } + //if ( pluginName.toLowerCase() == 'vlc multimedia plugin' || pluginName.toLowerCase() == 'vlc multimedia plug-in' ) { + // this.mediaPlayers.addPlayer( vlcPlayer ); + // continue; + //} + + if ( (type == 'video/mpeg' || type == 'video/x-msvideo') ){ + //pluginName.toLowerCase() == 'vlc multimedia plugin' ) { + //this.mediaPlayers.addPlayer( vlcMozillaPlayer ); + } + + if ( type == 'application/ogg' ) { + //if ( pluginName.toLowerCase() == 'vlc multimedia plugin' ) { + //this.mediaPlayers.addPlayer( vlcMozillaPlayer ); + //else if ( pluginName.indexOf( 'QuickTime' ) > -1 ) + //this.mediaPlayers.addPlayer(quicktimeMozillaPlayer); + //} else { + //this.mediaPlayers.addPlayer( oggPluginPlayer ); + //} + continue; + } else if ( uniqueMimesOnly ) { + if ( type == 'application/x-vlc-player' ) { + // this.mediaPlayers.addPlayer( vlcMozillaPlayer ); + continue; + } else if ( type == 'video/quicktime' ) { + // this.mediaPlayers.addPlayer(quicktimeMozillaPlayer); + continue; + } + } + } + } + + if ( mw.isIOS() ) { + this.mediaPlayers.addPlayer( vlcAppPlayer ); + } + + // Note IE 11 doesn't identify itself as 'MSIE'. + // For simplicity just check for the rendering engine codename 'Trident'. + if ( navigator.userAgent.indexOf( 'Trident' ) != -1 ) { + if ( this.mediaPlayers.isSupportedPlayer( 'webmNative' ) ) { + // IE has the WebM components already, leave it be! + } else if ( navigator.userAgent.indexOf( 'ARM' ) != -1 ) { + // Windows RT doesn't allow installation of the WebM components. + // Don't tease the poor user. + } else { + // Prompt user to install the WebM media components for IE 9+ + this.mediaPlayers.addPlayer( IEWebMPrompt ); + } + } + + // ogv.js compatibility detection... + if ( OGVCompat.supported( 'OGVPlayer' ) ) { + // ogv.js emscripten version + // + // Works in: + // * Safari 6.1+ on Mac OS X + // * Safari on iOS 8+ (best on 64-bit devices) + // * IE 10/11 on Windows 7/8/8.1 (requires Flash for audio) + // * Edge on Windows 10 (no plugins needed) + // + // Current Firefox, Chrome, Opera all work great too, but use + // native playback by default of course! + // + this.mediaPlayers.addPlayer( ogvJsPlayer ); + } + + // Allow extensions to detect and add their own "players" + mw.log("EmbedPlayer::trigger:embedPlayerUpdateMediaPlayersEvent"); + $( mw ).trigger( 'embedPlayerUpdateMediaPlayersEvent' , this.mediaPlayers ); + + }, + + /** + * Test IE for activeX by name + * + * @param {String} + * name Name of ActiveXObject to look for + */ + testActiveX : function ( name ) { + mw.log("EmbedPlayer::detect: test testActiveX: " + name); + var hasObj = true; + try { + // No IE, not a class called "name", it's a variable + var obj = new ActiveXObject( '' + name ); + } catch ( e ) { + hasObj = false; + } + return hasObj; + } +}; + + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaElement.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaElement.js new file mode 100644 index 00000000..9af48998 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaElement.js @@ -0,0 +1,491 @@ +/** + * A media element corresponding to a <video> element. + * + * It is implemented as a collection of mediaSource objects. The media sources + * will be initialized from the <video> element, its child <source> elements, + * and/or the ROE file referenced by the <video> element. + * + * @param {element} + * videoElement <video> element used for initialization. + * @constructor + */ +( function( mw, $ ) { "use strict"; + +mw.MediaElement = function( element ) { + this.init( element ); +}; + +mw.MediaElement.prototype = { + + // The array of mediaSource elements. + sources: null, + + // flag for ROE data being added. + addedROEData: false, + + // Selected mediaSource element. + selectedSource: null, + + /** + * Media Element constructor + * + * Sets up a mediaElement from a provided top level "video" element adds any + * child sources that are found + * + * @param {Element} + * videoElement Element that has src attribute or has children + * source elements + */ + init: function( videoElement ) { + var _this = this; + mw.log( "EmbedPlayer::mediaElement:init:" + videoElement.id ); + this.parentEmbedId = videoElement.id; + this.sources = new Array(); + + // Process the videoElement as a source element: + if( videoElement ){ + if ( $( videoElement ).attr( "src" ) ) { + _this.tryAddSource( videoElement ); + } + // Process elements source children + $( videoElement ).find( 'source,track' ).each( function( ) { + _this.tryAddSource( this ); + } ); + } + }, + + /** + * Updates the time request for all sources that have a standard time + * request argument (ie &t=start_time/end_time) + * + * @param {String} + * startNpt Start time in npt format + * @param {String} + * endNpt End time in npt format + */ + updateSourceTimes: function( startNpt, endNpt ) { + var _this = this; + $.each( this.sources, function( inx, mediaSource ) { + mediaSource.updateSrcTime( startNpt, endNpt ); + } ); + }, + + /** + * Get Text tracks + */ + getTextTracks: function(){ + var textTracks = []; + $.each( this.sources, function(inx, source ){ + if ( source.nodeName == 'track' || ( source.mimeType && source.mimeType.indexOf('text/') !== -1 )){ + textTracks.push( source ); + } + }); + return textTracks; + }, + /** + * Returns the array of mediaSources of this element. + * + * @param {String} + * [mimeFilter] Filter criteria for set of mediaSources to return + * @return {Array} mediaSource elements. + */ + getSources: function( mimeFilter ) { + if ( !mimeFilter ) { + return this.sources; + } + // Apply mime filter: + var source_set = new Array(); + for ( var i = 0; i < this.sources.length ; i++ ) { + if ( this.sources[i].mimeType && + this.sources[i].mimeType.indexOf( mimeFilter ) != -1 ) + { + source_set.push( this.sources[i] ); + } + } + return source_set; + }, + + /** + * Selects a source by id + * + * @param {String} + * sourceId Id of the source to select. + * @return {MediaSource} The selected mediaSource or null if not found + */ + getSourceById:function( sourceId ) { + for ( var i = 0; i < this.sources.length ; i++ ) { + if ( this.sources[i].id == sourceId ) { + return this.sources[i]; + } + } + return null; + }, + + /** + * Selects a particular source for playback updating the "selectedSource" + * + * @param {Number} + * index Index of source element to set as selectedSource + */ + setSourceByIndex: function( index ) { + mw.log( 'EmbedPlayer::mediaElement:selectSource: ' + index ); + var oldSrc = this.selectedSource.getSrc(); + var playableSources = this.getPlayableSources(); + for ( var i = 0; i < playableSources.length; i++ ) { + if ( i == index ) { + this.selectedSource = playableSources[i]; + break; + } + } + if( oldSrc != this.selectedSource.getSrc() ){ + $( '#' + this.parentEmbedId ).trigger( 'SourceChange'); + } + }, + /** + * Sets a the selected source to passed in source object + * @param {Object} Source + */ + setSource: function( source ){ + var oldSrc = this.selectedSource.getSrc(); + this.selectedSource = source; + if( oldSrc != this.selectedSource.getSrc() ){ + $( '#' + this.parentEmbedId ).trigger( 'SourceChange'); + } + }, + + + /** + * Selects the default source via cookie preference, default marked, or by + * id order + */ + autoSelectSource: function() { + mw.log( 'EmbedPlayer::mediaElement::autoSelectSource' ); + var _this = this; + // Select the default source + var playableSources = this.getPlayableSources(); + var flash_flag = false, ogg_flag = false; + // Check if there are any playableSources + if( playableSources.length == 0 ){ + return false; + } + var setSelectedSource = function( source ){ + _this.selectedSource = source; + return _this.selectedSource; + }; + + // Set via module driven preference: + $( this ).trigger( 'onSelectSource', playableSources ); + + if( _this.selectedSource ){ + mw.log('MediaElement::autoSelectSource: Set via trigger::' + _this.selectedSource.getTitle() ); + return _this.selectedSource; + } + + // Set via marked default: + $.each( playableSources, function( inx, source ){ + if ( source.markedDefault ) { + mw.log( 'MediaElement::autoSelectSource: Set via marked default: ' + source.markedDefault ); + return setSelectedSource( source );; + } + }); + + // Set apple adaptive ( if available ) + var vndSources = this.getPlayableSources('application/vnd.apple.mpegurl') + if( vndSources.length && mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( 'application/vnd.apple.mpegurl' ).length ){ + // Check for device flags: + var desktopVdn, mobileVdn; + $.each( vndSources, function( inx, source) { + // Kaltura tags vdn sources with iphonenew + if( source.getFlavorId() && source.getFlavorId().toLowerCase() == 'iphonenew' ){ + mobileVdn = source; + } else { + desktopVdn = source; + } + }) + // NOTE: We really should not have two VDN sources the point of vdn is to be a set of adaptive streams. + // This work around is a result of Kaltura HLS stream tagging + if( mw.isIphone() && mobileVdn ){ + setSelectedSource( mobileVdn ); + } else if( desktopVdn ){ + setSelectedSource( desktopVdn ); + } + } + if ( this.selectedSource ) { + mw.log('MediaElement::autoSelectSource: Set via Adaptive HLS: source flavor id:' + _this.selectedSource.getFlavorId() + ' src: ' + _this.selectedSource.getSrc() ); + return this.selectedSource; + } + + // Set via user bandwidth pref will always set source to closest bandwidth allocation while not going over EmbedPlayer.UserBandwidth + if( $.cookie('EmbedPlayer.UserBandwidth') ){ + var bandwidthDelta = 999999999; + var bandwidthTarget = $.cookie('EmbedPlayer.UserBandwidth'); + $.each( playableSources, function(inx, source ){ + if( source.bandwidth ){ + // Check if a native source ( takes president over bandwidth selection ) + var player = mw.EmbedTypes.getMediaPlayers().defaultPlayer( source.mimeType ); + if ( !player || player.library != 'Native' ) { + // continue + return true; + } + + if( Math.abs( source.bandwidth - bandwidthTarget ) < bandwidthDelta ){ + bandwidthDelta = Math.abs( source.bandwidth - bandwidthTarget ); + setSelectedSource( source ); + } + } + }); + } + + if ( this.selectedSource ) { + mw.log('MediaElement::autoSelectSource: Set via bandwidth prefrence: source ' + this.selectedSource.bandwidth + ' user: ' + $.cookie('EmbedPlayer.UserBandwidth') ); + return this.selectedSource; + } + + + // If we have at least one native source, throw out non-native sources + // for size based source selection: + var nativePlayableSources = []; + $.each( playableSources, function(inx, source ){ + var mimeType = source.mimeType; + var player = mw.EmbedTypes.getMediaPlayers().defaultPlayer( mimeType ); + if ( player && player.library == 'Native' ) { + nativePlayableSources.push( source ); + } + }); + + // Prefer native playback ( and prefer WebM over ogg and h.264 ) + var namedSourceSet = {}; + var useBogoSlow = false; // use benchmark only for ogv.js + $.each( playableSources, function(inx, source ){ + var mimeType = source.mimeType; + var player = mw.EmbedTypes.getMediaPlayers().defaultPlayer( mimeType ); + if ( player && ( player.library == 'Native' || player.library == 'OgvJs' ) ) { + switch( player.id ){ + case 'mp3Native': + var shortName = 'mp3'; + break; + case 'aacNative': + var shortName = 'aac'; + break; + case 'oggNative': + var shortName = 'ogg'; + break; + case 'ogvJsPlayer': + useBogoSlow = true; + var shortName = 'ogg'; + break; + case 'webmNative': + var shortName = 'webm'; + break; + case 'vp9Native': + var shortName = 'vp9'; + break; + case 'h264Native': + var shortName = 'h264'; + break; + case 'appleVdn': + var shortName = 'appleVdn'; + break; + } + if( !namedSourceSet[ shortName ] ){ + namedSourceSet[ shortName ] = []; + } + namedSourceSet[ shortName ].push( source ); + } + }); + + var codecPref = mw.config.get( 'EmbedPlayer.CodecPreference'); + + // if on android 4 use mp4 over webm + if( mw.isAndroid40() ){ + if( codecPref && codecPref[0] == 'webm' ){ + codecPref[0] = 'h264'; + codecPref[1] = 'webm'; + } + } + + if( codecPref ){ + for(var i =0; i < codecPref.length; i++){ + var codec = codecPref[ i ]; + if( ! namedSourceSet[ codec ] ){ + continue; + } + if( namedSourceSet[ codec ].length == 1 ){ + mw.log('MediaElement::autoSelectSource: Set 1 source via EmbedPlayer.CodecPreference: ' + namedSourceSet[ codec ][0].getTitle() ); + return setSelectedSource( namedSourceSet[ codec ][0] ); + } else if( namedSourceSet[ codec ].length > 1 ) { + // select based on size: + // Set via embed resolution closest to relative to display size + var minSizeDelta = null; + + // unless we're really slow... + var isBogoSlow = useBogoSlow && OGVCompat.isSlow(); + + if( this.parentEmbedId ){ + var displayWidth = $('#' + this.parentEmbedId).width(); + $.each( namedSourceSet[ codec ], function(inx, source ){ + if ( ( isBogoSlow && source.height > 240 ) + || (useBogoSlow && source.height > 360 ) ) { + // On iOS or slow Windows devices, large videos decoded in JavaScript are a bad idea! + // continue + return true; + } + if( source.width && displayWidth ){ + var sizeDelta = Math.abs( source.width - displayWidth ); + mw.log('MediaElement::autoSelectSource: size delta : ' + sizeDelta + ' for s:' + source.width ); + if( minSizeDelta == null || sizeDelta < minSizeDelta){ + minSizeDelta = sizeDelta; + setSelectedSource( source ); + } + } + }); + } + // If we found a source via display size return: + if ( this.selectedSource ) { + mw.log('MediaElement::autoSelectSource: from ' + this.selectedSource.mimeType + ' because of resolution:' + this.selectedSource.width + ' close to: ' + displayWidth ); + return this.selectedSource; + } + // if no size info is set just select the first source: + if( namedSourceSet[ codec ][0] ){ + return setSelectedSource( namedSourceSet[ codec ][0] ); + } + } + }; + } + + // Set h264 via native or flash fallback + $.each( playableSources, function(inx, source ){ + var mimeType = source.mimeType; + var player = mw.EmbedTypes.getMediaPlayers().defaultPlayer( mimeType ); + if ( mimeType == 'video/h264' + && player + && ( + player.library == 'Native' + || + player.library == 'Kplayer' + ) + ) { + if( source ){ + mw.log('MediaElement::autoSelectSource: Set h264 via native or flash fallback:' + source.getTitle() ); + return setSelectedSource( source ); + } + } + }); + + // Else just select the first playable source + if ( !this.selectedSource && playableSources[0] ) { + mw.log( 'MediaElement::autoSelectSource: Set via first source: ' + playableSources[0].getTitle() + ' mime: ' + playableSources[0].getMIMEType() ); + return setSelectedSource( playableSources[0] ); + } + // No Source found so no source selected + return false; + }, + + /** + * check if the mime is ogg + */ + isOgg: function( mimeType ){ + if ( mimeType == 'video/ogg' + || mimeType == 'ogg/video' + || mimeType == 'video/annodex' + || mimeType == 'application/ogg' + ) { + return true; + } + return false; + }, + + /** + * Returns the thumbnail URL for the media element. + * + * @returns {String} thumbnail URL + */ + getPosterSrc: function( ) { + return this.poster; + }, + + /** + * Checks whether there is a stream of a specified MIME type. + * + * @param {String} + * mimeType MIME type to check. + * @return {Boolean} true if sources include MIME false if not. + */ + hasStreamOfMIMEType: function( mimeType ) + { + for ( var i = 0; i < this.sources.length; i++ ) + { + if ( this.sources[i].getMIMEType() == mimeType ){ + return true; + } + } + return false; + }, + + /** + * Checks if media is a playable type + */ + isPlayableType: function( mimeType ) { + // mw.log("isPlayableType:: " + mimeType); + if ( mw.EmbedTypes.getMediaPlayers().defaultPlayer( mimeType ) ) { + mw.log("isPlayableType:: " + mimeType); + return true; + } else { + return false; + } + }, + + /** + * Adds a single mediaSource using the provided element if the element has a + * 'src' attribute. + * + * @param {Element} + * element <video>, <source> or <mediaSource> <text> element. + */ + tryAddSource: function( element ) { + //mw.log( 'mw.MediaElement::tryAddSource:' + $( element ).attr( "src" ) ); + var newSrc = $( element ).attr( 'src' ); + if ( newSrc ) { + // Make sure an existing element with the same src does not already exist: + for ( var i = 0; i < this.sources.length; i++ ) { + if ( this.sources[i].src == newSrc ) { + // Source already exists update any new attr: + this.sources[i].updateSource( element ); + return this.sources[i]; + } + } + } + // Create a new source + var source = new mw.MediaSource( element ); + + this.sources.push( source ); + //mw.log( 'tryAddSource: added source ::' + source + 'sl:' + this.sources.length ); + return source; + }, + + /** + * Get playable sources + * + *@pram mimeFilter {=string} (optional) Filter the playable sources set by mime filter + * + * @returns {Array} of playable media sources + */ + getPlayableSources: function( mimeFilter ) { + var playableSources = []; + for ( var i = 0; i < this.sources.length; i++ ) { + if ( this.isPlayableType( this.sources[i].mimeType ) + && + ( !mimeFilter || this.sources[i].mimeType.indexOf( mimeFilter) != -1 ) + ){ + playableSources.push( this.sources[i] ); + } + }; + mw.log( "MediaElement::GetPlayableSources mimeFilter:" + mimeFilter + " " + + playableSources.length + ' sources playable out of ' + this.sources.length ); + + return playableSources; + } +}; + +} )( mediaWiki, jQuery ); + diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayer.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayer.js new file mode 100644 index 00000000..94ef9708 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayer.js @@ -0,0 +1,85 @@ +/** + * mediaPlayer represents a media player plugin. + * + * @param {String} + * id id used for the plugin. + * @param {Array} + * supportedTypes an array of supported MIME types. + * @param {String} + * library external script containing the plugin interface code. + * @constructor + */ +( function( mw, $ ) { "use strict"; + +mw.MediaPlayer = function( id, supportedTypes, library ) +{ + this.id = id; + this.supportedTypes = supportedTypes; + this.library = library; + this.loaded = false; + this.loading_callbacks = new Array(); + return this; +}; +mw.MediaPlayer.prototype = { + // Id of the mediaPlayer + id:null, + + // Mime types supported by this player + supportedTypes:null, + + // Player library ie: native, vlc etc. + library:null, + + // Flag stores the mediaPlayer load state + loaded:false, + + /** + * Checks support for a given MIME type + * + * @param {String} + * type Mime type to check against supportedTypes + * @return {Boolean} true if mime type is supported false if mime type is + * unsupported + */ + supportsMIMEType: function( type ) { + for ( var i = 0; i < this.supportedTypes.length; i++ ) { + if ( this.supportedTypes[i] == type ) + return true; + } + return false; + }, + + /** + * Get the "name" of the player from a predictable msg key + */ + getName: function() { + // Give grep a chance to find the usages: + // mwe-embedplayer-ogg-player-vlc-player, mwe-embedplayer-ogg-player-oggNative, mwe-embedplayer-ogg-player-mp3Native, + // mwe-embedplayer-ogg-player-aacNative, mwe-embedplayer-ogg-player-h264Native, mwe-embedplayer-ogg-player-webmNative, + // mwe-embedplayer-ogg-player-oggPlugin, mwe-embedplayer-ogg-player-quicktime-mozilla, + // mwe-embedplayer-ogg-player-quicktime-activex, mwe-embedplayer-ogg-player-cortado, + // mwe-embedplayer-ogg-player-flowplayer, mwe-embedplayer-ogg-player-kplayer, mwe-embedplayer-ogg-player-selected, + // mwe-embedplayer-ogg-player-omtkplayer + return mw.msg( 'mwe-embedplayer-ogg-player-' + this.id ); + }, + + /** + * Loads the player library & player skin config ( if needed ) and then + * calls the callback. + * + * @param {Function} + * callback Function to be called once player library is loaded. + */ + load: function( callback ) { + // Load player library ( upper case the first letter of the library ) + mw.load( [ + 'mw.EmbedPlayer' + this.library.substr(0,1).toUpperCase() + this.library.substr(1) + ], function() { + if( callback ){ + callback(); + } + } ); + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayers.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayers.js new file mode 100644 index 00000000..9d1e34f4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaPlayers.js @@ -0,0 +1,195 @@ +/** + * mediaPlayers is a collection of mediaPlayer objects supported by the client. + * + * @constructor + */ +( function( mw, $ ) { "use strict"; + +mw.MediaPlayers = function(){ + this.init(); +}; + +mw.MediaPlayers.prototype = { + // The list of players supported + players : null, + + // Store per mime-type preferences for players + preference : { }, + + // Stores the default set of players for a given mime type + defaultPlayers : { }, + + /** + * Initializartion function sets the default order for players for a given + * mime type + */ + init: function() { + this.players = new Array(); + this.loadPreferences(); + + // Set up default players order for each library type + this.defaultPlayers['video/x-flv'] = ['Kplayer', 'Vlc']; + this.defaultPlayers['video/h264'] = ['Native', 'Kplayer', 'Vlc']; + + this.defaultPlayers['application/vnd.apple.mpegurl'] = ['Native']; + + this.defaultPlayers['video/ogg'] = ['Native', 'Vlc', 'OgvJs', 'Generic', 'VLCApp']; + this.defaultPlayers['audio/webm'] = ['Native', 'Vlc', 'VLCApp', 'IEWebMPrompt']; + this.defaultPlayers['video/webm'] = ['Native', 'Vlc', 'VLCApp', 'IEWebMPrompt']; + this.defaultPlayers['application/ogg'] = ['Native', 'Vlc', 'OgvJs', 'Generic', 'VLCApp']; + this.defaultPlayers['audio/ogg'] = ['Native', 'Vlc', 'OgvJs', 'VLCApp']; + this.defaultPlayers['audio/mpeg']= ['Native', 'Kplayer']; + this.defaultPlayers['audio/mp3']= ['Native', 'Kplayer']; + this.defaultPlayers['audio/mp4']= ['Native']; + this.defaultPlayers['video/mp4'] = ['Native', 'Vlc']; + this.defaultPlayers['video/mpeg'] = ['Vlc']; + this.defaultPlayers['video/x-msvideo'] = ['Vlc']; + + // this.defaultPlayers['text/html'] = ['Html']; + //this.defaultPlayers['image/svg'] = ['ImageOverlay']; + + this.defaultPlayers['image/jpeg'] = ['ImageOverlay']; + this.defaultPlayers['image/png'] = ['ImageOverlay']; + + }, + + /** + * Adds a Player to the player list + * + * @param {Object} + * player Player object to be added + */ + addPlayer: function( player ) { + for ( var i = 0; i < this.players.length; i++ ) { + if ( this.players[i].id == player.id ) { + // Player already found + return ; + } + } + // Add the player: + this.players.push( player ); + }, + + /** + * Checks if a player is supported by id + */ + isSupportedPlayer: function( playerId ){ + for( var i=0; i < this.players.length; i++ ){ + if( this.players[i].id == playerId ){ + return true; + } + } + return false; + }, + + /** + * get players that support a given mimeType + * + * @param {String} + * mimeType Mime type of player set + * @return {Array} Array of players that support a the requested mime type + */ + getMIMETypePlayers: function( mimeType ) { + var mimePlayers = new Array(); + var _this = this; + var baseMimeType = mimeType.split( ';' )[0]; + if ( this.defaultPlayers[ baseMimeType ] ) { + $.each( this.defaultPlayers[ baseMimeType ], function( d, lib ) { + var library = _this.defaultPlayers[ baseMimeType ][ d ]; + for ( var i = 0; i < _this.players.length; i++ ) { + if ( _this.players[i].library == library && _this.players[i].supportsMIMEType( mimeType ) ) { + mimePlayers.push( _this.players[i] ); + } + } + } ); + } + return mimePlayers; + }, + + /** + * Default player for a given mime type + * + * @param {String} + * mimeType Mime type of the requested player + * @return Player for mime type null if no player found + */ + defaultPlayer : function( mimeType ) { + // mw.log( "get defaultPlayer for " + mimeType ); + var mimePlayers = this.getMIMETypePlayers( mimeType ); + if ( mimePlayers.length > 0 ) + { + // Select the default player: + for ( var i = 0; i < mimePlayers.length; i++ ) { + // Check for native: + if( mimePlayers[i].librayr == 'Native' ){ + return mimePlayers[i]; + } + // else check for preference + if ( mimePlayers[i].id == this.preference[mimeType] ){ + return mimePlayers[i]; + } + } + // Otherwise just return the first compatible player + // (it will be chosen according to the defaultPlayers list + return mimePlayers[0]; + } + // mw.log( 'No default player found for ' + mimeType ); + return null; + }, + + /** + * Sets the format preference. + * + * @param {String} + * mimeFormat Prefered format + */ + setFormatPreference : function ( mimeFormat ) { + this.preference['formatPreference'] = mimeFormat; + $.cookie( 'EmbedPlayer.Preference', JSON.stringify( this.preference) ); + }, + + /** + * Loads the user preference settings from a cookie + */ + loadPreferences : function ( ) { + this.preference = { }; + // See if we have a cookie set to a clientSupported type: + if( $.cookie( 'EmbedPlayer.Preference' ) ) { + this.preference = JSON.parse( $.cookie( 'EmbedPlayer.Preference' ) ); + } + }, + + /** + * Sets the player preference + * + * @param {String} + * playerId Preferred player id + * @param {String} + * mimeType Mime type for the associated player stream + */ + setPlayerPreference : function( playerId, mimeType ) { + var selectedPlayer = null; + for ( var i = 0; i < this.players.length; i++ ) { + if ( this.players[i].id == playerId ) { + selectedPlayer = this.players[i]; + mw.log( 'EmbedPlayer::setPlayerPreference: choosing ' + playerId + ' for ' + mimeType ); + this.preference[ mimeType ] = playerId; + $.cookie( 'EmbedPlayer.Preference', JSON.stringify( this.preference ) ); + break; + } + } + // Update All the player instances on the page + if ( selectedPlayer ) { + $('.mwEmbedPlayer').each(function(inx, playerTarget ){ + var embedPlayer = $( playerTarget ).get( 0 ); + if ( embedPlayer.mediaElement.selectedSource + && ( embedPlayer.mediaElement.selectedSource.mimeType == mimeType ) ) + { + embedPlayer.selectPlayer( selectedPlayer ); + } + }); + } + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaSource.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaSource.js new file mode 100644 index 00000000..9449a5d4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.MediaSource.js @@ -0,0 +1,490 @@ +/** + * mediaSource class represents a source for a media element. + * + * @param {Element} + * element: MIME type of the source. + * @constructor + */ + +/** + * The base source attribute checks also see: + * http://dev.w3.org/html5/spec/Overview.html#the-source-element + */ + +( function( mw, $ ) { "use strict"; + +mw.mergeConfig( 'EmbedPlayer.SourceAttributes', [ + // source id + 'id', + + // media url + 'src', + + // Title string for the source asset + 'title', + + // boolean if we support temporal url requests on the source media + 'URLTimeEncoding', + + // Store the node name for type identification + 'nodeName', + + /** + * data- attributes ( not yet standards ) + */ + + // Media has a startOffset ( used for plugins that + // display ogg page time rather than presentation time + 'data-startoffset', + + // A hint to the duration of the media file so that duration + // can be displayed in the player without loading the media file + 'data-durationhint', + + // Source stream qualities + // NOTE data- is striped from the attribute as we build out the "mediaSource" object + 'data-shorttitle', // short title for stream ( useful for stream switching control bar widget) + 'data-width', // the width of the stream + 'data-height', // the height of the stream + 'data-bandwidth', // the overall bitrate of the stream in bytes + 'data-sizebytes', // the size of the stream in bytes + 'data-framerate', // the framereate of the stream + 'data-flavorid', // a source flavor id ( useful for targeting devices ) + 'data-aspect', // the aspect ratio, useful for adaptive protocal urls that don't have a strict height / width + + // Used as title in download panel + 'data-title', + + // Used for download attribute on mediawiki + 'data-mwtitle', + // used for setting the api provider for mediawiki + 'data-mwprovider', + + // to disable menu or timedText for a given embed + 'data-disablecontrols', + + // used for language direction of subtitles + 'data-dir', + + // Media start time + 'start', + + // Media end time + 'end', + + // If the source is the default source + 'default' +] ); + +mw.MediaSource = function( element ) { + this.init( element ); +}; + +mw.MediaSource.prototype = { + // MIME type of the source. + mimeType:null, + + // URI of the source. + uri:null, + + // Title of the source. + title: null, + + // True if the source has been marked as the default. + markedDefault: false, + + // True if the source supports url specification of offset and duration + URLTimeEncoding:false, + + // Start offset of the requested segment + startOffset: 0, + + // Duration of the requested segment (0 if not known) + duration:0, + + // source id + id: null, + + // Start time in npt format + startNpt: null, + + // End time in npt format + endNpt: null, + + // Language of the file + srclang: null, + /** + * MediaSource constructor: + */ + init : function( element ) { + var _this = this; + // mw.log('EmbedPlayer::adding mediaSource: ' + element); + this.src = $( element ).attr( 'src' ); + + // Set default URLTimeEncoding if we have a time url: + // not ideal way to discover if content is on an oggz_chop server. + // should check some other way. + var pUrl = new mw.Uri ( this.src ); + if ( typeof pUrl.query[ 't' ] != 'undefined' ) { + this.URLTimeEncoding = true; + } + + var sourceAttr = mw.config.get( 'EmbedPlayer.SourceAttributes' ); + $.each( sourceAttr, function( inx, attr ){ + if ( $( element ).attr( attr ) ) { + // strip data- from the attribute name + var attrName = ( attr.indexOf('data-') === 0) ? attr.substr(5) : attr + _this[ attrName ] = $( element ).attr( attr ); + } + }); + + // Normalize "label" to "title" ( label is the actual spec so use that over title ) + if( this.label ){ + this.title = this.label; + } + + // Set the content type: + if ( $( element ).attr( 'type' ) ) { + this.mimeType = $( element ).attr( 'type' ); + }else if ( $( element ).attr( 'content-type' ) ) { + this.mimeType = $( element ).attr( 'content-type' ); + }else if( $( element )[0].tagName.toLowerCase() == 'audio' ){ + // If the element is an "audio" tag set audio format + this.mimeType = 'audio/ogg'; + } else { + this.mimeType = this.detectType( this.src ); + } + + // Conform the mime type to ogg + if( this.mimeType == 'video/theora') { + this.mimeType = 'video/ogg'; + } + + if( this.mimeType == 'audio/vorbis') { + this.mimeType = 'audio/ogg'; + } + + // Check for parent elements ( supplies categories in "track" ) + if( $( element ).parent().attr('category') ) { + this.category = $( element ).parent().attr('category'); + } + + if( $( element ).attr( 'default' ) ){ + this.markedDefault = true; + } + + // Get the url duration ( if applicable ) + this.getURLDuration(); + }, + + /** + * Update Source title via Element + * + * @param {Element} + * element Source element to update attributes from + */ + updateSource: function( element ) { + // for now just update the title: + if ( $( element ).attr( "title" ) ) { + this.title = $( element ).attr( "title" ); + } + }, + + /** + * Updates the src time and start & end + * + * @param {String} + * start_time: in NPT format + * @param {String} + * end_time: in NPT format + */ + updateSrcTime: function ( startNpt, endNpt ) { + // mw.log("f:updateSrcTime: "+ startNpt+'/'+ endNpt + ' from org: ' + + // this.startNpt+ '/'+this.endNpt); + // mw.log("pre uri:" + this.src); + // if we have time we can use: + if ( this.URLTimeEncoding ) { + // make sure its a valid start time / end time (else set default) + if ( !mw.npt2seconds( startNpt ) ) { + startNpt = this.startNpt; + } + + if ( !mw.npt2seconds( endNpt ) ) { + endNpt = this.endNpt; + } + + this.src = mw.replaceUrlParams( this.src, { + 't': startNpt + '/' + endNpt + }); + + // update the duration + this.getURLDuration(); + } + }, + + /** + * Sets the duration and sets the end time if unset + * + * @param {Float} + * duration: in seconds + */ + setDuration: function ( duration ) { + this.duration = duration; + if ( !this.endNpt ) { + this.endNpt = mw.seconds2npt( this.startOffset + duration ); + } + }, + + /** + * MIME type accessor function. + * + * @return {String} the MIME type of the source. + */ + getMIMEType: function() { + if( this.mimeType ) { + return this.mimeType; + } + this.mimeType = this.detectType( this.src ); + return this.mimeType; + }, + /** + * Update the local src + * @param {String} + * src The URL to the media asset + */ + setSrc: function( src ){ + this.src = src; + }, + + /** + * URI function. + * + * @param {Number} + * serverSeekTime Int: Used to adjust the URI for url based + * seeks) + * @return {String} the URI of the source. + */ + getSrc: function( serverSeekTime ) { + if ( !serverSeekTime || !this.URLTimeEncoding ) { + return this.src; + } + var endvar = ''; + if ( this.endNpt ) { + endvar = '/' + this.endNpt; + } + return mw.replaceUrlParams( this.src, + { + 't': mw.seconds2npt( serverSeekTime ) + endvar + } + ); + }, + /** + * Title accessor function. + * + * @return {String} Title of the source. + */ + getTitle : function() { + if( this.title ){ + return this.title; + } + // Text tracks use "label" instead of "title" + if( this.label ){ + return this.label; + } + + // Return a Title based on mime type: + var mimeType = this.getMIMEType().split( ';' )[0]; + switch( mimeType ) { + case 'video/h264' : + case 'video/mp4' : + return mw.msg( 'mwe-embedplayer-video-h264' ); + break; + case 'video/x-flv' : + return mw.msg( 'mwe-embedplayer-video-flv' ); + break; + case 'video/webm' : + return mw.msg( 'mwe-embedplayer-video-webm'); + break; + case 'video/ogg' : + return mw.msg( 'mwe-embedplayer-video-ogg' ); + break; + case 'audio/ogg' : + return mw.msg( 'mwe-embedplayer-video-audio' ); + break; + case 'audio/mpeg' : + return mw.msg('mwe-embedplayer-audio-mpeg'); + break; + case 'video/3gp' : + return mw.msg('mwe-embedplayer-video-3gp'); + break; + case 'video/mpeg' : + return mw.msg('mwe-embedplayer-video-mpeg'); + break; + case 'video/x-msvideo' : + return mw.msg('mwe-embedplayer-video-msvideo' ); + break; + } + + // Return title based on file name: + try{ + var fileName = new mw.Uri( mw.absoluteUrl( this.getSrc() ) ).path.split('/').pop(); + if( fileName ){ + return fileName; + } + } catch(e){} + + // Return the mime type string if not known type. + return this.mimeType; + }, + /** + * Get a short title for the stream + */ + getShortTitle: function(){ + var _this =this; + if( this.shorttitle ){ + return this.shorttitle; + } + // Just use a short "long title" + var longTitle = this.getTitle(); + if(longTitle.length > 20) { + longTitle = longTitle.substring(0,17)+"..."; + } + return longTitle + }, + /** + * + * Get Duration of the media in milliseconds from the source url. + * + * Supports media_url?t=ntp_start/ntp_end url request format + */ + getURLDuration : function() { + // check if we have a URLTimeEncoding: + if ( this.URLTimeEncoding ) { + var annoURL = new mw.Uri( this.src ); + if ( annoURL.query.t ) { + var times = annoURL.query.t.split( '/' ); + this.startNpt = times[0]; + this.endNpt = times[1]; + this.startOffset = mw.npt2seconds( this.startNpt ); + this.duration = mw.npt2seconds( this.endNpt ) - this.startOffset; + } else { + // look for this info as attributes + if ( this.startOffset ) { + this.startNpt = mw.seconds2npt( this.startOffset ); + } + if ( this.duration ) { + this.endNpt = mw.seconds2npt( parseInt( this.duration ) + parseInt( this.startOffset ) ); + } + } + } + }, + /** + * Get the extension of a url + * @param String uri + */ + getExt : function( uri ){ + var urlParts = new mw.Uri( uri ); + // Get the extension from the url or from the relative name: + var ext = ( urlParts.file ) ? /[^.]+$/.exec( urlParts.file ) : /[^.]+$/.exec( uri ); + // remove the hash string if present + ext = /[^#]*/g.exec( ext.toString() ); + ext = ext || ''; + return ext.toString().toLowerCase(); + }, + /** + * Get the flavorId if available. + */ + getFlavorId: function(){ + if( this.flavorid ){ + return this.flavorid; + } + return ; + }, + + /** + * Attempts to detect the type of a media file based on the URI. + * + * @param {String} + * uri URI of the media file. + * @return {String} The guessed MIME type of the file. + */ + detectType: function( uri ) { + // NOTE: if media is on the same server as the javascript + // we can issue a HEAD request and read the mime type of the media... + // ( this will detect media mime type independently of the url name ) + // http://www.jibbering.com/2002/4/httprequest.html + switch( this.getExt( uri ) ) { + case 'smil': + case 'sml': + return 'application/smil'; + break; + case 'm4v': + case 'mp4': + return 'video/h264'; + break; + case 'm3u8': + return 'application/vnd.apple.mpegurl'; + break; + case 'webm': + return 'video/webm'; + break; + case '3gp': + return 'video/3gp'; + break; + case 'srt': + return 'text/x-srt'; + break; + case 'flv': + return 'video/x-flv'; + break; + case 'ogg': + case 'ogv': + return 'video/ogg'; + break; + case 'oga': + return 'audio/ogg'; + break; + case 'mp3': + return 'audio/mpeg'; + case 'm4a': + return 'audio/mp4'; + break; + case 'anx': + return 'video/ogg'; + break; + case 'xml': + return 'text/xml'; + break; + case 'avi': + return 'video/x-msvideo'; + break; + case 'mpg': + return 'video/mpeg'; + break; + case 'mpeg': + return 'video/mpeg'; + break; + } + mw.log( "Error: could not detect type of media src: " + uri ); + }, + /** + * bitrate is mesured in kbs rather than bandwith bytes per second + */ + getBitrate: function() { + if( this.bandwidth ){ + return this.bandwidth / 1024; + } + return 0; + }, + /** + * Get the size of the stream in bytes + */ + getSize: function(){ + if( this.sizebytes ){ + return this.sizebytes; + } + return 0; + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.processEmbedPlayers.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.processEmbedPlayers.js new file mode 100644 index 00000000..0748ccd0 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/mw.processEmbedPlayers.js @@ -0,0 +1,353 @@ +/** + * Selector based embedPlayer processing + * + * @param {Function=} + * callback Optional Function to be called once video interfaces + * are ready + * + */ + +( function( mw, $ ) { "use strict"; + +mw.processEmbedPlayers = function( playerSet, callback ) { + mw.log( 'processEmbedPlayers:: playerSet: ', playerSet); + // The player id list container + var playerIdList = []; + + // Check if the selected player set is ready if ready issue the parent callback + var areSelectedPlayersReady = function(){ + var playersLoaded = true; + $.each( playerIdList, function(inx, playerId){ + if( ! $( '#' + playerId )[0].playerReadyFlag ){ + playersLoaded = false; + return false; + } + }) + if( playersLoaded ){ + if( callback ){ + callback(); + } + } + } + + /** + * Adds a player element for the embedPlayer to rewrite + * + * uses embedPlayer interface on audio / video elements uses mvPlayList + * interface on playlist elements + * + * Once a player interface is established the following chain of functions + * are called; + * + * _this.checkPlayerSources() + * _this.setupSourcePlayer() + * _this.updatePlaybackInterface() + * _this.selectedPlayer.load() + * _this.showPlayer() + * + * @param {Element} + * playerElement DOM element to be swapped + */ + var addPlayerElement = function( playerElement ) { + var _this = this; + mw.log('EmbedPlayer:: addElement:: ' + playerElement.id ); + + // Be sure to "stop" the target ( Firefox 3x keeps playing + // the video even though its been removed from the DOM ) + if( playerElement.pause ){ + playerElement.pause(); + } + + // Allow modules to override the wait for metadata flag: + $( mw ).trigger( 'EmbedPlayerWaitForMetaCheck', playerElement ); + + // DOM *could* load height, width and duration eventually, in some browsers + // By default, don't bother waiting for this. + var waitForMeta = false; + + // if a plugin has told us not to waitForMeta, don't + if ( playerElement.waitForMeta !== false ) { + // Check if we should wait for metadata, after all + waitForMeta = waitForMetaCheck( playerElement ); + } + + var ranPlayerSwapFlag = false; + + // Local callback to runPlayer swap once playerElement has metadata + var runPlayerSwap = function () { + // Don't run player swap twice + if( ranPlayerSwapFlag ){ + return ; + } + ranPlayerSwapFlag = true; + mw.log( "processEmbedPlayers::runPlayerSwap::" + $( playerElement ).attr('id') ); + + var playerInterface = new mw.EmbedPlayer( playerElement ); + var inDomPlayer = swapEmbedPlayerElement( playerElement, playerInterface ); + + // IE/Edge with WebM components re-triggers autoplay after removal as well. + if( playerElement.pause ){ + playerElement.pause(); + } + + // Trigger the EmbedPlayerNewPlayer for embedPlayer interface + mw.log("processEmbedPlayers::trigger:: EmbedPlayerNewPlayer " + inDomPlayer.id ); + + // Allow plugins to add bindings to the inDomPlayer + $( mw ).trigger ( 'EmbedPlayerNewPlayer', inDomPlayer ); + + // Add a player ready binding: + $( inDomPlayer ).bind( 'playerReady.swap', function(event, id){ + $( inDomPlayer ).unbind( 'playerReady.swap' ); + areSelectedPlayersReady(); + }); + + // + // Allow modules to block player build out + // + // this is needed in cases where you need to do an asynchronous + // player interface setup. like iframes asynchronous announcing its ready for + // bindings that can affect player setup. + mw.log("EmbedPlayer::addPlayerElement :trigger startPlayerBuildOut:" + inDomPlayer.id ); + $( '#' + inDomPlayer.id ).triggerQueueCallback( 'startPlayerBuildOut', function(){ + // Issue the checkPlayerSources call to the new player + // interface: make sure to use the element that is in the DOM: + inDomPlayer.checkPlayerSources(); + }); + }; + + if( waitForMeta && mw.config.get('EmbedPlayer.WaitForMeta' ) ) { + mw.log('processEmbedPlayers::WaitForMeta ( video missing height (' + + $( playerElement ).attr('height') + '), width (' + + $( playerElement ).attr('width') + ') or duration: ' + + $( playerElement ).attr('duration') + ); + $( playerElement ).bind( "loadedmetadata", runPlayerSwap ); + + // Time-out of 5 seconds ( maybe still playable but no timely metadata ) + setTimeout( runPlayerSwap, 5000 ); + return ; + } else { + runPlayerSwap(); + return ; + } + }; + + /** + * Check if we should wait for metadata. + * + * @return true if the size is "likely" to be updated by waiting for metadata + * false if the size has been set via an attribute or is already loaded + */ + var waitForMetaCheck = function( playerElement ){ + var waitForMeta = false; + + // Don't wait for metadata for non html5 media elements + if( !playerElement ){ + return false; + } + if( !playerElement.tagName || ( playerElement.tagName.toLowerCase() != 'audio' && playerElement.tagName.toLowerCase() != 'video' ) ){ + return false; + } + // If we don't have a native player don't wait for metadata + if( !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'oggNative') && + !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'webmNative') && + !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'h264Native' ) && + !mw.EmbedTypes.getMediaPlayers().isSupportedPlayer( 'appleVdnPlayer' ) ) + { + return false; + } + + + var width = $( playerElement ).css( 'width' ); + var height = $( playerElement ).css( 'height' ); + // Css video defaults ( firefox ) + if( $( playerElement ).css( 'width' ) == '300px' && + $( playerElement ).css( 'height' ) == '150px' + ){ + waitForMeta = true; + } else { + // Check if we should wait for duration: + if( $( playerElement ).attr( 'duration') || + $( playerElement ).attr( 'durationHint') || + $( playerElement ).attr('data-durationhint') + ){ + // height, width and duration set; do not wait for meta data: + return false; + } else { + waitForMeta = true; + } + } + + // Firefox ~ sometimes~ gives -1 for unloaded media + if ( $(playerElement).attr( 'width' ) == -1 || $(playerElement).attr( 'height' ) == -1 ) { + waitForMeta = true; + } + + // Google Chrome / safari gives 0 width height for unloaded media + if( $(playerElement).attr( 'width' ) === 0 || + $(playerElement).attr( 'height' ) === 0 + ) { + waitForMeta = true; + } + + // Firefox default width height is ~sometimes~ 150 / 300 + if( playerElement.height == 150 && playerElement.width == 300 ){ + waitForMeta = true; + } + + // Make sure we have a src attribute or source child + // ( i.e not a video tag to be dynamically populated or looked up from + // xml resource description ) + if( waitForMeta && + ( + $( playerElement ).attr('src') || + $( playerElement ).find("source[src]").length !== 0 + ) + ) { + // Detect src type ( if no type set ) + return true; + } else { + // playerElement is not likely to update its meta data ( no src ) + return false; + } + }; + + /** + * swapEmbedPlayerElement + * + * Takes a video element as input and swaps it out with an embed player interface + * + * @param {Element} + * targetElement Element to be swapped + * @param {Object} + * playerInterface Interface to swap into the target element + */ + var swapEmbedPlayerElement = function( targetElement, playerInterface ) { + mw.log( 'processEmbedPlayers::swapEmbedPlayerElement: ' + targetElement.id ); + // Create a new element to swap the player interface into + var swapPlayerElement = document.createElement('div'); + + // Add a class that identifies all embedPlayers: + $( swapPlayerElement ).addClass( 'mwEmbedPlayer' ); + + // Get properties / methods from playerInterface: + for ( var method in playerInterface ) { + if ( method != 'readyState' ) { // readyState crashes IE ( don't include ) + swapPlayerElement[ method ] = playerInterface[ method ]; + } + } + // copy over css text: + swapPlayerElement.style.cssText = targetElement.style.cssText; + // player element must always be relative to host video and image layout + swapPlayerElement.style.position = 'relative'; + + // Copy any data attributes from the target player element over to the swapPlayerElement + var dataAttributes = mw.config.get("EmbedPlayer.DataAttributes"); + if( dataAttributes ){ + $.each( dataAttributes, function( attrName, na ){ + if( $( targetElement ).data( attrName ) ){ + $( swapPlayerElement ).data( attrName, $( targetElement ).data( attrName ) ); + } + }); + } + // Check for Persistent native player ( should keep the video embed around ) + if( playerInterface.isPersistentNativePlayer() + || + // Also check for native controls on a video or audio tag + ( playerInterface.useNativePlayerControls() + && + ( targetElement.nodeName == 'video' || targetElement.nodeName == 'audio' ) + ) + ) { + + $( targetElement ) + .attr( 'id', playerInterface.pid ) + .addClass( 'nativeEmbedPlayerPid' ) + .show() + .after( + $( swapPlayerElement ).css( 'display', 'none' ) + ); + + } else { + $( targetElement ).replaceWith( swapPlayerElement ); + } + + // If we don't already have a loadSpiner add one: + if( $('#loadingSpinner_' + playerInterface.id ).length == 0 && $.client.profile().name !== 'firefox' ){ + if( playerInterface.useNativePlayerControls() || playerInterface.isPersistentNativePlayer() ) { + var $spinner = $( targetElement ) + .getAbsoluteOverlaySpinner(); + }else{ + var $spinner = $( swapPlayerElement ).getAbsoluteOverlaySpinner(); + } + $spinner.attr('id', 'loadingSpinner_' + playerInterface.id ); + } + return swapPlayerElement; + }; + + // Add a loader for <div /> embed player rewrites: + $( playerSet ).each( function( index, playerElement) { + + // Make sure the playerElement has an id: + if( !$( playerElement ).attr('id') ){ + $( playerElement ).attr( "id", 'mwe_vid' + ( index ) ); + } + // Add the player Id to the playerIdList + playerIdList.push( $( playerElement ).attr( "id") ); + + // If we are dynamically embedding on a "div" check if we can + // add a poster image behind the loader: + if( playerElement.nodeName.toLowerCase() == 'div' + && + $(playerElement).attr( 'poster' ) ) + { + var posterSrc = $(playerElement).attr( 'poster' ); + + // Set image size: + var width = $( playerElement ).width(); + var height = $( playerElement ).height(); + if( !width ){ + var width = '100%'; + } + if( !height ){ + var height = '100%'; + } + + mw.log('EmbedPlayer:: set loading background: ' + posterSrc); + $( playerElement ).append( + $( '<img />' ) + .attr( 'src', posterSrc) + .css({ + 'position' : 'absolute', + 'width' : width, + 'height' : height + }) + ); + } + }); + + // Make sure we have user preference setup for setting preferences on video selection + var addedPlayersFlag = false; + mw.log("processEmbedPlayers:: Do: " + $( playerSet ).length + ' players '); + // Add each selected element to the player manager: + $( playerSet ).each( function( index, playerElement) { + // Make sure the video tag was not generated by our library: + if( $( playerElement ).hasClass( 'nativeEmbedPlayerPid' ) ){ + $( '#loadingSpinner_' + $( playerElement ).attr('id') ).remove(); + mw.log( 'processEmbedPlayers::$.embedPlayer skip embedPlayer gennerated video: ' + playerElement ); + } else { + addedPlayersFlag = true; + // Add the player + addPlayerElement( playerElement ); + } + }); + if( !addedPlayersFlag ){ + // Run the callback directly if no players were added + if( callback ){ + callback(); + } + } +}; + +})( mw, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/EmbedPlayer.css b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/EmbedPlayer.css new file mode 100644 index 00000000..9699c2e9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/EmbedPlayer.css @@ -0,0 +1,166 @@ +.ui-dialog-content .mediaContainer { margin: 0 auto; } +.mwPlayerContainer, video { width: 100%; height: 100%; } +.mwPlayerContainer { position: relative; height: 100%; background: #000; } +.videoHolder { + position: absolute; + top: 0px; + left:0px; + right:0px; + bottom:0px; + overflow: hidden; +} +.mwPlayerContainer.fullscreen { + position: absolute !important; + width: 100% !important; + height: 100%! important; + z-index: 9999; + min-height: 100%; + top: 0; + left: 0; + margin: 0; +} + +.mwEmbedPlayer { width: 100%; height: 100%; overflow: hidden; position: absolute; top: 0; left: 0; } + + +.player_select_list { + color:white; + font-size:10pt; +/* display:none;*/ +} +.player_select_list a:visited { + color:white; +} +.mv_playhead { + position:absolute; + top:0; + left:0; + width:17px; + height:21px; + /*http://art.gnome.org/themes/gtk2*/ +} + +.mv_status { + font-family:"Times New Roman", Times, serif; + font-size:14px; + float:left; +} +.set_ogg_player_pref{ + text-align:left; +} + +.large_play_button { + display:block; + width: 130px; + height: 96px; + margin: auto; +/* margin: -202px 0 0 154px;*/ + position: absolute; + z-index: 3; + cursor: pointer; +} + +/* jquery.ui overrides */ + +.ui-icon_link { + padding: .4em 1em .4em 20px; + text-decoration: none; + position: relative; +} +.ui-icon_link span.ui-icon { + margin: 0 5px 0 0; + position: absolute; + left: 0.2em; + right: auto; + top: 50%; + margin-top: -8px; + zoom: 1; +} +.ui-icon_link span.ui-text { + position: absolute; + left: 0.2em; + right: auto; + margin-top: -3px; + zoom: 1; +} + +.ui-progressbar-value{ + background-image: none; +} + +.kplayer .ui-widget-overlay { + background: black; opacity: .40; filter: Alpha(Opacity=40); +} + +.kplayer .ui-widget-content input { + padding: 5px; +} +.kplayer .ui-widget-content a { + color: #222; +} + +ul.ui-provider-selection { + list-style-type: none; + margin: 0 0 0.6em 0; + overflow: hidden; + padding: 0; + text-align: center; +} + +ul.ui-provider-selection li { + border-left: 1px solid black; + float: left; + line-height: 1.1em; + margin: 0 0.5em 0 -0.5em; + padding: 0 0.5em; + color: blue; + list-style-image:none; + cursor:pointer; +} + +ul.ui-provider-selection li .ui-selected { + color: black; + font-weight: bold; +} + +ul.ui-provider-selection li a.ui-active { + color: black; + font-weight: bold; +} + +ul.ui-provider-selection li a { + color: blue; + text-decoration: none; +} +.fg-menu .ui-icon{ + position:relative; + top:-1px; +} + +.ui-dialog-buttonpane a{ + float: right; + margin-right: 10px; +} + + +/* Custom */ +.mv-player .overlay-win { background: transparent; border: 0; } /* Custom */ +.mv-player .overlay-content { padding: 10px; } +.mv-player .overlay-content h3 { display: block; font-size: 16px; font-weight: bold; color: #fff; font-family: arial; } +.mv-player .overlay-win h2 { font-size: 18px; margin-top: 0; } +.mv-player .overlay-content div { font-size: 12px; color: #fff; font-weight: bold; } +.mv-player .overlay-content div a { color: #00a8ff } +.mv-player .overlay-content div a:hover { color: #3abcff } +.mv-player .overlay-content ul { list-style: none; margin: 0 0 10px 0; padding: 0; } +.mv-player .vol_container { + background: #272727; + opacity: .80; + filter:Alpha(Opacity=80); + position:absolute; + left:0px; +} +.mv-player .ui-icon ui-icon-closethick { border: 1px solid #606060; background: #222;font-weight: normal; color: #EEE; } +.mv-player .overlay-win textarea { background: #e4e4e4; height: 35px; padding: 6px; color: #666; border: 0; } +.mv-player .overlay-content .copycode { padding: 8px 12px; font-weight: bold; float: right; cursor: pointer; } +.control-bar .ui-icon_link { border: 0; } +.control-bar .ui-state-hover { border: 0; } diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/PlayerSkinKskin.css b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/PlayerSkinKskin.css new file mode 100644 index 00000000..f6c675d7 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/PlayerSkinKskin.css @@ -0,0 +1,484 @@ +/* +* K-skin player +*/ +.k-player { + color: #FFF; + background-color: #000; +} +.k-player .videoHolder a { + color: #0645AD; +} +.k-player .videoHolder a:visited { + color: #0B0080; +} +.k-player .ui-widget-content { + color: #555; + z-index: 1503; +} +.k-player .ui-widget-content a{ + color: #555; +} +/* large play button */ +.k-player .play-btn-large { + width: 70px; + height: 55px; + background: url(images/ksprite.png) no-repeat 0px -433px; + position: absolute; + cursor: pointer; + border: none; +} +@print { + .k-player .play-btn-large { + display: none; + } +} +/*.ui-state-default */ +.k-player .play-btn-large:hover { + background: url(images/ksprite.png) no-repeat 0px -377px; +} + +/* control icons: */ +.k-player .control-bar .ui-icon,.k-player .control-bar .ui-icon{ + background: transparent url(images/ksprite.png) no-repeat scroll 0 -48px; +} + +.k-player .ui-state-default .ui-icon-arrow-4-diag { + background-position: 0 -32px; +} +/* fullscreen */ +.k-player .ui-state-hover .ui-icon-arrow-4-diag { + background-position: -16px -32px; +} + +.k-player .ui-state-hover .ui-icon-volume-on{ + background-position: -16px -48px; +} + +/* cc icon */ +.k-player .ui-state-default .ui-icon-comment { + background-position: 0px -65px; +} + +.k-player .ui-state-default .ui-icon-play { + background: url(images/ksprite.png) no-repeat 0 0; +} + +.k-player .ui-state-hover .ui-icon-play { + background-position: -16px 0; +} + +.k-player .ui-state-default .ui-icon-pause { + background: url(images/ksprite.png) no-repeat 0 -17px; +} + +.k-player .ui-state-hover .ui-icon-pause { + background-position: -16px -17px; +} + +.k-player .control-bar { + border:1px solid #c8c8c8; + border-top: 0px; + border-right: 0px; + height: 21px; + padding: 2px 0 0 6px; + margin-top: 0px; + background: url(images/ksprite.png) repeat-x 0 -81px; + font: normal 11px arial, sans-serif; + color: #555; + + position:absolute; + bottom:0px; + left:0px; + right:0px; + + z-index: 2; +} + +.k-player .play_head { + background: url("images/ksprite.png") repeat-x scroll 0 -350px + transparent; + display: inline; + /* @noflip */ + float: left; + margin-left: 10px; + border: 1px solid #EEEEEE; + height: 8px; + margin: 5px 2px 0 0px; + position: relative; + /* @noflip */ + direction: ltr; +} + +.k-player .play_head .ui-slider-handle { + background: url("images/ksprite.png") no-repeat scroll -67px -341px + transparent !important; + border: 1px solid #888888; + display: block; + height: 8px; + margin: -1px 0 0 -5px; + position: absolute; + top: 0; + width: 8px; + cursor: pointer; + -moz-border-radius:5px 5px 5px 5px; + border-radius:5px 5px 5px 5px; + -webkit-border-radius:5px 5px 5px 5px; +} + +.k-player .ui-corner-all { + border-radius:5px 5px 5px 5px !important; + -webkit-border-radius:5px 5px 5px 5px !important; + -moz-border-radius:5px 5px 5px 5px !important; +} +.k-player ul.fg-menu{ + margin: 0.3em 0 0 .3em; + font-size: 1.2em; + padding: 0px; +} +.k-player .fg-menu-container{ + padding: 0px; + /* @noflip */ + right: 16px; + /* Add scroll bar to list */ + overflow: auto; +} + +.ui-dialog-content .k-player ul.fg-menu{ + font-size: 1.2em; +} + +.k-player .time-disp { + border: medium none; + display: inline; + color: #555555; + font: 11px arial, sans-serif; + line-height: 20px; + overflow: hidden; + width: 39px; + /* @noflip */ + float: right; +} + +.k-player .source-switch { + border: medium none; + display: inline; + color: #555; + font: 11px arial, sans-serif; + line-height: 20px; + overflow: hidden; + width: 70px; + cursor: pointer; + /* @noflip */ + float: right; + text-align: center; +} + +.k-player .lButton { + cursor: pointer; + /* @noflip */ + float: left; + list-style: none outside none; + margin: 2px; + padding: 0px 0; + width: 19px; + height: 16px; + position: relative; + background: none repeat scroll 0 0 transparent !important; + border: medium none; +} + +.k-player .rButton { + cursor: pointer; + /* @noflip */ + float: right; + list-style: none outside none; + margin-top: 2px; + padding: 0px 0; + width: 22px; + height: 16px; + position: relative; + background: none repeat scroll 0 0 transparent !important; + border: medium none; +} + +.k-player .k-options { + border: 1px solid #AAAAAA !important; + color: #555555 !important; + /* @noflip */ + float: right; + height: 21px; + margin-top: -2px; + margin-right: 0px; + width: 50px; + background: none repeat scroll 0 0 transparent !important; + font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; + font-size: 11px; + text-transform: uppercase; + text-align: center; +} + +.k-player .k-options span { + position: relative; + top: 4px; +} + +.k-player .k-menu-screens { + /* @noflip */ + float: left; + font-size: 14px; + text-align: left; + padding: 5px 5px 10px 5px; +} + +.k-player ul.k-menu-bar { + background: url("images/ksprite.png") no-repeat scroll -99px -104px + transparent; + bottom: 5px; + height: 128px; + list-style: none outside none; + padding: 0 0 5px; + position: absolute; + /* @noflip */ + right: 0; + margin-left: 0; +} + +.k-player .k-menu { + background: none repeat scroll 0 0 #181818; + border: medium none; + display: none; + left: 0; + position: absolute; + top: 0; +} + +.k-player .k-menu-bar li a { + background: url("images/ksprite.png") no-repeat scroll -51px -110px + transparent; + display: block; + height: 32px; + margin-left: 1px; + overflow: hidden; + text-indent: 99999px; + width: 49px; +} + +.k-menu-bar li a:hover { + background-position: -1px -110px; +} + +.k-menu-bar li.k-download-btn a { + background-position: -51px -203px; +} + +.k-menu-bar li.k-download-btn a:hover { + background-position: -1px -203px; +} + +.k-menu-bar li.k-share-btn a { + background-position: -51px -172px; +} + +.k-menu-bar li.k-share-btn a:hover { + background-position: -1px -172px; +} + +.k-menu-bar li.k-credits-btn a { + background-position: -51px -141px; +} + +.k-menu-bar li.k-credits-btn a:hover { + background-position: -1px -141px; +} + + + +.k-menu-screens p { + margin: 6px 0; +} + +.k-menu-screens a img { + border: none; +} + +.k-menu-screens ul { + padding: 0; + margin: 6px 0 0; + list-style: none outside none; +} + +.k-edit-screen { + width: 370px; + height: 223px; + padding-top: 77px; + text-align: center; + background: #181818; + color: #fff; +} + +.k-edit-screen div { + +} + +.k-edit-screen a { + color: #7BB8FC; +} + +.k-edit-screen a img { + border: none; +} + + +.k-menu-screens h2, .k-menu-screens h3 { + padding: 0 0 5px 15px; + clear: both; + font-size: 12px; + color: #999; + border-bottom: 0; +} + +.k-menu-screens p { + margin: 6px 0; +} + +.k-menu-screens a img { + border: none; +} + +.k-menu-screens ul { + padding: 0; + margin: 6px 0 0; + list-style: none outside none; +} + +.k-menu-screens li { + margin-bottom: 6px; +} + +.k-menu-screens li a { + padding-left: 22px; + padding-right: 22px; + background: url(images/ksprite.png) no-repeat -85px -274px; + text-decoration: none; + color: #BBB; +} + +.k-menu-screens li a.active,.k-menu-screens li a:hover .active { + background-position: -85px -245px; +} + +.k-menu-screens li a:hover { + background-position: -85px -259px; +} + +.k-menu textarea { + background: none repeat scroll 0 0 transparent; + border-color: #000000 -moz-use-text-color -moz-use-text-color #000000; + border-style: solid none none solid; + border-width: 2px medium medium 2px; + color: #CCCCCC; + font: 11px arial, sans-serif; + overflow: hidden; + padding-left: 2px; + width: 95%; +} + +.menu-screen.menu-share button { + background: url("images/ksprite.png") no-repeat scroll 0 -81px #D4D4D4; + border: 1px solid #000000; + color: #000000; + float: right; + height: 34px; + padding: 0 5px 3px; + font-size: 1em; +} + +.k-player .menu-screen { + height: 100%; + overflow-y: auto; + overflow-x: hidden; +} + + +.k-player .menu-screen.menu-share div.ui-state-highlight { + background: none repeat scroll 0 0 transparent; + border-color: #554926; + color: #FFE96E; + float: left; + padding: 2px 5px; +} + +.k-player .menu-screen.menu-share div.ui-state-highlight a { + color: #FFE96E; + font-weight: bold; +} + +.k-player .volume_control { + /* @noflip */ + margin-right: 2px; + width: 16px; +} + +.k-player .volume_control span { + margin-right: 0px; +} + +.k-player .volume-slider { + width: 20px; + /* @noflip */ + direction: ltr; +} + +.k-player .volume-slider .ui-slider-range { + -moz-border-radius: 0 0 0 0; + background: url("images/ksprite.png") repeat-x scroll -66px -306px transparent !important; + height: 17px; + position: absolute; +} + +.k-player .volume-slider a.ui-slider-handle { + background: none repeat scroll 0 0 transparent; + border: medium none; + display: block; + height: 18px; + margin: -3px 5px 0 -1px; + position: absolute; + width: 8px; +} + +.k-player .ui-slider-horizontal .ui-slider-range-min { + /* @noflip */ + left: 0; +} + +.k-player .credits_box { + background-attachment:scroll; + background-color:white; + background-image:none; + background-position:0 0; + bottom: 20px; + left: 20px; + position:absolute; + right: 20px; + top: 30px; + overflow:hidden; +} +.k-player .credits_box a{ + color:#666; + text-decoration: underline; +} +.k-player .creditline img { + float: left; + width: 90px; + margin: 4px; +} + +.k-player .k-attribution{ + position:absolute; + bottom: 5px; + right : 20px; + background: url("images/kaltura_open_source_video_platform.png"); + width : 51px; + height : 12px; + cursor: pointer; +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/kaltura_open_source_video_platform.gif b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/kaltura_open_source_video_platform.gif Binary files differnew file mode 100644 index 00000000..cf05af25 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/kaltura_open_source_video_platform.gif diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/kaltura_open_source_video_platform.png b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/kaltura_open_source_video_platform.png Binary files differnew file mode 100644 index 00000000..77f2a32a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/kaltura_open_source_video_platform.png diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/ksprite.png b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/ksprite.png Binary files differnew file mode 100644 index 00000000..53c772eb --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/images/ksprite.png diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/mw.PlayerSkinKskin.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/mw.PlayerSkinKskin.js new file mode 100644 index 00000000..39b43834 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/kskin/mw.PlayerSkinKskin.js @@ -0,0 +1,394 @@ +/** +* Skin js allows you to override contrlBuilder html/class output +*/ + +( function( mw, $ ) {"use strict"; + +mw.PlayerSkinKskin = { + + // The parent class for all kskin css: + playerClass: 'k-player', + + // Display time string length + longTimeDisp: false, + + // Default control bar height + height: 20, + + // Volume control layout is horizontal + volumeLayout: 'horizontal', + + // Skin "kskin" is specific for wikimedia we have an + // api Title key so the "credits" menu item can be showed. + supportedMenuItems: { + 'credits': true + }, + // Stores the current menu item id + currentMenuItem: null, + + // Extends base components with kskin specific options: + components: { + 'pause': { + 'w': 28 + }, + 'volumeControl': { + 'w': 40 + }, + 'playButtonLarge' : { + 'h' : 55 + }, + 'options': { + 'w': 52, + 'o': function( ctrlObj ) { + return $( '<div />' ) + .attr( 'title', mw.msg( 'mwe-embedplayer-player_options' ) ) + .addClass( "ui-state-default ui-corner-bl rButton k-options" ) + .append( + $( '<span />' ) + .text( mw.msg( 'mwe-embedplayer-menu_btn' ) ) + ); + } + }, + // No attributionButton component for kSkin ( its integrated into the credits screen ) + 'attributionButton' : false, + + // Time display: + 'timeDisplay': { + 'w': 52 + }, + 'optionsMenu': { + 'w' : 0, + 'o' : function( ctrlObj ) { + var embedPlayer = ctrlObj.embedPlayer; + var $menuOverlay = $( '<div />') + .addClass( 'overlay-win k-menu ui-widget-content' ) + .css( { + 'width' : '100%', + 'position': 'absolute', + 'top' : '0px', + 'bottom' : ( ctrlObj.getHeight() + 2 ) + 'px' + } ); + + // Note safari can't display video overlays with text: + // see bug https://bugs.webkit.org/show_bug.cgi?id=48379 + + var userAgent = navigator.userAgent.toLowerCase(); + if( userAgent.indexOf('safari') != -1 ){ + $menuOverlay.css('opacity', '0.9'); + } + // Setup menu offset ( if player height < getOverlayHeight ) + // This displays the menu outside of the player on small embeds + if ( embedPlayer.getPlayerHeight() < ctrlObj.getOverlayHeight() ) { + var topPos = ( ctrlObj.isOverlayControls() ) + ? embedPlayer.getPlayerHeight() + : embedPlayer.getPlayerHeight() + ctrlObj.getHeight(); + + if( embedPlayer.isAudio() ){ + topPos = ctrlObj.embedPlayer.getInterface().height(); + } + + $menuOverlay.css( { + 'top' : topPos + 'px', + 'bottom' : null, + 'width' : ctrlObj.getOverlayWidth(), + 'height' : ctrlObj.getOverlayHeight() + 'px' + } ); + // Special common overflow hack for thumbnail display of player + $( embedPlayer ).parents( '.thumbinner' ).css( 'overflow', 'visible' ); + } + + var $menuBar = $( '<ul />' ) + .addClass( 'k-menu-bar' ); + + // Don't include about player menu item ( FIXME should be moved to a init function ) + delete ctrlObj.supportedMenuItems['aboutPlayerLibrary']; + + // Output menu item containers: + for ( var menuItem in ctrlObj.supportedMenuItems ) { + // Give grep a chance to find the usages: + // mwe-embedplayer-playerSelect, mwe-embedplayer-download, + // mwe-embedplayer-share, mwe-embedplayer-credits + $menuBar.append( + $( '<li />') + // Add the menu item class: + .addClass( 'k-' + menuItem + '-btn' ) + .attr( 'rel', menuItem ) + .append( + $( '<a />' ) + .attr( { + 'title' : mw.msg( 'mwe-embedplayer-' + menuItem ), + 'href' : '#' + }) + ) + ); + } + + // Add the menuBar to the menuOverlay + $menuOverlay.append( $menuBar ); + + var $menuScreens = $( '<div />' ) + .addClass( 'k-menu-screens' ) + .css( { + 'position' : 'absolute', + 'top' : '0px', + 'left' : '0px', + 'bottom' : '0px', + 'right' : '45px', + 'overflow' : 'hidden' + } ); + for ( var menuItem in ctrlObj.supportedMenuItems ) { + $menuScreens.append( + $( '<div />' ) + .addClass( 'menu-screen menu-' + menuItem ) + ); + } + + // Add the menuScreens to the menuOverlay + $menuOverlay.append( $menuScreens ); + + return $menuOverlay; + + } + } + }, + + /** + * Get minimal width for interface overlay + */ + getOverlayWidth: function(){ + return ( this.embedPlayer.getPlayerWidth() < 220 )? 220 : this.embedPlayer.getPlayerWidth(); + }, + + /** + * Get minimal height for interface overlay + */ + getOverlayHeight: function(){ + return ( this.embedPlayer.getPlayerHeight() < 160 )? 160 : this.embedPlayer.getPlayerHeight(); + }, + + /** + * Adds the skin Control Bindings + */ + addSkinControlBindings: function() { + var embedPlayer = this.embedPlayer; + var _this = this; + + // Set up control bar pointer + this.$playerTarget = embedPlayer.$interface; + // Set the menu target: + + + // Options menu display: + this.$playerTarget.find( '.k-options' ) + .unbind() + .click( function() { + _this.checkMenuOverlay(); + var $kmenu = _this.$playerTarget.find( '.k-menu' ); + if ( $kmenu.is( ':visible' ) ) { + _this.closeMenuOverlay( ); + } else { + _this.showMenuOverlay(); + // no other item is selected by default show the media credits: + if ( !_this.currentMenuItem ){ + _this.showMenuItem('credits'); + // Hide the others + _this.$playerTarget.find( '.menu-screen' ).hide(); + // Show credits + _this.$playerTarget.find( '.menu-credits' ).fadeIn( "fast" ); + } + } + } ); + + }, + + /** + * checks for menu overlay and runs menu bindings if unset + */ + checkMenuOverlay: function(){ + var _this = this; + var embedPlayer = this.embedPlayer; + if ( _this.$playerTarget.find( '.k-menu' ).length == 0 ) { + // Stop the player if it does not support overlays: + if ( !embedPlayer.supports['overlays'] ) { + embedPlayer.stop(); + } + + // Add the menu binding + _this.addMenuBinding(); + } + }, + + /** + * Close the menu overlay + */ + closeMenuOverlay: function() { + mw.log("PlayerSkinKskin:: close menu overlay" ); + var embedPlayer = this.embedPlayer; + var $optionsMenu = embedPlayer.getInterface().find( '.k-options' ); + var $kmenu = embedPlayer.getInterface().find( '.k-menu' ); + $kmenu.fadeOut( "fast", function() { + $optionsMenu.find( 'span' ) + .text ( mw.msg( 'mwe-embedplayer-menu_btn' ) ); + } ); + // show the play button if not playing + if( !embedPlayer.isPlaying() ){ + embedPlayer.getInterface().find( '.play-btn-large' ).fadeIn( 'fast' ); + } + + // re-display the control bar if hidden: + this.showControlBar(); + + // Set close overlay menu flag: + this.displayOptionsMenuFlag = false; + }, + + /** + * Show the menu overlay + */ + showMenuOverlay: function( $ktxt ) { + var $optionsMenu = this.$playerTarget.find( '.k-options' ); + var $kmenu = this.$playerTarget.find( '.k-menu' ); + + $kmenu.fadeIn( "fast", function() { + $optionsMenu.find( 'span' ) + .text ( mw.msg( 'mwe-embedplayer-close_btn' ) ); + } ); + this.$playerTarget.find( '.play-btn-large' ).fadeOut( 'fast' ); + + $(this.embedPlayer).trigger( 'displayMenuOverlay' ); + + // Set the Options Menu display flag to true: + this.displayOptionsMenuFlag = true; + }, + + /** + * Adds binding for the options menu + * + * @param {Object} $tp Target video container for + */ + addMenuBinding: function() { + var _this = this; + var embedPlayer = this.embedPlayer; + // Set local player target pointer: + var $playerTarget = embedPlayer.$interface; + + // Check if k-menu already exists: + if ( $playerTarget.find( '.k-menu' ).length != 0 ) + return false; + + // Add options menu to top of player target children: + $playerTarget.append( + _this.getComponent( 'optionsMenu' ) + ); + + // By default its hidden: + $playerTarget.find( '.k-menu' ).hide(); + + // Add menu-items bindings: + for ( var menuItem in _this.supportedMenuItems ) { + $playerTarget.find( '.k-' + menuItem + '-btn' ).click( function( ) { + + // Grab the context from the "clicked" menu item + var mk = $( this ).attr( 'rel' ); + + // hide all menu items + var $targetItem = $playerTarget.find( '.menu-' + mk ); + + // call the function showMenuItem + _this.showMenuItem( mk ); + + // Hide the others + $playerTarget.find( '.menu-screen' ).hide(); + + // Show the target menu item: + $targetItem.fadeIn( "fast" ); + + // Don't follow the # link + return false; + } ); + } + }, + + /** + * Shows a selected menu_item + * + * NOTE: this should be merged with parent mw.PlayerControlBuilder optionMenuItems + * binding mode + * + * @param {String} menu_itme Menu item key to display + */ + showMenuItem:function( menuItem ) { + var embedPlayer = this.embedPlayer; + this.currentMenuItem = menuItem; + //handle special k-skin specific display; + switch( menuItem ){ + case 'credits': + this.showCredits(); + break; + case 'playerSelect': + embedPlayer.$interface.find( '.menu-playerSelect').html( + this.getPlayerSelect() + ); + break; + case 'download' : + embedPlayer.$interface.find( '.menu-download').text( + mw.msg('mwe-loading_txt' ) + ); + // Call show download with the target to be populated + this.showDownload( + embedPlayer.$interface.find( '.menu-download') + ); + break; + case 'share': + embedPlayer.$interface.find( '.menu-share' ).html( + this.getShare() + ); + break; + } + }, + + /** + * Show the credit screen ( presently specific to kaltura skin ) + */ + showCredits: function() { + // Set up the shortcuts: + var embedPlayer = this.embedPlayer; + var _this = this; + var $target = embedPlayer.$interface.find( '.menu-credits' ); + + $target.empty().append( + $('<h2 />') + .text( mw.msg( 'mwe-embedplayer-credits' ) ), + $('<div />') + .addClass( "credits_box ui-corner-all" ) + .append( + $('<div/>') + .loadingSpinner() + .css({'position':'absolute','top':'50%','left':'50%'}) + ) + ); + + if( mw.config.get( 'EmbedPlayer.KalturaAttribution' ) == true ){ + $target.append( + $( '<div />' ) + .addClass( 'k-attribution' ) + .attr({ + 'title': mw.msg('mwe-embedplayer-kaltura-platform-title') + }) + .click( function( ) { + window.location = 'http://html5video.org'; + }) + ); + } + var $creditBox = $target.find('.credits_box'); + $creditBox.data( 'playerId', embedPlayer.id ); + $( embedPlayer ).triggerQueueCallback('showCredits', $creditBox, function( addedCredits ){ + if( !addedCredits ){ + $creditBox.find('.credits_box').text( mw.msg( 'mwe-embedplayer-nocredits') ) + } + }); + } + +}; + +} )( mw, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/PlayerSkinMvpcf.css b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/PlayerSkinMvpcf.css new file mode 100644 index 00000000..a9664ec5 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/PlayerSkinMvpcf.css @@ -0,0 +1,194 @@ +/** + * reference player skin + */ + + +/*.ui-state-default */ +.mv-player a:link {color: #2060c1; text-decoration: underline;} +.mv-player a:visited {color: #2060c1; text-decoration: underline;} +/*a:visited {color: #75a5e4; text-decoration: underline;}*/ /*Not sure if you want this*/ +.mv-player a:hover {color: #75a5e4; text-decoration: underline;} +.mv-player img, .mv-player img a, .mv-player img a:hover {border: 0;} + + +.mv-player .video { + display: block; + position: relative; + font-size: 1px; + height: 305px; +} +.mv-player .control-bar { + overflow: hidden; + height: 29px; + margin: 0; + padding: 0; + border: 0; + z-index: 2; +} +.mv-player .controlInnerSmall { +/* width: 430px;*/ + height: 29px; + float: left; + display: inline; +} + +.mv-player .lButton { + cursor:pointer; + float:left; + list-style:none outside none; + margin:2px; + padding:4px 0; + width: 24px; + height:16px; + position:relative; +} +.mv-player .rButton { + cursor:pointer; + float:right; + list-style:none outside none; + margin:2px; + padding:4px 0; + width: 23px; + height:16px; + position:relative; +} + +.mv-player .volume_icon { + float: right; + display: inline; + width: 22px; + height: 29px; + padding: 0 0 0 0; + +} + +.mv-player .vol_container{ + z-index:99; + width:23px; + height:75px; + width:23px; + position:absolute; + left:0px; + background: #CCC; +} +.mv-player .vol_container_below{ + top:30px; +} +.mv-player .vol_container_top{ + top:-77px; +} +.mv-player .vol_container .volume-slider{ + margin-top:5px; + height:65px; + width:10px; + margin-left: auto ; + margin-right: auto ; +} +.mv-player .vol_container .ui-slider-handle{ + cursor : pointer; + width:10px; + height:10px; + position:absolute; + left:-1px; +} + +.mv-player .time-disp { + line-height: 32px; + height: 29px; + overflow: visible; + font-size: 10.2px; + float: right; + display: inline; + border:none; + padding-right:4px; +} + +.mv-player .source-switch { + border: medium none; + display: inline; + color: #eee; + font: 11px arial, sans-serif; + line-height: 20px; + overflow: hidden; + width: 70px; + cursor: pointer; + float: right; + text-align: center; + padding-top:6px; +} + + +.mv-player .play_head{ + float: left; + display: inline; + height: 10px; + margin-left:8px; + margin-top:10px; + margin-right: 8px; + position:relative; +} + +.mv-player .play_head .ui-slider-handle{ + width:10px; + height:15px; + margin-left:-5px; + margin-top: -0px; + z-index: 2; +} + +.mv-player .inOutSlider .ui-slider-handle{ + width:8px; + cusror: move; +} + +.mv-player .overlay-win textarea { + background:none repeat scroll 0 0 transparent; + border: 2px solid #333; + color: #fff; + font: 11px arial,sans-serif; + height:15px; + overflow:hidden; + padding-left:2px; + width:97%; +} + +.mv-player .overlay-win div.ui-state-highlight { + background:none repeat scroll 0 0 transparent; + border-color:#554926; + color:#FFE96E; + float:left; + padding:2px 5px; +} + +.mv-player .videoOptionsComplete div.ui-state-highlight a { + color:#eee; + font-weight:bold; +} + +.mv-player .overlay-win h2{ + font-size: 115%; +} + +.mv-player .overlay-win{ + font-family : arial,sans-serif; + font-size : 85%; +} +.mv-player .overlay-win a{ + text-decoration: none; +} + +.mv-player .overlay-win ul{ + padding-left: 15px; +} + +.mv-player a:hover {} + +.mv-player .overlay-win ul li span { font-weight:bold; color:#fff;} + +.mv-player .overlay-win h2 { font-size:16px;} +.mv-player .overlay-win h3 { font-size:14px;} + +.active { font-size: 12px; } + +.ui-slider-horizontal.volume-slider { width: 44px; height: 2px; top: 7px; } +.ui-slider-horizontal.volume-slider .ui-slider-handle { border-width: 1px; } diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/images/player_big_play_button.png b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/images/player_big_play_button.png Binary files differnew file mode 100644 index 00000000..155f15e1 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/images/player_big_play_button.png diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/mw.PlayerSkinMvpcf.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/mw.PlayerSkinMvpcf.js new file mode 100644 index 00000000..4b270418 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mvpcf/mw.PlayerSkinMvpcf.js @@ -0,0 +1,7 @@ +/* +mvpcf skin config +*/ + +mw.PlayerSkinMvpcf = { + playerClass : 'mv-player' +};
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js new file mode 100644 index 00000000..5ef54d4f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/resources/skins/mw.PlayerControlBuilder.js @@ -0,0 +1,2721 @@ +/** +* Msg text is inherited from embedPlayer +*/ + +( function( mw, $ ) { "use strict"; +/** +* mw.PlayerControlBuilder object +* @param the embedPlayer element we are targeting +*/ +mw.PlayerControlBuilder = function( embedPlayer, options ) { + return this.init( embedPlayer, options ); +}; + +/** + * ControlsBuilder prototype: + */ +mw.PlayerControlBuilder.prototype = { + //Default Local values: + + // Parent css Class name + playerClass : 'mv-player', + + // Long string display of time value + longTimeDisp: true, + + // Default volume layout is "vertical" + volumeLayout : 'vertical', + + // Default control bar height + height: mw.config.get( 'EmbedPlayer.ControlsHeight' ), + + // Default supported components is merged with embedPlayer set of supported types + supportedComponents: { + // All playback types support options + 'options': true + }, + + // Default supported menu items is merged with skin menu items + supportedMenuItems: { + // Player Select + 'playerSelect' : true, + + // Download the file menu + 'download' : true, + + // Share the video menu + 'share' : true, + + // Player library link + 'aboutPlayerLibrary': true + }, + + // Flag to store the current fullscreen mode + inFullScreen: false, + + // Flag to store if a warning binding has been added + addWarningFlag: false, + + // Flag to store state of overlay on player + displayOptionsMenuFlag: false, + + // Local storage of ControlBar Callback + hideControlBarCallback: false, + + // Flag to store controls status (disabled/enabled) + controlsDisabled: false, + + // binding postfix + bindPostfix: '.controlBuilder', + + /** + * Initialization Object for the control builder + * + * @param {Object} embedPlayer EmbedPlayer interface + */ + init: function( embedPlayer ) { + var _this = this; + this.embedPlayer = embedPlayer; + // Check for skin overrides for controlBuilder + var skinClass = embedPlayer.skinName.substr(0,1).toUpperCase() + embedPlayer.skinName.substr( 1 ); + if ( mw['PlayerSkin' + skinClass ] ) { + // Clone as to not override prototype with the skin config + _this = $.extend( true, { }, this, mw['PlayerSkin' + skinClass ] ); + } + if ( _this.embedPlayer.mediaElement.getPlayableSources().length <= 1 + && _this.supportedMenuItems.playerSelect ) { + delete _this.supportedMenuItems.playerSelect; + } + // Return the controlBuilder Object: + return _this; + }, + + /** + * Get the control bar height + * @return {Number} control bar height + */ + getHeight: function(){ + return this.height; + }, + + + /** + * Add the controls html to player interface + */ + addControls: function() { + // Set up local pointer to the embedPlayer + var embedPlayer = this.embedPlayer, + profile = $.client.profile(); + + // Set up local controlBuilder + var _this = this; + + // Remove any old controls & old overlays: + embedPlayer.getInterface().find( '.control-bar,.overlay-win' ).remove(); + + // Reset flags: + _this.displayOptionsMenuFlag = false; + + // Setup the controlBar container ( starts hidden ) + var $controlBar = $('<div />') + .addClass( 'ui-state-default ui-widget-header ui-helper-clearfix control-bar' ) + .css( 'height', this.height ); + + // Controls are hidden by default if overlaying controls: + if( _this.isOverlayControls() ){ + $controlBar.hide(); + } else { + // Include the control bar height when calculating the layout + $controlBar.addClass('block'); + } + + // Make room for audio controls in the interface: + if( embedPlayer.isAudio() && embedPlayer.getInterface().height() == 0 ){ + embedPlayer.getInterface().css( { + 'height' : this.height + } ); + } + + // Add the controls to the interface + embedPlayer.getInterface().append( $controlBar ); + + if ( profile.name === 'firefox' && profile.versionNumber < 2 ) { + embedPlayer.triggerHelper( 'resizeIframeContainer', [ {'height' : embedPlayer.height + $controlBar.height() - 1} ] ); + } + + // Add the Controls Component + this.addControlComponents(); + + // Add top level Controls bindings + this.addControlBindings(); + }, + + /** + * Add control components as defined per this.components + */ + addControlComponents: function( ) { + var _this = this; + + // Set up local pointer to the embedPlayer + var embedPlayer = this.embedPlayer; + + //Set up local var to control container: + var $controlBar = embedPlayer.getInterface().find( '.control-bar' ); + + this.availableWidth = embedPlayer.getPlayerWidth(); + + mw.log( 'PlayerControlsBuilder:: addControlComponents into:' + this.availableWidth ); + // Build the supportedComponents list + this.supportedComponents = $.extend( this.supportedComponents, embedPlayer.supports ); + + // Check for Attribution button + if( mw.config.get( 'EmbedPlayer.AttributionButton' ) && embedPlayer.attributionbutton ){ + this.supportedComponents[ 'attributionButton' ] = true; + } + // Check global fullscreen enabled flag + if( mw.config.get( 'EmbedPlayer.EnableFullscreen' ) === false ){ + this.supportedComponents[ 'fullscreen'] = false; + } + // Check if the options item is available + if( mw.config.get( 'EmbedPlayer.EnableOptionsMenu' ) === false ){ + this.supportedComponents[ 'options'] = false; + } + // Check for volume control + if( mw.config.get( 'EmbedPlayer.EnableVolumeControl') === false ){ + this.supportedComponents[ 'volumeControl'] = false; + } + + // Check if we have multiple playable sources ( if only one source don't display source switch ) + + if( embedPlayer.mediaElement.getPlayableSources().length == 1 ){ + this.supportedComponents[ 'sourceSwitch' ] = false; + + } + + // Give embeds option to explicitly disable components via flag + var source = embedPlayer.mediaElement.getPlayableSources()[0]; + if ( !embedPlayer.disablecontrols && source ) { + embedPlayer.disablecontrols = source.disablecontrols; + } + if ( embedPlayer.disablecontrols ) { + embedPlayer.disablecontrols.split(',').forEach(function( key ) { + mw.log( 'PlayerControlBuilder:: disabled component via flag:' + key ); + _this.supportedComponents[ key ] = false; + }); + } + + $( embedPlayer ).trigger( 'addControlBarComponent', this ); + + var components = []; + var largestPos = 0; + var addComponent = function( componentId ){ + if ( _this.supportedComponents[ componentId ] ) { + if ( _this.availableWidth >= _this.components[ componentId ].w ) { + _this.availableWidth -= _this.components[ componentId ].w; + // Check if position is defined, if not, place at end of known positions + var position = _this.components[ componentId ].position ? + _this.components[ componentId ].position: + largestPos+1 + if( position > largestPos ){ + largestPos = position; + } + components.push({ + 'id': componentId, + 'position': position + }); + //mw.log(" availableWidth:" + _this.availableWidth + ' ' + componentId + ' took: ' + _this.components[ componentId ].w ) + } else { + mw.log( 'PlayerControlBuilder:: Not enough space for control component:' + componentId ); + } + } + }; + + var addComponents = function() { + components.sort(function(a, b) { + return b.position - a.position; + }); + for(var i=0;i<components.length;i++) { + $controlBar.append( + _this.getComponent( components[ i ]['id'] ) + ); + } + } + + // Output components + for ( var componentId in this.components ) { + // Check for (component === false ) and skip + if( this.components[ componentId ] === false ){ + continue; + } + + // Special case with playhead and time ( to make sure they are to the left of everything else ) + if ( componentId == 'playHead' ){ + continue; + } + if( componentId == 'timeDisplay' && !mw.config.get( 'EmbedPlayer.EnableTimeDisplay' ) ){ + continue; + } + + // Skip "fullscreen" button for assets or where height is 0px ( audio ) + if( componentId == 'fullscreen' && this.embedPlayer.isAudio() ){ + continue; + } + // Skip sourceSwitch if width < smalles derivative + if ( componentId == 'sourceSwitch' && this.availableWidth < 320) { + continue; + } + addComponent( componentId ); + } + if( this.availableWidth > 30 ){ + addComponent( 'playHead' ); + } + addComponents(); + $(embedPlayer).trigger( 'controlBarBuildDone' ); + }, + + /** + * Get a window size for the player while preserving aspect ratio: + * + * @@TODO This has similar logic to mw.embedPlayerNative applyIntrinsicAspect we should look + * at merging their functionality. + * + * @param {object} windowSize + * object that set { 'width': {width}, 'height':{height} } of target window + * @return {object} + * css settings for fullscreen player + */ + getAspectPlayerWindowCss: function( windowSize ) { + var embedPlayer = this.embedPlayer; + var _this = this; + // Setup target height width based on max window size + if( !windowSize ){ + var windowSize = { + 'width' : $( window ).width(), + 'height' : $( window ).height() + }; + } + windowSize.width = parseInt( windowSize.width ); + windowSize.height = parseInt( windowSize.height ); + // See if we need to leave space for control bar + if( !_this.isOverlayControls() ){ + //targetHeight = targetHeight - this.height; + windowSize.height = windowSize.height - this.height; + } + + // Set target width + var targetWidth = windowSize.width; + var targetHeight = targetWidth * ( 1 / _this.getIntrinsicAspect() ); + // Check if it exceeds the height constraint: + if( targetHeight > windowSize.height ){ + targetHeight = windowSize.height; + targetWidth = parseInt( targetHeight * _this.getIntrinsicAspect() ); + } + var offsetTop = 0; + // Move the video down 1/2 of the difference of window height + offsetTop+= ( targetHeight < windowSize.height )? ( windowSize.height- targetHeight ) / 2 : 0; + // if the video is very tall in a short window adjust the size: + var offsetLeft = ( targetWidth < windowSize.width )? parseInt( windowSize.width- targetWidth ) / 2 : 0; + + var position = (mw.isIOS4() && mw.isIphone()) ? 'static' : 'absolute'; + mw.log( 'PlayerControlBuilder::getAspectPlayerWindowCss: ' + ' h:' + targetHeight + ' w:' + targetWidth + ' t:' + offsetTop + ' l:' + offsetLeft ); + return { + 'position' : position, + 'height': parseInt( targetHeight ), + 'width' : parseInt( targetWidth ), + 'top' : parseInt( offsetTop ), + 'left': parseInt( offsetLeft) + }; + }, + + /** + * Get the intrinsic aspect ratio of media ( width / height ) + * @return {float} + * size object with width and height + */ + getIntrinsicAspect: function(){ + var vid = this.embedPlayer.getPlayerElement(); + // Check for raw intrinsic media size: + if( vid && vid.videoWidth && vid.videoHeight ){ + return vid.videoWidth / vid.videoHeight; + } + + // See if we have source data attributes available: + if( this.embedPlayer.mediaElement && + this.embedPlayer.mediaElement.selectedSource ) + { + var ss = this.embedPlayer.mediaElement.selectedSource; + // See if we have a hardcoded aspect to the source ( Adaptive streams don't have width / height ) + if( ss.aspect ){ + return ss.aspect; + } + + if( ss.width && ss.height ){ + return ss.width / ss.height + } + } + + // check for posterImage size: ( should have Intrinsic aspect size as well ) + var img = this.embedPlayer.getInterface().find('.playerPoster')[0]; + if( img && img.naturalWidth && img.naturalHeight){ + return img.naturalWidth / img.naturalHeight + } + + // if all else fails use embedPlayer.getWidth() + return this.embedPlayer.getWidth() / this.embedPlayer.getHeight() + }, + + /** + * Get the play button css + */ + getPlayButtonPosition: function() { + var _this = this; + return { + 'position' : 'absolute', + 'left' : '50%', + 'top' : '50%', + 'margin-left' : - .5 * this.getComponentWidth( 'playButtonLarge' ), + 'margin-top' : - .5 * this.getComponentHeight( 'playButtonLarge' ) + }; + }, + + /** + * Check if we're in Fullscreen + * @return {boolean) + */ + isInFullScreen: function() { + return this.inFullScreen; + }, + + /** + * Toggles full screen by calling + * doFullScreenPlayer to enable fullscreen mode + * restoreWindowPlayer to restore window mode + */ + toggleFullscreen: function( forceClose ) { + var _this = this; + // Do normal in-page fullscreen handling: + if( this.isInFullScreen() ){ + this.restoreWindowPlayer(); + }else { + this.doFullScreenPlayer(); + } + // Don't follow the # link: + return false; + }, + + /** + * Do full-screen mode + */ + doFullScreenPlayer: function( callback ) { + mw.log("PlayerControlBuilder:: doFullScreenPlayer" ); + // Setup pointer to control builder : + var _this = this, + profile = $.client.profile(); + + // Store the page vertical scroll + var doc = window.document; + var context = window; + this.verticalScrollPosition = doc.all ? doc.scrollTop : context.pageYOffset; + + // Setup local reference to embed player: + var embedPlayer = this.embedPlayer; + + // Setup a local reference to the player interface: + var $interface = embedPlayer.getInterface(); + // Check fullscreen state ( if already true do nothing ) + if( this.isInFullScreen() == true ){ + return ; + } + this.inFullScreen = true; + + // Add fullscreen class to interface: + $interface.addClass( 'fullscreen' ); + + // if overlaying controls add hide show player binding. + if( _this.isOverlayControls() && !embedPlayer.isTouchDevice() ){ + _this.addFullscreenMouseMoveHideShowControls(); + } + + // Store the current scroll location on the iframe: + $( embedPlayer ).trigger( 'fullScreenStoreVerticalScroll' ); + + if( window.fullScreenApi.supportsFullScreen ) { + _this.preFullscreenPlayerSize = this.getPlayerSize(); + var fullscreenHeight = null; + var fsTarget = this.getFsTarget(); + + var escapeFullscreen = function( event ) { + // grab the correct document target to check for fullscreen + if ( ! window.fullScreenApi.isFullScreen( window.document ) ) { + _this.restoreWindowPlayer(); + } + } + // remove any old binding: + fsTarget.removeEventListener( fullScreenApi.fullScreenEventName, escapeFullscreen ); + // Add a binding to catch "escape" fullscreen + fsTarget.addEventListener( fullScreenApi.fullScreenEventName, escapeFullscreen ); + // Make the iframe fullscreen: + window.fullScreenApi.requestFullScreen( fsTarget ); + + // There is a bug with mozfullscreenchange event in all versions of firefox with supportsFullScreen + // https://bugzilla.mozilla.org/show_bug.cgi?id=724816 + // so we have to have an extra binding to check for size change and then restore. + if( profile.name === 'firefox' ){ + _this.fullscreenRestoreCheck = setInterval( function(){ + if( fullscreenHeight && $(window).height() < fullscreenHeight ){ + // Mozilla triggered size change: + clearInterval ( _this.fullscreenRestoreCheck ); + _this.restoreWindowPlayer(); + } + // set fullscreen height: + if( ! fullscreenHeight && _this.preFullscreenPlayerSize.height != $(window).height() ){ + fullscreenHeight = $(window).height(); + } + }, 250 ); + } + } else { + // Check for hybrid html controls / native fullscreen support: + var vid = this.embedPlayer.getPlayerElement(); + if( mw.config.get('EmbedPlayer.EnableIpadNativeFullscreen') + && + vid && vid.webkitSupportsFullscreen + ){ + this.doHybridNativeFullscreen(); + return ; + } else { + // make the player traget or iframe fullscreen + this.doContextTargetFullscreen(); + } + } + + // Bind escape to restore in page clip ( IE9 needs a secondary escape binding ) + $( window ).keyup( function( event ) { + // Escape check + if( event.keyCode == 27 ){ + _this.restoreWindowPlayer(); + } + } ); + + // trigger the open fullscreen event: + $( embedPlayer ).trigger( 'onOpenFullScreen' ); + + // re draw the controls after a timeout ( to allow the screen dom to update ) + setTimeout( function(){ + _this.addControls(); + },100) + }, + + /** + * Make the target player interface or iframe fullscreen + */ + doContextTargetFullscreen: function() { + var + _this = this, + doc = window.document, + $doc = $( doc ), + $target = $( this.getFsTarget() ), + context = window; + + // update / reset local restore properties + this.parentsAbsoluteList = []; + this.parentsRelativeList = []; + + // Set the original parent page scale if possible: + this.orginalParnetViewPortContent = $doc.find( 'meta[name="viewport"]' ).attr( 'content' ); + this.orginalTargetElementLayout = { + 'style' : $target[0].style.cssText, + 'width' : $target.width(), + 'height' : $target.height() + }; + + mw.log("PlayerControls:: doParentIframeFullscreen> verticalScrollPosition:" + this.verticalScrollPosition); + context.scroll(0, 0); + + // Make sure the parent page page has a zoom of 1: + if( ! $doc.find('meta[name="viewport"]').length ){ + $doc.find('head').append( $( '<meta />' ).attr('name', 'viewport') ); + } + $doc.find('meta[name="viewport"]').attr('content', 'initial-scale=1; maximum-scale=1; minimum-scale=1;' ); + + // iPad 5 supports fixed position in a bad way, use absolute pos for iOS + var playerCssPosition = ( mw.isIOS() ) ? 'absolute': 'fixed'; + + // Remove absolute css of the $target's parents + $target.parents().each( function() { + var $parent = $( this ); + if( $parent.css( 'position' ) == 'absolute' ) { + _this.parentsAbsoluteList.push( $parent ); + $parent.css( 'position', 'static' ); + } + if( $parent.css( 'position' ) == 'relative' ) { + _this.parentsRelativeList.push( $parent ); + $parent.css( 'position', 'static' ); + } + }); + + // Make the $target fullscreen + $target + .css({ + 'z-index': mw.config.get( 'EmbedPlayer.FullScreenZIndex' ), + 'position': playerCssPosition, + 'top' : '0px', + 'left' : '0px', + 'margin': 0 + }) + .data( + 'isFullscreen', true + ); + + var updateTargetSize = function() { + context.scroll(0, 0); + $target.css({ + 'width' : context.innerWidth, + 'height' : context.innerHeight + }); + // update player size if needed: + _this.embedPlayer.applyIntrinsicAspect(); + }; + + updateTargetSize(); + + // Bind orientation change to resize player ( if fullscreen ) + $( context ).bind( 'orientationchange', function(e){ + if( _this.isInFullScreen() ){ + updateTargetSize(); + } + }); + + // prevent scrolling when in fullscreen: ( both iframe and dom target use document ) + document.ontouchmove = function( e ){ + if( _this.isInFullScreen() ){ + e.preventDefault(); + } + }; + }, + /** + * Restore the player interface or iframe to a window player + */ + restoreContextPlayer: function(){ + var + _this = this, + doc = window.document, + $doc = $( doc ), + $target = $( this.getFsTarget() ), + context = window; + + mw.log("PlayerControlsBuilder:: restoreContextPlayer> verticalScrollPosition:" + this.verticalScrollPosition ); + + // Restore document zoom: + if( this.orginalParnetViewPortContent ){ + $doc.find('meta[name="viewport"]').attr('content', this.orginalParnetViewPortContent ); + } else { + // Restore user zoom: ( NOTE, there does not appear to be a way to know the + // initial scale, so we just restore to 1 in the absence of explicit viewport tag ) + // In order to restore zoom, we must set maximum-scale to a valid value + $doc.find('meta[name="viewport"]').attr('content', 'initial-scale=1; maximum-scale=8; minimum-scale=1;' ); + } + if( this.orginalTargetElementLayout ) { + $target[0].style.cssText = this.orginalTargetElementLayout.style; + $target.attr({ + 'width': this.orginalTargetElementLayout.width, + 'height': this.orginalTargetElementLayout.height + }); + // update player size if needed: + _this.embedPlayer.applyIntrinsicAspect(); + } + // Restore any parent absolute pos: + $doc.find( _this.parentsAbsoluteList ).each( function() { + $( this ).css( 'position', 'absolute' ); + } ); + $doc.find( _this.parentsRelativeList ).each( function() { + $( this ).css( 'position', 'relative' ); + } ); + }, + + /** + * Supports hybrid native fullscreen, player html controls, and fullscreen is native + */ + doHybridNativeFullscreen: function(){ + var vid = this.embedPlayer.getPlayerElement(); + var _this = this; + vid.webkitEnterFullscreen(); + // start to pull for exit fullscreen: + this.fsIntervalID = setInterval( function(){ + var currentFS = vid.webkitDisplayingFullscreen; + // Check if we have entered fullscreen but the player + // has exited fullscreen with native controls click + if( _this.isInFullScreen() && !currentFS ){ + // restore non-fullscreen player state + _this.inFullScreen = false; + // Trigger the onCloseFullscreen event: + $( _this.embedPlayer ).trigger( 'onCloseFullScreen' ); + // stop polling for state change. + clearInterval( _this.fsIntervalID ); + } + }, 250 ); + }, + getWindowSize: function(){ + return { + 'width' : $(window).width(), + 'height' : $(window).height() + }; + }, + doDomFullscreen: function(){ + var _this = this; + var embedPlayer = this.embedPlayer; + var $interface = embedPlayer.getInterface(); + // Remove any old mw-fullscreen-overlay + $( '.mw-fullscreen-overlay' ).remove(); + + _this.preFullscreenPlayerSize = this.getPlayerSize(); + + // Add the css fixed fullscreen black overlay as a sibling to the video element + // iOS4 does not respect z-index + $interface.after( + $( '<div />' ) + .addClass( 'mw-fullscreen-overlay' ) + // Set some arbitrary high z-index + .css('z-index', mw.config.get( 'EmbedPlayer.FullScreenZIndex' ) ) + .hide() + .fadeIn("slow") + ); + + // get the original interface to absolute positioned: + if( ! this.windowPositionStyle ){ + this.windowPositionStyle = $interface.css( 'position' ); + } + if( !this.windowZindex ){ + this.windowZindex = $interface.css( 'z-index' ); + } + // Get the base offset: + this.windowOffset = this.getWindowOffset(); + + // Change the z-index of the interface + $interface.css( { + 'position' : 'fixed', + 'z-index' : mw.config.get( 'EmbedPlayer.FullScreenZIndex' ) + 1, + 'top' : this.windowOffset.top, + 'left' : this.windowOffset.left + } ); + + // If native persistent native player update z-index: + if( embedPlayer.isPersistentNativePlayer() ){ + $( embedPlayer.getPlayerElement() ).css( { + 'z-index': mw.config.get( 'EmbedPlayer.FullScreenZIndex' ) + 1, + 'position': 'absolute' + }); + } + + // Empty out the parent absolute index + _this.parentsAbsolute = []; + + // Hide the body scroll bar + $('body').css( 'overflow', 'hidden' ); + + var topOffset = '0px'; + var leftOffset = '0px'; + + // Check if we have an offsetParent + if( $interface.offsetParent()[0].tagName + && + $interface.offsetParent()[0].tagName.toLowerCase() != 'body' ) + { + topOffset = -this.windowOffset.top + 'px'; + leftOffset = -this.windowOffset.left + 'px'; + } + + // Overflow hidden in fullscreen: + $interface.css( 'overlow', 'hidden' ); + + // Remove absolute css of the interface parents + $interface.parents().each( function() { + //mw.log(' parent : ' + $( this ).attr('id' ) + ' class: ' + $( this ).attr('class') + ' pos: ' + $( this ).css( 'position' ) ); + if( $( this ).css( 'position' ) == 'absolute' ) { + _this.parentsAbsolute.push( $( this ) ); + $( this ).css( 'position', null ); + mw.log( 'PlayerControlBuilder:: should update position: ' + $( this ).css( 'position' ) ); + } + }); + + // Bind escape to restore in page clip + $( window ).keyup( function( event ) { + // Escape check + if( event.keyCode == 27 ){ + _this.restoreWindowPlayer(); + } + } ); + }, + addFullscreenMouseMoveHideShowControls:function(){ + var _this = this; + // Bind mouse move in interface to hide control bar + _this.mouseMovedFlag = false; + _this.embedPlayer.getInterface().mousemove( function(e){ + _this.mouseMovedFlag = true; + }); + + // Check every 2 seconds reset flag status if controls are overlay + var checkMovedMouse = function(){ + if( _this.isInFullScreen() ){ + if( _this.mouseMovedFlag ){ + _this.mouseMovedFlag = false; + _this.showControlBar(); + // Once we move the mouse keep displayed for 3 seconds + setTimeout(checkMovedMouse, 3000); + } else { + // Check for mouse movement every 250ms + _this.hideControlBar(); + setTimeout(checkMovedMouse, 250 ); + } + return; + } + }; + // always initially show the control bar: + _this.showControlBar(); + // start monitoring for moving mouse + checkMovedMouse(); + }, + getWindowOffset: function(){ + var windowOffset = this.embedPlayer.getInterface().offset(); + windowOffset.top = windowOffset.top - $(document).scrollTop(); + windowOffset.left = windowOffset.left - $(document).scrollLeft(); + this.windowOffset = windowOffset; + return this.windowOffset; + }, + // Display a fullscreen tip if configured to do and the browser supports it. + displayFullscreenTip: function(){ + var _this = this; + // Mobile devices don't have f11 key + if( mw.isMobileDevice() ){ + return ; + } + // Safari does not have a DOM fullscreen ( no subtitles, no controls ) + if ( $.client.profile().name === 'safari' ) { + return; + } + + // OSX has a different short cut than windows and liux + var toolTipMsg = ( navigator.userAgent.indexOf('Mac OS X') != -1 )? + mw.msg( 'mwe-embedplayer-fullscreen-tip-osx') : + mw.msg( 'mwe-embedplayer-fullscreen-tip'); + + var $targetTip = this.addWarningBinding( 'EmbedPlayer.FullscreenTip', + $('<h3/>').html( + toolTipMsg + ) + ); + + // Display the target warning: + $targetTip.show(); + + var hideTip = function(){ + mw.setConfig('EmbedPlayer.FullscreenTip', false ); + $targetTip.fadeOut('fast'); + }; + + // Hide fullscreen tip if: + // We leave fullscreen, + $( this.embedPlayer ).bind( 'onCloseFullScreen', hideTip ); + // After 5 seconds, + setTimeout( hideTip, 5000 ); + // Or if we catch an f11 button press + $( document ).keyup( function( event ){ + if( event.keyCode == 122 ){ + hideTip(); + } + return true; + }); + }, + // TOOD fullscreen iframe vs inpage object abstraction + //( avoid repatiave conditionals in getters ) + getPlayerSize: function(){ + var height = $(window).height() - this.getHeight(); + if( mw.config.get('EmbedPlayer.IsIframeServer' ) ){ + return { + 'height' : height, + 'width' : $(window).width() + } + } else { + return { + 'height' : this.embedPlayer.getInterface().height(), + 'width' : this.embedPlayer.getInterface().width() + } + } + }, + getFsTarget: function(){ + var $interface = this.embedPlayer.getInterface(); + return $interface[0]; + }, + /** + * Restore the window player + */ + restoreWindowPlayer: function() { + var _this = this; + mw.log("PlayerControlBuilder :: restoreWindowPlayer" ); + var embedPlayer = this.embedPlayer; + + // Check if fullscreen mode is already restored: + if( this.isInFullScreen() === false ){ + return ; + } + // Set fullscreen mode to false + this.inFullScreen = false; + + // remove the fullscreen interface + embedPlayer.getInterface().removeClass( 'fullscreen' ); + + // Check for native support for fullscreen and support native fullscreen restore + if ( window.fullScreenApi.supportsFullScreen ) { + var fsTarget = this.getFsTarget(); + window.fullScreenApi.cancelFullScreen( fsTarget ); + } + + // Restore the iFrame context player + this.restoreContextPlayer(); + + // Restore scrolling on iPad + $( document ).unbind( 'touchend.fullscreen' ); + + // Trigger the onCloseFullscreen event: + $( embedPlayer ).trigger( 'onCloseFullScreen' ); + + // Scroll back to the previews position ( do in async call to allow dom fullscreen restore ) + setTimeout( function(){ + window.scroll( 0, _this.verticalScrollPosition ); + }, 100 ); + + // re draw the controls after a timeout ( to allow the screen dom to update ) + setTimeout( function(){ + _this.addControls(); + },100) + }, + restoreDomPlayer: function(){ + var _this = this; + // local ref to embedPlayer: + var embedPlayer = this.embedPlayer; + + var $interface = embedPlayer.$interface; + var interfaceHeight = ( _this.isOverlayControls() ) + ? embedPlayer.getHeight() + : embedPlayer.getHeight() + _this.getHeight(); + + mw.log( 'restoreWindowPlayer:: h:' + interfaceHeight + ' w:' + embedPlayer.getWidth()); + $('.mw-fullscreen-overlay').remove( 'slow' ); + + mw.log( 'restore embedPlayer:: ' + embedPlayer.getWidth() + ' h: ' + embedPlayer.getHeight() ); + + // Restore the player: + embedPlayer.getInterface().css( { + 'width' : _this.preFullscreenPlayerSize.width, + 'height' : _this.preFullscreenPlayerSize.height + }); + var topPos = { + 'position' : _this.windowPositionStyle, + 'z-index' : _this.windowZindex, + 'overlow' : 'visible', + 'top' : '0px', + 'left' : '0px' + }; + // Restore non-absolute layout: + $( [ $interface, $interface.find('.playerPoster'), embedPlayer ] ).css( topPos ); + if( embedPlayer.getPlayerElement() ){ + $( embedPlayer.getPlayerElement() ) + .css( topPos ) + } + // Restore the body scroll bar + $('body').css( 'overflow', 'auto' ); + + // If native player restore z-index: + if( embedPlayer.isPersistentNativePlayer() ){ + $( embedPlayer.getPlayerElement() ).css( { + 'z-index': 'auto' + }); + } + }, + /** + * Get minimal width for interface overlay + */ + getOverlayWidth: function( ) { + return ( this.embedPlayer.getPlayerWidth() < 300 )? 300 : this.embedPlayer.getPlayerWidth(); + }, + + /** + * Get minimal height for interface overlay + */ + getOverlayHeight: function( ) { + return ( this.embedPlayer.getPlayerHeight() < 200 )? 200 : this.embedPlayer.getPlayerHeight(); + }, + + /** + * addControlBindings + * Adds control hooks once controls are in the DOM + */ + addControlBindings: function( ) { + // Set up local pointer to the embedPlayer + var embedPlayer = this.embedPlayer, + _this = this, + $interface = embedPlayer.getInterface(), + profile = $.client.profile(); + + _this.onControlBar = false; + + // Remove any old interface bindings + $( embedPlayer ).unbind( this.bindPostfix ); + + var bindFirstPlay = false; + _this.addRightClickBinding(); + + // add the player click bindings + _this.addPlayerClickBindings(); + + // Bind into play.ctrl namespace ( so we can unbind without affecting other play bindings ) + $( embedPlayer ).bind( 'onplay' + this.bindPostfix, function() { //Only bind once played + // add right click binding again ( in case the player got swaped ) + embedPlayer.controlBuilder.addRightClickBinding(); + }); + + $( embedPlayer ).bind( 'timeupdate' + this.bindPostfix, function(){ + embedPlayer.updatePlayheadStatus() + }); + + // Update buffer information + $( embedPlayer ).bind( 'progress' + this.bindPostfix, function( event, jEvent, id){ + // regain scope + var embedPlayer = $( '#' + id )[0]; + embedPlayer.updateBufferStatus(); + }); + + // Bind to EnableInterfaceComponents + $( embedPlayer ).bind( 'onEnableInterfaceComponents' + this.bindPostfix, function() { + embedPlayer.controlBuilder.controlsDisabled = false; + embedPlayer.controlBuilder.addPlayerClickBindings(); + }); + + // Bind to DisableInterfaceComponents + $( embedPlayer ).bind( 'onDisableInterfaceComponents' + this.bindPostfix, function() { + embedPlayer.controlBuilder.controlsDisabled = true; + embedPlayer.controlBuilder.removePlayerClickBindings(); + }); + + + // TODO select a player on the page + var bindSpaceUp = function(){ + $(window).bind('keyup' + _this.bindPostfix, function(e) { + if( e.keyCode == 32 ) { + if(embedPlayer.paused) { + embedPlayer.play(); + } else { + embedPlayer.pause(); + } + return false; + } + }); + }; + + var bindSpaceDown = function() { + $(window).unbind( 'keyup' + _this.bindPostfix ); + }; + + // Bind to resize event + /* + var triggerUpdate; + $( window ).resize(function() { + // We use setTimeout because of iOS 4.2 issues + clearTimeout(triggerUpdate); + triggerUpdate = setTimeout(function() { + //embedPlayer.triggerHelper('updateLayout'); + }, 100); + }); + */ + + $(window).on("debouncedresize", function() { + embedPlayer.triggerHelper('updateLayout'); + }); + + // Add hide show bindings for control overlay (if overlay is enabled ) + if( ! _this.isOverlayControls() ) { + $interface + .show() + .hover( bindSpaceUp, bindSpaceDown ); + + // include touch start pause binding + $( embedPlayer).bind( 'touchstart' + this.bindPostfix, function() { + embedPlayer._playContorls = true; + mw.log( "PlayerControlBuilder:: touchstart:" + ' isPause:' + embedPlayer.paused); + if( embedPlayer.paused ) { + embedPlayer.play(); + } else { + embedPlayer.pause(); + } + }); + } else { // hide show controls: + // Bind a startTouch to show controls + $( embedPlayer).bind( 'touchstart' + this.bindPostfix, function() { + if ( embedPlayer.getInterface().find( '.control-bar' ).is( ':visible' ) ) { + if( embedPlayer.paused ) { + embedPlayer.play(); + } else { + embedPlayer.pause(); + } + } else { + _this.showControlBar(); + } + clearTimeout( _this.hideControlBarCallback ); + _this.hideControlBarCallback = setTimeout( function() { + _this.hideControlBar(); + }, 60000 ); + // ( Once the user touched the video "don't hide" ) + return true; + } ); + + var hoverIntentConfig = { + 'sensitivity': 100, + 'timeout' : 1000, + 'over' : function(e){ + // Clear timeout on IE9 + if( mw.isIE9() ) { + clearTimeout(_this.hideControlBarCallback); + _this.hideControlBarCallback = false; + } + // Show controls with a set timeout ( avoid fade in fade out on short mouse over ) + _this.showControlBar(); + bindSpaceUp(); + }, + 'out' : function(e){ + _this.hideControlBar(); + bindSpaceDown(); + } + }; + + // Check if we should display the interface: + // special check for IE9 ( does not count hover on non-visiable inerface div + if( mw.isIE9() ){ + $( embedPlayer.getPlayerElement() ).hoverIntent( hoverIntentConfig ); + + // Add hover binding to control bar + embedPlayer.getInterface().find( '.control-bar' ).hover( function(e) { + _this.onControlBar = true; + embedPlayer.getInterface().find( '.control-bar' ).show(); + }, function( e ) { + if (!_this.hideControlBarCallback) { + _this.hideControlBarCallback = setTimeout(function(){ + _this.hideControlBar(); + },1000); + } + _this.onControlBar = false; + }); + + } else { + if ( !mw.isIpad() ) { + $interface.hoverIntent( hoverIntentConfig ); + } + } + + } + + // Add recommend firefox if we have non-native playback: + if ( _this.checkNativeWarning( ) ) { + _this.addWarningBinding( + 'EmbedPlayer.ShowNativeWarning', + mw.msg( 'mwe-embedplayer-for_best_experience', + $('<div>').append( + $('<a />') + .attr({ + 'href': 'http://www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download', + 'target' : '_new' + }) + )[0].innerHTML + ) + ); + } + + // Do png fix for ie6 + if ( profile.name === 'msie' && profile.versionNumber <= 6 ) { + $( '#' + embedPlayer.id + ' .play-btn-large' ).pngFix(); + } + + this.doVolumeBinding(); + + // Check if we have any custom skin Bindings to run + if ( this.addSkinControlBindings && typeof( this.addSkinControlBindings ) == 'function' ){ + this.addSkinControlBindings(); + } + + mw.log( 'trigger::addControlBindingsEvent' ); + $( embedPlayer ).trigger( 'addControlBindingsEvent' ); + }, + removePlayerClickBindings: function(){ + $( this.embedPlayer ) + .unbind( "click" + this.bindPostfix ) + .unbind( "dblclick" + this.bindPostfix ); + }, + addPlayerClickBindings: function(){ + + var _this = this; + var embedPlayer = this.embedPlayer; + + // prevent scrolling when in fullscreen: + document.ontouchmove = function( e ){ + if( _this.isInFullScreen() ){ + e.preventDefault(); + } + }; + // Remove old click bindings before adding: + this.removePlayerClickBindings(); + + // Setup "dobuleclick" fullscreen binding to embedPlayer ( if enabled ) + if ( this.supportedComponents['fullscreen'] ){ + $( embedPlayer ).bind( "dblclick" + _this.bindPostfix, function(){ + embedPlayer.fullscreen(); + }); + } + + var dblClickTime = 300; + var lastClickTime = 0; + var didDblClick = false; + + var playerClickCb = function( event ) { + // make sure the event matches: + if( event.currentTarget.id != embedPlayer.id ){ + embedPlayer = $( '#' + event.currentTarget.id )[0]; + } + mw.log( "PlayerControlBuilder:: click:" + embedPlayer.id + ' isPause:' + embedPlayer.paused); + // Don't do anything if touch interface or native controls are shown + if( embedPlayer.useNativePlayerControls() + || + _this.isControlsDisabled() + || + embedPlayer.isTouchDevice() + ) { + return true; + } + var clickTime = new Date().getTime(); + if( clickTime -lastClickTime < dblClickTime ) { + didDblClick = true; + setTimeout( function(){ + didDblClick = false; + }, dblClickTime + 10 ); + } + lastClickTime = clickTime; + setTimeout( function(){ + // check if no click has since the time we called the setTimeout + if( !didDblClick ){ + if( embedPlayer.paused ) { + embedPlayer.play(); + } else { + embedPlayer.pause(); + } + } + }, dblClickTime ); + return true; + }; + // Add click binding: ( $(embedPlayer).click ) has scope issues ) + if ( embedPlayer.attachEvent ) { + embedPlayer.attachEvent("onclick", playerClickCb); + } else{ + // Firefox 3.5 requires third argument to addEventListener + embedPlayer.addEventListener('click', playerClickCb, false ); + } + + }, + addRightClickBinding: function(){ + var embedPlayer = this.embedPlayer; + // check config: + if( mw.config.get( 'EmbedPlayer.EnableRightClick') === false ){ + document.oncontextmenu= function(e){return false;}; + $(embedPlayer).mousedown(function(e){ + if( e.button == 2 ) { + return false; + } + }); + } + }, + /** + * Hide the control bar. + */ + hideControlBar : function(){ + var animateDuration = 'fast'; + var _this = this; + + // Do not hide control bar if overlay menu item is being displayed: + if( _this.displayOptionsMenuFlag || _this.keepControlBarOnScreen ) { + setTimeout( function(){ + _this.hideControlBar(); + }, 200 ); + return ; + } + + // IE9: If the user mouse is on the control bar, don't hide it + if( this.onControlBar === true ) { + return ; + } + + // Hide the control bar + this.embedPlayer.getInterface().find( '.control-bar') + .fadeOut( animateDuration ); + //mw.log('about to trigger hide control bar') + // Allow interface items to update: + $( this.embedPlayer ).trigger('onHideControlBar', [ {'bottom' : 15}, this.embedPlayer.id ] ); + + }, + restoreControlsHover:function(){ + if( this.isOverlayControls() ){ + this.keepControlBarOnScreen = false; + } + }, + /** + * Show the control bar + */ + showControlBar: function( keepOnScreen ){ + var animateDuration = 'fast'; + if(! this.embedPlayer ) + return ; + + if( this.embedPlayer.getPlayerElement && ! this.embedPlayer.isPersistentNativePlayer() ){ + $( this.embedPlayer.getPlayerElement() ).css( 'z-index', '1' ); + } + mw.log( 'PlayerControlBuilder:: ShowControlBar, keep on screen: ' + keepOnScreen ); + + // Show interface controls + this.embedPlayer.getInterface().find( '.control-bar' ) + .fadeIn( animateDuration ); + + if( keepOnScreen ){ + this.keepControlBarOnScreen = true; + } + + // Trigger the screen overlay with layout info: + $( this.embedPlayer ).trigger( 'onShowControlBar', [{ + 'bottom' : this.getHeight() + 15 + }, this.embedPlayer.id ] ); + }, + + /** + * Checks if the browser supports overlays and the controlsOverlay is + * set to true for the player or via config + */ + isOverlayControls: function(){ + //if the player "supports" overlays: + if( ! this.embedPlayer.supports['overlays'] ){ + return false; + } + + // If disabled via the player + if( this.embedPlayer.overlaycontrols === false ){ + return false; + } + + // Don't overlay controls if in audio mode: + if( this.embedPlayer.isAudio() ){ + return false; + } + + + // If the config is false + if( mw.config.get( 'EmbedPlayer.OverlayControls' ) === false){ + return false; + } + + if( this.embedPlayer.controls === false ){ + return false; + } + + // Past all tests OverlayControls is true: + return true; + }, + + /* Check if the controls are disabled */ + + isControlsDisabled: function() { + return this.controlsDisabled; + }, + + /** + * Check if a warning should be issued to non-native playback systems + * + * dependent on mediaElement being setup + */ + checkNativeWarning: function( ) { + if( mw.config.get( 'EmbedPlayer.ShowNativeWarning' ) === false ){ + return false; + } + + // Don't show for imageOverlay player: + if( this.embedPlayer.instanceOf == 'ImageOverlay' ){ + return false; + } + + // If the resolution is too small don't display the warning + if( parseInt( this.embedPlayer.getPlayerHeight() ) < 199 ){ + return false; + } + + // See if we have we have native support + if( this.embedPlayer.instanceOf == 'Native' ){ + return false; + } + + // Not a lot of good options for an iPhone + if( this.embedPlayer.instanceOf == 'VLCApp' ){ + return false; + } + if( this.embedPlayer.instanceOf == 'OgvJs' ){ + return false; + } + + // Chrome's webM support is oky though: + if( /chrome/.test(navigator.userAgent.toLowerCase() ) && + mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( 'video/webm' ).length ){ + return false; + } + + + // Check for h264 and or flash/flv source and playback support and don't show warning + if( + ( mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( 'video/h264' ).length + && this.embedPlayer.mediaElement.getSources( 'video/h264' ).length ) + || + ( mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( 'video/x-flv' ).length + && this.embedPlayer.mediaElement.getSources( 'video/x-flv' ).length ) + || + ( mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( 'application/vnd.apple.mpegurl' ).length + && this.embedPlayer.mediaElement.getSources( 'application/vnd.apple.mpegurl' ).length ) + || + ( mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( 'audio/mpeg' ).length + && this.embedPlayer.mediaElement.getSources( 'audio/mpeg' ).length ) + ){ + // No firefox link if a h.264 or flash/flv stream is present + return false; + } + + // Should issue the native warning + return true; + }, + + /** + * Does a native warning check binding to the player on mouse over. + * @param {string} preferenceId The preference Id + * @param {object} warningMsg The jQuery object warning message to be displayed. + * + */ + /** + * Display a warning message on the player + * checks a preference Id to enable or disable it. + * @param {string} preferenceId The preference Id + * @param {object} warningMsg The jQuery object warning message to be displayed. + * @param {boolean} if the hide ui should be exposed + * + */ + addWarningBinding: function( preferenceId, warningMsg, hideDisableUi ) { + mw.log( 'mw.PlayerControlBuilder: addWarningBinding: ' + preferenceId + ' wm: ' + warningMsg); + // Set up local pointer to the embedPlayer + var embedPlayer = this.embedPlayer; + var _this = this; + // make sure the player is large enough + if( embedPlayer.getWidth() < 200 ){ + return false; + } + + // Can be uncommented to reset hide prefrence + //$.cookie( preferenceId, '' ); + + // Check if a cookie has been set to hide the warning: + if ( mw.config.get( preferenceId ) === true && $.cookie( preferenceId ) == 'hidewarning' ){ + return ; + } + + var warnId = "warningOverlay_" + embedPlayer.id; + $( '#' + warnId ).remove(); + + // Add the targetWarning: + var $targetWarning = $('<div />') + .attr( { + 'id': warnId + } ) + .addClass( 'ui-corner-all' ) + .css({ + 'position' : 'absolute', + 'background' : '#FFF', + 'color' : '#111', + 'top' : '10px', + 'left' : '10px', + 'right' : '10px', + 'padding' : '4px', + // z-index should be > than play button, as well as greater + // than the dialog box (in pop up video), or link won't work. + 'z-index' : '1502', + }) + .html( warningMsg ); + + embedPlayer.getInterface().append( + $targetWarning + ); + + $targetWarning.append( + $('<br />') + ); + // check if we should show the checkbox + if( !hideDisableUi ){ + + $targetWarning.append( + $( '<input type="checkbox" />' ) + .attr({ + 'id' : 'ffwarn_' + embedPlayer.id, + 'name' : 'ffwarn_' + embedPlayer.id + }) + .click( function() { + mw.log("WarningBindinng:: set " + preferenceId + ' to hidewarning ' ); + // Set up a cookie for 30 days: + $.cookie( preferenceId, 'hidewarning', {expires: 30} ); + // Set the current instance + mw.setConfig( preferenceId, false ); + $( '#warningOverlay_' + embedPlayer.id ).fadeOut( 'slow' ); + // set the local preference to false + _this.addWarningFlag = false; + } ) + ); + $targetWarning.append( + $('<label />') + .text( mw.msg( 'mwe-embedplayer-do_not_warn_again' ) ) + .attr( 'for', 'ffwarn_' + embedPlayer.id ) + ); + } + + return $targetWarning; + }, + + /** + * Binds the volume controls + */ + doVolumeBinding: function( ) { + var embedPlayer = this.embedPlayer; + var _this = this; + embedPlayer.getInterface().find( '.volume_control' ).unbind().buttonHover().click( function() { + mw.log( 'Volume control toggle' ); + embedPlayer.toggleMute(); + } ); + + // Add vertical volume display hover + if ( this.volumeLayout == 'vertical' ) { + // Default volume binding: + var hoverOverDelay = false; + var $targetvol = embedPlayer.getInterface().find( '.vol_container' ).hide(); + embedPlayer.getInterface().find( '.volume_control' ).hover( + function() { + $targetvol.addClass( 'vol_container_top' ); + // Set to "below" if playing and embedType != native + if ( embedPlayer && embedPlayer.isPlaying && embedPlayer.isPlaying() && !embedPlayer.supports['overlays'] ) { + $targetvol.removeClass( 'vol_container_top' ).addClass( 'vol_container_below' ); + } + $targetvol.fadeIn( 'fast' ); + hoverOverDelay = true; + }, + function() { + hoverOverDelay = false; + setTimeout( function() { + if ( !hoverOverDelay ) { + $targetvol.fadeOut( 'fast' ); + } + }, 500 ); + } + ); + } + var userSlide=false; + // Setup volume slider: + var sliderConf = { + range: "min", + value: 80, + min: 0, + max: 100, + slide: function( event, ui ) { + var percent = ui.value / 100; + mw.log('PlayerControlBuilder::slide:update volume:' + percent); + embedPlayer.setVolume( percent ); + userSlide = true; + }, + change: function( event, ui ) { + var percent = ui.value / 100; + if ( percent == 0 ) { + embedPlayer.getInterface().find( '.volume_control span' ).removeClass( 'ui-icon-volume-on' ).addClass( 'ui-icon-volume-off' ); + } else { + embedPlayer.getInterface().find( '.volume_control span' ).removeClass( 'ui-icon-volume-off' ).addClass( 'ui-icon-volume-on' ); + } + mw.log('PlayerControlBuilder::change:update volume:' + percent); + embedPlayer.setVolume( percent, userSlide ); + userSlide = false; + } + }; + + if ( this.volumeLayout == 'vertical' ) { + sliderConf[ 'orientation' ] = "vertical"; + } + + embedPlayer.getInterface().find( '.volume-slider' ).slider( sliderConf ); + }, + + /** + * Get the options menu ul with li menu items + */ + getOptionsMenu: function( ) { + var $optionsMenu = $( '<ul />' ); + for( var menuItemKey in this.optionMenuItems ){ + + // Make sure its supported in the current controlBuilder config: + if( $.inArray( menuItemKey, mw.config.get( 'EmbedPlayer.EnabledOptionsMenuItems' ) ) === -1 ) { + continue; + } + + $optionsMenu.append( + this.optionMenuItems[ menuItemKey ]( this ) + ); + } + return $optionsMenu; + }, + + /** + * Allow the controlBuilder to do interface actions onDone + */ + onClipDone: function(){ + // Related videos could be shown here + }, + + /** + * The ctrl builder updates the interface on seeking + */ + onSeek: function(){ + //mw.log( "controlBuilder:: onSeek" ); + // Update the interface: + this.setStatus( mw.msg( 'mwe-embedplayer-seeking' ) ); + // add a loading spinner: + this.embedPlayer.addPlayerSpinner(); + // hide once playing again: + this.embedPlayer.hideSpinnerOncePlaying(); + }, + + /** + * Updates the player status that displays short text msgs and the play clock + * @param {String} value Status string value to update + */ + setStatus: function( value ) { + // update status: + if( this.embedPlayer.getInterface() ){ + this.embedPlayer.getInterface().find( '.time-disp' ).text( value ); + } + }, + + /** + * Option menu items + * + * @return + * 'li' a li line item with click action for that menu item + */ + optionMenuItems: { + // Share the video menu + 'share': function( ctrlObj ) { + return $.getLineItem( + mw.msg( 'mwe-embedplayer-share' ), + 'mail-closed', + function( ) { + ctrlObj.displayMenuOverlay( + ctrlObj.getShare() + ); + $( ctrlObj.embedPlayer ).trigger( 'showShareEvent' ); + } + ); + }, + + 'aboutPlayerLibrary' : function( ctrlObj ){ + return $.getLineItem( + mw.msg( 'mwe-embedplayer-about-library' ), + 'info', + function( ) { + ctrlObj.displayMenuOverlay( + ctrlObj.aboutPlayerLibrary() + ); + $( ctrlObj.embedPlayer ).trigger( 'aboutPlayerLibrary' ); + } + ); + } + }, + + /** + * Close a menu overlay + */ + closeMenuOverlay: function(){ + var _this = this; + var embedPlayer = this.embedPlayer; + var $overlay = embedPlayer.getInterface().find( '.overlay-win,.ui-widget-overlay,.ui-widget-shadow' ); + + this.displayOptionsMenuFlag = false; + //mw.log(' closeMenuOverlay: ' + this.displayOptionsMenuFlag); + + $overlay.fadeOut( "slow", function() { + $overlay.remove(); + } ); + + // Show the big play button: ( if not in an ad .. TODO clean up ) + if( embedPlayer.isStopped() && + ( + embedPlayer.sequenceProxy && + embedPlayer.sequenceProxy.isInSequence == false + ) + ){ + embedPlayer.getInterface().find( '.play-btn-large' ).fadeIn( 'slow' ); + } + + $(embedPlayer).trigger( 'closeMenuOverlay' ); + + return false; // onclick action return false + }, + + /** + * Generic function to display custom HTML overlay on video. + * + * @param {String} overlayContent content to be displayed + */ + displayMenuOverlay: function( overlayContent, closeCallback, hideCloseButton ) { + var _this = this; + var embedPlayer = this.embedPlayer; + mw.log( 'PlayerControlBuilder:: displayMenuOverlay' ); + // set the overlay display flag to true: + this.displayOptionsMenuFlag = true; + + if ( !this.supportedComponents[ 'overlays' ] ) { + embedPlayer.stop(); + } + + + // Hide the big play button: + embedPlayer.hideLargePlayBtn(); + + // Check if overlay window is already present: + if ( embedPlayer.getInterface().find( '.overlay-win' ).length != 0 ) { + //Update the content + embedPlayer.getInterface().find( '.overlay-content' ).html( + overlayContent + ); + return ; + } + + // Add an overlay + embedPlayer.getInterface().append( + $('<div />') + .addClass( 'ui-widget-overlay' ) + .css( { + 'height' : '100%', + 'width' : '100%', + 'z-index' : 2 + } ) + ); + + var $closeButton = []; + + if ( !hideCloseButton ) { + // Setup the close button + $closeButton = $('<div />') + .addClass( 'ui-state-default ui-corner-all ui-icon_link rButton') + .css({ + 'position': 'absolute', + 'cursor' : 'pointer', + 'top' : '2px', + 'right' : '2px' + }) + .click( function() { + _this.closeMenuOverlay(); + if( closeCallback ){ + closeCallback(); + } + } ) + .append( + $('<span />') + .addClass( 'ui-icon ui-icon-closethick' ) + ); + } + + var controlBarHeight = embedPlayer.getInterface().find( '.control-bar' ).height(); + var overlayWidth = (embedPlayer.getWidth() - 30); + var overlayHeight = (embedPlayer.getHeight() - (controlBarHeight + 30)); + var overlayTop = (( (embedPlayer.getInterface().height() - controlBarHeight) - overlayHeight) / 2); + var overlayLeft = ((embedPlayer.getInterface().width() - overlayWidth) / 2); + + var overlayMenuCss = { + 'height' : overlayHeight + 'px', + 'width' : overlayWidth + 'px', + 'position' : 'absolute', + 'top' : overlayTop + 'px', + 'left': overlayLeft + 'px', + 'margin': '0 10px 10px 0', + 'overflow' : 'auto', + 'padding' : '4px', + 'z-index' : 3 + }; + var $overlayMenu = $('<div />') + .addClass( 'overlay-win ui-state-default ui-widget-header ui-corner-all' ) + .css( overlayMenuCss ) + .append( + $closeButton, + $('<div />') + .addClass( 'overlay-content' ) + .append( overlayContent ) + ); + + + // Append the overlay menu to the player interface + embedPlayer.getInterface().prepend( + $overlayMenu + ) + .find( '.overlay-win' ) + .fadeIn( "slow" ); + + // Trigger menu overlay display + $( embedPlayer ).trigger( 'displayMenuOverlay' ); + + return false; // onclick action return false + }, + + /** + * Close an alert + */ + closeAlert: function( keepOverlay ) { + var embedPlayer = this.embedPlayer; + var $alert = $( '#alertContainer' ); + + mw.log( 'mw.PlayerControlBuilder::closeAlert' ); + if ( !keepOverlay || ( mw.isIpad() && this.inFullScreen ) ) { + embedPlayer.controlBuilder.closeMenuOverlay(); + if ( mw.isIpad() ) { + embedPlayer.disablePlayControls(); + } + } + + $alert.remove(); + + return false; // onclick action return false; + }, + + /** + * Generic function to display custom alert overlay on video. + * + * @param (Object) Object which includes: + * title Alert Title + * body Alert body + * buttonSet[label,callback] Array of buttons + * style CSS object + */ + displayAlert: function( alertObj ) { + var embedPlayer = this.embedPlayer; + var callback; + mw.log( 'PlayerControlBuilder::displayAlert:: ' + alertObj.title ); + // Check if callback is external or internal (Internal by default) + + // Check if overlay window is already present: + if ( embedPlayer.getInterface().find( '.overlay-win' ).length != 0 ) { + return; + } + if( typeof alertObj.callbackFunction == 'string' ) { + if ( alertObj.isExternal ) { + // TODO better support of running external JS functions, instead of window.parent + try{ + callback = window.parent[ alertObj.callbackFunction ]; + } catch ( e ){ + // could not call parent method + } + } else { + callback = window[ alertObj.callbackFunction ]; + } + } else if( typeof alertObj.callbackFunction == 'function' ) { + // Make life easier for internal usage of the listener mapping by supporting + // passing a callback by function ref + callback = alertObj.callbackFunction; + } else { + mw.log( "PlayerControlBuilder :: displayAlert :: Error: bad callback type" ); + callback = function() {}; + } + + var $container = $( '<div />' ).attr( 'id', 'alertContainer' ).addClass( 'alert-container' ); + var $title = $( '<div />' ).text( alertObj.title ).addClass( 'alert-title alert-text' ); + if ( alertObj.props && alertObj.props.titleTextColor ) { + $title.removeClass( 'alert-text' ); + $title.css( 'color', mw.getHexColor( alertObj.props.titleTextColor ) ); + } + var $message = $( '<div />' ).text( alertObj.message ).addClass( 'alert-message alert-text' ); + if ( alertObj.isError ) { + $message.addClass( 'error' ); + } + if ( alertObj.props && alertObj.props.textColor ) { + $message.removeClass( 'alert-text' ); + $message.css( 'color', mw.getHexColor( alertObj.props.textColor ) ); + } + var $buttonsContainer = $( '<div />' ).addClass( 'alert-buttons-container' ); + if ( alertObj.props && alertObj.props.buttonRowSpacing ) { + $buttonsContainer.css( 'margin-top', alertObj.props.buttonRowSpacing ); + } + var $buttonSet = alertObj.buttons || []; + + // If no button was passed display just OK button + var buttonsNum = $buttonSet.length; + if ( buttonsNum == 0 && !alertObj.noButtons ) { + $buttonSet = ["OK"]; + buttonsNum++; + } + + $.each( $buttonSet, function(i) { + var label = this.toString(); + var $currentButton = $( '<button />' ) + .addClass( 'alert-button' ) + .text( label ) + .click( function( eventObject ) { + callback( eventObject ); + embedPlayer.controlBuilder.closeAlert( alertObj.keepOverlay ); + } ); + if ( alertObj.props && alertObj.props.buttonHeight ) { + $currentButton.css( 'height', alertObj.props.buttonHeight ); + } + // Apply buttons spacing only when more than one is present + if (buttonsNum > 1) { + if (i < buttonsNum-1) { + if ( alertObj.props && alertObj.props.buttonSpacing ) { + $currentButton.css( 'margin-right', alertObj.props.buttonSpacing ); + } + } + } + $buttonsContainer.append( $currentButton ); + } ) + $container.append( $title, $message, $buttonsContainer ); + return embedPlayer.controlBuilder.displayMenuOverlay( $container, false, true ); + }, + + aboutPlayerLibrary: function(){ + return $( '<div />' ) + .append( + $( '<h2 />' ) + .text( + mw.msg('mwe-embedplayer-about-library') + ) + , + $( '<span />') + .append( + mw.msg('mwe-embedplayer-about-library-desc', + $('<div>').append( + $('<a />').attr({ + 'href' : mw.config.get( 'EmbedPlayer.LibraryPage' ), + 'target' : '_new' + }) + )[0].innerHTML + ) + ) + ); + }, + /** + * Get the "share" interface + * + * TODO share should be enabled via <embed> tag usage to be compatible + * with sites social networking sites that allow <embed> tags but not js + * + * @param {Object} $target Target jQuery object to set share html + */ + getShare: function( ) { + var embedPlayer = this.embedPlayer; + var embed_code = embedPlayer.getSharingEmbedCode(); + var embed_wiki_code = embedPlayer.getWikiEmbedCode(); + var _this = this; + + var $shareInterface = $('<div />'); + + var $shareList = $( '<ul />' ); + + $shareList + .append( + $('<li />').text( + mw.msg( 'mwe-embedplayer-embed_site_or_blog' ) + ) + /* + .append( + $('<a />') + .attr('href', '#') + .addClass( 'active' ) + .text( + mw.msg( 'mwe-embedplayer-embed_site_or_blog' ) + ) + ) + */ + ); + + $shareInterface.append( + $( '<h2 />' ) + .text( embedPlayer.isAudio() ? + mw.msg( 'mwe-embedplayer-share_this_audio' ) : + mw.msg( 'mwe-embedplayer-share_this_video' ) ) + ); + + if ( embed_wiki_code ) { + $shareInterface.append( + $('<ul />').append( + $('<li />').text( + mw.msg( 'mwe-embedplayer-embed_wiki' ) + ) + ), + $( '<textarea />' ) + .attr( 'rows', 1 ) + .html( embed_wiki_code ) + .click( function() { + $( this ).select(); + }), + $('<br />') + ); + } + + $shareInterface.append( + $shareList + ); + + $shareInterface.append( + + $( '<textarea />' ) + .attr( 'rows', 4 ) + .html( embed_code ) + .click( function() { + $( this ).select(); + }), + + $('<br />'), + $('<br />') + ); + return $shareInterface; + }, + + /** + * Shows the Player Select interface + * + * @param {Object} $target jQuery target for output + */ + getPlayerSelect: function( ) { + mw.log('PlayerControlBuilder::getPlayerSelect: source:' + + this.embedPlayer.mediaElement.selectedSource.getSrc() + + ' player: ' + this.embedPlayer.selectedPlayer.id ); + + var embedPlayer = this.embedPlayer; + + var _this = this; + + var $playerSelect = $('<div />') + .append( + $( '<h2 />' ) + .text( mw.msg( 'mwe-embedplayer-choose_player' ) ) + ); + + $.each( embedPlayer.mediaElement.getPlayableSources(), function( sourceId, source ) { + + var isPlayable = (typeof mw.EmbedTypes.getMediaPlayers().defaultPlayer( source.getMIMEType() ) == 'object' ); + var isSelected = ( source.getSrc() == embedPlayer.mediaElement.selectedSource.getSrc() ); + + $playerSelect.append( + $( '<h3 />' ) + .text( source.getTitle() ) + ); + + if ( isPlayable ) { + var $playerList = $('<ul />'); + // output the player select code: + + var supportingPlayers = mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( source.getMIMEType() ); + + for ( var i = 0; i < supportingPlayers.length ; i++ ) { + // Add link to select the player if not already selected ) + if( embedPlayer.selectedPlayer.id == supportingPlayers[i].id && isSelected ) { + // Active player ( no link ) + var $playerLine = $( '<span />' ) + .append( + $('<a />') + .attr({ + 'href' : '#' + }) + .addClass( 'active') + .text( + supportingPlayers[i].getName() + ).click( function(){ + embedPlayer.controlBuilder.closeMenuOverlay(); + // Don't follow the # link: + return false; + }) + ); + //.addClass( 'ui-state-highlight ui-corner-all' ); removed by ran + } else { + // Non active player add link to select: + $playerLine = $( '<a />') + .attr({ + 'href' : '#', + 'id' : 'sc_' + sourceId + '_' + supportingPlayers[i].id + }) + .addClass( 'ui-corner-all') + .text( supportingPlayers[i].getName() ) + .click( function() { + var iparts = $( this ).attr( 'id' ).replace(/sc_/ , '' ).split( '_' ); + var sourceId = iparts[0]; + var player_id = iparts[1]; + mw.log( 'PlayerControlBuilder:: source id: ' + sourceId + ' player id: ' + player_id ); + + embedPlayer.controlBuilder.closeMenuOverlay(); + + // Close fullscreen if we are in fullscreen mode + if( _this.isInFullScreen() ){ + _this.restoreWindowPlayer(); + } + + embedPlayer.mediaElement.setSourceByIndex( sourceId ); + var playableSources = embedPlayer.mediaElement.getPlayableSources(); + + mw.EmbedTypes.getMediaPlayers().setPlayerPreference( + player_id, + playableSources[ sourceId ].getMIMEType() + ); + + // Issue a stop + embedPlayer.stop(); + + // Don't follow the # link: + return false; + } ) + .hover( + function(){ + $( this ).addClass('active'); + }, + function(){ + $( this ).removeClass('active'); + } + ); + } + + // Add the player line to the player list: + $playerList.append( + $( '<li />' ).append( + $playerLine + ) + ); + } + + // Append the player list: + $playerSelect.append( $playerList ); + + } else { + // No player available: + $playerSelect.append( mw.msg( 'mwe-embedplayer-no-player', source.getTitle() ) ); + } + } ); + + // Return the player select elements + return $playerSelect; + }, + + /** + * Loads sources and calls showDownloadWithSources + * @param {Object} $target jQuery target to output to + */ + showDownload: function( $target ) { + var _this = this; + var embedPlayer = this.embedPlayer; + _this.showDownloadWithSources( $target ); + }, + + /** + * Shows the download interface with sources loaded + * @param {Object} $target jQuery target to output to + */ + showDownloadWithSources : function( $target ) { + var _this = this; + mw.log( 'PlayerControlBuilder:: showDownloadWithSources::' + $target.length ); + var embedPlayer = this.embedPlayer; + // Empty the target: + $target.empty(); + $target.append( $('<div />') ); + $target = $target.find('div'); + + var $mediaList = $( '<ul />' ); + var $textList = $( '<ul />' ); + $.each( embedPlayer.mediaElement.getSources(), function( index, source ) { + if( source.getSrc() ) { + mw.log("showDownloadWithSources:: Add src: " + source.getTitle() ); + var fileName = source.mwtitle; + if ( !fileName ) { + var path = new mw.Uri( source.getSrc() ).path; + var pathParts = path.split( '/' ); + fileName = pathParts[ pathParts.length -1 ]; + } + var $dlLine = $( '<li />').append( + $('<a />') + .attr( { + 'href': source.getSrc(), + 'download': fileName + }) + .text( source.getTitle() ) + ); + // Add link to correct "bucket" + + //Add link to time segment: + if ( source.getSrc().indexOf( '?t=' ) !== -1 ) { + $target.append( $dlLine ); + } else if ( this.getMIMEType().indexOf('text') === 0 ) { + // Add link to text list + $textList.append( $dlLine ); + } else { + // Add link to media list + $mediaList.append( $dlLine ); + } + + } + } ); + if( $mediaList.find('li').length != 0 ) { + $target.append( + $('<h2 />') + .text( embedPlayer.isAudio() ? + mw.msg( 'mwe-embedplayer-download_full_audio' ) : + mw.msg( 'mwe-embedplayer-download_full_video' ) ), + $mediaList + ); + } + + if( $textList.find('li').length != 0 ) { + $target.append( + $('<h2 />') + .html( mw.msg( 'mwe-embedplayer-download_text' ) ), + $textList + ); + } + }, + getSwitchSourceMenu: function(){ + var _this = this; + var embedPlayer = this.embedPlayer; + // for each source with "native playback" + var $sourceMenu = $('<ul />'); + + // Local function to closure the "source" variable scope: + function addToSourceMenu( source ){ + // Check if source is selected: + var icon = ( source.getSrc() == embedPlayer.mediaElement.selectedSource.getSrc() ) ? 'bullet' : 'radio-on'; + $sourceMenu.append( + $.getLineItem( source.getShortTitle() , icon, function(){ + mw.log( 'PlayerControlBuilder::SwitchSourceMenu: ' + source.getSrc() ); + // update menu selecting parent li siblings + $( this ).parent().siblings().find('span.ui-icon').removeClass( 'ui-icon-bullet').addClass( 'ui-icon-radio-on' ); + $( this ).find('span.ui-icon').removeClass( 'ui-icon-radio-on').addClass( 'ui-icon-bullet' ); + // update control bar text + embedPlayer.getInterface().find( '.source-switch' ).text( source.getShortTitle() ); + + + // TODO this logic should be in mw.EmbedPlayer + embedPlayer.mediaElement.setSource( source ); + if( ! _this.embedPlayer.isStopped() ){ + // Get the exact play time from the video element ( instead of parent embed Player ) + var oldMediaTime = _this.embedPlayer.getPlayerElement().currentTime; + var oldPaused = _this.embedPlayer.paused; + // Do a live switch + embedPlayer.playerSwitchSource( source, function( vid ){ + // issue a seek + embedPlayer.setCurrentTime( oldMediaTime, function(){ + // reflect pause state + if( oldPaused ){ + embedPlayer.pause(); + } + } ); + }); + } + }) + ); + } + var addedSources = {}; + $.each( this.embedPlayer.mediaElement.getPlayableSources(), function( sourceIndex, source ) { + // Output the player select code: + var supportingPlayers = mw.EmbedTypes.getMediaPlayers().getMIMETypePlayers( source.getMIMEType() ); + for ( var i = 0; i < supportingPlayers.length ; i++ ) { + var lib = supportingPlayers[i].library; + if( lib === 'Native' || lib === 'OgvJs' ){ // @fixme use supports.sourceSwitch ... if preloaded? + if ( !( source.getSrc() in addedSources ) ) { + addedSources[source.getSrc()] = true; + addToSourceMenu( source ); + } + } + } + }); + return $sourceMenu; + }, + + /** + * Get component + * + * @param {String} componentId Component key to grab html output + */ + getComponent: function( componentId ) { + if ( this.components[ componentId ] ) { + return this.components[ componentId ].o( this ); + } else { + return false; + } + }, + + /** + * Get a component height + * + * @param {String} componentId Component key to grab height + * @return height or false if not set + */ + getComponentHeight: function( componentId ) { + if ( this.components[ componentId ] + && this.components[ componentId ].h ) + { + return this.components[ componentId ].h; + } + return 0; + }, + + /** + * Get a component width + * @param {String} componentId Component key to grab width + * @return width or false if not set + */ + getComponentWidth: function( componentId ){ + if ( this.components[ componentId ] + && this.components[ componentId ].w ) + { + return this.components[ componentId ].w; + } + return 0; + }, + + // Set up the disable playhead function: + // TODO this will move into the disableSeekBar binding in the new theme framework + disableSeekBar : function(){ + var $playHead = this.embedPlayer.getInterface().find( ".play_head" ); + if( $playHead.length ){ + $playHead.slider( "option", "disabled", true ); + } + }, + enableSeekBar : function(){ + var $playHead = this.embedPlayer.getInterface().find( ".play_head" ); + if( $playHead.length ){ + $playHead.slider( "option", "disabled", false); + } + }, + + /** + * Components Object + * Take in the embedPlayer and return some html for the given component. + * + * components can be overwritten by skin javascript + * + * Component JSON structure is as follows: + * 'o' Function to return a binded jQuery object ( accepts the ctrlObject as a parameter ) + * 'w' The width of the component + * 'h' The height of the component ( if height is undefined the height of the control bar is used ) + * 'position' elements are inserted into the dom based on component order and available space. + * if the element is inserted, position is then used to set relative dom insert order. + */ + components: { + /** + * The pause / play button + */ + 'pause': { + 'w': 28, + 'position': 1, + 'o': function( ctrlObj ) { + return $( '<div />' ) + .attr( 'title', mw.msg( 'mwe-embedplayer-play_clip' ) ) + .addClass ( "ui-state-default ui-corner-all ui-icon_link lButton play-btn" ) + .append( + $( '<span />' ) + .addClass( "ui-icon ui-icon-play" ) + ) + // Play / pause binding + .buttonHover() + .click( function() { + ctrlObj.embedPlayer.play(); + // Don't follow the # link: + return false; + }); + } + }, + + /** + * The volume control interface html + */ + 'volumeControl': { + 'w' : 28, + 'position': 7, + 'o' : function( ctrlObj ) { + mw.log( 'PlayerControlBuilder::Set up volume control for: ' + ctrlObj.embedPlayer.id ); + var $volumeOut = $( '<span />' ); + if ( ctrlObj.volumeLayout == 'horizontal' ) { + $volumeOut.append( + $( '<div />' ) + .addClass( "ui-slider ui-slider-horizontal rButton volume-slider" ) + ); + } + + // Add the volume control icon + $volumeOut.append( + $('<div />') + .attr( 'title', mw.msg( 'mwe-embedplayer-volume_control' ) ) + .addClass( "ui-state-default ui-corner-all ui-icon_link rButton volume_control" ) + .append( + $( '<span />' ) + .addClass( "ui-icon ui-icon-volume-on" ) + ) + ); + if ( ctrlObj.volumeLayout == 'vertical' ) { + $volumeOut.find('.volume_control').append( + $( '<div />' ) + .hide() + .addClass( "vol_container ui-corner-all" ) + .append( + $( '<div />' ) + .addClass ( "volume-slider" ) + ) + ); + } + //Return the inner html + return $volumeOut.html(); + } + }, + + /** + * The large play button in center of the player + */ + 'playButtonLarge': { + 'w' : 70, + 'h' : 53, + 'position': 2, + 'o' : function( ctrlObj ) { + return $( '<div />' ) + .attr( { + 'title' : mw.msg( 'mwe-embedplayer-play_clip' ), + 'class' : "play-btn-large" + } ) + // Get dynamic position for big play button + .css( ctrlObj.getPlayButtonPosition() ) + // Add play hook: + .click( function() { + ctrlObj.embedPlayer.play(); + return false; // Event Stop Propagation + } ); + } + }, + + /** + * The Attribution button ( by default this is kaltura-icon + */ + 'attributionButton' : { + 'w' : 28, + 'position': 3, + 'o' : function( ctrlObj ){ + var buttonConfig = mw.config.get( 'EmbedPlayer.AttributionButton'); + // Check for source ( by configuration convention this is a 16x16 image + if( buttonConfig.iconurl ){ + var $icon = $('<img />') + .attr('src', buttonConfig.iconurl ); + } else { + var $icon = $('<span />') + .addClass( 'ui-icon' ); + if( buttonConfig['class'] ){ + $icon.addClass( buttonConfig['class'] ); + } + } + if( typeof buttonConfig.style != 'object'){ + buttonConfig.style = {}; + } + // update the configured size of the attribution button if we have a specific width configured + if( buttonConfig.style.width ){ + this.w = parseInt( buttonConfig.style.width ); + } else { + buttonConfig.style.width = parseInt( this.w ) + 'px'; + } + + return $( '<div />' ) + .addClass( 'rButton' ) + .css({ + 'top' : '1px', + 'left' : '2px' + }) + // Allow button config style to override + .css( buttonConfig.style ) + .append( + $('<a />') + .attr({ + 'href': buttonConfig.href, + 'title' : buttonConfig.title, + 'target' : '_new' + }) + .append( $icon ) + ); + } + }, + + /* + * The time display area + */ + 'timeDisplay': { + 'w' : mw.config.get( 'EmbedPlayer.TimeDisplayWidth' ), + 'position': 6, + 'o' : function( ctrlObj ) { + return $( '<div />' ) + .addClass( "ui-widget time-disp" ) + .append( + ctrlObj.embedPlayer.getTimeRange() + ); + } + }, + + /** + * The options button, invokes display of the options menu + */ + 'options': { + 'w': 28, + 'position': 10, + 'o': function( ctrlObj ) { + return $( '<div />' ) + .attr( 'title', mw.msg( 'mwe-embedplayer-player_options' ) ) + .addClass( 'ui-state-default ui-corner-all ui-icon_link rButton options-btn' ) + .append( + $('<span />') + .addClass( 'ui-icon ui-icon-wrench' ) + ) + .buttonHover() + // Options binding: + .embedMenu( { + 'content' : ctrlObj.getOptionsMenu(), + 'zindex' : mw.config.get( 'EmbedPlayer.FullScreenZIndex' ) + 2, + 'positionOpts': { + 'directionV' : 'up', + 'offsetY' : 30, + 'directionH' : 'left', + 'offsetX' : -28 + } + } ); + } + }, + + /** + * The fullscreen button for displaying the video fullscreen + */ + 'fullscreen': { + 'w': 24, + 'position': 8, + 'o': function( ctrlObj ) { + var $btn = $( '<div />' ) + .attr( 'title', mw.msg( 'mwe-embedplayer-player_fullscreen' ) ) + .addClass( "ui-state-default ui-corner-all ui-icon_link rButton fullscreen-btn" ) + .append( + $( '<span />' ) + .addClass( "ui-icon ui-icon-arrow-4-diag" ) + ) + // Fullscreen binding: + .buttonHover(); + // Link out to another window if iPad 3x ( broken iframe resize ) + if( ( + mw.config.get('EmbedPlayer.IsIframeServer') + && + mw.isIpad3() + ) + || + mw.config.get( "EmbedPlayer.NewWindowFullscreen" ) + || + ( mw.config.get('EmbedPlayer.IsIframeServer') && mw.config.get('EmbedPlayer.EnableIframeApi') === false ) + ){ + // Get the iframe url: + var url = ctrlObj.embedPlayer.getIframeSourceUrl(); + // Change button into new window ( of the same url as the iframe ) : + return $('<a />').attr({ + 'href': url, + 'target' : '_new' + }) + .click(function(){ + // Update the url: + var url = $(this).attr('href'); + var iframeMwConfig = {}; + + iframeMwConfig['EmbedPlayer.IsFullscreenIframe'] = true; + // add a seek offset: + iframeMwConfig['EmbedPlayer.IframeCurrentTime'] = ctrlObj.embedPlayer.currentTime; + // add play state: + iframeMwConfig['EmbedPlayer.IframeIsPlaying'] = ctrlObj.embedPlayer.isPlaying(); + + // Append the configuration and request domain to the iframe hash: + + // Add the parentUrl to the iframe config: + iframeMwConfig['EmbedPlayer.IframeParentUrl'] = document.URL; + + url += '#' + encodeURIComponent( + JSON.stringify({ + 'mwConfig' :iframeMwConfig, + 'playerId' : playerId + }) + ); + ctrlObj.embedPlayer.pause(); + // try and do a browser popup: + var newwin = window.open( + url, + ctrlObj.embedPlayer.id, + // Fullscreen window params: + 'width=' + screen.width + + ', height=' + ( screen.height - 90 ) + + ', top=0, left=0' + + ', fullscreen=yes' + ); + // if for some reason we could not open the window run the href link: + if( newwin === null){ + return true; + } + if ( window.focus ) { + newwin.focus(); + } + // Else do not follow the href link + return false; + }) + .append($btn); + } else { + return $btn.click( function() { + ctrlObj.embedPlayer.fullscreen(); + } ); + } + } + }, + + 'sourceSwitch' : { + 'w' : 70, + 'position': 9, + 'o' : function( ctrlObj ){ + var $menuContainer = $('<div />').addClass( 'swMenuContainer' ).hide(); + ctrlObj.embedPlayer.getInterface().append( + $menuContainer + ) + // Stream switching widget ( display the current selected stream text ) + return $( '<div />' ) + .addClass('ui-widget source-switch') + .append( + ctrlObj.embedPlayer.mediaElement.selectedSource.getShortTitle() + ).embedMenu( { + 'content' : ctrlObj.getSwitchSourceMenu(), + 'zindex' : mw.config.get( 'EmbedPlayer.FullScreenZIndex' ) + 2, + 'keepPosition' : true, + 'targetMenuContainer' : $menuContainer, + 'width' : 130, + 'showSpeed': 0, + 'createMenuCallback' : function(){ + var $interface = ctrlObj.embedPlayer.getInterface(); + var $sw = $interface.find( '.source-switch' ); + var $swMenuContainer = $interface.find('.swMenuContainer'); + var height = $swMenuContainer.find( 'li' ).length * 30; + // position from top ( unkown why we can't use bottom here ) + var top = $interface.height() - height - ctrlObj.getHeight() - 6; + $menuContainer.css({ + 'position' : 'absolute', + 'left': $sw[0].offsetLeft, + 'top' : top, + 'bottom': ctrlObj.getHeight(), + 'height' : height + }) + ctrlObj.showControlBar( true ); + }, + 'closeMenuCallback' : function(){ + ctrlObj.restoreControlsHover() + } + } ); + } + }, + + /** + * The playhead component + */ + 'playHead': { + 'w':0, // special case (takes up remaining space) + 'position': 5, + 'o':function( ctrlObj ) { + + var sliderConfig = { + range: "min", + value: 0, + min: 0, + max: 1000, + start: function( event, ui ) { + var id = ( embedPlayer.pc != null ) ? embedPlayer.pc.pp.id:embedPlayer.id; + embedPlayer.userSlide = true; + $( id + ' .play-btn-large' ).fadeOut( 'fast' ); + // If playlist always start at 0 + embedPlayer.startTimeSec = ( embedPlayer.instanceOf == 'mvPlayList' ) ? 0: + mw.npt2seconds( embedPlayer.getTimeRange().split( '/' )[0] ); + }, + slide: function( event, ui ) { + var perc = ui.value / 1000; + embedPlayer.jumpTime = mw.seconds2npt( parseFloat( parseFloat( embedPlayer.getDuration() ) * perc ) + embedPlayer.startTimeSec ); + // mw.log('perc:' + perc + ' * ' + embedPlayer.getDuration() + ' jt:'+ this.jumpTime); + if ( _this.longTimeDisp ) { + ctrlObj.setStatus( mw.msg( 'mwe-embedplayer-seek_to', embedPlayer.jumpTime ) ); + } else { + ctrlObj.setStatus( embedPlayer.jumpTime ); + } + // Update the thumbnail / frame + if ( embedPlayer.isPlaying == false ) { + embedPlayer.updateThumbPerc( perc ); + } + }, + change: function( event, ui ) { + // Only run the onChange event if done by a user slide + // (otherwise it runs times it should not) + if ( embedPlayer.userSlide ) { + embedPlayer.userSlide = false; + embedPlayer.seeking = true; + + var perc = ui.value / 1000; + // set seek time (in case we have to do a url seek) + embedPlayer.seekTimeSec = mw.npt2seconds( embedPlayer.jumpTime, true ); + mw.log( 'PlayerControlBuilder:: seek to: ' + embedPlayer.jumpTime + ' perc:' + perc + ' sts:' + embedPlayer.seekTimeSec ); + ctrlObj.setStatus( mw.msg( 'mwe-embedplayer-seeking' ) ); + if( embedPlayer.isStopped() ){ + embedPlayer.play(); + } + embedPlayer.seek( perc ); + } + } + }; + + var embedPlayer = ctrlObj.embedPlayer; + var _this = this; + var $playHead = $( '<div />' ) + .addClass ( "play_head" ) + .css({ + "position" : 'absolute', + "left" : '33px', + "right" : ( ( embedPlayer.getPlayerWidth() - ctrlObj.availableWidth - 33 ) ) + 'px' + }) + // Playhead binding + .slider( sliderConfig ); + + // Up the z-index of the default status indicator: + $playHead.find( '.ui-slider-handle' ).css( 'z-index', 4 ); + $playHead.find( '.ui-slider-range' ).addClass( 'ui-corner-all' ).css( 'z-index', 2 ); + + // Add buffer html: + $playHead.append( + $('<div />') + .addClass( "ui-slider-range ui-slider-range-min ui-widget-header") + .addClass( "ui-state-highlight ui-corner-all mw_buffer") + ); + + // Show video timeline position on hover and when dragging playhead + function showPosition(event) { + var pos = ( event.clientX - $playHead.offset().left ) / $playHead.width(); + var time = mw.seconds2npt( parseFloat( embedPlayer.getDuration() ) * pos + (embedPlayer.startTimeSec || 0) ); + $playHead.attr('title', time); + } + $playHead.on({ + mouseenter: showPosition, + mouseleave: function(event) { + $playHead.attr({title: ''}); + }, + mousemove: showPosition + }); + + return $playHead; + } + } + } +}; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Audio.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Audio.html new file mode 100644 index 00000000..e0d0c19e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Audio.html @@ -0,0 +1,16 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <!-- <script type="text/javascript" src="../../../ResourceLoader.php?class=window.jQuery,mwEmbed&&debug=true"></script> --> + <script type="text/javascript" src="../../../mwEmbedStartup.php"></script> +<title>Audio Player sample</title> +</head> +<body> +<h3> Audio Player </h3> +<audio class="kskin" src="http://upload.wikimedia.org/wikipedia/commons/4/4c/Faurepiece.ogg" durationHint="164"></audio> +<h3> Audio Player mp3 </h3> +<audio src="http://ia600300.us.archive.org/35/items/tube122/tube122-02-entia_non_-_perfunctory_jousting.mp3" durationHint="133"></audio> + +</body> +</html>
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_DynamicEmbed.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_DynamicEmbed.html new file mode 100644 index 00000000..135e1713 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_DynamicEmbed.html @@ -0,0 +1,24 @@ +<html> + <head> + <script type="text/javascript" src="../../../mwEmbedStartup.php"></script> + </head> +<body> + + <div style="width:640px; height:480px;" id="mwplayer"></div> + + <script> + mw.ready(function(){ + + mw.load('EmbedPlayer', function(){ + // seems to trip a bug in IE8/win7 + $('#mwplayer').embedPlayer({ + 'poster' : "http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/bbb480.jpg", + 'sources':[{ + 'src':'http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/bbb_trailer_iphone.m4v', + 'type':'video/h264'}] + }); + }); + }); + </script> + +</body> diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_IncludeJQuery.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_IncludeJQuery.html new file mode 100644 index 00000000..ebe3bac9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_IncludeJQuery.html @@ -0,0 +1,27 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>Player sources</title> + +<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js" type="text/javascript"></script> +<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7/jquery-ui.min.js" type="text/javascript"></script> +<script type="text/javascript" src="../../../mwEmbedStartup.php"></script> +<script type="text/javascript"> + $(document).ready(function(){ + $('#test').text('jQuery $ supported' ); + }); +</script> +</head> +<body> +<div id="test"></div> + +<video poster="http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/elephants-dream.jpg" + duration="10:53" preload="auto"> + <source type="video/webm" src="http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/elephants-dream_400p.webm" /> + <source type="video/h264" src="http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/elephants-dream_iphone.m4v" /> + <source type="video/ogg" src="http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/elephants-dream_400p.ogv" /> +</video> + + +</body> +</html>
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Native_Bindings.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Native_Bindings.html new file mode 100644 index 00000000..433ffa21 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Native_Bindings.html @@ -0,0 +1,129 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>Native Player html5 bindings </title> + + +</head> +<body> +<div style="position:absolute;display:block; left: 500px; width:300px; background: #eee; border:solid thin black"> + <table style="font-size:.8em"> + <tr> + <td colspan="2"> + <b>Media Events:</b> + </td> + </tr> + <tr> + <td colspan="2"><textarea style="width:288px" rows="10" id="mediaeventlog"></textarea></td> + </tr> + + + <tr> + <td colspan="2"> + <b>Events logging: (not quite there yet)</b> + </td> + </tr> + <tr> + <td colspan="2"><div id="eventSelectors"> </div></td> + </tr> + + </table> +</div> + +<div style="width:500px;height:300px;display:block;position:relative"> + <video id="myVid" poster="http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/elephants-dream.jpg" + duration="10:53" preload="auto" controls> + <source type="video/h264" src="http://www.archive.org/download/ElephantsDream/ed_1024_512kb.mp4" > + <source type="video/ogg" src="http://www.archive.org/download/ElephantsDream/ed_hd.ogv" > + </video> +</div> + + +<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.3.min.js"></script> +<script type="text/javascript" src="../../../mwEmbedStartup.php"></script> +<script type="text/javascript"> + /* + Media Event Bindings + from http://www.w3.org/TR/html5/video.html + 4.8.9.12 Event summary + The following events fire on media elements as part of the processing model described above: + */ + var vid, + mediaEvents = [ + { event: 'loadstart', logMessage: 'The user agent has begun looking for media data, as part of the resource selection algorithm.' }, + { event: 'progress', logMessage: 'The user agent is fetching media data.' }, + { event: 'suspend', logMessage: 'The user agent is intentionally not currently fetching media data, but does not have the entire media resource downloaded.' }, + { event: 'abort', logMessage: 'The user agent stops fetching the media data before it is completely downloaded, but not due to an error.' }, + { event: 'error', logMessage: 'An error occurs while fetching the media data.' }, + { event: 'emptied', logMessage: "A media element whose networkState was previously not in the NETWORK_EMPTY state has just switched to that state (either because of a fatal error during load that's about to be reported, or because the load() method was invoked while the resource selection algorithm was already running)." }, + { event: 'stalled', logMessage: 'The user agent is trying to fetch media data, but data is unexpectedly not forthcoming.' }, + { event: 'play', logMessage: 'Playback has begun. Fired after the play() method has returned, or when the autoplay attribute has caused playback to begin.' }, + { event: 'pause', logMessage: 'Playback has been paused. Fired after the pause() method has returned.' }, + { event: 'loadedmetadata', logMessage: 'The user agent has just determined the duration and dimensions of the media resource' }, + { event: 'loadeddata', logMessage: 'The user agent can render the media data at the current playback position for the first time.' }, + { event: 'waiting', logMessage: 'Playback has stopped because the next frame is not available, but the user agent expects that frame to become available in due course.' }, + { event: 'playing', logMessage: 'Playback has started.' }, + { event: 'canplay', logMessage: 'The user agent can resume playback of the media data, but estimates that if playback were to be started now, the media resource could not be rendered at the current playback rate up to its end without having to stop for further buffering of content.' }, + { event: 'canplaythrough', logMessage: 'The user agent estimates that if playback were to be started now, the media resource could be rendered at the current playback rate all the way to its end without having to stop for further buffering.' }, + { event: 'seeking', logMessage: 'The seeking IDL attribute changed to true and the seek operation is taking long enough that the user agent has time to fire the event.' }, + { event: 'seeked', logMessage: 'The seeking IDL attribute changed to false.' }, + { event: 'timeupdate', logMessage: 'The current playback position changed as part of normal playback or in an especially interesting way, for example discontinuously.' }, + { event: 'ended', logMessage: 'Playback has stopped because the end of the media resource was reached.' }, + { event: 'ratechange', logMessage: 'Either the defaultPlaybackRate or the playbackRate attribute has just been updated.' }, + { event: 'durationchange', logMessage: 'The duration attribute has just been updated.' }, + { event: 'volumechange', logMessage: 'Either the volume attribute or the muted attribute has changed.' } + ]; + +// log to textarea +function logME(event) { + $('#mediaeventlog').append(event+'\n'); +} + + +// setup logging for an event or tear it down +function setLogging(event, isActive, message) { + if ( isActive === true ) { + $(mediaEvents).each(function (i, e) { + if ( e.event === event ) { + message = e.logMessage; + } + }); + $j('#myVid').bind( event, function() { logME('* ' + event + ' fired: ' + message); }); + } else { + $j('#myVid').unbind( event ); + } + +} + +mw.ready(function() { + + var vid = $j('#myVid'); + + // setup checkboxes to control logging + $(mediaEvents).each(function (i, e) { + var event = e.event; + var message = e.logMessage; + $('#eventSelectors').append('<input class="eventSelector" type=checkbox checked name="' + event +'">' + event + '</input><br />'); + setLogging(event, true, message); + }); + + //$('.eventSelector').each(function(i, s) { //change(console.log('changed')); + +// +//console.log(s); +// $(s).change('click'); +//}); + + //disable logging for timeupdate + setLogging('timeupdate', false); + $('input[name=timeupdate]').prop( 'checked', false ); + + logME('* the media player is ready'); + +}); + + +</script> + +</body> +</html> diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Seek.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Seek.html new file mode 100644 index 00000000..8c0f8e9d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Seek.html @@ -0,0 +1,35 @@ +<html> + <head> + <script type="text/javascript" src="../../../mwEmbedStartup.php"></script> + </head> + <body> + <h2>mwEmbed / archive.org server side seek</h2> + Start Playing at <input id="startTime" size="5" value ="50"></input> seconds. <input value="go" type="button" id="doPageSeek"></input></br> + <video id="vid1" poster="http://www.archive.org/download/night_of_the_living_dead/format=Thumbnail&x.jpg" + style="width:400px;height:300px" durationHint="5717.21"> + <source src="http://www.archive.org/download/night_of_the_living_dead/night_of_the_living_dead_512kb.mp4"/> + <source src="http://www.archive.org/download/night_of_the_living_dead/night_of_the_living_dead.ogv"/> + </video> + <script type="text/javascript"> + mw.ready( function(){ + // check for hash: + var urlParts = new mw.Uri ( document.URL); + if( urlParts.anchor ){ + // run the start offset: + var startTime = urlParts.anchor.split('=')[1]; + + //update the input box: + $j('#startTime').val( startTime ); + + // update current time then play: + $j('#vid1')[0].currentTime = startTime; + $j('#vid1')[0].play(); + } + // bind button: + $j('#doPageSeek').click(function(){ + document.location = 'Player_Seek.html?' + Math.random(1) + '#start=' + $j("#startTime").val(); + }); + }); + </script> + </body> +</html> diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSeek.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSeek.html new file mode 100644 index 00000000..6a9d7d04 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSeek.html @@ -0,0 +1,35 @@ +<html> + <head> + <script type="text/javascript" src="../../../mwEmbedStartup.php"></script> + </head> + <body> + <h2>mwEmbed / archive.org server side seek</h2> + Start Playing at <input id="startTime" size="5" value="50"></input> seconds. <input value="go" type="button" id="doPageSeek"></input></br> + <video id="vid1" poster="http://www.archive.org/download/night_of_the_living_dead/format=Thumbnail&x.jpg" + style="width:400px;height:300px" durationHint="5717.21"> + <source URLTimeEncoding='true' src="http://www.archive.org/download/night_of_the_living_dead/night_of_the_living_dead_512kb.mp4"/> + <source URLTimeEncoding='true' src="http://www.archive.org/download/night_of_the_living_dead/night_of_the_living_dead.ogv"/> + </video> + <script type="text/javascript"> + mw.ready( function(){ + // check for hash: + var urlParts = new mw.Uri( document.URL); + if( urlParts.anchor ){ + // run the start offset: + var startTime = urlParts.anchor.split('=')[1]; + + //update the input box: + $j('#startTime').val( startTime ); + + // update current time then play: + $j('#vid1')[0].currentTime = startTime; + $j('#vid1')[0].play(); + } + // bind button: + $j('#doPageSeek').click(function(){ + document.location = 'Player_ServerSeek.html?' + Math.random(1) + '#start=' + $j("#startTime").val(); + }); + }); + </script> + </body> +</html> diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSideSeek.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSideSeek.html new file mode 100644 index 00000000..26c87a6a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_ServerSideSeek.html @@ -0,0 +1,14 @@ +<html> + <head> + <script type="text/javascript" src="../../../mwEmbedStartup.php"></script> + </head> + <body> + <h2>mwEmbed / archive.org server side seek</h2> + + <video poster="http://www.archive.org/download/night_of_the_living_dead/format=Thumbnail&x.jpg" + style="width:400px;height:300px" durationHint="5717.21"> + <source URLTimeEncoding="true" src="http://www.archive.org/download/night_of_the_living_dead/night_of_the_living_dead_512kb.mp4"/> + <source URLTimeEncoding="true" src="http://www.archive.org/download/night_of_the_living_dead/night_of_the_living_dead.ogv"/> + </video> + </body> +</html> diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Sources.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Sources.html new file mode 100644 index 00000000..244ae1fa --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Sources.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>Player sources</title> + + <script type="text/javascript" src="../../../mwEmbedStartup.php"></script> +<!-- <script type="text/javascript" src="http://html5.kaltura.org/js"></script>--> + +<meta http-equiv="X-UA-Compatible" content="IE=9"/> +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> + +</head> +<body> + +<video id="vid1" width="480" height="267" + poster="http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/bbb480.jpg" + durationHint="33" + controls > + <source type="video/h264" src="http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/bbb_trailer_iphone.m4v"></source> + <source type="video/ogg" src="http://cdn.kaltura.org/apis/html5lib/kplayer-examples/media/bbb_trailer_400p.ogv"></source> +</video> + +</body> +</html> diff --git a/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Themable.html b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Themable.html new file mode 100644 index 00000000..d70b4084 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer/tests/Player_Themable.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" +"http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> + <title> Sample Themed Player </title> + Pre-loading demo ( stuff ) likely needed for video display + <!-- <script type="text/javascript" src="../../../ResourceLoader.php?debug=true&class=mwEmbed"></script> --> + <script type="text/javascript" src="../../../mwEmbedStartup.php"></script> + +</head> +<script type="text/javascript"> + // Show the controls ( this is a theme demo ) + mw.setConfig( 'EmbedPlayer.OverlayControls', false ); +</script> +<body> + +<h3> Sample Themable Player:</h3> +To play with dynamic Themes install <a href="http://jqueryui.com/themeroller/developertool/">Themeroller</a><p><p> + +<div style="width:450px;float:left"> +<video + style="width:400px;height:300px" + src="http://upload.wikimedia.org/wikipedia/commons/2/29/Charles_Lindbergh_flight_to_Brussels.ogg" + poster="http://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Charles_Lindbergh_flight_to_Brussels.ogg/mid-Charles_Lindbergh_flight_to_Brussels.ogg.jpg" + apiTitleKey="Charles_Lindbergh_flight_to_Brussels.ogg" + apiProvider="commons" + durationHint="60" > +</video> + +<video + style="width:208px;height:160px;float:left" + src="http://upload.wikimedia.org/wikipedia/commons/2/29/Charles_Lindbergh_flight_to_Brussels.ogg" + apiTitleKey="Charles_Lindbergh_flight_to_Brussels.ogg" + apiProvider="commons" + poster="http://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Charles_Lindbergh_flight_to_Brussels.ogg/mid-Charles_Lindbergh_flight_to_Brussels.ogg.jpg" + durationHint="60"> + </video> + +<b>Source Code used:</b><br> +<textarea cols="50" rows="7"><video style="width:400px;height:288px" poster="http://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Charles_Lindbergh_flight_to_Brussels.ogg/mid-Charles_Lindbergh_flight_to_Brussels.ogg.jpg" +src="http://upload.wikimedia.org/wikipedia/commons/2/29/Charles_Lindbergh_flight_to_Brussels.ogg"></video></textarea> +</div> + +<div style="width:450px;float:left"> +<video + class="kskin" + style="width:400px;height:300px" + src="http://upload.wikimedia.org/wikipedia/commons/2/29/Charles_Lindbergh_flight_to_Brussels.ogg" + apiTitleKey="Charles_Lindbergh_flight_to_Brussels.ogg" + apiProvider="commons" + poster="http://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Charles_Lindbergh_flight_to_Brussels.ogg/mid-Charles_Lindbergh_flight_to_Brussels.ogg.jpg" + durationHint="60"> +</video> +<video + class="kskin" + apiTitleKey="Charles_Lindbergh_flight_to_Brussels.ogg" + apiProvider="commons" + style="width:208px;height:160px;float:left;" src="http://upload.wikimedia.org/wikipedia/commons/2/29/Charles_Lindbergh_flight_to_Brussels.ogg" + poster="http://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Charles_Lindbergh_flight_to_Brussels.ogg/mid-Charles_Lindbergh_flight_to_Brussels.ogg.jpg" + durationHint="60"> +</video> + +<b>(kskin) Source Code used:</b><br> +<textarea cols="50" rows="7"><video class="kskin" style="width:400px;height:288px" poster="http://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Charles_Lindbergh_flight_to_Brussels.ogg/mid-Charles_Lindbergh_flight_to_Brussels.ogg.jpg" +src="http://upload.wikimedia.org/wikipedia/commons/2/29/Charles_Lindbergh_flight_to_Brussels.ogg"></video></textarea> +</div> + + +</body> +</html> + diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.config.php b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.config.php new file mode 100644 index 00000000..46547697 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.config.php @@ -0,0 +1,31 @@ +<?php + /** + * Do not edit this file instead use LocalSettings.php and + * $wgMwEmbedModuleConfig[ {configuration name} ] = value; format + */ + + return array( + // If the Timed Text interface should be displayed: + // 'always' Displays link and call to contribute always + // 'auto' Looks for child timed text elements or "apiTitleKey" & load interface + // 'off' Does not display the timed text interface + "TimedText.ShowInterface" => "auto", + + /** + * If the "add timed text" link / interface should be exposed + * allows usere to upload text files to the wiki + */ + 'TimedText.ShowAddTextLink' => false, + + // If the link to request a transcript should be shown on video files + 'TimedText.ShowRequestTranscript' => false, + + // The category for listing videos that need transcription: + 'TimedText.NeedsTranscriptCategory' => 'Videos needing subtitles', + + // The default bottom text padding + 'TimedText.BottomPadding' => 10, + + // Height of black box below video. + 'TimedText.BelowVideoBlackBoxHeight' => 40 + ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.loader.js b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.loader.js new file mode 100644 index 00000000..bbd62d0e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.loader.js @@ -0,0 +1,52 @@ +/** +* TimedText loader. +*/ +// Scope everything in "mw" ( keeps the global namespace clean ) +( function( mw, $ ) { + + /** + * Check if the video tags in the page support timed text + * this way we can add our timed text libraries to the player + * library request. + */ + // Update the player loader request with timedText library if the embedPlayer + // includes timedText tracks. + $( mw ).bind( 'EmbedPlayerUpdateDependencies', function( event, playerElement, classRequest ) { + if( mw.isTimedTextSupported( playerElement ) ) { + classRequest = $.merge( classRequest, ['mw.TimedText'] ); + } + } ); + // On new embed player check if we need to add timedText + $( mw ).bind( 'EmbedPlayerNewPlayer', function( event, embedPlayer ){ + if( mw.isTimedTextSupported( embedPlayer ) ){ + embedPlayer.timedText = new mw.TimedText( embedPlayer ); + } + }); + + /** + * Check timedText is active for a given embedPlayer + * @param {object} embedPlayer The player to be checked for timedText properties + */ + mw.isTimedTextSupported = function( embedPlayer ) { + //EmbedPlayerNewPlayer passes a div with data-mwprovider set, + //EmbedPlayerUpdateDependencies passes video element with data attribute + //catch both + var mwprovider = embedPlayer['data-mwprovider'] || $( embedPlayer ).data('mwprovider'); + var showInterface = mw.config.get( 'TimedText.ShowInterface.' + mwprovider ) || + mw.config.get( 'TimedText.ShowInterface' ); + + if ( showInterface == 'always' ) { + return true; + } else if ( showInterface == 'off' ) { + return false; + } + + // Check for standard 'track' attribute: + if ( $( embedPlayer ).find( 'track' ).length != 0 ) { + return true; + } else { + return false; + } + }; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.php b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.php new file mode 100644 index 00000000..57f50043 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/TimedText.php @@ -0,0 +1,21 @@ +<?php + + // Register all the timedText modules + return array( + "mw.TimedText" => array( + 'scripts' => "resources/mw.TimedText.js", + 'styles' => "resources/mw.style.TimedText.css", + 'dependencies' => array( + 'mw.EmbedPlayer', + 'mw.TextSource' + ), + 'messageDir' => 'i18n', + ), + "mw.TextSource" => array( + 'scripts' => "resources/mw.TextSource.js", + 'dependencies' => array( + 'mediawiki.UtilitiesTime', + "mw.ajaxProxy", + ) + ) + ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/af.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/af.json new file mode 100644 index 00000000..0024412a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/af.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Naudefj" + ] + }, + "mwe-timedtext-back-btn": "Terug", + "mwe-timedtext-textcat-cc": "Onderskrifte", + "mwe-timedtext-textcat-lrc": "Lirieke" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ar.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ar.json new file mode 100644 index 00000000..48597e00 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ar.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Meno25", + "Ų±ŁŲ®Ł" + ] + }, + "mwe-timedtext-back-btn": "Ų±Ų¬ŁŲ¹", + "mwe-timedtext-layout-off": "Ų„Ų®ŁŲ§Ų” Ų§ŁŲŖŲ±Ų¬Ł
Ų§ŲŖ", + "mwe-timedtext-loading-text": "Ų¬Ų§Ų±Ł ŲŖŲŁ
ŁŁ Ų§ŁŁŲµ...", + "mwe-timedtext-textcat-cc": "ŁŲµŁŲµ ŲŖŁŲ¶ŁŲŁŲ©", + "mwe-timedtext-textcat-cue": "ŁŁŲ§Ų· ŲŖŁŁ
ŁŲ", + "mwe-timedtext-upload-timed-text": "Ų„Ų¶Ų§ŁŲ© Ų§ŁŲŖŲ±Ų¬Ł
Ų§ŲŖ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ast.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ast.json new file mode 100644 index 00000000..9df51f24 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ast.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Xuacu" + ] + }, + "mwe-timedtext-back-btn": "Anterior", + "mwe-timedtext-layout-off": "Tapecer subtĆtulos", + "mwe-timedtext-loading-text": "Cargando'l testu...", + "mwe-timedtext-textcat-cc": "Lleendes", + "mwe-timedtext-textcat-sub": "SubtĆtulos", + "mwe-timedtext-textcat-tad": "DescripciĆ³n del sonĆu", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Testu en movimientu", + "mwe-timedtext-textcat-ar": "Rexones actives", + "mwe-timedtext-textcat-nb": "AnotaciĆ³n", + "mwe-timedtext-textcat-meta": "Metadatos cronometraos", + "mwe-timedtext-textcat-trx": "TrescripciĆ³n", + "mwe-timedtext-textcat-lrc": "Lletra", + "mwe-timedtext-textcat-lin": "Formatu llingĆ¼Ćsticu", + "mwe-timedtext-textcat-cue": "Puntos de referencia", + "mwe-timedtext-no-subs": "Nun hai pistes de testu disponibles", + "mwe-timedtext-language-subtitles-for-clip": "SubtĆtulos en $1 pal videu: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Nun s'alcontraron los subtĆtulos en $1 pal videu: $2", + "mwe-timedtext-upload-timed-text": "AƱadir subtĆtulos" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/be-tarask.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/be-tarask.json new file mode 100644 index 00000000..5c25527d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/be-tarask.json @@ -0,0 +1,28 @@ +{ + "@metadata": { + "authors": [ + "EugeneZelenko", + "Jim-by", + "Wizardist" + ] + }, + "mwe-timedtext-back-btn": "ŠŃŃŠ½ŃŃŃŠ°", + "mwe-timedtext-layout-off": "Š”Ń
Š°Š²Š°ŃŃ ŃŃŠ±ŃŃŃŃŃ", + "mwe-timedtext-loading-text": "ŠŠ°Š³ŃŃŠ·ŠŗŠ° ŃŃŠŗŃŃŃā¦", + "mwe-timedtext-textcat-cc": "Š”ŃŠ±ŃŃŃŃŃ", + "mwe-timedtext-textcat-sub": "Š”ŃŠ±ŃŃŃŃŃ:", + "mwe-timedtext-textcat-tad": "ŠŃŠ“ŃŃ-Š°ŠæŃŃŠ°Š½ŃŠ½Šµ", + "mwe-timedtext-textcat-ktv": "ŠŠ°ŃŠ°Š¾ŠŗŠµ", + "mwe-timedtext-textcat-tik": "Š¢ŃŠŗŃŃŠ°Š²ŃŃ ŠŗŠ°ŃŃŠŗŃ", + "mwe-timedtext-textcat-ar": "ŠŠŗŃŃŃŠ½ŃŃ ŃŃŠ³ŃŃŠ½Ń", + "mwe-timedtext-textcat-nb": "ŠŠ½Š°ŃŠ°ŃŃŃ", + "mwe-timedtext-textcat-meta": "Š”ŃŠ½Ń
ŃŠ°Š½ŃŠ·Š°Š²Š°Š½ŃŃ Š¼ŠµŃŠ°-Š·ŃŠ²ŠµŃŃŠŗŃ", + "mwe-timedtext-textcat-trx": "Š”ŃŃŠ½Š°Š³ŃŠ°Š¼Š°", + "mwe-timedtext-textcat-lrc": "Š”Š»Š¾Š²Ń", + "mwe-timedtext-textcat-lin": "ŠŃŠ½Š³Š²ŃŃŃŃŃŠ½Š°Ń ŃŠ°Š·ŃŠ¼ŠµŃŠŗŠ°", + "mwe-timedtext-textcat-cue": "Š”ŃŠ³Š½Š°Š»ŃŠ½ŃŃ ŠŗŃŠ¾ŠæŠŗŃ", + "mwe-timedtext-no-subs": "Š”ŃŠ±ŃŃŃŃŠ°Ń Š½ŃŠ¼Š°", + "mwe-timedtext-language-subtitles-for-clip": "$1 ŃŃŠ±ŃŃŃŃŃ Š“Š»Ń ŠŗŠ»ŃŠæŃ: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Š”ŃŠ±ŃŃŃŃŃ $1 Š“Š»Ń ŠŗŠ»ŃŠæŃ Š½Ń Š·Š½Š¾Š¹Š“Š·ŠµŠ½ŃŃ: $2", + "mwe-timedtext-upload-timed-text": "ŠŠ°Š“Š°ŃŃ ŃŃŠ±ŃŃŃŃŃ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bg.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bg.json new file mode 100644 index 00000000..b88de95d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bg.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "mwe-timedtext-back-btn": "ŠŠ°Š·Š°Š“" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bn.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bn.json new file mode 100644 index 00000000..395fbe7b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bn.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Aftab1995", + "Bellayet" + ] + }, + "mwe-timedtext-back-btn": "ą¦Ŗą¦æą¦ą¦Øą§", + "mwe-timedtext-layout-off": "ą¦ą¦Ŗą¦¶ą¦æą¦°ą§ą¦Øą¦¾ą¦® ą¦²ą§ą¦ą¦¾ą¦", + "mwe-timedtext-loading-text": "ą¦ą§ą¦ą§ą¦øą¦ ą¦²ą§ą¦” ą¦¹ą¦ą§ą¦ą§ ...", + "mwe-timedtext-textcat-cc": "ą¦Ŗą¦°ą¦æą¦ą¦Æą¦¼ą¦²ą¦æą¦Ŗą¦æ", + "mwe-timedtext-textcat-sub": "ą¦ą¦Ŗą¦¶ą¦æą¦°ą§ą¦Øą¦¾ą¦®", + "mwe-timedtext-textcat-tad": "ą¦
ą¦”ą¦æą¦ ą¦¬ą¦æą¦¬ą¦°ą¦£", + "mwe-timedtext-upload-timed-text": "ą¦ą¦Ŗą¦¶ą¦æą¦°ą§ą¦Øą¦¾ą¦® ą¦Æą§ą¦ą§ą¦¤ ą¦ą¦°ą§ą¦Ø" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/br.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/br.json new file mode 100644 index 00000000..eacd0f20 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/br.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Fulup", + "Y-M D" + ] + }, + "mwe-timedtext-back-btn": "DistreiƱ", + "mwe-timedtext-layout-off": "Kuzhat an istitloĆ¹", + "mwe-timedtext-loading-text": "O kargaƱ an destenn...", + "mwe-timedtext-textcat-cc": "Alc'hwezioĆ¹", + "mwe-timedtext-textcat-sub": "IstitloĆ¹", + "mwe-timedtext-textcat-tad": "Deskrivadur son", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Barenn titouroĆ¹", + "mwe-timedtext-textcat-ar": "RannvroioĆ¹ oberiant", + "mwe-timedtext-textcat-nb": "Notennadur", + "mwe-timedtext-textcat-meta": "MetaroadennoĆ¹ sinkronelaet", + "mwe-timedtext-textcat-trx": "TreuzskrivaƱ", + "mwe-timedtext-textcat-lrc": "KomzoĆ¹", + "mwe-timedtext-textcat-lin": "BalizennoĆ¹ yezhel", + "mwe-timedtext-textcat-cue": "Poent lec'hiaƱ", + "mwe-timedtext-language-subtitles-for-clip": "$1 istitl evit ar c'hlip : $2", + "mwe-timedtext-language-no-subtitles-for-clip": "N'eo ket bet kavet $1 istitl evit ar c'hlip : $2", + "mwe-timedtext-upload-timed-text": "EnporzhiaƱ istitloĆ¹" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bs.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bs.json new file mode 100644 index 00000000..f8d0cd23 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/bs.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "CERminator" + ] + }, + "mwe-timedtext-back-btn": "Nazad", + "mwe-timedtext-textcat-sub": "Podnaslovi", + "mwe-timedtext-textcat-tad": "Opis zvuka" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ca.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ca.json new file mode 100644 index 00000000..ce45bfb5 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ca.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Pitort" + ] + }, + "mwe-timedtext-back-btn": "Enrere", + "mwe-timedtext-textcat-sub": "SubtĆtols" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ce.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ce.json new file mode 100644 index 00000000..f1580f0d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ce.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Š£Š¼Š°Ń" + ] + }, + "mwe-timedtext-textcat-tad": "ŠŃŠ“ŠøŠ¾-Ń
Š°Š°Š¼" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/cs.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/cs.json new file mode 100644 index 00000000..94a5e7eb --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/cs.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Mormegil", + "Vks" + ] + }, + "mwe-timedtext-back-btn": "ZpÄt", + "mwe-timedtext-layout-off": "SkrĆ½t titulky", + "mwe-timedtext-loading-text": "NaÄĆtĆ” se textā¦", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-nb": "Anotace", + "mwe-timedtext-textcat-trx": "PÅepis", + "mwe-timedtext-language-subtitles-for-clip": "Titulky ke klipu $2 v jazyce $1", + "mwe-timedtext-language-no-subtitles-for-clip": "Ke klipu $2 nebyly nalezeny titulky v jazyce $1" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/cy.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/cy.json new file mode 100644 index 00000000..fd0eea45 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/cy.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Lloffiwr", + "Robin Owain" + ] + }, + "mwe-timedtext-back-btn": "Yn Ć“l", + "mwe-timedtext-layout-off": "Cuddio'r isdeitlau", + "mwe-timedtext-loading-text": "Yn llwytho'r testun...", + "mwe-timedtext-textcat-cc": "Geiriad", + "mwe-timedtext-textcat-sub": "Isdeitlau", + "mwe-timedtext-textcat-tad": "Disgrifiad o'r sain", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Testun", + "mwe-timedtext-textcat-ar": "Ardaloedd gweithredolo", + "mwe-timedtext-textcat-nb": "Anodiad", + "mwe-timedtext-textcat-meta": "Metadata a amserwyd", + "mwe-timedtext-textcat-trx": "Trawsysgrif", + "mwe-timedtext-textcat-lrc": "Geiriau", + "mwe-timedtext-textcat-cue": "Cerrig milltir", + "mwe-timedtext-no-subs": "Dim traciau testun ar gael", + "mwe-timedtext-language-subtitles-for-clip": "$1 isdeitl ar gael ar gyfer clip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Dim $1 isdeitl ar gael ar gyfer: $2", + "mwe-timedtext-upload-timed-text": "Ychwanegu isdeitlau" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/de-formal.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/de-formal.json new file mode 100644 index 00000000..10c9c650 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/de-formal.json @@ -0,0 +1,7 @@ +{ + "@metadata": { + "authors": [ + "Kghbln" + ] + } +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/de.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/de.json new file mode 100644 index 00000000..35d1cef9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/de.json @@ -0,0 +1,28 @@ +{ + "@metadata": { + "authors": [ + "Kghbln", + "Metalhead64", + "Purodha" + ] + }, + "mwe-timedtext-back-btn": "ZurĆ¼ck", + "mwe-timedtext-layout-off": "Untertitel ausblenden", + "mwe-timedtext-loading-text": "Text wird geladen ā¦", + "mwe-timedtext-textcat-cc": "Legenden", + "mwe-timedtext-textcat-sub": "Untertitel", + "mwe-timedtext-textcat-tad": "Beschreibung (Audio)", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Text-Ticker", + "mwe-timedtext-textcat-ar": "Aktive Regionen", + "mwe-timedtext-textcat-nb": "Annotation", + "mwe-timedtext-textcat-meta": "āTimed Textā-Metadaten", + "mwe-timedtext-textcat-trx": "Abschrift", + "mwe-timedtext-textcat-lrc": "Liedtext", + "mwe-timedtext-textcat-lin": "Sprachliche Beschreibung", + "mwe-timedtext-textcat-cue": "Cue-Punkte", + "mwe-timedtext-no-subs": "Es sind keine Untertitel verfĆ¼gbar", + "mwe-timedtext-language-subtitles-for-clip": "Untertitel auf $1 fĆ¼r den Videoclip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Keine Untertitel auf $1 fĆ¼r den Videoclip gefunden: $2", + "mwe-timedtext-upload-timed-text": "Untertitel hinzufĆ¼gen" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/diq.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/diq.json new file mode 100644 index 00000000..ee86ed2c --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/diq.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Erdemaslancan", + "Mirzali" + ] + }, + "mwe-timedtext-back-btn": "Peyser", + "mwe-timedtext-textcat-cc": "BınnuÅte", + "mwe-timedtext-textcat-sub": "SernuÅtey bıni", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-nb": "Ole Åınasiye" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/dsb.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/dsb.json new file mode 100644 index 00000000..362d95c8 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/dsb.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "Derbeth", + "Michawiki" + ] + }, + "mwe-timedtext-back-btn": "SlÄdk", + "mwe-timedtext-layout-off": "PĆ³dtitele schowaÅ", + "mwe-timedtext-loading-text": "Tekst se zacytujo...", + "mwe-timedtext-textcat-cc": "Wopisanja", + "mwe-timedtext-textcat-sub": "PĆ³dtitele", + "mwe-timedtext-textcat-tad": "Awdiowopisanje", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "BÄžecy tekst", + "mwe-timedtext-textcat-ar": "Aktiwne regiony", + "mwe-timedtext-textcat-nb": "Anotacija", + "mwe-timedtext-textcat-meta": "SynchronizÄrowane metadaty", + "mwe-timedtext-textcat-trx": "PÅepisaÅ", + "mwe-timedtext-textcat-lrc": "Spiwny tekst", + "mwe-timedtext-textcat-lin": "RÄcywÄdne wopisanje", + "mwe-timedtext-textcat-cue": "Zastupne dypki", + "mwe-timedtext-no-subs": "Žedne pĆ³dtitele k dispoziciji", + "mwe-timedtext-language-subtitles-for-clip": "$1 {{PLURAL:$1|pĆ³dtitel|pĆ³dtitela|pĆ³dtitele|oĆ³dtitelow}} za klip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Žedne pĆ³dtitele $1 su se za klip namakali: $2", + "mwe-timedtext-upload-timed-text": "PĆ³dtitele pÅidaÅ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/el.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/el.json new file mode 100644 index 00000000..9de04eff --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/el.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Geraki" + ] + }, + "mwe-timedtext-back-btn": "ĪĻĪ¹ĻĻĻĪæĻĪ®", + "mwe-timedtext-layout-off": "ĪĻĻĪŗĻĻ
ĻĪ· Ļ
ĻĻĻĪ¹ĻĪ»ĻĪ½", + "mwe-timedtext-loading-text": "Ī¦ĻĻĻĻĻĪ· ĪŗĪµĪÆĪ¼ĪµĪ½ĪæĻ
...", + "mwe-timedtext-textcat-cc": "ĪĪµĪ¶Ī¬Ī½ĻĪµĻ", + "mwe-timedtext-textcat-sub": "Ī„ĻĻĻĪ¹ĻĪ»ĪæĪ¹", + "mwe-timedtext-textcat-tad": "ĪĪŗĪæĻ
ĻĻĪ¹ĪŗĪ® ĻĪµĻĪ¹Ī³ĻĪ±ĻĪ®", + "mwe-timedtext-textcat-ktv": "ĪĪ±ĻĪ±ĻĪŗĪµ", + "mwe-timedtext-textcat-tik": "ĪĻ
Ī»Ī¹ĻĪ¼ĪµĪ½Īæ ĪŗĪµĪÆĪ¼ĪµĪ½Īæ", + "mwe-timedtext-textcat-ar": "ĪĪ½ĪµĻĪ³ĪĻ ĻĪµĻĪ¹ĪæĻĪĻ", + "mwe-timedtext-textcat-nb": "Ī£ĻĻĪ»Ī¹Īæ", + "mwe-timedtext-textcat-meta": "Ī§ĻĪæĪ½Ī¹ĻĪ¼ĪĪ½Ī± Ī¼ĪµĻĪ±Ī“ĪµĪ“ĪæĪ¼ĪĪ½Ī±", + "mwe-timedtext-textcat-trx": "ĪĪµĻĪ±Ī³ĻĪ±ĻĪ®", + "mwe-timedtext-textcat-lrc": "Ī£ĻĪÆĻĪæĪ¹", + "mwe-timedtext-textcat-lin": "ĪĪ»ĻĻĻĪæĪ»ĪæĪ³Ī¹ĪŗĪ® ĻĻĪ½ĻĪ±Ī¾Ī·", + "mwe-timedtext-textcat-cue": "Cue points", + "mwe-timedtext-language-subtitles-for-clip": "$1 Ļ
ĻĻĻĪ¹ĻĪ»ĪæĪ¹ Ī³Ī¹Ī± ĻĪæ Ī²ĪÆĪ½ĻĪµĪæ: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "ĪĪµĪ½ Ī²ĻĪĪøĪ·ĪŗĪ±Ī½ Ļ
ĻĻĻĪ¹ĻĪ»ĪæĪ¹ $1 Ī³Ī¹Ī± ĻĪæ Ī²ĪÆĪ½ĻĪµĪæ: $2" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/en.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/en.json new file mode 100644 index 00000000..0505d5b7 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/en.json @@ -0,0 +1,25 @@ +{ + "@metadata": { + "authors": [] + }, + "mwe-timedtext-back-btn": "Back", + "mwe-timedtext-layout-off": "Hide subtitles", + "mwe-timedtext-loading-text": "Loading text ...", + "mwe-timedtext-key-language": "$1, $2", + "mwe-timedtext-textcat-cc": "Captions", + "mwe-timedtext-textcat-sub": "Subtitles", + "mwe-timedtext-textcat-tad": "Audio description", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Ticker text", + "mwe-timedtext-textcat-ar": "Active regions", + "mwe-timedtext-textcat-nb": "Annotation", + "mwe-timedtext-textcat-meta": "Timed metadata", + "mwe-timedtext-textcat-trx": "Transcript", + "mwe-timedtext-textcat-lrc": "Lyrics", + "mwe-timedtext-textcat-lin": "Linguistic markup", + "mwe-timedtext-textcat-cue": "Cue points", + "mwe-timedtext-no-subs": "No text tracks available", + "mwe-timedtext-language-subtitles-for-clip": "$1 subtitles for clip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "No $1 subtitles were found for clip: $2", + "mwe-timedtext-upload-timed-text": "Add subtitles" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/eo.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/eo.json new file mode 100644 index 00000000..f787b8a6 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/eo.json @@ -0,0 +1,7 @@ +{ + "@metadata": { + "authors": [ + "Yekrats" + ] + } +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/es.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/es.json new file mode 100644 index 00000000..e753ece1 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/es.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Armando-Martin", + "Crazymadlover", + "Locos epraix", + "Pertile", + "Translationista" + ] + }, + "mwe-timedtext-back-btn": "AtrĆ”s", + "mwe-timedtext-layout-off": "Ocultar subtĆtulos", + "mwe-timedtext-loading-text": "Cargando texto ...", + "mwe-timedtext-textcat-cc": "Leyendas", + "mwe-timedtext-textcat-sub": "SubtĆtulos", + "mwe-timedtext-textcat-tad": "DescripciĆ³n de audio", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Texto desplazable", + "mwe-timedtext-textcat-ar": "Regiones activas", + "mwe-timedtext-textcat-nb": "AnotaciĆ³n", + "mwe-timedtext-textcat-meta": "Metadatos sincronizados", + "mwe-timedtext-textcat-trx": "Transcribir", + "mwe-timedtext-textcat-lrc": "Letra", + "mwe-timedtext-textcat-lin": "Marcador lingĆ¼Ćstico", + "mwe-timedtext-textcat-cue": "Puntos de referencia", + "mwe-timedtext-no-subs": "No hay pistas de texto disponibles", + "mwe-timedtext-language-subtitles-for-clip": "$1 subtĆtulos para el clip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "No se ha encontrado subtĆtulos $1 para el clip: $2", + "mwe-timedtext-upload-timed-text": "AƱadir subtĆtulos" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/et.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/et.json new file mode 100644 index 00000000..a57273aa --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/et.json @@ -0,0 +1,18 @@ +{ + "@metadata": { + "authors": [ + "Avjoska", + "Pikne" + ] + }, + "mwe-timedtext-layout-off": "Peida alltiitrid", + "mwe-timedtext-loading-text": "Teksti laadimine...", + "mwe-timedtext-textcat-sub": "Alltiitrid", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-meta": "Ajastatud metaandmed", + "mwe-timedtext-textcat-lrc": "LaulusƵnad", + "mwe-timedtext-no-subs": "Alltiitreid pole saadaval", + "mwe-timedtext-language-subtitles-for-clip": "LƵigu $2 $1 alltiitrid", + "mwe-timedtext-language-no-subtitles-for-clip": "LƵigu $2 jaoks ei leitud $1 alltiitreid", + "mwe-timedtext-upload-timed-text": "Lisa alltiitrid" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/eu.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/eu.json new file mode 100644 index 00000000..5c30fe9d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/eu.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ", + "Subi" + ] + }, + "mwe-timedtext-back-btn": "Atzera", + "mwe-timedtext-textcat-ktv": "Karaokea" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fa.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fa.json new file mode 100644 index 00000000..c6fa166e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fa.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Armin1392", + "Ebraminio", + "Pouyana", + "Reza1615", + "Ł¾Ų§ŁŲ§Ų±ŁŁ
Ų§" + ] + }, + "mwe-timedtext-back-btn": "ŲØŲ§Ų²ŚÆŲ“ŲŖ", + "mwe-timedtext-layout-off": "Ł¾ŁŁŲ§Ł Ś©Ų±ŲÆŁ Ų²ŪŲ±ŁŁŪŲ³", + "mwe-timedtext-loading-text": "ŲÆŲ± ŲŲ§Ł ŲØŲ§Ų±ŚÆŪŲ±Ū Ł
ŲŖŁ ...", + "mwe-timedtext-textcat-cc": "Ų¹ŁŲ§ŁŪŁ:", + "mwe-timedtext-textcat-sub": "Ų²ŪŲ±ŁŁŪŲ³", + "mwe-timedtext-textcat-tad": "ŲŖŁŲ¶ŪŲ ŲµŁŲŖŪ", + "mwe-timedtext-textcat-ktv": "Ś©Ų§Ų±Ų§Ų¦ŁŚ©Ł", + "mwe-timedtext-textcat-tik": "Ł
ŲŖŁ ŲŖŪŚ©Ų±", + "mwe-timedtext-textcat-ar": "Ł
ŁŲ§Ų·Ł ŁŲ¹Ų§Ł", + "mwe-timedtext-textcat-nb": "ŪŲ§ŲÆŲÆŲ§Ų“ŲŖ", + "mwe-timedtext-textcat-meta": "ŁŲ±Ų§ŲÆŲ§ŲÆŁŁ ŲØŁ ŁŁŚÆŲ§Ł
", + "mwe-timedtext-textcat-trx": "Ų±ŁŁŁŲ“ŲŖ", + "mwe-timedtext-textcat-lrc": "Ł
ŲŖŁ ŲŖŲ±Ų§ŁŁāŁŲ§", + "mwe-timedtext-textcat-lin": "Ų²ŲØŲ§Ł ŁŲ“Ų§ŁŁāŚÆŲ°Ų§Ų±Ū", + "mwe-timedtext-textcat-cue": "ŁŁŲ§Ų· ŁŲ“Ų§ŁŁ", + "mwe-timedtext-no-subs": "ŁŪŚ Ų¢ŁŁŚÆ Ł
ŲŖŁŪ ŲÆŲ±ŲÆŲ³ŲŖŲ±Ų³ ŁŪŲ³ŲŖ", + "mwe-timedtext-language-subtitles-for-clip": "$1 Ų²ŪŲ±ŁŁŪŲ³ ŲØŲ±Ų§Ū Ś©ŁŪŁ¾: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "ŁŪŚ $1 Ų²ŪŲ±ŁŁŪŲ³Ū ŲØŲ±Ų§Ū Ś©ŁŪŁ¾ Ł¾ŪŲÆŲ§ ŁŲ“ŲÆ: $2", + "mwe-timedtext-upload-timed-text": "Ų§Ų¶Ų§ŁŁ Ś©Ų±ŲÆŁ Ų²ŪŲ±ŁŁŪŲ³" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fi.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fi.json new file mode 100644 index 00000000..e0fa5944 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fi.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Nedergard", + "Nike", + "Silvonen" + ] + }, + "mwe-timedtext-back-btn": "Takaisin", + "mwe-timedtext-layout-off": "Piilota tekstitys", + "mwe-timedtext-loading-text": "Ladataan tekstiƤ...", + "mwe-timedtext-textcat-cc": "Kuvatekstit", + "mwe-timedtext-textcat-sub": "Tekstitykset", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-upload-timed-text": "LisƤƤ tekstitys" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fr.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fr.json new file mode 100644 index 00000000..4e74e546 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fr.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "IAlex", + "Peter17", + "Tititou36", + "Verdy p" + ] + }, + "mwe-timedtext-back-btn": "ArriĆØre", + "mwe-timedtext-layout-off": "Masquer les sous-titres", + "mwe-timedtext-loading-text": "Chargement du texte ...", + "mwe-timedtext-textcat-cc": "LĆ©gendes", + "mwe-timedtext-textcat-sub": "Sous-titres", + "mwe-timedtext-textcat-tad": "Description audio", + "mwe-timedtext-textcat-ktv": "KaraokĆ©", + "mwe-timedtext-textcat-tik": "Barre d'informations", + "mwe-timedtext-textcat-ar": "RĆ©gions actives", + "mwe-timedtext-textcat-nb": "Annotation", + "mwe-timedtext-textcat-meta": "mĆ©tadonnĆ©es synchronisĆ©es", + "mwe-timedtext-textcat-trx": "Transcription", + "mwe-timedtext-textcat-lrc": "Paroles", + "mwe-timedtext-textcat-lin": "Balisage linguistique", + "mwe-timedtext-textcat-cue": "Points de repĆØre", + "mwe-timedtext-no-subs": "Aucun texte de piste disponible", + "mwe-timedtext-language-subtitles-for-clip": "$1 sous-titres pour clip : $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Aucun sous-titre $1 n'a Ć©tĆ© trouvĆ© pour le clip : $2", + "mwe-timedtext-upload-timed-text": "Ajouter des sous-titres" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/frp.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/frp.json new file mode 100644 index 00000000..eeb629b9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/frp.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "ChrisPtDe" + ] + }, + "mwe-timedtext-back-btn": "Tornar", + "mwe-timedtext-layout-off": "CachiĆ©r los sot-titros", + "mwe-timedtext-loading-text": "Chargement du tĆØxto ...", + "mwe-timedtext-textcat-cc": "LĆØgendes", + "mwe-timedtext-textcat-sub": "Sot-titros", + "mwe-timedtext-textcat-tad": "DĆØscripcion Ć“diĆ“", + "mwe-timedtext-textcat-ktv": "CaraoquĆØ", + "mwe-timedtext-textcat-tik": "BĆ¢rra dāenformacions", + "mwe-timedtext-textcat-ar": "RĆØgĀ·ions actives", + "mwe-timedtext-textcat-nb": "Nota", + "mwe-timedtext-textcat-meta": "MĆØtabalyĆŖs sincronisĆ¢s", + "mwe-timedtext-textcat-trx": "Transcripcion", + "mwe-timedtext-textcat-lrc": "Paroles", + "mwe-timedtext-textcat-lin": "BalisĆ¢jo lengouistico", + "mwe-timedtext-textcat-cue": "Pouents de repĆØro", + "mwe-timedtext-no-subs": "Gins de pista de tĆØxto disponibla", + "mwe-timedtext-language-subtitles-for-clip": "$1 sot-titros por clipe : $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Nion sot-titro $1 at Ć©tĆ¢ trovĆ¢ por lo clipe : $2", + "mwe-timedtext-upload-timed-text": "Apondre des sot-titros" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fy.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fy.json new file mode 100644 index 00000000..69f89218 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/fy.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Robin0van0der0vliet" + ] + }, + "mwe-timedtext-back-btn": "Foarige" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/gl.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/gl.json new file mode 100644 index 00000000..df9d0409 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/gl.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "ToliƱo" + ] + }, + "mwe-timedtext-back-btn": "Volver", + "mwe-timedtext-layout-off": "Agochar os subtĆtulos", + "mwe-timedtext-loading-text": "Cargando o texto...", + "mwe-timedtext-textcat-cc": "PĆ©s de foto", + "mwe-timedtext-textcat-sub": "SubtĆtulos", + "mwe-timedtext-textcat-tad": "DescriciĆ³n do son", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Barra de informaciĆ³n", + "mwe-timedtext-textcat-ar": "RexiĆ³ns activas", + "mwe-timedtext-textcat-nb": "AnotaciĆ³n", + "mwe-timedtext-textcat-meta": "Metadatos sincronizados", + "mwe-timedtext-textcat-trx": "TranscriciĆ³n", + "mwe-timedtext-textcat-lrc": "Letra", + "mwe-timedtext-textcat-lin": "Formato lingĆ¼Ćstico", + "mwe-timedtext-textcat-cue": "Puntos de sinal", + "mwe-timedtext-no-subs": "Non hai pistas de texto dispoƱibles", + "mwe-timedtext-language-subtitles-for-clip": "SubtĆtulos en $1 para o vĆdeo: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Non se atoparon os subtĆtulos en $1 para o vĆdeo: $2", + "mwe-timedtext-upload-timed-text": "Engadir subtĆtulos" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/gsw.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/gsw.json new file mode 100644 index 00000000..c48c3c0c --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/gsw.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "Als-ChlƤmens", + "Als-Holder" + ] + }, + "mwe-timedtext-back-btn": "Zruck", + "mwe-timedtext-layout-off": "Untertitel uusblƤnde", + "mwe-timedtext-loading-text": "Am Lade vum Text ...", + "mwe-timedtext-textcat-cc": "Bschryybige", + "mwe-timedtext-textcat-sub": "Untertitel", + "mwe-timedtext-textcat-tad": "Audio-Bschryybig", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Text-Ticker", + "mwe-timedtext-textcat-ar": "Aktivi Regione", + "mwe-timedtext-textcat-nb": "Aamerkig", + "mwe-timedtext-textcat-meta": "Ćchtzyt-Metadate", + "mwe-timedtext-textcat-trx": "Abschrift", + "mwe-timedtext-textcat-lrc": "Liedtext", + "mwe-timedtext-textcat-lin": "Sprochwisseschaftligi Bschryybig", + "mwe-timedtext-textcat-cue": "Cue-Pinkt", + "mwe-timedtext-no-subs": "Untertitel sin nit verfiegbar", + "mwe-timedtext-language-subtitles-for-clip": "$1 Untertitel gfunde fir dr Videoclip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Kei $1 Untertitel gfunde fir dr Videoclip: $2", + "mwe-timedtext-upload-timed-text": "Untertitel uffelade" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/he.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/he.json new file mode 100644 index 00000000..5137aa27 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/he.json @@ -0,0 +1,28 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Guycn2", + "YaronSh" + ] + }, + "mwe-timedtext-back-btn": "×××Ø×", + "mwe-timedtext-layout-off": "××”×Ŗ×Ø×Ŗ ××Ŗ×××××Ŗ", + "mwe-timedtext-loading-text": "××¢×× ×Ŗ ×קה×...", + "mwe-timedtext-textcat-cc": "×××Ŗ×Ø××Ŗ", + "mwe-timedtext-textcat-sub": "××Ŗ×××××Ŗ", + "mwe-timedtext-textcat-tad": "×Ŗ××××Ø ×ש××¢", + "mwe-timedtext-textcat-ktv": "ק×Ø××ק×", + "mwe-timedtext-textcat-tik": "שפ×Ŗ ×ש××Ø× ××Øצ×", + "mwe-timedtext-textcat-ar": "××××Ø×× ×¤×¢××××", + "mwe-timedtext-textcat-nb": "פ×Ø×©× ××Ŗ", + "mwe-timedtext-textcat-meta": "×××Ö¾××Ŗ×× ×× ××Ŗ×××× ××", + "mwe-timedtext-textcat-trx": "×Ŗ××××", + "mwe-timedtext-textcat-lrc": "×××××Ŗ ×ש××Ø", + "mwe-timedtext-textcat-lin": "×”×××× ×××©× ×", + "mwe-timedtext-textcat-cue": "× ×§××××Ŗ ×”××× ××Ŗ", + "mwe-timedtext-no-subs": "××× ×Øצ××¢×Ŗ ×Ŗ×××× ×××× ×", + "mwe-timedtext-language-subtitles-for-clip": "××Ŗ×××××Ŗ ×{{grammar:×Ŗ×××××Ŗ|$1}} ×¢×××Ø ××”×Ø××× $2", + "mwe-timedtext-language-no-subtitles-for-clip": "×× × ×צ×× ××Ŗ×××××Ŗ ×{{grammar:×Ŗ×××××Ŗ|$1}} ×¢×××Ø $2", + "mwe-timedtext-upload-timed-text": "××הפ×Ŗ ××Ŗ×××××Ŗ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/hsb.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/hsb.json new file mode 100644 index 00000000..325044d8 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/hsb.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Michawiki" + ] + }, + "mwe-timedtext-back-btn": "WrĆ³Äo", + "mwe-timedtext-layout-off": "Podtitule schowaÄ", + "mwe-timedtext-loading-text": "Tekst so zaÄituje...", + "mwe-timedtext-textcat-cc": "Nadpisma", + "mwe-timedtext-textcat-sub": "Podtitule", + "mwe-timedtext-textcat-tad": "Awdiowopisanje", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Tekstowy bÄžacy pask", + "mwe-timedtext-textcat-ar": "Aktiwne regiony", + "mwe-timedtext-textcat-nb": "Anotacija", + "mwe-timedtext-textcat-meta": "Synchronizowane metadaty", + "mwe-timedtext-textcat-trx": "PÅepis", + "mwe-timedtext-textcat-lrc": "SpÄwowy tekst", + "mwe-timedtext-textcat-lin": "RÄÄespytne wopisanje", + "mwe-timedtext-textcat-cue": "Zastupne dypki", + "mwe-timedtext-no-subs": "Žane podtitule k dispoziciji", + "mwe-timedtext-language-subtitles-for-clip": "$1 {{PLURAL:$1|podtitul|podtitulej|podtitule|podtitulow}} za klip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Žane podtitule $1 za klip namakane: $2", + "mwe-timedtext-upload-timed-text": "Podtitule pÅidaÄ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/hu.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/hu.json new file mode 100644 index 00000000..a5eb9692 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/hu.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Dani", + "Glanthor Reviol", + "Misibacsi" + ] + }, + "mwe-timedtext-back-btn": "Vissza", + "mwe-timedtext-layout-off": "Feliratok elrejtĆ©se", + "mwe-timedtext-loading-text": "Szƶveg betƶltĆ©seā¦", + "mwe-timedtext-textcat-cc": "Feliratok", + "mwe-timedtext-textcat-sub": "Felirat", + "mwe-timedtext-textcat-tad": "Hang leĆrĆ”sa", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-ar": "AktĆv rĆ©giĆ³k", + "mwe-timedtext-textcat-nb": "AnnotĆ”ciĆ³", + "mwe-timedtext-textcat-meta": "IdÅzĆtett metaadatok", + "mwe-timedtext-textcat-trx": "Ćtirat", + "mwe-timedtext-textcat-lrc": "Dalszƶveg", + "mwe-timedtext-textcat-lin": "Nyelvi jelƶlĆ©s", + "mwe-timedtext-upload-timed-text": "Felirat hozzĆ”adĆ”sa" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ia.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ia.json new file mode 100644 index 00000000..624dc45d --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ia.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "McDutchie" + ] + }, + "mwe-timedtext-back-btn": "Retornar", + "mwe-timedtext-layout-off": "Celar subtitulos", + "mwe-timedtext-loading-text": "Carga textoā¦", + "mwe-timedtext-textcat-cc": "Subtitulos", + "mwe-timedtext-textcat-sub": "Subtitulos", + "mwe-timedtext-textcat-tad": "Description audio", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Barra de information", + "mwe-timedtext-textcat-ar": "Regiones active", + "mwe-timedtext-textcat-nb": "Annotation", + "mwe-timedtext-textcat-meta": "Metadatos de synchronisation", + "mwe-timedtext-textcat-trx": "Transcription", + "mwe-timedtext-textcat-lrc": "Lyricos", + "mwe-timedtext-textcat-lin": "Marcation lingusitic", + "mwe-timedtext-textcat-cue": "Punctos de entrata", + "mwe-timedtext-no-subs": "Subtitulos non disponibile", + "mwe-timedtext-language-subtitles-for-clip": "Subtitulos in $1 pro le clip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Nulle subtitulos in $1 ha essite trovate pro le clip: $2", + "mwe-timedtext-upload-timed-text": "Adder subtitulos" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/id.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/id.json new file mode 100644 index 00000000..12a35bd7 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/id.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "Farras", + "IvanLanin" + ] + }, + "mwe-timedtext-back-btn": "Kembali", + "mwe-timedtext-layout-off": "Sembunyikan subjudul", + "mwe-timedtext-loading-text": "Memuat teks ...", + "mwe-timedtext-textcat-cc": "Keterangan", + "mwe-timedtext-textcat-sub": "Subjudul", + "mwe-timedtext-textcat-tad": "Deskripsi audio", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Teks tik", + "mwe-timedtext-textcat-ar": "Wilayah aktif", + "mwe-timedtext-textcat-nb": "Anotasi", + "mwe-timedtext-textcat-meta": "Data meta berjangka waktu", + "mwe-timedtext-textcat-trx": "Transkrip", + "mwe-timedtext-textcat-lrc": "Lirik", + "mwe-timedtext-textcat-lin": "Ubahan linguistik", + "mwe-timedtext-textcat-cue": "Titik acuan", + "mwe-timedtext-no-subs": "Jalur teks tidak tersedia", + "mwe-timedtext-language-subtitles-for-clip": "Subjudul $1 untuk klip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Tidak ada subjudul $1 yang ditemukan untuk klip: $2", + "mwe-timedtext-upload-timed-text": "Unggah teks film" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/it.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/it.json new file mode 100644 index 00000000..4e2fad3a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/it.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "Beta16", + "Darth Kule", + "F. Cosoleto", + "Gianfranco" + ] + }, + "mwe-timedtext-back-btn": "Indietro", + "mwe-timedtext-layout-off": "Nascondi sottotitoli", + "mwe-timedtext-loading-text": "Caricamento testo...", + "mwe-timedtext-textcat-cc": "Didascalie", + "mwe-timedtext-textcat-sub": "Sottotitoli", + "mwe-timedtext-textcat-tad": "Descrizione audio", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Testo in movimento", + "mwe-timedtext-textcat-ar": "Regioni attive", + "mwe-timedtext-textcat-nb": "Annotazione", + "mwe-timedtext-textcat-meta": "Metadati temporizzati", + "mwe-timedtext-textcat-trx": "Trascrizione", + "mwe-timedtext-textcat-lrc": "Testi", + "mwe-timedtext-textcat-lin": "Markup linguistico", + "mwe-timedtext-textcat-cue": "Punti d'entrata", + "mwe-timedtext-no-subs": "Nessuna traccia di testo disponibile", + "mwe-timedtext-language-subtitles-for-clip": "sottotitoli in $1 per il filmato: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Sottotitoli in $1 non trovati per il filmato: $2", + "mwe-timedtext-upload-timed-text": "Aggiungi sottotitoli" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ja.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ja.json new file mode 100644 index 00000000..7e048693 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ja.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "Aotake", + "Hosiryuhosi", + "Shirayuki", + "Yanajin66", + "éåå®ę" + ] + }, + "mwe-timedtext-back-btn": "ę»ć", + "mwe-timedtext-layout-off": "åå¹ćé ć", + "mwe-timedtext-loading-text": "ććć¹ćć®čŖćæč¾¼ćæäø...", + "mwe-timedtext-textcat-cc": "č¦åŗć", + "mwe-timedtext-textcat-sub": "åå¹", + "mwe-timedtext-textcat-tad": "é³å£°ć®čŖ¬ę", + "mwe-timedtext-textcat-ktv": "ć«ć©ćŖć±", + "mwe-timedtext-textcat-tik": "ćć£ćć«ć¼ęē« ", + "mwe-timedtext-textcat-ar": "ć¢ćÆćć£ććŖé å", + "mwe-timedtext-textcat-nb": "ę³Øé", + "mwe-timedtext-textcat-meta": "ęéć”ćæćć¼ćæ", + "mwe-timedtext-textcat-trx": "č¤å", + "mwe-timedtext-textcat-lrc": "ęč©", + "mwe-timedtext-textcat-lin": "čØčŖćć¼ćÆ", + "mwe-timedtext-textcat-cue": "ćć„ć¼ćć¤ć³ć", + "mwe-timedtext-language-subtitles-for-clip": "ćÆćŖćć $2 ć®$1åå¹", + "mwe-timedtext-language-no-subtitles-for-clip": "ćÆćŖćć $2 ć«ćÆ$1åå¹ćććć¾ćć", + "mwe-timedtext-upload-timed-text": "åå¹ćčæ½å " +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ka.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ka.json new file mode 100644 index 00000000..05eb95f5 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ka.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "David1010" + ] + }, + "mwe-timedtext-back-btn": "į£įįį", + "mwe-timedtext-layout-off": "į”į£įį¢įį¢į įįįį” įįįįįįį", + "mwe-timedtext-loading-text": "įį¢įįį įįįį į¢įį„į”į¢į ...", + "mwe-timedtext-textcat-cc": "į¬įį į¬įį įįį", + "mwe-timedtext-textcat-sub": "į”į£įį¢įį¢į įįį", + "mwe-timedtext-textcat-tad": "įį£įįį įį¦į¬įį į", + "mwe-timedtext-textcat-ktv": "įįį įįįį", + "mwe-timedtext-textcat-tik": "į¢įį„į”į¢į£į į įįį įįįįį", + "mwe-timedtext-textcat-ar": "įį„į¢įį£į į į įįįįįįįį", + "mwe-timedtext-textcat-nb": "įįįį¢įįŖįį", + "mwe-timedtext-textcat-meta": "į”įįį„į įįįįįį įįį£įį įįį¢įįįįįįŖįįįįį", + "mwe-timedtext-textcat-trx": "į”į¢įįįįį įįį", + "mwe-timedtext-textcat-lrc": "į”įįį¦įį įį” į¢įį„į”į¢įįį", + "mwe-timedtext-textcat-lin": "įįįįįįį”į¢į£į į įįįįįįį¢į", + "mwe-timedtext-textcat-cue": "įįįØįį£įį į¬įį į¢įįįįį", + "mwe-timedtext-language-subtitles-for-clip": "$1 į”į£įį¢įį¢į įįį įįįįįį”įįįįį”: $2", + "mwe-timedtext-upload-timed-text": "į”į£įį¢įį¢į įįįį” įįįįį¢įįį" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ko.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ko.json new file mode 100644 index 00000000..9b4faaf5 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ko.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "ģė¼" + ] + }, + "mwe-timedtext-back-btn": "ė¤ė”", + "mwe-timedtext-layout-off": "ģė§ ģØźø°źø°", + "mwe-timedtext-loading-text": "ķ
ģ¤ķø ė¶ė¬ģ¤ė ģ¤ ...", + "mwe-timedtext-textcat-cc": "ģ¤ėŖ
", + "mwe-timedtext-textcat-sub": "ģė§", + "mwe-timedtext-textcat-tad": "ģė¦¬ ģ¤ėŖ
", + "mwe-timedtext-textcat-ktv": "ź°ė¼ģ¤ģ¼", + "mwe-timedtext-textcat-tik": "ķģźø° ė¬øģ", + "mwe-timedtext-textcat-ar": "ķģ± ģģ", + "mwe-timedtext-textcat-nb": "ģ£¼ģ", + "mwe-timedtext-textcat-meta": "ģź° ė©ķė°ģ“ķ°", + "mwe-timedtext-textcat-trx": "ė³µģ¬", + "mwe-timedtext-textcat-lrc": "ź°ģ¬", + "mwe-timedtext-textcat-lin": "ģøģ“ ė§ķ¬ģ
", + "mwe-timedtext-textcat-cue": "ķ ķ¬ģøķø", + "mwe-timedtext-no-subs": "ģ¬ģ©ķ ģ ģė ķ
ģ¤ķø ķøėģ“ ģģµėė¤", + "mwe-timedtext-language-subtitles-for-clip": "ķ“ė¦½ģ ėķ $1 ģė§: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "ķ“ė¦½ģ ėķ $1 ģė§ģ ģ°¾ģ ģ ģģµėė¤: $2", + "mwe-timedtext-upload-timed-text": "ģė§ ģ¶ź°" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ksh.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ksh.json new file mode 100644 index 00000000..13036810 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ksh.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Purodha" + ] + }, + "mwe-timedtext-language-no-subtitles-for-clip": "Mer han kei $1 Ongertittelle jefonge fƶr dat Shtƶck: $2" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lb.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lb.json new file mode 100644 index 00000000..ad8d40e7 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lb.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Robby", + "Soued031" + ] + }, + "mwe-timedtext-back-btn": "ZrĆ©ck", + "mwe-timedtext-layout-off": "Ćnnertitele verstoppen", + "mwe-timedtext-loading-text": "Text gĆ«tt gelueden ...", + "mwe-timedtext-textcat-sub": "Ćnnertitelen", + "mwe-timedtext-textcat-tad": "Audio-Beschreiwung", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Text-Ticker", + "mwe-timedtext-textcat-ar": "Aktiv Regiounen", + "mwe-timedtext-textcat-nb": "Notiz", + "mwe-timedtext-textcat-lrc": "Liddertext", + "mwe-timedtext-textcat-lin": "Linguistesch MarkĆ©ierung", + "mwe-timedtext-textcat-cue": "Referenz-Punkten", + "mwe-timedtext-language-subtitles-for-clip": "$1 Ćnnertitele fir de Clip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Keng $1 Ćnnertitele goufe fonnt fir de Clip: $2", + "mwe-timedtext-upload-timed-text": "Ćnnertitelen derbƤisetzen" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lt.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lt.json new file mode 100644 index 00000000..af653701 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lt.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Hugo.arg" + ] + }, + "mwe-timedtext-no-subs": "NÄra tekstinių takelių", + "mwe-timedtext-upload-timed-text": "PridÄti subtitrus" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lv.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lv.json new file mode 100644 index 00000000..55f99f5a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/lv.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Papuass" + ] + }, + "mwe-timedtext-textcat-nb": "AnotÄcija", + "mwe-timedtext-textcat-trx": "Transkripts" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/mk.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/mk.json new file mode 100644 index 00000000..1dd29c01 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/mk.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Bjankuloski06" + ] + }, + "mwe-timedtext-back-btn": "ŠŠ°Š·Š°Š“", + "mwe-timedtext-layout-off": "Š”ŠŗŃŠøŃ ŃŠøŃŠ»Š¾Š²Šø", + "mwe-timedtext-loading-text": "ŠŠ¾ Š²ŃŠøŃŃŠ²Š°Š¼ ŃŠµŠŗŃŃŠ¾Ń...", + "mwe-timedtext-textcat-cc": "ŠŠæŠøŃ", + "mwe-timedtext-textcat-sub": "Š¢ŠøŃŠ»Š¾Š²Šø", + "mwe-timedtext-textcat-tad": "ŠŃŠ“ŠøŠ¾-Š¾ŠæŠøŃ", + "mwe-timedtext-textcat-ktv": "ŠŠ°ŃŠ°Š¾ŠŗŠµ", + "mwe-timedtext-textcat-tik": "Š¢ŠµŠŗŃŃ-ŠŗŠ°ŃŃŠøŃŠŗŠø", + "mwe-timedtext-textcat-ar": "ŠŠŗŃŠøŠ²Š½Šø ŃŠµŠ³ŠøŠ¾Š½Šø", + "mwe-timedtext-textcat-nb": "ŠŃŠøŠ±ŠµŠ»ŠµŃŠŗŠ°", + "mwe-timedtext-textcat-meta": "Š”ŠøŠ½Ń
ŃŠ¾Š½ŠøŠ·ŠøŃŠ°Š½Šø Š¼ŠµŃŠ°ŠæŠ¾Š“Š°ŃŠ¾ŃŠø", + "mwe-timedtext-textcat-trx": "Š”ŃŠµŠ½Š¾Š³ŃŠ°Š¼", + "mwe-timedtext-textcat-lrc": "Š¢ŠµŠŗŃŃ Š½Š° ŠæŠµŃŠ½Š°ŃŠ°", + "mwe-timedtext-textcat-lin": "ŠŠøŠ½Š³Š²ŠøŃŃŠøŃŠŗŠ¾ Š¾Š·Š½Š°ŃŃŠ²Š°ŃŠµ", + "mwe-timedtext-textcat-cue": "ŠŠ¾Š¼ŠµŠ½ŃŠ½Šø ŃŠ¾ŃŠŗŠø", + "mwe-timedtext-no-subs": "ŠŠµŠ¼Š° ŃŠøŃŠ»Š¾Š²Šø Š½Š° ŃŠ°ŃŠæŠ¾Š»Š°Š³Š°ŃŠµ", + "mwe-timedtext-language-subtitles-for-clip": "$1 ā ŃŠøŃŠ»Š¾Š²Šø Š·Š° ŃŠ½ŠøŠ¼ŠŗŠ°ŃŠ°: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "ŠŠµŠ¼Š° ŠæŃŠ¾Š½Š°ŃŠ“ŠµŠ½Š¾ ŃŠøŃŠ»Š¾Š²Šø Š½Š° $1 Š·Š° ŃŠ½ŠøŠ¼ŠŗŠ°ŃŠ°: $2", + "mwe-timedtext-upload-timed-text": "Š”ŃŠ°Š²Šø ŃŠøŃŠ»Š¾Š²Šø" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ml.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ml.json new file mode 100644 index 00000000..a8d34824 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ml.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Praveenp" + ] + }, + "mwe-timedtext-back-btn": "ą“Ŗąµą“±ą“ąµą“ąµą“ąµ", + "mwe-timedtext-layout-off": "ą“øą“ą“ą“¾ą“·ą“£ą“°ąµą“ ą“®ą“±ą“Æąµą“ąµą“ąµą“", + "mwe-timedtext-loading-text": "ą“ą““ąµą“¤ąµą“¤ąµ ą“¶ąµą“ą“°ą“æą“ąµą“ąµą“Øąµą“Øąµ...", + "mwe-timedtext-textcat-cc": "ą“¤ą“²ą“µą“¾ą“ąµą“Æą“", + "mwe-timedtext-textcat-sub": "ą“øą“ą“ą“¾ą“·ą“£ą“°ąµą“ą“ąµ¾", + "mwe-timedtext-textcat-tad": "ą“¶ą“¬ąµą“¦ą“¤ąµą“¤ą“æą“Øąµą“±ąµ ą“µą“æą“µą“°ą“£ą“", + "mwe-timedtext-textcat-ktv": "ą“ą“°ąµą“ąµą“ąµ", + "mwe-timedtext-textcat-tik": "ą“®ą“æą“Øąµą“Øą“æą“µą“°ąµą“Øąµą“Ø ą“ą““ąµą“¤ąµą“¤ąµ", + "mwe-timedtext-textcat-ar": "ą“øą“ąµą“µą“®ą“¾ą“Æ ą“Ŗąµą“°ą“¦ąµą“¶ą“ąµą“ąµ¾", + "mwe-timedtext-textcat-nb": "ą“ą“æą“Ŗąµą“Ŗą“£ą“æ", + "mwe-timedtext-textcat-meta": "ą“øą“®ą“Æą“®ą“Øąµą“øą“°ą“æą“ąµą“ąµą“³ąµą“³ ą“®ąµą“±ąµą“±ą“¾ą“”ąµą“±ąµą“±", + "mwe-timedtext-textcat-trx": "ą“Ŗą“ąµ¼ą“¤ąµą“¤ą“æą“Æąµą““ąµą“¤ąµą“¤ąµ", + "mwe-timedtext-textcat-lrc": "ą“µą“°ą“æą“ąµ¾", + "mwe-timedtext-textcat-lin": "ą“ą“¾ą“·ą“¾ą“øą“ą“¬ą“Øąµą“§ą“æą“Æą“¾ą“Æ ą“
ą“ą“Æą“¾ą“³ą“ą“¾ą“·", + "mwe-timedtext-textcat-cue": "ą“øąµą“ą“ ą“¬ą“æą“Øąµą“¦ąµą“ąµą“ąµ¾", + "mwe-timedtext-no-subs": "ą“ą““ąµą“¤ąµą“¤ąµą“ą“³ąµą“ąµ ą“µą“°ą“æ ą“²ą“ąµą“Æą“®ą“²ąµą“²", + "mwe-timedtext-language-subtitles-for-clip": "ą“ ą“®ąµą“”ą“æą“Æą“¶ą“ą“²ą“¤ąµą“¤ą“æą“Øąµ $1 ą“ą“¾ą“·ą“Æą“æą“²ąµą“³ąµą“³ ą“øą“ą“ą“¾ą“·ą“£ą“°ąµą“: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "ą“ ą“®ąµą“”ą“æą“Æą“¶ą“ą“²ą“¤ąµą“¤ą“æą“Øąµ $1 ą“ą“¾ą“·ą“Æą“æą“²ąµą“³ąµą“³ ą“øą“ą“ą“¾ą“·ą“£ą“°ąµą“ą“Æąµą“Øąµą“Øąµą“ ą“ą“£ąµą“ąµą“¤ąµą“¤ą“¾ą“Øą“¾ą“Æą“æą“²ąµą“²: $2", + "mwe-timedtext-upload-timed-text": "ą“øą“ą“ą“¾ą“·ą“£ą“°ąµą“ ą“ąµą“ąµą“ą“æą“ąµą“ąµąµ¼ą“ąµą“ąµą“" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ms.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ms.json new file mode 100644 index 00000000..712fff27 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ms.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Anakmalaysia" + ] + }, + "mwe-timedtext-back-btn": "Kembali", + "mwe-timedtext-layout-off": "Sorokkan sari kata", + "mwe-timedtext-loading-text": "Teks sedang dimuatkan...", + "mwe-timedtext-textcat-cc": "Kapsyen", + "mwe-timedtext-textcat-sub": "Sari kata", + "mwe-timedtext-textcat-tad": "Keterangan audio", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Teks ticker", + "mwe-timedtext-textcat-ar": "Kawasan aktif", + "mwe-timedtext-textcat-nb": "Anotasi", + "mwe-timedtext-textcat-meta": "Metadata bermasa", + "mwe-timedtext-textcat-trx": "Transkrip", + "mwe-timedtext-textcat-lrc": "Lirik", + "mwe-timedtext-textcat-lin": "Penanda linguistik", + "mwe-timedtext-textcat-cue": "Titik kiu", + "mwe-timedtext-no-subs": "Tidak terdapat runut teks", + "mwe-timedtext-language-subtitles-for-clip": "Sari kata $1 untuk klip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Tidak terdapat sari kata $1 untuk klip: $2", + "mwe-timedtext-upload-timed-text": "Letak sari kata" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nb.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nb.json new file mode 100644 index 00000000..a273d46b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nb.json @@ -0,0 +1,25 @@ +{ + "@metadata": { + "authors": [ + "Danmichaelo", + "Nghtwlkr" + ] + }, + "mwe-timedtext-back-btn": "Tilbake", + "mwe-timedtext-layout-off": "Gjem undertekster", + "mwe-timedtext-loading-text": "Laster tekst ...", + "mwe-timedtext-textcat-cc": "Undertektster", + "mwe-timedtext-textcat-sub": "Undertekster", + "mwe-timedtext-textcat-tad": "Lydbeskrivelse", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Tekst-ticker", + "mwe-timedtext-textcat-ar": "Aktive regioner", + "mwe-timedtext-textcat-nb": "Merknad", + "mwe-timedtext-textcat-meta": "Tidsbestemt metadata", + "mwe-timedtext-textcat-trx": "Transkripsjon", + "mwe-timedtext-textcat-lrc": "Tekster", + "mwe-timedtext-no-subs": "Ingen tekstspor finnes", + "mwe-timedtext-language-subtitles-for-clip": "Undertekster pĆ„ $1 for klippet: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Ingen undertekster pĆ„ $1 ble funnet for klippet: $2", + "mwe-timedtext-upload-timed-text": "Legg til undertekster" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nl.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nl.json new file mode 100644 index 00000000..7b225402 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nl.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Siebrand" + ] + }, + "mwe-timedtext-back-btn": "Terug", + "mwe-timedtext-layout-off": "Ondertitels verbergen", + "mwe-timedtext-loading-text": "Bezig met het laden van de tekst...", + "mwe-timedtext-textcat-cc": "Ondertitels", + "mwe-timedtext-textcat-sub": "Ondertitels", + "mwe-timedtext-textcat-tad": "Audiobeschrijving", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Informatiebalk", + "mwe-timedtext-textcat-ar": "Actieve gebieden", + "mwe-timedtext-textcat-nb": "Annotatie", + "mwe-timedtext-textcat-meta": "Tijdgebaseerde metadata", + "mwe-timedtext-textcat-trx": "Transcriptie", + "mwe-timedtext-textcat-lrc": "Songteksten", + "mwe-timedtext-textcat-lin": "Taalkundige markup", + "mwe-timedtext-textcat-cue": "Richtpunten", + "mwe-timedtext-no-subs": "Er zijn geen teksttracks beschikbaar", + "mwe-timedtext-language-subtitles-for-clip": "Ondertitels in het $1 voor clip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Er zijn geen ondertitels in de taal $1 gevonden voor clip: $2", + "mwe-timedtext-upload-timed-text": "Ondertitels toevoegen" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nn.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nn.json new file mode 100644 index 00000000..696c63d4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/nn.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Njardarlogar" + ] + }, + "mwe-timedtext-layout-off": "GĆøym undertekstar", + "mwe-timedtext-textcat-sub": "Undertekstar", + "mwe-timedtext-textcat-lrc": "Tekstar", + "mwe-timedtext-no-subs": "Ingen tekstspor er tilgjengelege", + "mwe-timedtext-language-subtitles-for-clip": "$1 undertekstar for klippet: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Ingen undertekster pĆ„ $1 vart funne for klippet: $2", + "mwe-timedtext-upload-timed-text": "Legg til undertekstar" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pdc.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pdc.json new file mode 100644 index 00000000..56c9fe84 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pdc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Xqt" + ] + }, + "mwe-timedtext-back-btn": "Zerrick" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pfl.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pfl.json new file mode 100644 index 00000000..2e41e363 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pfl.json @@ -0,0 +1,7 @@ +{ + "@metadata": { + "authors": [ + "Manuae" + ] + } +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pl.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pl.json new file mode 100644 index 00000000..544812d0 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pl.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "BeginaFelicysym", + "Leinad", + "Shadown", + "Sp5uhe" + ] + }, + "mwe-timedtext-back-btn": "Wstecz", + "mwe-timedtext-layout-off": "Ukryj napisy", + "mwe-timedtext-loading-text": "Åadowanie tekstu...", + "mwe-timedtext-textcat-cc": "Podpisy", + "mwe-timedtext-textcat-sub": "Napisy do filmu", + "mwe-timedtext-textcat-tad": "Opis Åcieżki dÅŗwiÄkowej", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Notatka", + "mwe-timedtext-textcat-ar": "Aktywne regiony", + "mwe-timedtext-textcat-nb": "Adnotacja", + "mwe-timedtext-textcat-meta": "Metadane ze znacznikami czasu", + "mwe-timedtext-textcat-trx": "Rozpisz", + "mwe-timedtext-textcat-lrc": "Teksty piosenek", + "mwe-timedtext-textcat-lin": "Znaczniki jÄzykowe", + "mwe-timedtext-textcat-cue": "Punkty kontrolne", + "mwe-timedtext-no-subs": "Nie ma dostÄpnych Åcieżek tekstowych", + "mwe-timedtext-language-subtitles-for-clip": "$1 napisy do filmu: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Nie odnaleziono $1 napisĆ³w do filmu: $2", + "mwe-timedtext-upload-timed-text": "Dodaj napisy" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pms.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pms.json new file mode 100644 index 00000000..7ffca36c --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pms.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "BorichĆØt", + "DragonĆ²t" + ] + }, + "mwe-timedtext-back-btn": "AndrĆ©", + "mwe-timedtext-layout-off": "StĆ«rmĆ© ij sot-tƬtoj", + "mwe-timedtext-loading-text": "Cariament dĆ«l test...", + "mwe-timedtext-textcat-cc": "Descrission", + "mwe-timedtext-textcat-sub": "Sot-tƬtoj", + "mwe-timedtext-textcat-tad": "Descrission Ć udio", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Test Ć«d la telescrivent", + "mwe-timedtext-textcat-ar": "Region ative", + "mwe-timedtext-textcat-nb": "NĆ²ta", + "mwe-timedtext-textcat-meta": "Metadat sincronisĆ ", + "mwe-timedtext-textcat-trx": "Trascrission", + "mwe-timedtext-textcat-lrc": "LƬriche", + "mwe-timedtext-textcat-lin": "Marcador lenghƬstich", + "mwe-timedtext-textcat-cue": "Pont d'arferiment", + "mwe-timedtext-no-subs": "Gnun-e marche Ć«d test disponƬbij", + "mwe-timedtext-language-subtitles-for-clip": "$1 sot-tƬtoj pĆ«r Ć«l tĆ²ch: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "A l'Ć© trovasse gnun sot-tƬtoj $1 per Ć«l tĆ²ch: $2", + "mwe-timedtext-upload-timed-text": "GiontĆ© dij sot-tƬtoj" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ps.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ps.json new file mode 100644 index 00000000..fd556365 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ps.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Ahmed-Najib-Biabani-Ibrahimkhel" + ] + }, + "mwe-timedtext-textcat-ktv": "Ś©Ų§Ų±Ų§Ų§ŁŚ©Ł" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pt-br.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pt-br.json new file mode 100644 index 00000000..008c55ba --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pt-br.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Dianakc", + "Giro720", + "Luckas", + "Luckas Blade", + "555" + ] + }, + "mwe-timedtext-back-btn": "Voltar", + "mwe-timedtext-layout-off": "Ocultar legendas", + "mwe-timedtext-loading-text": "Carregando o texto ...", + "mwe-timedtext-textcat-cc": "TĆtulos", + "mwe-timedtext-textcat-sub": "Legendas", + "mwe-timedtext-textcat-tad": "DescriĆ§Ć£o do Ć”udio", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Texto deslizante", + "mwe-timedtext-textcat-ar": "RegiƵes ativas", + "mwe-timedtext-textcat-nb": "AnotaĆ§Ć£o", + "mwe-timedtext-textcat-meta": "Metadados sincronizados", + "mwe-timedtext-textcat-trx": "TranscriĆ§Ć£o", + "mwe-timedtext-textcat-lrc": "Letra", + "mwe-timedtext-textcat-lin": "MarcaĆ§Ć£o linguĆstica", + "mwe-timedtext-textcat-cue": "Pontos de entrada", + "mwe-timedtext-no-subs": "NĆ£o hĆ” nenhum texto disponĆvel", + "mwe-timedtext-language-subtitles-for-clip": "Legendas em $1 para o clipe: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "NĆ£o foram encontradas legendas em $1 para o clipe: $2", + "mwe-timedtext-upload-timed-text": "Adicionar legendas" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pt.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pt.json new file mode 100644 index 00000000..4917da79 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/pt.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Giro720", + "Hamilton Abreu", + "Luckas", + "SandroHc", + "Vitorvicentevalente" + ] + }, + "mwe-timedtext-back-btn": "Voltar", + "mwe-timedtext-layout-off": "Ocultar legendas", + "mwe-timedtext-loading-text": "A carregar o texto ...", + "mwe-timedtext-textcat-cc": "TĆtulos", + "mwe-timedtext-textcat-sub": "Legendas", + "mwe-timedtext-textcat-tad": "DescriĆ§Ć£o de Ć”udio", + "mwe-timedtext-textcat-ktv": "Caraoque", + "mwe-timedtext-textcat-tik": "CotaƧƵes", + "mwe-timedtext-textcat-ar": "RegiƵes activas", + "mwe-timedtext-textcat-nb": "AnotaĆ§Ć£o", + "mwe-timedtext-textcat-meta": "Metadados de sincronizaĆ§Ć£o", + "mwe-timedtext-textcat-trx": "TranscriĆ§Ć£o", + "mwe-timedtext-textcat-lrc": "Letra", + "mwe-timedtext-textcat-lin": "MarcaĆ§Ć£o linguĆstica", + "mwe-timedtext-textcat-cue": "Pontos de entrada", + "mwe-timedtext-no-subs": "NĆ£o hĆ” nenhuma faixa de texto disponĆvel", + "mwe-timedtext-language-subtitles-for-clip": "Legendas em $1 para o clipe: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "NĆ£o foram encontradas legendas em $1 para o clipe: $2", + "mwe-timedtext-upload-timed-text": "Adicionar legendas" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/qqq.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/qqq.json new file mode 100644 index 00000000..4714d5b1 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/qqq.json @@ -0,0 +1,19 @@ +{ + "@metadata": { + "authors": [ + "EugeneZelenko", + "Shirayuki", + "Siebrand", + "Umherirrender" + ] + }, + "mwe-timedtext-back-btn": "{{Identical|Back}}", + "mwe-timedtext-key-language": "{{optional}}\nParameters:\n* $1 - language key. e.g. \"en\"\n* $2 - language name", + "mwe-timedtext-textcat-cc": "{{Identical|Caption}}", + "mwe-timedtext-textcat-sub": "{{Identical|Subtitle}}", + "mwe-timedtext-textcat-ktv": "See [[w:Karaoke]].", + "mwe-timedtext-textcat-nb": "{{Identical|Annotation}}", + "mwe-timedtext-language-subtitles-for-clip": "$1 is language name for subtitles (e.g. \"English\"), $2 is title of file that timed text is for.\nShown as the page title on a TimedText namespace page when the page exists. See also mwe-timedtext-language-no-subtitles-for-clip.", + "mwe-timedtext-language-no-subtitles-for-clip": "$1 is language name, $2 is title of file that timed text is for.\nShown as the page title on a TimedText namespace page when the page does not exist. See also mwe-timedtext-language-subtitles-for-clip", + "mwe-timedtext-upload-timed-text": "After clicking the 'CC' button on the video player, the button on the resulting menu to add subtitles to a video file." +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ro.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ro.json new file mode 100644 index 00000000..77892ab4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ro.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "Minisarm", + "Stelistcristi" + ] + }, + "mwe-timedtext-back-btn": "Ćnapoi", + "mwe-timedtext-layout-off": "Ascunde subtitrÄrile", + "mwe-timedtext-loading-text": "Se Ć®ncarcÄ textul...", + "mwe-timedtext-textcat-cc": "Legende", + "mwe-timedtext-textcat-sub": "SubtitrÄri", + "mwe-timedtext-textcat-tad": "Descriere audio", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Text mai gros", + "mwe-timedtext-textcat-ar": "Regiuni active", + "mwe-timedtext-textcat-nb": "Adnotare", + "mwe-timedtext-textcat-meta": "Metadate sincronizate", + "mwe-timedtext-textcat-trx": "TranscripČie", + "mwe-timedtext-textcat-lrc": "Versuri", + "mwe-timedtext-textcat-lin": "Etichete lingvistice", + "mwe-timedtext-textcat-cue": "Puncte de tac", + "mwe-timedtext-no-subs": "Niciun text de piesÄ disponibil", + "mwe-timedtext-language-subtitles-for-clip": "Subtitrare Ć®n limba $1 pentru clip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Nu s-a gÄsit nicio subtitrare Ć®n limba $1 pentru clip: $2", + "mwe-timedtext-upload-timed-text": "AdaugÄ subtitrÄri" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/roa-tara.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/roa-tara.json new file mode 100644 index 00000000..a26678a4 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/roa-tara.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Joetaras" + ] + }, + "mwe-timedtext-back-btn": "Rrete", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-nb": "Annotazione", + "mwe-timedtext-textcat-meta": "Metadate temborizzate", + "mwe-timedtext-textcat-trx": "Trascrive", + "mwe-timedtext-textcat-lrc": "Teste", + "mwe-timedtext-upload-timed-text": "Aggiunge le sottotitole" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ru.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ru.json new file mode 100644 index 00000000..8b3ff81c --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ru.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "MaxSem", + "Okras", + "ŠŠ»ŠµŠŗŃŠ°Š½Š“Ń Š”ŠøŠ³Š°ŃŃŠ²", + "Kaganer" + ] + }, + "mwe-timedtext-back-btn": "ŠŠ°Š·Š°Š“", + "mwe-timedtext-layout-off": "Š”ŠŗŃŃŃŃ ŃŃŠ±ŃŠøŃŃŃ", + "mwe-timedtext-loading-text": "ŠŠ°Š³ŃŃŠ·ŠŗŠ° ŃŠµŠŗŃŃŠ°ā¦", + "mwe-timedtext-textcat-cc": "Š”ŃŠ±ŃŠøŃŃŃ-Š¾ŠæŠøŃŠ°Š½ŠøŃ", + "mwe-timedtext-textcat-sub": "Š”ŃŠ±ŃŠøŃŃŃ", + "mwe-timedtext-textcat-tad": "ŠŠæŠøŃŠ°Š½ŠøŠµ Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š°", + "mwe-timedtext-textcat-ktv": "ŠŠ°ŃŠ°Š¾ŠŗŠµ", + "mwe-timedtext-textcat-tik": "Š¢ŠµŠŗŃŃŠ¾Š²ŃŠµ ŠŗŠ°ŃŃŠ¾ŃŠŗŠø", + "mwe-timedtext-textcat-ar": "ŠŠŗŃŠøŠ²Š½ŃŠµ Š¾Š±Š»Š°ŃŃŠø", + "mwe-timedtext-textcat-nb": "ŠŠ½Š½Š¾ŃŠ°ŃŠøŃ", + "mwe-timedtext-textcat-meta": "Š”ŠøŠ½Ń
ŃŠ¾Š½ŠøŠ·ŠøŃŠ¾Š²Š°Š½Š½ŃŠµ Š¼ŠµŃŠ°Š“Š°Š½Š½ŃŠµ", + "mwe-timedtext-textcat-trx": "Š”ŃŠµŠ½Š¾Š³ŃŠ°Š¼Š¼Š°", + "mwe-timedtext-textcat-lrc": "Š”Š»Š¾Š²Š° ŠæŠµŃŠ½Šø", + "mwe-timedtext-textcat-lin": "ŠŠøŠ½Š³Š²ŠøŃŃŠøŃŠµŃŠŗŠ°Ń ŃŠ°Š·Š¼ŠµŃŠŗŠ°", + "mwe-timedtext-textcat-cue": "ŠŠ½Š°ŠŗŠ¾Š²ŃŠµ ŃŠ¾ŃŠŗŠø", + "mwe-timedtext-no-subs": "ŠŠµŃ ŃŠµŠŗŃŃŠ¾Š²ŃŃ
Š“Š¾ŃŠ¾Š¶ŠµŠŗ", + "mwe-timedtext-language-subtitles-for-clip": "$1 ā ŃŃŠ±ŃŠøŃŃŃ Š“Š»Ń ŠŗŠ»ŠøŠæŠ°: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "ŠŠµ Š½Š°Š¹Š“ŠµŠ½Š¾ ŃŃŠ±ŃŠøŃŃŠ¾Š² Š½Š° $1 Š“Š»Ń ŠŗŠ»ŠøŠæŠ°: $2", + "mwe-timedtext-upload-timed-text": "ŠŠ¾Š±Š°Š²ŠøŃŃ ŃŃŠ±ŃŠøŃŃŃ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/rue.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/rue.json new file mode 100644 index 00000000..1cc92d6f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/rue.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Gazeb" + ] + }, + "mwe-timedtext-back-btn": "ŠŠ°Š·Š°Š“" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/si.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/si.json new file mode 100644 index 00000000..8af0327f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/si.json @@ -0,0 +1,25 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "mwe-timedtext-back-btn": "ą¶ą¶“ą·ą·", + "mwe-timedtext-layout-off": "ą¶ą¶“ą·ą·ą¶»ą·ą· ą·ą¶ą·ą¶±ą·ą¶±", + "mwe-timedtext-loading-text": "ą¶“ą·ą·
ą¶“ą·ą¶»ą¶«ą¶ŗ ą·ą·ą¶øą·ą¶±ą· ...", + "mwe-timedtext-textcat-cc": "ą¶ą¶“ą¶±ą·āą¶ŗą·ą·", + "mwe-timedtext-textcat-sub": "ą¶ą¶“ą·ą·ą¶»ą·ą·", + "mwe-timedtext-textcat-tad": "ą·ą·āą¶»ą·ą·āą¶ŗ ą·ą·ą·ą·ą¶ą¶»ą¶ŗ", + "mwe-timedtext-textcat-ktv": "ą¶ą·ą¶»ą·ą¶ą·", + "mwe-timedtext-textcat-tik": "ą¶ą¶»ą¶½ą·ą·ą· ą¶“ą·ą·
", + "mwe-timedtext-textcat-ar": "ą·ą¶ą·āą¶»ą·ą¶ŗ ą¶“ą·āą¶»ą¶Æą·ą·", + "mwe-timedtext-textcat-nb": "ą¶§ą·ą¶ą·ą·", + "mwe-timedtext-textcat-meta": "ą¶ą·ą¶½ą·ą¶ ą¶“ą·ą¶»ą¶Æą¶ą·ą¶", + "mwe-timedtext-textcat-trx": "ą¶“ą·āą¶»ą¶ą·ą¶½ą·ą¶ą¶±ą¶ŗ", + "mwe-timedtext-textcat-lrc": "ą¶ą·ą¶“ą¶Æą·ą·ą¶½ą·", + "mwe-timedtext-textcat-lin": "ą¶·ą·ą·ą·ą¶øą¶ŗ ą¶
ą¶°ą·ą¶ą¶ŗ", + "mwe-timedtext-textcat-cue": "ą¶ą¶ą¶ą·ą¶ ą¶ą¶ą·ą¶ą·ą¶«", + "mwe-timedtext-no-subs": "ą¶øą·ą·
ą¶ ą¶“ą¶® ą¶½ą¶¶ą·ą¶ą¶ ą¶±ą·ą·ą·ą¶", + "mwe-timedtext-language-subtitles-for-clip": "ą¶ą·ą¶½ą·ą¶“ą¶ŗ ą·ą¶³ą·ą· $1 ą¶ą¶“ą·ą·ą¶»ą·ą·: $2", + "mwe-timedtext-upload-timed-text": "ą¶ą¶“ą·ą·ą¶»ą·ą· ą¶ą¶ą· ą¶ą¶»ą¶±ą·ą¶±" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sl.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sl.json new file mode 100644 index 00000000..8df43558 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sl.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Dbc334" + ] + }, + "mwe-timedtext-back-btn": "Nazaj" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/so.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/so.json new file mode 100644 index 00000000..6a979a8b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/so.json @@ -0,0 +1,7 @@ +{ + "@metadata": { + "authors": [ + "Abshirdheere" + ] + } +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sr-ec.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sr-ec.json new file mode 100644 index 00000000..f3dfbbc6 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sr-ec.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Rancher", + "ŠŠøŃ
Š°ŃŠ»Š¾ ŠŠ½ŃŠµŠ»ŠŗŠ¾Š²ŠøŃ" + ] + }, + "mwe-timedtext-back-btn": "ŠŠ°Š·Š°Š“", + "mwe-timedtext-layout-off": "Š”Š°ŠŗŃŠøŃ ŃŠ°Š±ŃŠ°ŃŃŠ»Š¾Š²Šµ", + "mwe-timedtext-loading-text": "Š£ŃŠøŃŠ°Š²Š° ŃŠµ ŃŠµŠŗŃŃ ...", + "mwe-timedtext-key-language": "$1, $2", + "mwe-timedtext-textcat-cc": "ŠŠ·Š½Š°ŠŗŠµ", + "mwe-timedtext-textcat-sub": "ŠŠ¾Š“Š½Š°ŃŠ»Š¾Š²Šø", + "mwe-timedtext-textcat-trx": "Š¢ŃŠ°Š½ŃŠŗŃŠøŠæŃ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sr-el.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sr-el.json new file mode 100644 index 00000000..100a6fc3 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sr-el.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Rancher" + ] + }, + "mwe-timedtext-back-btn": "Nazad", + "mwe-timedtext-layout-off": "Sakrij sabtajtlove", + "mwe-timedtext-loading-text": "UÄitava se tekst ...", + "mwe-timedtext-key-language": "$1, $2", + "mwe-timedtext-textcat-cc": "Oznake", + "mwe-timedtext-textcat-sub": "Podnaslovi", + "mwe-timedtext-textcat-trx": "Transkript" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sv.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sv.json new file mode 100644 index 00000000..a0b693cd --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/sv.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "Ainali", + "Dafer45" + ] + }, + "mwe-timedtext-back-btn": "Tillbaka", + "mwe-timedtext-layout-off": "Dƶlj undertexter", + "mwe-timedtext-loading-text": "Laddar text ...", + "mwe-timedtext-textcat-cc": "Undertexter", + "mwe-timedtext-textcat-sub": "Undertexter", + "mwe-timedtext-textcat-tad": "Ljudbeskrivning", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Rullande text", + "mwe-timedtext-textcat-ar": "Aktiva regioner", + "mwe-timedtext-textcat-nb": "AnmƤrkning", + "mwe-timedtext-textcat-meta": "TidsbestƤmd metadata", + "mwe-timedtext-textcat-trx": "Transkription", + "mwe-timedtext-textcat-lrc": "Texter", + "mwe-timedtext-textcat-lin": "SprĆ„kliga markeringar", + "mwe-timedtext-textcat-cue": "Referenspunkter", + "mwe-timedtext-no-subs": "Inga textspĆ„r finns", + "mwe-timedtext-language-subtitles-for-clip": "$1 undertexter fƶr klipp: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Inga $1 undertexter hittades fƶr klipp: $2", + "mwe-timedtext-upload-timed-text": "LƤgga till undertexter" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ta.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ta.json new file mode 100644 index 00000000..6e9ef3e8 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ta.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Karthi.dr", + "Shanmugamp7", + "ą®®ą®¤ą®©ą®¾ą®¹ą®°ą®©ąÆ" + ] + }, + "mwe-timedtext-back-btn": "ą®Ŗą®æą®©ąÆą®ąÆą®²ąÆ", + "mwe-timedtext-layout-off": "ą®¤ąÆą®£ąÆą®¤ąÆą®¤ą®²ąÆą®ŖąÆą®ŖąÆą®ąÆą®ą®³ąÆ ą®®ą®±ąÆ", + "mwe-timedtext-loading-text": "ą®ą®°ąÆą®ÆąÆ ą®ą®±ąÆą®±ąÆą®ą®æą®±ą®¤ąÆ ...", + "mwe-timedtext-textcat-sub": "ą®¤ąÆą®£ąÆą®¤ąÆą®¤ą®²ąÆą®ŖąÆą®ŖąÆą®ąÆą®ą®³ąÆ", + "mwe-timedtext-textcat-tad": "ą®ą®²ą®æą®¤ ą®µą®æą®µą®°ą®£ą®®ąÆ", + "mwe-timedtext-textcat-lrc": "ą®Ŗą®¾ą®ą®²ąÆ ą®µą®°ą®æą®ą®³ąÆ", + "mwe-timedtext-upload-timed-text": "ą®¤ąÆą®£ąÆą®¤ąÆą®¤ą®²ąÆą®ŖąÆą®ŖąÆą®ąÆą®ą®³ąÆą®ąÆ ą®ąÆą®°ąÆ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/te.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/te.json new file mode 100644 index 00000000..50688138 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/te.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Veeven" + ] + }, + "mwe-timedtext-back-btn": "ą°µą±ą°Øą°ą±ą°ą°æ", + "mwe-timedtext-textcat-sub": "ą°ą°Ŗą°¶ą±ą°°ą±ą°·ą°æą°ą°²ą±" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/tl.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/tl.json new file mode 100644 index 00000000..971a8f30 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/tl.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "AnakngAraw" + ] + }, + "mwe-timedtext-back-btn": "Bumalik", + "mwe-timedtext-layout-off": "Itago ang kabahaging mga pamagat", + "mwe-timedtext-loading-text": "Ikinakarga ang teksto ...", + "mwe-timedtext-key-language": "$1, $2", + "mwe-timedtext-textcat-cc": "Mga paliwanag", + "mwe-timedtext-textcat-sub": "Kabahaging mga pamagat", + "mwe-timedtext-textcat-tad": "Paglalarawan ng naririnig", + "mwe-timedtext-textcat-ktv": "Karaoke", + "mwe-timedtext-textcat-tik": "Teksto ng pampulso", + "mwe-timedtext-textcat-ar": "Masisiglang mga rehiyon", + "mwe-timedtext-textcat-nb": "Paliwanag", + "mwe-timedtext-textcat-meta": "Inorasang metadato", + "mwe-timedtext-textcat-trx": "Sipi ng salin", + "mwe-timedtext-textcat-lrc": "Titik ng awit", + "mwe-timedtext-textcat-lin": "Markang-pantaas ng lingguwistika", + "mwe-timedtext-textcat-cue": "Mga tuldok ng pahiwatig", + "mwe-timedtext-no-subs": "Walang makukuhang mga bakas ng teksto", + "mwe-timedtext-language-subtitles-for-clip": "$1 kabahaging mga pamagat para sa putol na: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Walang natagpuang $1 kabahaging mga pamagat para sa putol na: $2", + "mwe-timedtext-upload-timed-text": "Magdagdag ng kabahaging mga pamagat" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/tr.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/tr.json new file mode 100644 index 00000000..8b26730a --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/tr.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Emperyan" + ] + }, + "mwe-timedtext-back-btn": "Geri", + "mwe-timedtext-textcat-sub": "Alt yazılar", + "mwe-timedtext-no-subs": "ParƧa metni yok", + "mwe-timedtext-upload-timed-text": "Alt yazı ekle" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/uk.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/uk.json new file mode 100644 index 00000000..916f0395 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/uk.json @@ -0,0 +1,27 @@ +{ + "@metadata": { + "authors": [ + "Base", + "Š¢ŠµŃŃ" + ] + }, + "mwe-timedtext-back-btn": "ŠŠ°Š·Š°Š“", + "mwe-timedtext-layout-off": "ŠŃŠøŃ
Š¾Š²Š°ŃŠø ŃŃŠ±ŃŠøŃŃŠø", + "mwe-timedtext-loading-text": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠµŠ½Š½Ń ŃŠµŠŗŃŃŃā¦", + "mwe-timedtext-textcat-cc": "Š”ŃŠ±ŃŠøŃŃŠø-ŠæŃŠ“ŠæŠøŃŠø", + "mwe-timedtext-textcat-sub": "Š”ŃŠ±ŃŠøŃŃŠø", + "mwe-timedtext-textcat-tad": "ŠŃŠ“ŃŠ¾-Š¾ŠæŠøŃ", + "mwe-timedtext-textcat-ktv": "ŠŠ°ŃŠ°Š¾ŠŗŠµ", + "mwe-timedtext-textcat-tik": "Š¢ŠµŠŗŃŃŠ¾Š²Ń ŠŗŠ°ŃŃŠŗŠø", + "mwe-timedtext-textcat-ar": "ŠŠŗŃŠøŠ²Š½Ń Š¾Š±Š»Š°ŃŃŃ", + "mwe-timedtext-textcat-nb": "ŠŠ½Š¾ŃŠ°ŃŃŃ", + "mwe-timedtext-textcat-meta": "Š”ŠøŠ½Ń
ŃŠ¾Š½ŃŠ·Š¾Š²Š°Š½Ń Š¼ŠµŃŠ°Š“Š°Š½Ń", + "mwe-timedtext-textcat-trx": "Š”ŃŠµŠ½Š¾Š³ŃŠ°Š¼Š°", + "mwe-timedtext-textcat-lrc": "Š”Š»Š¾Š²Š° ŠæŃŃŠ½Ń", + "mwe-timedtext-textcat-lin": "ŠŃŠ½Š³Š²ŃŃŃŠøŃŠ½Š° ŃŠ¾Š·Š¼ŃŃŠŗŠ°", + "mwe-timedtext-textcat-cue": "ŠŠ½Š°ŠŗŠ¾Š²Ń ŃŠ¾ŃŠŗŠø", + "mwe-timedtext-no-subs": "ŠŠµŠ¼Š°Ń ŃŠµŠŗŃŃŠ¾Š²ŠøŃ
Š“Š¾ŃŃŠ¶Š¾Šŗ", + "mwe-timedtext-language-subtitles-for-clip": "$1 ā ŃŃŠ±ŃŠøŃŃŠø Š“Š»Ń ŠŗŠ»ŃŠæŃ: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "ŠŠµ Š·Š½Š°Š¹Š“ŠµŠ½Š¾ ŃŃŠ±ŃŠøŃŃŃŠ² $1 Š“Š»Ń ŠŗŠ»ŃŠæŃ: $2", + "mwe-timedtext-upload-timed-text": "ŠŠ¾Š“Š°ŃŠø ŃŃŠ±ŃŠøŃŃŠø" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ur.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ur.json new file mode 100644 index 00000000..baafae32 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/ur.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "mwe-timedtext-back-btn": "ŁŲ§Ł¾Ų³", + "mwe-timedtext-textcat-sub": "Ų±ŁŁ
Ų§ŁŪŪ" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/vi.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/vi.json new file mode 100644 index 00000000..5ee9bb9b --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/vi.json @@ -0,0 +1,18 @@ +{ + "@metadata": { + "authors": [ + "Minh Nguyen", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "mwe-timedtext-back-btn": "Quay lįŗ”i", + "mwe-timedtext-layout-off": "įŗØn phį»„ Äį»", + "mwe-timedtext-loading-text": "Äang tįŗ£i vÄn bįŗ£nā¦", + "mwe-timedtext-textcat-sub": "Phį»„ Äį»", + "mwe-timedtext-textcat-tad": "Lį»i miĆŖu tįŗ£ Ć¢m thanh", + "mwe-timedtext-textcat-ktv": "KaraĆ“kĆŖ", + "mwe-timedtext-textcat-meta": "SiĆŖu dį»Æ liį»u Äį»ng bį»", + "mwe-timedtext-textcat-lrc": "Lį»i hĆ”t", + "mwe-timedtext-textcat-lin": "ÄĆ”nh dįŗ„u ngĆ“n ngį»Æ hį»c", + "mwe-timedtext-upload-timed-text": "ThĆŖm phį»„ Äį»" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/wa.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/wa.json new file mode 100644 index 00000000..c8d2fdf6 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/wa.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "Srtxg" + ] + }, + "mwe-timedtext-layout-off": "CatchĆ® les dzo-tites", + "mwe-timedtext-loading-text": "Dji tchedje li tecse...", + "mwe-timedtext-textcat-cc": "Ledjindes", + "mwe-timedtext-textcat-sub": "Dizo-tites", + "mwe-timedtext-textcat-lrc": "Paroles", + "mwe-timedtext-textcat-lin": "Etiketes di lingaedje", + "mwe-timedtext-language-subtitles-for-clip": "Dizo-tites e $1 pol clip: $2", + "mwe-timedtext-language-no-subtitles-for-clip": "Nou dzo-tite $1 di trovĆ© pol clip: $2" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/yi.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/yi.json new file mode 100644 index 00000000..c05e1576 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/yi.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "פ××××שע×Ø" + ] + }, + "mwe-timedtext-back-btn": "צ××Ø×ק", + "mwe-timedtext-textcat-cc": "××ש×Ø××××× ××¢×" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/zh-hans.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/zh-hans.json new file mode 100644 index 00000000..d13683e9 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/zh-hans.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Shizhao", + "Simon Shek", + "Wilsonmess", + "Xiaomingyan", + "Yfdyh000" + ] + }, + "mwe-timedtext-back-btn": "čæå", + "mwe-timedtext-layout-off": "éčåå¹", + "mwe-timedtext-loading-text": "ę£åØč½½å
„ęę¬...", + "mwe-timedtext-textcat-cc": "čÆ“ę", + "mwe-timedtext-textcat-sub": "åÆę é¢", + "mwe-timedtext-textcat-tad": "声é³čÆ“ę", + "mwe-timedtext-textcat-ktv": "å”ęOK", + "mwe-timedtext-textcat-tik": "ę»åØęę¬", + "mwe-timedtext-textcat-ar": "ä½ēØåŗå", + "mwe-timedtext-textcat-nb": "ę³Øé", + "mwe-timedtext-textcat-meta": "åå¹å
ę°ę®", + "mwe-timedtext-textcat-trx": "åå¹", + "mwe-timedtext-textcat-lrc": "ęčÆ", + "mwe-timedtext-textcat-lin": "čÆčØę č®°", + "mwe-timedtext-textcat-cue": "ęē¤ŗē¹", + "mwe-timedtext-no-subs": "ę²”ęåÆēØēåå¹", + "mwe-timedtext-language-subtitles-for-clip": "ēꮵ$2ē$1åå¹", + "mwe-timedtext-language-no-subtitles-for-clip": "ę²”ęę¾å°ēꮵ$2ē$1åå¹", + "mwe-timedtext-upload-timed-text": "ę·»å åå¹" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/zh-hant.json b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/zh-hant.json new file mode 100644 index 00000000..b653aeb1 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/i18n/zh-hant.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "Justincheng12345", + "Mark85296341", + "Simon Shek", + "LNDDYL" + ] + }, + "mwe-timedtext-back-btn": "čæå", + "mwe-timedtext-layout-off": "é±čåå¹", + "mwe-timedtext-loading-text": "ę£åØč®åęåā¦ā¦", + "mwe-timedtext-textcat-cc": "ęØé”", + "mwe-timedtext-textcat-sub": "åÆęØé”", + "mwe-timedtext-textcat-tad": "é³čØčŖŖę", + "mwe-timedtext-textcat-ktv": "å”ęOK", + "mwe-timedtext-textcat-tik": "ę»¾åęę¬", + "mwe-timedtext-textcat-ar": "ęęåå", + "mwe-timedtext-textcat-nb": "čØ»č§£", + "mwe-timedtext-textcat-meta": "åå¹å
č³ę", + "mwe-timedtext-textcat-trx": "åå¹", + "mwe-timedtext-textcat-lrc": "ęč©", + "mwe-timedtext-textcat-lin": "čŖčØęØčØ", + "mwe-timedtext-textcat-cue": "ęé»", + "mwe-timedtext-no-subs": "ē”åÆēØåå¹", + "mwe-timedtext-language-subtitles-for-clip": "ēꮵē$1åå¹ę件ļ¼$2", + "mwe-timedtext-language-no-subtitles-for-clip": "ę²ęę¾å°ēꮵē$1åå¹ę件ļ¼$2", + "mwe-timedtext-upload-timed-text": "ę·»å åå¹" +} diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.TextSource.js b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.TextSource.js new file mode 100644 index 00000000..cce8310f --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.TextSource.js @@ -0,0 +1,504 @@ +/** + * Base mw.TextSource object + * + * @param {Object} source Source object to extend + * @param {Object} textProvider [Optional] The text provider interface ( to load source from api ) + */ +( function( mw, $ ) { "use strict"; + + mw.TextSource = function( source ) { + return this.init( source ); + }; + mw.TextSource.prototype = { + + //The load state: + loaded: false, + + // Container for the captions + // captions include "start", "end" and "content" fields + captions: [], + + // The css style for captions ( some file formats specify display types ) + styleCss: {}, + + // The previous index of the timed text served + // Avoids searching the entire array on time updates. + prevIndex: 0, + + /** + * @constructor Inherits mediaSource from embedPlayer + * @param {source} Base source element + * @param {Object} Pointer to the textProvider + */ + init: function( source , textProvider) { + // Inherits mediaSource + for( var i in source){ + this[ i ] = source[ i ]; + } + + // Set default category to subtitle if unset: + if( ! this.kind ) { + this.kind = 'subtitle'; + } + //Set the textProvider if provided + if( textProvider ) { + this.textProvider = textProvider; + } + return this; + }, + + /** + * Function to load and parse the source text + * @param {Function} callback Function called once text source is loaded + */ + load: function( callback ) { + var _this = this; + mw.log("TextSource:: load src "+ _this.getSrc() ); + + // Setup up a callback ( in case it was not defined ) + if( !callback ){ + callback = function(){ return ; }; + } + + // Check if the captions have already been loaded: + if( this.loaded ){ + return callback(); + } + + // Try to load src via XHR source + if( !this.getSrc() ) { + mw.log( "Error: TextSource no source url for text track"); + return callback(); + } + + // Check type for special loaders: + $( mw ).triggerQueueCallback( 'TimedText_LoadTextSource', _this, function(){ + if( _this.loaded ){ + callback(); + } else { + // if no module loaded the text source use the normal ajax proxy: + new mw.ajaxProxy({ + url: _this.getSrc(), + success: function( resultXML ) { + _this.captions = _this.getCaptions( resultXML ); + _this.loaded = true; + mw.log("mw.TextSource :: loaded from " + _this.getSrc() + " Found: " + _this.captions.length + ' captions' ); + callback(); + }, + error: function() { + mw.log("Error: TextSource Error with http response"); + _this.loaded = true; + callback(); + } + }); + } + }) + }, + /** + * Returns the text content for requested time + * + * @param {Number} time Time in seconds + */ + getCaptionForTime: function ( time ) { + var prevCaption = this.captions[ this.prevIndex ]; + var captionSet = {}; + + // Setup the startIndex: + if( prevCaption && time >= prevCaption.start ) { + var startIndex = this.prevIndex; + }else{ + // If a backwards seek start searching at the start: + var startIndex = 0; + } + var firstCapIndex = 0; + // Start looking for the text via time, add all matches that are in range + for( var i = startIndex ; i < this.captions.length; i++ ) { + var caption = this.captions[ i ]; + // Don't handle captions with 0 or -1 end time: + if( caption.end == 0 || caption.end == -1) + continue; + + if( time >= caption.start && + time <= caption.end ) { + // set the earliest valid time to the current start index: + if( !firstCapIndex ){ + firstCapIndex = caption.start; + } + + //mw.log("Start cap time: " + caption.start + ' End time: ' + caption.end ); + captionSet[i] = caption ; + } + // captions are stored in start order stop search if we get larger than time + if( caption.start > time ){ + break; + } + } + // Update the prevIndex: + this.prevIndex = firstCapIndex; + //Return the set of captions in range: + return captionSet; + }, + + /** + * Check if the caption is an overlay format ( and must be ontop of the player ) + */ + isOverlay: function(){ + return this.mimeType == 'text/xml'; + }, + + getCaptions: function( data ){ + // Detect caption data type: + switch( this.mimeType ){ + case 'text/mw-srt': + return this.getCaptiosnFromMediaWikiSrt( data ); + break; + case 'text/x-srt': + return this.getCaptionsFromSrt( data); + break; + case 'text/xml': + return this.getCaptionsFromTMML( data ); + break; + } + // caption mime not found return empty set: + return []; + }, + + getStyleCssById: function( styleId ){ + if( this.styleCss[ styleId ] ){ + return this.styleCss[ styleId ]; + } + return {}; + }, + /** + * Grab timed text from TMML format + * + * @param data + * @return + */ + getCaptionsFromTMML: function( data ){ + var _this = this; + mw.log("TextSource::getCaptionsFromTMML", data); + // set up display information: + var captions = []; + var xml = ( $( data ).find("tt").length ) ? data : $.parseXML( data ); + + // Check for parse error: + try { + if( !xml || $( xml ).find('parsererror').length ){ + mw.log("Error: close caption parse error: " + $( xml ).find('parsererror').text() ); + return captions; + } + } catch ( e ) { + mw.log( "Error: close caption parse error: " + e.toString() ); + return captions; + } + + // Set the body Style + var bodyStyleId = $( xml ).find('body').attr('style'); + + // Set style translate ttml to css + $( xml ).find( 'style').each( function( inx, style){ + var cssObject = {}; + // Map CamelCase css properties: + $( style.attributes ).each(function(inx, attr){ + var attrName = attr.name; + if( attrName.substr(0, 4) !== 'tts:' ){ + // skip + return true; + } + var cssName = ''; + for( var c = 4; c < attrName.length; c++){ + if( attrName[c].toLowerCase() != attrName[c] ){ + cssName += '-' + attrName[c].toLowerCase(); + } else { + cssName+= attrName[c] + } + } + cssObject[ cssName ] = attr.nodeValue; + }); + // for(var i =0; i< style.length ) + _this.styleCss[ $( style).attr('id') ] = cssObject; + }); + + $( xml ).find( 'p' ).each( function( inx, p ){ + // Get text content by converting ttml node to html + var content = ''; + $.each( p.childNodes, function(inx, node){ + content+= _this.convertTTML2HTML( node ); + }); + // Get the end time: + var end = null; + if( $( p ).attr( 'end' ) ){ + end = mw.npt2seconds( $( p ).attr( 'end' ) ); + } + // Look for dur + if( !end && $( p ).attr( 'dur' )){ + end = mw.npt2seconds( $( p ).attr( 'begin' ) ) + + mw.npt2seconds( $( p ).attr( 'dur' ) ); + } + + // Create the caption object : + var captionObj ={ + 'start': mw.npt2seconds( $( p ).attr( 'begin' ) ), + 'end': end, + 'content': content + }; + + // See if we have custom metadata for position of this caption object + // there are 35 columns across and 15 rows high + var $meta = $(p).find( 'metadata' ); + if( $meta.length ){ + captionObj['css'] = { + 'position': 'absolute' + }; + if( $meta.attr('cccol') ){ + captionObj['css']['left'] = ( $meta.attr('cccol') / 35 ) * 100 +'%'; + // also means the width has to be reduced: + //captionObj['css']['width'] = 100 - parseInt( captionObj['css']['left'] ) + '%'; + } + if( $meta.attr('ccrow') ){ + captionObj['css']['top'] = ( $meta.attr('ccrow') / 15 ) * 100 +'%'; + } + } + if( $(p).attr('tts:textAlign') ){ + if( !captionObj['css'] ){ + captionObj['css'] = {}; + } + captionObj['css']['text-align'] = $(p).attr('tts:textAlign'); + + // Remove text align is "right" flip the css left: + if( captionObj['css']['text-align'] == 'right' && captionObj['css']['left'] ){ + //captionObj['css']['width'] = captionObj['css']['left']; + captionObj['css']['left'] = null; + } + } + + // check if this p has any style else use the body parent + if( $(p).attr('style') ){ + captionObj['styleId'] = $(p).attr('style') ; + } else { + captionObj['styleId'] = bodyStyleId; + } + captions.push( captionObj); + }); + return captions; + }, + convertTTML2HTML: function( node ){ + var _this = this; + + // look for text node: + if( node.nodeType == 3 ){ + return node.textContent; + } + // skip metadata nodes: + if( node.nodeName == 'metadata' ){ + return ''; + } + // if a br just append + if( node.nodeName == 'br' ){ + return '<br />'; + } + // Setup tts mappings TODO should be static property of a ttmlSource object. + var ttsStyleMap = { + 'tts:color' : 'color', + 'tts:fontWeight' : 'font-weight', + 'tts:fontStyle' : 'font-style' + }; + if( node.childNodes.length ){ + var nodeString = ''; + var styleVal = ''; + for( var attr in ttsStyleMap ){ + if( node.getAttribute( attr ) ){ + styleVal+= ttsStyleMap[ attr ] + ':' + node.getAttribute( attr ) + ';'; + } + } + nodeString += '<' + node.nodeName + ' style="' + styleVal + '" >'; + $.each( node.childNodes, function( inx, childNode ){ + nodeString += _this.convertTTML2HTML( childNode ); + }); + nodeString += '</' + node.nodeName + '>'; + return nodeString; + } + }, + /** + * srt timed text parse handle: + * @param {String} data Srt string to be parsed + */ + getCaptionsFromSrt: function ( data ){ + mw.log("TextSource::getCaptionsFromSrt"); + var _this = this; + // Check if the "srt" parses as an XML + try{ + var xml = $.parseXML( data ); + if( xml && $( xml ).find('parsererror').length == 0 ){ + return this.getCaptionsFromTMML( data ); + } + } catch ( e ){ + // srt should not be xml + } + // Remove dos newlines + var srt = data.replace(/\r+/g, ''); + + // Trim white space start and end + srt = srt.replace(/^\s+|\s+$/g, ''); + + // Remove all html tags for security reasons + srt = srt.replace(/<[a-zA-Z\/][^>]*>/g, ''); + + // Get captions + var captions = []; + var caplist = srt.split('\n\n'); + for (var i = 0; i < caplist.length; i++) { + var captionText = ""; + var caption = false; + captionText = caplist[i]; + var s = captionText.split(/\n/); + if (s.length < 2) { + // file format error or comment lines + continue; + } + if (s[0].match(/^\d+$/) && s[1].match(/\d+:\d+:\d+/)) { + // ignore caption number in s[0] + // parse time string + var m = s[1].match(/(\d+):(\d+):(\d+)(?:,(\d+))?\s*--?>\s*(\d+):(\d+):(\d+)(?:,(\d+))?/); + if (m) { + caption = _this.match2caption( m ); + } else { + // Unrecognized timestring + continue; + } + if( caption ){ + // concatenate text lines to html text + caption['content'] = s.slice(2).join("<br>"); + } + } else { + // file format error or comment lines + continue; + } + // Add the current caption to the captions set: + captions.push( caption ); + } + + return captions; + }, + + /** + * Get srts from a mediawiki html / srt string + * + * Right now wiki -> html is not always friendly to our srt parsing. + * The long term plan is to move the srt parsing to server side and have the api + * server up the srt's times in JSON form + * + * Also see https://bugzilla.wikimedia.org/show_bug.cgi?id=29126 + * + * TODO move to mediaWiki specific module. + */ + getCaptiosnFromMediaWikiSrt: function( data ){ + mw.log("TimedText::getCaptiosnFromMediaWikiSrt:"); + var _this = this; + var captions = [ ]; + var curentCap = { + 'content': '' + }; + var parseNextAsTime = false; + // Note this string concatenation and html error wrapping sometimes causes + // parse issues where the wikitext includes many native <p /> tags without child + // subtitles. In prating this is not a deal breakers because the wikitext for + // TimedText namespace and associated srts already has a specific format. + // Long term we will move to server side parsing. + $( '<div>' + data + '</div>' ).find('p').each( function() { + var currentPtext = $(this).html(); + //mw.log( 'pText: ' + currentPtext ); + + // We translate raw wikitext gennerated html into a matched srt time sample. + // The raw html looks like: + // # + // hh:mm:ss,ms --> hh:mm:ss,ms + // text + // + // You can read more about the srt format here: + // http://en.wikipedia.org/wiki/SubRip + // + // We attempt to be fairly robust in our regular expression to catch a few + // srt variations such as omition of commas and empty text lines. + var m = currentPtext + .replace('-->', '-->') // restore --> with --> for easier srt parsing: + .match(/\d+\s([\d\-]+):([\d\-]+):([\d\-]+)(?:,([\d\-]+))?\s*--?>\s*([\d\-]+):([\d\-]+):([\d\-]+)(?:,([\d\-]+))?\n?(.*)/); + + if (m) { + captions.push( + _this.match2caption( m ) + ); + return true; + } + + /*** + * Handle multi line sytle output + * + * Handles cases parse cases where an entire line can't be parsed in the single + * regular expression above, Since the diffrent captions pars are outputed in + * diffrent <p /> tags by the wikitext parser output. + */ + + // Check if we have reached the end of a multi line match + if( parseInt( currentPtext ) == currentPtext ) { + if( curentCap.content != '' ) { + captions.push( curentCap ); + } + // Clear out the current caption content + curentCap = { + 'content': '' + }; + return true; + } + // Check only for time match: + var m = currentPtext + .replace('-->', '-->') + .match(/(\d+):(\d+):(\d+)(?:,(\d+))?\s*--?>\s*(\d+):(\d+):(\d+)(?:,(\d+))?/); + if (m) { + // Update the currentCap: + curentCap = _this.match2caption( m ); + return true; + } + // Else append contnet for the curentCap + if( currentPtext != '<br>' ) { + curentCap['content'] += currentPtext; + } + }); + //Push last subtitle: + if( curentCap.length != 0) { + captions.push( curentCap ); + } + mw.log( "TimedText::getCaptiosnFromMediaWikiSrt found " + captions.length + ' captions'); + return captions; + }, + /** + * Takes a regular expresion match and converts it to a caption object + */ + match2caption: function( m ){ + var caption = {}; + // Look for ms: + var startMs = (m[4]) ? parseInt(m[4], 10) : 0; + var endMs = (m[8]) ? parseInt(m[8], 10) : 0; + caption['start'] = this.timeParts2seconds( m[1], m[2], m[3], startMs ); + caption['end'] = this.timeParts2seconds( m[5], m[6], m[7], endMs ); + if( m[9] ){ + caption['content'] = $.trim( m[9] ); + } + return caption; + }, + /** + * Takes time parts in hours, min, seconds and milliseconds and coverts to float seconds. + */ + timeParts2seconds: function( hours, min, sec, ms ){ + return mw.measurements2seconds({ + 'hours': hours, + 'minutes': min, + 'seconds' : sec, + 'milliseconds': ms + }); + } + }; + + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.TimedText.js b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.TimedText.js new file mode 100644 index 00000000..2a69343e --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.TimedText.js @@ -0,0 +1,1313 @@ +/** + * The Core timed Text interface object + * + * handles class mappings for: + * menu display ( jquery.ui themeable ) + * timed text loading request + * timed text edit requests + * timed text search & seek interface ( version 2 ) + * + * @author: Michael Dale + * + */ + +( function( mw, $ ) {"use strict"; + + // Merge in timed text related attributes: + mw.mergeConfig( 'EmbedPlayer.SourceAttributes', [ + 'srclang', + 'kind', + 'label' + ]); + + /** + * Timed Text Object + * @param embedPlayer Host player for timedText interfaces + */ + mw.TimedText = function( embedPlayer ) { + return this.init( embedPlayer ); + }; + + mw.TimedText.prototype = { + + /** + * Preferences config order is presently: + * 1) user cookie + * 2) defaults provided in this config var: + */ + config: { + // Layout for basic "timedText" type can be 'ontop', 'off', 'below' + 'layout' : 'ontop', + + //Set the default local ( should be grabbed from the browser ) + 'userLanguage' : mw.config.get( 'wgUserLanguage' ) || 'en', + + //Set the default kind of timedText to display ( un-categorized timed-text is by default "subtitles" ) + 'userKind' : 'subtitles' + }, + + // The default display mode is 'ontop' + defaultDisplayMode : 'ontop', + + // Save last layout mode + lastLayout : 'ontop', + + // The bind prefix: + bindPostFix: '.timedText', + + // Default options are empty + options: {}, + + /** + * The list of enabled sources + */ + enabledSources: [], + + // First loading flag - To set the layout at first load + firstLoad: true, + + /** + * The current language key + */ + currentLangKey : null, + + /** + * The direction of the current language + */ + currentLangDir : null, + + /** + * Stores the last text string per kind to avoid dom checks for updated text + */ + prevText: [], + + /** + * Text sources ( a set of textSource objects ) + */ + textSources: [], + + /** + * Valid "Track" categories + */ + validCategoriesKeys: [ + "CC", + "SUB", + "TAD", + "KTV", + "TIK", + "AR", + "NB", + "META", + "TRX", + "LRC", + "LIN", + "CUE" + ], + + /** + * @constructor + * @param {Object} embedPlayer Host player for timedText interfaces + */ + init: function( embedPlayer ) { + var _this = this; + mw.log("TimedText: init() "); + this.embedPlayer = embedPlayer; + // don't display captions on native player: + if( embedPlayer.useNativePlayerControls() ){ + return this; + } + + // Load user preferences config: + var preferenceConfig = $.cookie( 'TimedText.Preferences' ); + if( preferenceConfig !== "false" && preferenceConfig != null ) { + this.config = JSON.parse( preferenceConfig ); + } + // remove any old bindings on change media: + $( this.embedPlayer ).bind( 'onChangeMedia' + this.bindPostFix , function(){ + _this.destroy(); + }); + + // Remove any old bindings before we add the current bindings: + _this.destroy(); + + // Add player bindings + _this.addPlayerBindings(); + return this; + }, + destroy: function(){ + // remove any old player bindings; + $( this.embedPlayer ).unbind( this.bindPostFix ); + // Clear out enabled sources: + this.enabledSources = []; + // Clear out text sources: + this.textSources = []; + }, + /** + * Add timed text related player bindings + * @return + */ + addPlayerBindings: function(){ + var _this = this; + var embedPlayer = this.embedPlayer; + + // Check for timed text support: + _this.addInterface(); + + $( embedPlayer ).bind( 'timeupdate' + this.bindPostFix, function( event, jEvent, id ) { + // regain scope + _this = $('#' + id)[0].timedText; + // monitor text updates + _this.monitor(); + } ); + + $( embedPlayer ).bind( 'firstPlay' + this.bindPostFix, function(event, id ) { + // regain scope + _this = $('#' + id)[0].timedText; + // Will load and setup timedText sources (if not loaded already loaded ) + _this.setupTextSources(); + // Hide the caption menu if presently displayed + $( '#textMenuContainer_' + _this.embedPlayer.id ).hide(); + } ); + + // Re-Initialize when changing media + $( embedPlayer ).bind( 'onChangeMedia' + this.bindPostFix, function() { + _this.destroy(); + _this.updateLayout(); + _this.setupTextSources(); + $( '#textMenuContainer_' + embedPlayer.id ).hide(); + } ); + + // Resize the timed text font size per window width + $( embedPlayer ).bind( 'onCloseFullScreen' + this.bindPostFix + ' onOpenFullScreen' + this.bindPostFix, function() { + // Check if we are in fullscreen or not, if so add an additional bottom offset of + // double the default bottom padding. + var textOffset = _this.embedPlayer.controlBuilder.inFullScreen ? + mw.config.get("TimedText.BottomPadding") * 2 : + mw.config.get("TimedText.BottomPadding"); + + var textCss = _this.getInterfaceSizeTextCss({ + 'width' : embedPlayer.getInterface().width(), + 'height' : embedPlayer.getInterface().height() + }); + + mw.log( 'TimedText::set text size for: : ' + embedPlayer.getInterface().width() + ' = ' + textCss['font-size'] ); + if ( embedPlayer.controlBuilder.isOverlayControls() && !embedPlayer.getInterface().find( '.control-bar' ).is( ':hidden' ) ) { + textOffset += _this.embedPlayer.controlBuilder.getHeight(); + } + embedPlayer.getInterface().find( '.track' ) + .css( textCss ) + .css({ + // Get the text size scale then set it to control bar height + TimedText.BottomPadding; + 'bottom': textOffset + 'px' + }); + }); + + // Update the timed text size + $( embedPlayer ).bind( 'updateLayout'+ this.bindPostFix, function() { + // If the the player resize action is an animation, animate text resize, + // else instantly adjust the css. + var textCss = _this.getInterfaceSizeTextCss( { + 'width': embedPlayer.getPlayerWidth(), + 'height': embedPlayer.getPlayerHeight() + }); + mw.log( 'TimedText::updateLayout: ' + textCss['font-size']); + embedPlayer.getInterface().find( '.track' ).css( textCss ); + }); + + // Setup display binding + $( embedPlayer ).bind( 'onShowControlBar'+ this.bindPostFix, function(event, layout, id ){ + // update embedPlayer ref: + var embedPlayer = $('#' + id )[0]; + if ( embedPlayer.controlBuilder.isOverlayControls() ) { + // Move the text track if present + embedPlayer.getInterface().find( '.track' ) + .stop() + .animate( layout, 'fast' ); + } + }); + + $( embedPlayer ).bind( 'onHideControlBar' + this.bindPostFix, function(event, layout, id ){ + var embedPlayer = $('#' + id )[0]; + if ( embedPlayer.controlBuilder.isOverlayControls() ) { + // Move the text track down if present + embedPlayer.getInterface().find( '.track' ) + .stop() + .animate( layout, 'fast' ); + } + }); + + $( embedPlayer ).bind( 'AdSupport_StartAdPlayback' + this.bindPostFix, function() { + if ( $( '#textMenuContainer_' + embedPlayer.id ).length ) { + $( '#textMenuContainer_' + embedPlayer.id ).hide(); + } + var $textButton = embedPlayer.getInterface().find( '.timed-text' ); + if ( $textButton.length ) { + $textButton.unbind( 'click' ); + } + _this.lastLayout = _this.getLayoutMode(); + _this.setLayoutMode( 'off' ); + } ); + + $( embedPlayer ).bind( 'AdSupport_EndAdPlayback' + this.bindPostFix, function() { + var $textButton = embedPlayer.getInterface().find( '.timed-text' ); + if ( $textButton.length ) { + _this.bindTextButton( $textButton ); + } + _this.setLayoutMode( _this.lastLayout ); + } ); + + }, + addInterface: function(){ + var _this = this; + // By default we include a button in the control bar. + $( _this.embedPlayer ).bind( 'addControlBarComponent' + this.bindPostFix, function(event, controlBar ){ + if( controlBar.supportedComponents['timedText'] !== false && + _this.includeCaptionButton() ) { + controlBar.supportedComponents['timedText'] = true; + controlBar.components['timedText'] = _this.getTimedTextButton(); + } + }); + }, + includeCaptionButton:function(){ + return mw.config.get( 'TimedText.ShowInterface' ) == 'always' || + this.embedPlayer.getTextTracks().length; + }, + /** + * Get the current language key + * @return + * @type {string} + */ + getCurrentLangKey: function(){ + return this.currentLangKey; + }, + /** + * Get the current language direction + * @return + * @type {string} + */ + getCurrentLangDir: function(){ + if ( !this.currentLangDir ) { + var source = this.getSourceByLanguage( this.getCurrentLangKey() ); + this.currentLangDir = source.dir; + } + return this.currentLangDir; + }, + + /** + * The timed text button to be added to the interface + */ + getTimedTextButton: function(){ + var _this = this; + /** + * The closed captions button + */ + return { + 'w': 30, + 'position': 6.9, + 'o': function( ctrlObj ) { + var $textButton = $( '<div />' ) + .attr( 'title', mw.msg( 'mwe-embedplayer-timed_text' ) ) + .addClass( "ui-state-default ui-corner-all ui-icon_link rButton timed-text" ) + .append( + $( '<span />' ) + .addClass( "ui-icon ui-icon-comment" ) + ) + // Captions binding: + .buttonHover(); + _this.bindTextButton( $textButton ); + return $textButton; + + } + }; + }, + bindTextButton: function( $textButton ){ + var _this = this; + $textButton.unbind('click.textMenu').bind('click.textMenu', function() { + _this.showTextMenu(); + return true; + } ); + }, + + /** + * Get the fullscreen text css + */ + getInterfaceSizeTextCss: function( size ) { + //mw.log(' win size is: ' + $( window ).width() + ' ts: ' + textSize ); + return { + 'font-size' : this.getInterfaceSizePercent( size ) + '%' + }; + }, + + /** + * Show the text interface library and show the text interface near the player. + */ + showTextMenu: function() { + var embedPlayer = this.embedPlayer; + var loc = embedPlayer.getInterface().find( '.rButton.timed-text' ).offset(); + mw.log('TimedText::showTextMenu:: ' + embedPlayer.id + ' location: ', loc); + // TODO: Fix menu animation + var $menuButton = this.embedPlayer.getInterface().find( '.timed-text' ); + // Check if a menu has already been built out for the menu button: + if ( $menuButton[0].m ) { + $menuButton.embedMenu( 'show' ); + } else { + // Bind the text menu: + this.buildMenu( true ); + } + }, + getTextMenuContainer: function(){ + var textMenuId = 'textMenuContainer_' + this.embedPlayer.id; + if( !$( '#' + textMenuId ).length ){ + //Setup the menu: + this.embedPlayer.getInterface().append( + $('<div>') + .addClass('ui-widget ui-widget-content ui-corner-all') + .attr( 'id', textMenuId ) + .css( { + 'position' : 'absolute', + 'height' : '180px', + 'width' : '180px', + 'font-size' : '12px', + 'display' : 'none', + 'overflow' : 'auto' + } ) + + ); + } + return $( '#' + textMenuId ); + }, + /** + * Gets a text size percent relative to about 30 columns of text for 400 + * pixel wide player, at 100% text size. + * + * @param size {object} The size of the target player area width and height + */ + getInterfaceSizePercent: function( size ) { + // This is a ugly hack we should read "original player size" and set based + // on some standard ish normal 31 columns 15 rows + var sizeFactor = 4; + if( size.height / size.width < .7 ){ + sizeFactor = 6; + } + var textSize = size.width / sizeFactor; + if( textSize < 95 ){ + textSize = 95; + } + if( textSize > 150 ){ + textSize = 150; + } + return textSize; + }, + + /** + * Setups available text sources + * loads text sources + * auto-selects a source based on the user language + * @param {Function} callback Function to be called once text sources are setup. + */ + setupTextSources: function( callback ) { + mw.log( 'TimedText::setupTextSources'); + var _this = this; + // Load textSources + _this.loadTextSources( function() { + // Enable a default source and issue a request to "load it" + _this.autoSelectSource(); + + // Load and parse the text value of enabled text sources: + _this.loadEnabledSources(); + + if( callback ) { + callback(); + } + } ); + }, + + /** + * Binds the timed text menu + * and updates its content from "getMainMenu" + * + * @param {Object} target to display the menu + * @param {Boolean} autoShow If the menu should be displayed + */ + buildMenu: function( autoShow ) { + var _this = this; + var embedPlayer = this.embedPlayer; + // Setup text sources ( will callback inline if already loaded ) + _this.setupTextSources( function() { + var $menuButton = _this.embedPlayer.getInterface().find( '.timed-text' ); + + var positionOpts = { }; + if( _this.embedPlayer.supports[ 'overlays' ] ){ + var positionOpts = { + 'directionV' : 'up', + 'offsetY' : _this.embedPlayer.controlBuilder.getHeight(), + 'directionH' : 'left', + 'offsetX' : -28 + }; + } + + if( !_this.embedPlayer.getInterface() ){ + mw.log("TimedText:: interface called before interface ready, just wait for interface"); + return ; + } + var $menuButton = _this.embedPlayer.getInterface().find( '.timed-text' ); + var ctrlObj = _this.embedPlayer.controlBuilder; + // NOTE: Button target should be an option or config + $menuButton.embedMenu( { + 'content' : _this.getMainMenu(), + 'zindex' : mw.config.get( 'EmbedPlayer.FullScreenZIndex' ) + 2, + 'crumbDefaultText' : ' ', + 'autoShow': autoShow, + 'keepPosition' : true, + 'showSpeed': 0, + 'height' : 100, + 'width' : 300, + 'targetMenuContainer' : _this.getTextMenuContainer(), + 'positionOpts' : positionOpts, + 'backLinkText' : mw.msg( 'mwe-timedtext-back-btn' ), + 'createMenuCallback' : function(){ + var $interface = _this.embedPlayer.getInterface(); + var $textContainer = _this.getTextMenuContainer(); + var textHeight = 130; + var top = $interface.height() - textHeight - ctrlObj.getHeight() - 6; + if( top < 0 ){ + top = 0; + } + // check for audio + if( _this.embedPlayer.isAudio() ){ + top = _this.embedPlayer.controlBuilder.getHeight() + 4; + } + $textContainer.css({ + 'top' : top, + 'height': textHeight, + 'position' : 'absolute', + 'left': $menuButton[0].offsetLeft - 165, + 'bottom': ctrlObj.getHeight() + }) + ctrlObj.showControlBar( true ); + }, + 'closeMenuCallback' : function(){ + ctrlObj.restoreControlsHover(); + } + }); + }); + }, + + /** + * Monitor video time and update timed text filed[s] + */ + monitor: function() { + //mw.log(" timed Text monitor: " + this.enabledSources.length ); + var embedPlayer = this.embedPlayer; + // Setup local reference to currentTime: + var currentTime = embedPlayer.currentTime; + + // Get the text per kind + var textCategories = [ ]; + + var source = this.enabledSources[ 0 ]; + if( source ) { + this.updateSourceDisplay( source, currentTime ); + } + }, + + /** + * Load all the available text sources from the inline embed + * @param {Function} callback Function to call once text sources are loaded + */ + loadTextSources: function( callback ) { + var _this = this; + // check if text sources are already loaded ( not em ) + if( this.textSources.length ){ + callback( this.textSources ); + return ; + } + this.textSources = []; + // load inline text sources: + $.each( this.embedPlayer.getTextTracks(), function( inx, textSource ){ + _this.textSources.push( new mw.TextSource( textSource ) ); + }); + // return the callback with sources + callback( _this.textSources ); + }, + + /** + * Get the layout mode + * + * Takes into consideration: + * Playback method overlays support ( have to put subtitles below video ) + * + */ + getLayoutMode: function() { + // Re-map "ontop" to "below" if player does not support + if( this.config.layout == 'ontop' && !this.embedPlayer.supports['overlays'] ) { + this.config.layout = 'below'; + } + return this.config.layout; + }, + + /** + * Auto selects a source given the local configuration + * + * NOTE: presently this selects a "single" source. + * In the future we could support multiple "enabled sources" + */ + autoSelectSource: function() { + var _this = this; + // If a source is enabled then don't auto select + if ( this.enabledSources.length ) { + return false; + } + this.enabledSources = []; + + var setDefault = false; + // Check if any source is marked default: + $.each( this.textSources, function(inx, source){ + if( source['default'] ){ + _this.enableSource( source ); + setDefault = true; + return false; + } + }); + if ( setDefault ) { + return true; + } + + var setLocalPref = false; + // Check if any source matches our "local" pref + $.each( this.textSources, function(inx, source){ + if( _this.config.userLanguage == source.srclang.toLowerCase() + && + _this.config.userKind == source.kind + ) { + _this.enableSource( source ); + setLocalPref = true; + return false; + } + }); + if ( setLocalPref ) { + return true; + } + + var setEnglish = false; + // If no userLang, source try enabling English: + if( this.enabledSources.length == 0 ) { + for( var i=0; i < this.textSources.length; i++ ) { + var source = this.textSources[ i ]; + if( source.srclang.toLowerCase() == 'en' ) { + _this.enableSource( source ); + setEnglish = true; + return false; + } + } + } + if ( setEnglish ) { + return true; + } + + var setFirst = false; + // If still no source try the first source we get; + if( this.enabledSources.length == 0 ) { + for( var i=0; i < this.textSources.length; i++ ) { + var source = this.textSources[ i ]; + _this.enableSource( source ); + setFirst = true; + return false; + } + } + if ( setFirst ) { + return true; + } + + return false; + }, + /** + * Enable a source and update the currentLangKey + * @param {object} source + * @return + */ + enableSource: function( source ){ + var _this = this; + // check if we have any source set yet: + if( !_this.enabledSources.length ){ + _this.enabledSources.push( source ); + _this.currentLangKey = source.srclang; + _this.currentLangDir = null; + return ; + } + var sourceEnabled = false; + // Make sure the source is not already enabled + $.each( this.enabledSources, function( inx, enabledSource ){ + if( source.id == enabledSource.id ){ + sourceEnabled = true; + } + }); + if ( !sourceEnabled ) { + _this.enabledSources.push( source ); + _this.currentLangKey = source.srclang; + _this.currentLangDir = null; + } + }, + + /** + * Get the current source sub captions + * @param {function} callback function called once source is loaded + */ + loadCurrentSubSource: function( callback ){ + mw.log("loadCurrentSubSource:: enabled source:" + this.enabledSources.length); + for( var i =0; i < this.enabledSources.length; i++ ){ + var source = this.enabledSources[i]; + if( source.kind == 'SUB' ){ + source.load( function(){ + callback( source); + return ; + }); + } + } + return false; + }, + + /** + * Get sub captions by language key: + * + * @param {string} langKey Key of captions to load + * @pram {function} callback function called once language key is loaded + */ + getSubCaptions: function( langKey, callback ){ + for( var i=0; i < this.textSources.length; i++ ) { + var source = this.textSources[ i ]; + if( source.srclang.toLowerCase() === langKey ) { + var source = this.textSources[ i ]; + source.load( function(){ + callback( source.captions ); + }); + } + } + }, + + /** + * Issue a request to load all enabled Sources + * Should be called anytime enabled Source list is updated + */ + loadEnabledSources: function() { + var _this = this; + mw.log( "TimedText:: loadEnabledSources " + this.enabledSources.length ); + $.each( this.enabledSources, function( inx, enabledSource ) { + // check if the source requires ovelray ( ontop ) layout mode: + if( enabledSource.isOverlay() && _this.config.layout== 'ontop' ){ + _this.setLayoutMode( 'ontop' ); + } + enabledSource.load(function(){ + // Trigger the text loading event: + $( _this.embedPlayer ).trigger('loadedTextSource', enabledSource); + }); + }); + }, + /** + * Checks if a source is "on" + * @return {Boolean} + * true if source is on + * false if source is off + */ + isSourceEnabled: function( source ) { + // no source is "enabled" if subtitles are "off" + if( this.getLayoutMode() == 'off' ){ + return false; + } + var isEnabled = false; + $.each( this.enabledSources, function( inx, enabledSource ) { + if( source.id ) { + if( source.id === enabledSource.id ){ + isEnabled = true; + } + } + if( source.src ){ + if( source.src == enabledSource.src ){ + isEnabled = true; + } + } + }); + return isEnabled; + }, + + /** + * Marks the active captions in the menu + */ + markActive: function( source ) { + var $menu = $( '#textMenuContainer_' + this.embedPlayer.id ); + if ( $menu.length ) { + var $captionRows = $menu.find( '.captionRow' ); + if ( $captionRows.length ) { + $captionRows.each( function() { + $( this ).removeClass( 'ui-icon-bullet ui-icon-radio-on' ); + var iconClass = ( $( this ).data( 'caption-id' ) === source.id ) ? 'ui-icon-bullet' : 'ui-icon-radio-on'; + $( this ).addClass( iconClass ); + } ); + } + } + }, + + /** + * Marks the active layout mode in the menu + */ + markLayoutActive: function ( layoutMode ) { + var $menu = $( '#textMenuContainer_' + this.embedPlayer.id ); + if ( $menu.length ) { + var $layoutRows = $menu.find( '.layoutRow' ); + if ( $layoutRows.length ) { + $layoutRows.each( function() { + $( this ).removeClass( 'ui-icon-bullet ui-icon-radio-on' ); + var iconClass = ( $( this ).data( 'layoutMode' ) === layoutMode ) ? 'ui-icon-bullet' : 'ui-icon-radio-on'; + $( this ).addClass( iconClass ); + } ); + } + } + }, + + /** + * Get a source object by language, returns "false" if not found + * @param {string} langKey The language key filter for selected source + */ + getSourceByLanguage: function ( langKey ) { + for(var i=0; i < this.textSources.length; i++) { + var source = this.textSources[ i ]; + if( source.srclang == langKey ){ + return source; + } + } + return false; + }, + + /** + * Builds the core timed Text menu and + * returns the binded jquery object / dom set + * + * Assumes text sources have been setup: ( _this.setupTextSources() ) + * + * calls a few sub-functions: + * Basic menu layout: + * Chose Language + * All Subtiles here ( if we have categories list them ) + * Layout + * Below video + * Ontop video ( only available to supported plugins ) + * TODO features: + * [ Search Text ] + * [ This video ] + * [ All videos ] + * [ Chapters ] seek to chapter + */ + getMainMenu: function() { + var _this = this; + + // Set the menut to avaliable languages: + var $menu = _this.getLanguageMenu(); + + if( _this.textSources.length == 0 ){ + $menu.append( + $.getLineItem( mw.msg( 'mwe-timedtext-no-subs'), 'close' ) + ); + } else { + // Layout Menu option if not in an iframe and we can expand video size: + $menu.append( + $.getLineItem( + mw.msg( 'mwe-timedtext-layout-off'), + ( _this.getLayoutMode() == 'off' ) ? 'bullet' : 'radio-on', + function() { + _this.setLayoutMode( 'off' ); + }, + 'layoutRow', + { 'layoutMode' : 'off' } + ) + ) + } + // Allow other modules to add to the timed text menu: + $( _this.embedPlayer ).trigger( 'TimedText_BuildCCMenu', [ $menu, _this.embedPlayer.id ] ) ; + + // Test if only one menu item move its children to the top level + if( $menu.children('li').length == 1 ){ + $menu.find('li > ul > li').detach().appendTo( $menu ); + $menu.find('li').eq(0).remove(); + } + + return $menu; + }, + + /** + * Utility function to assist in menu build out: + * Get menu line item (li) html: <li><a> msgKey </a></li> + * + * @param {String} msgKey Msg key for menu item + */ + + /** + * Get line item (li) from source object + * @param {Object} source Source to get menu line item from + */ + getLiSource: function( source ) { + var _this = this; + //See if the source is currently "on" + var sourceIcon = ( this.isSourceEnabled( source ) )? 'bullet' : 'radio-on'; + if( source.title ) { + return $.getLineItem( source.title, sourceIcon, function() { + _this.selectTextSource( source ); + }, 'captionRow', { 'caption-id' : source.id } ); + } + if( source.srclang ) { + var langKey = source.srclang.toLowerCase(); + return $.getLineItem( + mw.msg('mwe-timedtext-key-language', langKey, _this.getLanguageName ( langKey ) ), + sourceIcon, + function() { + // select the current text source: + _this.selectTextSource( source ); + }, + 'captionRow', + { 'caption-id' : source.id } + ); + } + }, + + /** + * Get language name from language key + * @param {String} lang_key Language key + */ + getLanguageName: function( lang_key ) { + if( mw.Language.names[ lang_key ]) { + return mw.Language.names[ lang_key ]; + } + return false; + }, + + + /** + * set the layout mode + * @param {Object} layoutMode The selected layout mode + */ + setLayoutMode: function( layoutMode ) { + var _this = this; + mw.log("TimedText:: setLayoutMode: " + layoutMode + ' ( old mode: ' + _this.config.layout + ' )' ); + if( ( layoutMode != _this.config.layout ) || _this.firstLoad ) { + // Update the config and redraw layout + _this.config.layout = layoutMode; + // Update the display: + _this.updateLayout(); + _this.firstLoad = false; + } + _this.markLayoutActive( layoutMode ); + }, + + toggleCaptions: function(){ + mw.log( "TimedText:: toggleCaptions was:" + this.config.layout ); + if( this.config.layout == 'off' ){ + this.setLayoutMode( this.defaultDisplayMode ); + } else { + this.setLayoutMode( 'off' ); + } + }, + /** + * Updates the timed text layout ( should be called when config.layout changes ) + */ + updateLayout: function() { + mw.log( "TimedText:: updateLayout " ); + var $playerTarget = this.embedPlayer.getInterface(); + if( $playerTarget ) { + // remove any existing caption containers: + $playerTarget.find('.captionContainer,.captionsOverlay').remove(); + } + this.refreshDisplay(); + }, + + /** + * Select a new source + * + * @param {Object} source Source object selected + */ + selectTextSource: function( source ) { + var _this = this; + mw.log("TimedText:: selectTextSource: select lang: " + source.srclang ); + + // enable last non-off layout: + _this.setLayoutMode( _this.lastLayout ); + + // For some reason we lose binding for the menu ~sometimes~ re-bind + this.bindTextButton( this.embedPlayer.getInterface().find('timed-text') ); + + this.currentLangKey = source.srclang; + this.currentLangDir = null; + + // Update the config language if the source includes language + if( source.srclang ){ + this.config.userLanguage = source.srclang; + } + + if( source.kind ){ + this.config.userKind = source.kind; + } + + // (@@todo update kind & setup kind language buckets? ) + + // Remove any other sources selected in sources kind + this.enabledSources = []; + + this.enabledSources.push( source ); + + // Set any existing text target to "loading" + if( !source.loaded ) { + var $playerTarget = this.embedPlayer.getInterface(); + $playerTarget.find('.track').text( mw.msg('mwe-timedtext-loading-text') ); + // Load the text: + source.load( function(){ + // Refresh the interface: + _this.refreshDisplay(); + }); + } else { + _this.refreshDisplay(); + } + + _this.markActive( source ); + + // Trigger the event + $( this.embedPlayer ).trigger( 'TimedText_ChangeSource' ); + }, + + /** + * Refresh the display, updates the timedText layout, menu, and text display + * also updates the cookie preference. + * + * Called after a user option change + */ + refreshDisplay: function() { + // Update the configuration object + $.cookie( 'TimedText.Preferences', JSON.stringify( this.config ) ); + + // Empty out previous text to force an interface update: + this.prevText = []; + + // Refresh the Menu (if it has a target to refresh) + mw.log( 'TimedText:: bind menu refresh display' ); + this.buildMenu(); + this.resizeInterface(); + + // add an empty catption: + this.displayTextTarget( $( '<span /> ').text( '') ); + + // Issues a "monitor" command to update the timed text for the new layout + this.monitor(); + }, + + /** + * Builds the language source list menu + * Cehck if the "track" tags had the "kind" attribute. + * + * The kind attribute forms "categories" of text tracks like "subtitles", + * "audio description", "chapter names". We check for these categories + * when building out the language menu. + */ + getLanguageMenu: function() { + var _this = this; + + // See if we have categories to worry about + // associative array of SUB etc categories. Each kind contains an array of textSources. + var categorySourceList = {}; + var sourcesWithCategoryCount = 0; + + // ( All sources should have a kind (depreciate ) + var sourcesWithoutCategory = [ ]; + for( var i=0; i < this.textSources.length; i++ ) { + var source = this.textSources[ i ]; + if( source.kind ) { + var categoryKey = source.kind ; + // Init Category menu item if it does not already exist: + if( !categorySourceList[ categoryKey ] ) { + // Set up catList pointer: + categorySourceList[ categoryKey ] = []; + sourcesWithCategoryCount++; + } + // Append to the source kind key menu item: + categorySourceList[ categoryKey ].push( + _this.getLiSource( source ) + ); + }else{ + sourcesWithoutCategory.push( _this.getLiSource( source ) ); + } + } + var $langMenu = $('<ul>'); + // Check if we have multiple categories ( if not just list them under the parent menu item) + if( sourcesWithCategoryCount > 1 ) { + for(var categoryKey in categorySourceList) { + var $catChildren = $('<ul>'); + for(var i=0; i < categorySourceList[ categoryKey ].length; i++) { + $catChildren.append( + categorySourceList[ categoryKey ][i] + ); + } + // Append a cat menu item for each kind list + // Give grep a chance to find the usages: + // mwe-timedtext-textcat-cc, mwe-timedtext-textcat-sub, mwe-timedtext-textcat-tad, + // mwe-timedtext-textcat-ktv, mwe-timedtext-textcat-tik, mwe-timedtext-textcat-ar, + // mwe-timedtext-textcat-nb, mwe-timedtext-textcat-meta, mwe-timedtext-textcat-trx, + // mwe-timedtext-textcat-lrc, mwe-timedtext-textcat-lin, mwe-timedtext-textcat-cue + $langMenu.append( + $.getLineItem( mw.msg( 'mwe-timedtext-textcat-' + categoryKey.toLowerCase() ) ).append( + $catChildren + ) + ); + } + } else { + for(var categoryKey in categorySourceList) { + for(var i=0; i < categorySourceList[ categoryKey ].length; i++) { + $langMenu.append( + categorySourceList[ categoryKey ][i] + ); + } + } + } + // Add any remaning sources that did nto have a category + for(var i=0; i < sourcesWithoutCategory.length; i++) { + $langMenu.append( sourcesWithoutCategory[i] ); + } + + return $langMenu; + }, + + /** + * Updates a source display in the interface for a given time + * @param {object} source Source to update + * @param {number} time Caption time used to add and remove active captions. + */ + updateSourceDisplay: function ( source, time ) { + var _this = this; + if( this.timeOffset ){ + time = time + parseInt( this.timeOffset ); + } + + // Get the source text for the requested time: + var activeCaptions = source.getCaptionForTime( time ); + var addedCaption = false; + // Show captions that are on: + $.each( activeCaptions, function( capId, caption ){ + var $cap = _this.embedPlayer.getInterface().find( '.track[data-capId="' + capId +'"]'); + if( caption.content != $cap.html() ){ + // remove old + $cap.remove(); + // add the updated value: + _this.addCaption( source, capId, caption ); + addedCaption = true; + } + }); + + // hide captions that are off: + _this.embedPlayer.getInterface().find( '.track' ).each(function( inx, caption){ + if( !activeCaptions[ $( caption ).attr('data-capId') ] ){ + if( addedCaption ){ + $( caption ).remove(); + } else { + $( caption ).fadeOut( mw.config.get('EmbedPlayer.MonitorRate'), function(){$(this).remove();} ); + } + } + }); + }, + addCaption: function( source, capId, caption ){ + if( this.getLayoutMode() == 'off' ){ + return ; + } + + // use capId as a class instead of id for easy selections and no conflicts with + // multiple players on page. + var $textTarget = $('<div />') + .addClass( 'track' ) + .attr( 'data-capId', capId ) + .hide(); + + // Update text ( use "html" instead of "text" so that subtitle format can + // include html formating + // TOOD we should scrub this for non-formating html + $textTarget.append( + $('<span>') + .addClass( 'ttmlStyled' ) + .css( 'pointer-events', 'auto') + .css( this.getCaptionCss() ) + .append( + $('<span>') + // Prevent background (color) overflowing TimedText + // http://stackoverflow.com/questions/9077887/avoid-overlapping-rows-in-inline-element-with-a-background-color-applied + .css( 'position', 'relative' ) + .html( caption.content ) + ) + ); + + + // Add/update the lang option + $textTarget.attr( 'lang', source.srclang.toLowerCase() ); + + // Update any links to point to a new window + $textTarget.find( 'a' ).attr( 'target', '_blank' ); + + // Add TTML or other complex text styles / layouts if we have ontop captions: + if( this.getLayoutMode() == 'ontop' ){ + if( caption.css ){ + $textTarget.css( caption.css ); + } else { + $textTarget.css( this.getDefaultStyle() ); + } + } + // Apply any custom style ( if we are ontop of the video ) + this.displayTextTarget( $textTarget ); + + // apply any interface size adjustments: + $textTarget.css( this.getInterfaceSizeTextCss({ + 'width' : this.embedPlayer.getInterface().width(), + 'height' : this.embedPlayer.getInterface().height() + }) + ); + + // Update the style of the text object if set + if( caption.styleId ){ + var capCss = source.getStyleCssById( caption.styleId ); + $textTarget.find('span.ttmlStyled').css( + capCss + ); + } + $textTarget.fadeIn('fast'); + }, + displayTextTarget: function( $textTarget ){ + var embedPlayer = this.embedPlayer; + var $interface = embedPlayer.getInterface(); + var controlBarHeight = embedPlayer.controlBuilder.getHeight(); + + if( this.getLayoutMode() == 'off' ){ + // sync player size per audio player: + if( embedPlayer.isAudio() ){ + $interface.find( '.overlay-win' ).css( 'top', controlBarHeight ); + $interface.css( 'height', controlBarHeight ); + } + return; + } + + if( this.getLayoutMode() == 'ontop' ){ + this.addTextOverlay( + $textTarget + ); + } else if( this.getLayoutMode() == 'below' ){ + this.addTextBelowVideo( $textTarget ); + } else { + mw.log("Possible Error, layout mode not recognized: " + this.getLayoutMode() ); + } + + // sync player size per audio player: + if( embedPlayer.isAudio() && embedPlayer.getInterface().height() < 80 ){ + $interface.find( '.overlay-win' ).css( 'top', 80); + $interface.css( 'height', 80 ); + + $interface.find('.captionsOverlay' ) + .css('bottom', embedPlayer.controlBuilder.getHeight() ) + } + + }, + getDefaultStyle: function(){ + var defaultBottom = 15; + if( this.embedPlayer.controlBuilder.isOverlayControls() && !this.embedPlayer.getInterface().find( '.control-bar' ).is( ':hidden' ) ) { + defaultBottom += this.embedPlayer.controlBuilder.getHeight(); + } + var baseCss = { + 'position':'absolute', + 'bottom': defaultBottom, + 'width': '100%', + 'display': 'block', + 'opacity': .8, + 'text-align': 'center' + }; + baseCss =$.extend( baseCss, this.getInterfaceSizeTextCss({ + 'width' : this.embedPlayer.getInterface().width(), + 'height' : this.embedPlayer.getInterface().height() + })); + return baseCss; + }, + addTextOverlay: function( $textTarget ){ + var _this = this; + var $captionsOverlayTarget = this.embedPlayer.getInterface().find('.captionsOverlay'); + var layoutCss = { + 'left': 0, + 'top': 0, + 'bottom': 0, + 'right': 0, + 'position': 'absolute', + 'direction': this.getCurrentLangDir(), + 'z-index': mw.config.get( 'EmbedPlayer.FullScreenZIndex' ) + }; + + if( $captionsOverlayTarget.length == 0 ){ + // TODO make this look more like addBelowVideoCaptionsTarget + $captionsOverlayTarget = $( '<div />' ) + .addClass( 'captionsOverlay' ) + .css( layoutCss ) + .css('pointer-events', 'none'); + this.embedPlayer.getVideoHolder().append( $captionsOverlayTarget ); + } + // Append the text: + $captionsOverlayTarget.append( $textTarget ); + + }, + /** + * Applies the default layout for a text target + */ + addTextBelowVideo: function( $textTarget ) { + var $playerTarget = this.embedPlayer.getInterface(); + // Get the relative positioned player class from the controlBuilder: + this.embedPlayer.controlBuilder.keepControlBarOnScreen = true; + if( !$playerTarget.find('.captionContainer').length || this.embedPlayer.useNativePlayerControls() ) { + this.addBelowVideoCaptionContainer(); + } + $playerTarget.find('.captionContainer').html( + $textTarget.css( { + 'color':'white' + } ) + ); + }, + addBelowVideoCaptionContainer: function(){ + var _this = this; + mw.log( "TimedText:: addBelowVideoCaptionContainer" ); + var $playerTarget = this.embedPlayer.getInterface(); + if( $playerTarget.find('.captionContainer').length ) { + return ; + } + // Append after video container + this.embedPlayer.getVideoHolder().after( + $('<div>').addClass( 'captionContainer block' ) + .css({ + 'width' : '100%', + 'height' : mw.config.get( 'TimedText.BelowVideoBlackBoxHeight' ) + 'px', + 'background-color' : '#000', + 'text-align' : 'center', + 'padding-top' : '5px' + } ) + ); + + _this.embedPlayer.triggerHelper('updateLayout'); + }, + /** + * Resize the interface for layoutMode == 'below' ( if not in full screen) + */ + resizeInterface: function(){ + var _this = this; + if( !_this.embedPlayer.controlBuilder ){ + // too soon + return ; + } + if( !_this.embedPlayer.controlBuilder.inFullScreen && _this.originalPlayerHeight ){ + _this.embedPlayer.triggerHelper( 'resizeIframeContainer', [{'height' : _this.originalPlayerHeight}] ); + } else { + // removed resize on container content, since syncPlayerSize calls now handle keeping player aspect. + _this.embedPlayer.triggerHelper('updateLayout'); + } + }, + /** + * Build css for caption using this.options + */ + getCaptionCss: function() { + return {}; + } + }; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.style.TimedText.css b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.style.TimedText.css new file mode 100644 index 00000000..e924ba34 --- /dev/null +++ b/extensions/TimedMediaHandler/MwEmbedModules/TimedText/resources/mw.style.TimedText.css @@ -0,0 +1,18 @@ +.ttmlStyled { + color: white; + letter-spacing: 0.04em; + text-align: center; + padding: 0.2em; + /* + // Text shadow is too slow with current browsers use background-color + text-shadow:0 2px 1px #000000, -1px 3px 1px #000000, -2px 2px 1px #000000, -2px 1px 1px #000000, -2px 0 1px #000000, 2px 2px 1px #000000, 1px 2px 1px #000000, 0 -2px 1px #000000, 2px -2px 1px #000000, -2px -1px 1px #000000, -1px -3px 1px #000000, -3px -2px 1px #000000, 0 0 25px #000000, 0 0 35px #000000, 0 0 35px #000000, 0 0 31px #FFFFFF, 0 0 31px #FFFFFF, 0 0 31px #FFFFFF; + */ + background-color: #333; +} +.ttmlStyled a { + text-decoration: none; + color : #BBF; +} +.ttmlStyled a:visited{ + color : #BBF; +} diff --git a/extensions/TimedMediaHandler/README b/extensions/TimedMediaHandler/README new file mode 100644 index 00000000..c37c5ad8 --- /dev/null +++ b/extensions/TimedMediaHandler/README @@ -0,0 +1,127 @@ +== TimedMediaHandler == + +This extension provides a media handler for the Ogg, WebM, mp4 container format. +When enabled, a player will be automatically embedded in the file description +page, or any wiki page while still using the same syntax as for images. + +* Broad support for input file formats +* Transcoder to make video at web resolutions when embedding clips in a page +* include support for timed Text per the w3c "track" recommendation +* use embedPlayer mwEmbed javascript module for playback + +To install this extension, add the following to the end of your +LocalSettings.php: + + // You need mwEmbedSupport ( if not already added ) + require( "$IP/extensions/MwEmbedSupport/MwEmbedSupport.php" ); + + // TimedMediaHandler + require( "$IP/extensions/TimedMediaHandler/TimedMediaHandler.php" ); + + +== Running Transcodes == + +Transcoding a video to another resolution or format takes a good amount which +prevents that processing to be handled as a web service. Instead, the extension +implements an asynchronous job, named webVideoTranscode, which you must be +running regularly as your web server user. + +The job can be run using the MediaWiki maintenance/runJobs.php utility (do not +forget to su as a webserver user): + + php runJobs.php --type webVideoTranscode --maxjobs 1 + + +== Kaltura HTML5 player library == + +TimedMediaHandler uses the Kaltura HTML5 player library for video playback, it +relies on the <video> element as well as JavaScript. + +For more information about the player library visit: + http://www.html5video.org/kaltura-player/docs + + +== Libav == + +We use Libav for two purposes: + - creating still images of videos (aka thumbnails) + - transcoding WebM, H.264 videos + +Wikimedia currently uses libav as shipped in Ubuntu 12.04 (libav 0.8.x). +For best experience use that or any later release from http://libav.org. + +On Ubuntu/Debian: + apt-get install libav-tools + +For H.264 support: + apt-get install libav-tools libavcodec-extra-53 + +If you operating system does not include the required libav software, +you can download static builds for multiple platforms at: + http://firefogg.org/nightly/ + +You can also build libav/ffmpeg from source. +Guide for building ffmpeg with H.264 for Ubuntu: +https://ffmpeg.org/trac/ffmpeg/wiki/UbuntuCompilationGuide + +Some old versions of FFmpeg had a bug which made it extremely slow to seek in +large theora videos in order to generate a thumbnail. If you are using an old +version of FFmpeg and find that performance is extremely poor (tens of seconds) +to generate thumbnails of theora videos that are several minutes or more in +length. Please update to a more recent version. + +In MediaWiki configuration, after the require line in LocalSettings.php, you +will have to specify the FFmpeg binary location with: + + $wgFFmpegLocation = '/path/to/ffmpeg'; + +Default being `/usr/bin/avconv`. + + +== ffmpeg2theora == + +We use ffmpeg2theora for extract metadata from videos, you will need a copy on +your server. For best experience, use the latest release of ffmpeg2theora. At a +minimum you need to use ffmpeg2thoera 0.27. + +You can download static ffmpeg2theora builds for multiple platforms at: +http://firefogg.org/nightly/ + +Set the ffmpeg2theora binary location with: + + $wgFFmpeg2theoraLocation = '/path/to/ffmpeg2theora'; + +Default being `/usr/bin/ffmpeg2theora`. + +oggThumb +------- + +We use oggvideotools for creating still images of videos, you will need a copy on your +server. + +Set the oggThumb binary location with: + + $wgOggThumbLocation = '/path/to/oggThumb'; + +Download oggThumb from: http://dev.streamnik.de/oggvideotools.html + +== PEAR File_Ogg == + +Tim Starling, a Wikimedia developer, forked the PEAR File_Ogg package and +improved it significantly to support this extension. + +The PEAR bundle is licensed under the LGPL, you can get informations about +this package on the pear webpage: + + http://pear.php.net/package/File_Ogg + +== getID3 == + +getID3 is used for metadata of WebM files. + +getID3() by James Heinrich <info@getid3.org> +available at http://getid3.sourceforge.net +or http://www.getid3.org/ + +getID3 code is released under the GNU GPL: +http://www.gnu.org/copyleft/gpl.html diff --git a/extensions/TimedMediaHandler/SpecialOrphanedTimedText.php b/extensions/TimedMediaHandler/SpecialOrphanedTimedText.php new file mode 100644 index 00000000..52e86bf4 --- /dev/null +++ b/extensions/TimedMediaHandler/SpecialOrphanedTimedText.php @@ -0,0 +1,258 @@ +<?php +/** + * Implements Special:OrphanedTimedText + * + * @author Brian Wolff + * @file + * @ingroup SpecialPage + */ + +/** + * Lists TimedText pages that don't have a corresponding video. + * + * @ingroup SpecialPage + */ +class SpecialOrphanedTimedText extends PageQueryPage { + + /** @var Array with keys being names of valid files */ + private $existingFiles; + + public function __construct( $name = 'OrphanedTimedText' ) { + parent::__construct( $name ); + } + + /** + * This is alphabetical, so sort ascending. + */ + public function sortDescending() { + return false; + } + + /** + * Should this be cached? + * + * This query is actually almost cheap given the current + * number of things in TimedText namespace. + */ + public function isExpensive() { + return true; + } + + /** + * Main execution function + * + * @param $par String subpage + */ + public function execute( $par ) { + global $wgEnableLocalTimedText; + + if ( !$wgEnableLocalTimedText ) { + $this->setHeaders(); + $this->getOutput()->addWikiMsg( 'orphanedtimedtext-notimedtext' ); + return; + } elseif ( !$this->canExecuteQuery() ) { + $this->setHeaders(); + $this->outputHeader(); + $this->getOutput()->addWikiMsg( 'orphanedtimedtext-unsupported' ); + return; + } + return parent::execute( $par ); + } + + /** + * Can we cache the results of this query? + * + * Only if we support the query. + * @return bool + */ + public function isCacheable() { + return $this->canExecute(); + } + + /** + * List in Special:SpecialPages? + * + * @return bool + */ + public function isListed() { + return $this->canExecute(); + } + + /** + * Can we execute this special page? + * + * The query uses a mysql specific feature (substring_index), so disable on non mysql dbs. + * + * @return bool + */ + private function canExecuteQuery() { + $dbr = wfGetDB( DB_SLAVE ); + return $dbr->getType() === 'mysql'; + } + + /** + * Can we execute this special page + * + * That is, db is mysql, and TimedText namespace enabled. + */ + private function canExecute() { + global $wgEnableLocalTimedText; + + return $this->canExecuteQuery() && $wgEnableLocalTimedText; + } + + /** + * Get query info + * + * The query here is meant to retrieve all pages in the TimedText namespace, + * such that if you strip the last two extensions (e.g. Foo.bar.baz.en.srt -> Foo.bar.baz) + * there is no corresponding img_name in image table. So if there is a page in TimedText + * namespace named TimedText:My.Dog.webm.ceb.srt, it will include it in the list provided + * that File:My.Dog.webm is not uploaded. + * + * TimedText does not support file redirects or foreign files, so we don't have + * to worry about those. + * + * Potentially this should maybe also include pages not ending in + * .<valid lang code>.srt . However, determining what a valid lang code + * is, is pretty hard (although perhaps it could check if its [a-z]{2,3} + * however then we've got things like roa-tara, cbk-zam, etc) + * and TimedText throws away the final .srt extension and will work with + * any extension, so things not ending in .srt arguably aren't oprhaned. + * + * @note This uses "substring_index" which is a mysql extension. + * @return Array Standard query info values. + */ + function getQueryInfo() { + $tables = array( 'page', 'image' ); + $fields = array( + 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 0, + ); + $conds = array( + 'img_name' => null, + 'page_namespace' => NS_TIMEDTEXT, + ); + + // Now for the complicated bit + // Note: This bit is mysql specific. Probably could do something + // equivalent in postgress via split_part or regex substr, + // but my sql-fu is not good enough to figure out how to do + // this in standard sql, or in sqlite. + $baseCond = 'substr( page_title, 1, length( page_title ) - ' + . "length( substring_index( page_title, '.' ,-2 ) ) - 1 )"; + $joinConds = array( + 'image' => array( + 'LEFT OUTER JOIN', + $baseCond . ' = img_name' + ) + ); + return array( + 'tables' => $tables, + 'fields' => $fields, + 'conds' => $conds, + 'join_conds' => $joinConds + ); + } + + public function getOrderFields() { + return array( 'namespace', 'title' ); + } + + /** + * Is the TimedText page really orphaned? + * + * Given a title like "TimedText:Some bit here.webm.en.srt" + * check to see if "File:Some bit here.webm" really exists (locally). + * @return bool True if we should cross out the line. + */ + protected function existenceCheck( Title $title ) { + $fileTitle = $this->getCorrespondingFile( $title ); + if ( !$fileTitle ) { + return $title && !$title->isKnown(); + } + return !$title->isKnown() || + ( isset( $this->existingFiles[ $fileTitle->getDBKey() ] ) + && $this->existingFiles[$fileTitle->getDBKey()]->getHandler() + && $this->existingFiles[$fileTitle->getDBKey()]->getHandler() instanceof TimedMediaHandler ); + } + + /** + * Given a TimedText title, get the File title + * + * @return Title|null Title in File namespace. null on error. + */ + private function getCorrespondingFile( Title $timedText ) { + if ( !$timedText ) { + return false; + } + $titleParts = explode( '.', $timedText->getDBkey() ); + array_pop( $titleParts ); + array_pop( $titleParts ); + $fileTitle = Title::makeTitleSafe( NS_FILE, implode( '.', $titleParts ) ); + return $fileTitle; + } + + /** + * What group to include this page in on Special:SpecialPages + * @return String + */ + protected function getGroupName() { + return 'media'; + } + + /** + * Preprocess result to do existence checks all at once. + * + * @param $db Database + * @param $res ResultWraper + */ + public function preprocessResults( $db, $res ) { + parent::preprocessResults( $db, $res ); + + if ( !$res->numRows() ) { + return; + } + + $filesToLookFor = array(); + foreach( $res as $row ) { + $title = Title::makeTitle( $row->namespace, $row->title ); + $fileTitle = $this->getCorrespondingFile( $title ); + if ( !$fileTitle ) { + continue; + } + $filesToLookFor[] = array( 'title' => $fileTitle, 'ignoreRedirect' => true ); + } + $this->existingFiles = RepoGroup::singleton()->getLocalRepo()->findFiles( $filesToLookFor ); + $res->seek( 0 ); + } + + /** + * Format the result as a simple link to the page + * + * Based on parent class but with an existence check added. + * + * @param Skin $skin + * @param object $row Result row + * @return string + */ + public function formatResult( $skin, $row ) { + global $wgContLang; + + $title = Title::makeTitleSafe( $row->namespace, $row->title ); + + if ( $title instanceof Title ) { + $text = $wgContLang->convert( $title->getPrefixedText() ); + $link = Linker::link( $title, htmlspecialchars( $text ) ); + if ( $this->existenceCheck( $title ) ) { + // File got uploaded since this page was cached + $link = '<del>' . $link . '</del>'; + } + return $link; + } else { + return Html::element( 'span', array( 'class' => 'mw-invalidtitle' ), + Linker::getInvalidTitleDescription( $this->getContext(), $row->namespace, $row->title ) ); + } + } +} diff --git a/extensions/TimedMediaHandler/SpecialTimedMediaHandler.php b/extensions/TimedMediaHandler/SpecialTimedMediaHandler.php new file mode 100644 index 00000000..46f2fef8 --- /dev/null +++ b/extensions/TimedMediaHandler/SpecialTimedMediaHandler.php @@ -0,0 +1,235 @@ +<?php +/** + * Special:TimedMediaHandler + * + * Show some information about unprocessed jobs + * + * @file + * @ingroup SpecialPage + */ + +class SpecialTimedMediaHandler extends SpecialPage { + private $transcodeStates = array( + 'active' => 'transcode_time_startwork IS NOT NULL AND transcode_time_success IS NULL AND transcode_time_error IS NULL', + 'failed' => 'transcode_error != "" AND transcode_time_success IS NULL', + 'queued' => 'transcode_time_startwork IS NULL AND transcode_time_success IS NULL AND transcode_time_error IS NULL', + + ); + private $formats = array( + 'ogg' => 'img_major_mime="application" AND img_minor_mime = "ogg"', + 'webm' => 'img_major_mime="video" AND img_minor_mime = "webm"', + ); + private $audioFormats = array( + 'ogg' => 'img_major_mime="application" AND img_minor_mime = "ogg"', + 'webm' => 'img_major_mime="audio" AND img_minor_mime = "webm"', + 'flac' => 'img_major_mime="audio" AND img_minor_mime="x-flac"', + 'wav' => 'img_major_mime="audio" AND img_minor_mime="wav"', + ); + + public function __construct( $request = null, $par = null ) { + parent::__construct( 'TimedMediaHandler', 'transcode-status' ); + } + + public function execute( $par ) { + $this->setHeaders(); + $out = $this->getOutput(); + + $out->addModuleStyles( 'mediawiki.special' ); + + $stats = $this->getStats(); + + foreach( array( 'audios', 'videos' ) as $type ) { + // for grep timedmedia-audios, timedmedia-videos + $out->addHTML( + "<h2>" + . $this->msg( 'timedmedia-' . $type )->numParams( $stats[$type]['total'] )->escaped() + . "</h2>" + ); + // Give grep a chance to find the usages: timedmedia-ogg-videos, timedmedia-webm-videos, + // timedmedia-ogg-audios, timedmedia-flac-audios, timedmedia-wav-audios + $formats = $type == 'audios' ? $this->audioFormats : $this->formats; + foreach ( $formats as $format => $condition ) { + if ( $stats[ $type ][ $format ] ) { + $out->addHTML( + $this->msg( "timedmedia-$format-$type" )->numParams( $stats[ $type ][ $format ] )->escaped() + . Html::element( 'br' ) + ); + } + } + } + + $states = $this->getStates(); + $this->renderState( $out, 'transcodes', $states, false ); + foreach ( $this->transcodeStates as $state => $condition ) { + $this->renderState( $out, $state, $states ); + } + } + + /** + * @param OutputPage $out + * @param $state + * @param $states + * @param bool $showTable + */ + private function renderState ( $out, $state, $states, $showTable = true ) { + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet; + $allTranscodes = array_merge( $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet ); + if ( $states[ $state ][ 'total' ] ) { + // Give grep a chance to find the usages: + // timedmedia-derivative-state-transcodes, timedmedia-derivative-state-active, + // timedmedia-derivative-state-queued, timedmedia-derivative-state-failed + $out->addHTML( + "<h2>" + . $this->msg( 'timedmedia-derivative-state-' . $state )->numParams( $states[ $state ]['total'] )->escaped() + . "</h2>" + ); + foreach( $allTranscodes as $key ) { + if ( isset( $states[ $state ] ) + && isset( $states[ $state ][ $key ] ) + && $states[ $state ][ $key ] ) { + $out->addHTML( + htmlspecialchars( $this->getLanguage()->formatNum( $states[ $state ][ $key ] ) ) + . ' ' + . $this->msg( 'timedmedia-derivative-desc-' . $key )->escaped() + . "<br>" ); + } + } + if ( $showTable ) { + $out->addHTML( $this->getTranscodesTable( $state ) ); + } + } + } + + private function getTranscodes ( $state, $limit = 50 ) { + global $wgMemc; + $memcKey = wfMemcKey( 'TimedMediaHandler', 'files', $state ); + $files = $wgMemc->get( $memcKey ); + if ( !$files ) { + $dbr = wfGetDB( DB_SLAVE ); + $files = array(); + $res = $dbr->select( + 'transcode', + '*', + $this->transcodeStates[ $state ], + __METHOD__, + array( 'LIMIT' => $limit, 'ORDER BY' => 'transcode_time_error DESC' ) + ); + foreach( $res as $row ) { + $transcode = array(); + foreach( $row as $k => $v ){ + $transcode[ str_replace( 'transcode_', '', $k ) ] = $v; + } + $files[] = $transcode; + } + $wgMemc->add( $memcKey, $files, 60 ); + } + return $files; + } + + private function getTranscodesTable ( $state, $limit = 50 ) { + $table = '<table class="wikitable">' . "\n" + . '<tr>' + . '<th>' . $this->msg( 'timedmedia-transcodeinfo' )->escaped() . '</th>' + . '<th>' . $this->msg( 'timedmedia-file' )->escaped() . '</th>' + . '</tr>' + . "\n"; + + foreach( $this->getTranscodes( $state, $limit ) as $transcode ) { + $title = Title::newFromText( $transcode[ 'image_name' ], NS_FILE ); + $table .= '<tr>' + . '<td>' . $this->msg('timedmedia-derivative-desc-' . $transcode[ 'key' ] )->escaped() . '</td>' + . '<td>' . Linker::link( $title, $transcode[ 'image_name' ] ) . '</td>' + . '</tr>' + . "\n"; + } + $table .= '</table>'; + return $table; + } + + private function getStats() { + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet, $wgMemc; + $allTranscodes = array_merge( $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet ); + + $memcKey= wfMemcKey( 'TimedMediaHandler', 'stats', '1' /* version */ ); + $stats = $wgMemc->get( $memcKey ); + if ( !$stats ) { + $dbr = wfGetDB( DB_SLAVE ); + $stats = array(); + $stats[ 'videos' ] = array( 'total' => 0 ); + foreach( $this->formats as $format => $condition ) { + $stats[ 'videos' ][ $format ] = (int)$dbr->selectField( + 'image', + 'COUNT(*)', + 'img_media_type = "VIDEO" AND (' . $condition . ')', + __METHOD__ + ); + $stats[ 'videos' ][ 'total' ] += $stats[ 'videos' ][ $format ]; + } + $stats[ 'audios' ] = array( 'total' => 0 ); + foreach( $this->audioFormats as $format => $condition ) { + $stats[ 'audios' ][ $format ] = (int)$dbr->selectField( + 'image', + 'COUNT(*)', + 'img_media_type = "AUDIO" AND (' . $condition . ')', + __METHOD__ + ); + $stats[ 'audios' ][ 'total' ] += $stats[ 'audios' ][ $format ]; + } + } + return $stats; + } + + private function getStates() { + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet, $wgMemc; + $allTranscodes = array_merge( $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet ); + + $memcKey = wfMemcKey( 'TimedMediaHandler', 'states' ); + $states = $wgMemc->get( $memcKey ); + if ( !$states ) { + $dbr = wfGetDB( DB_SLAVE ); + $states = array(); + $states[ 'transcodes' ] = array( 'total' => 0 ); + foreach ( $this->transcodeStates as $state => $condition ) { + $states[ $state ] = array( 'total' => 0 ); + foreach( $allTranscodes as $type ) { + // Important to pre-initialize, as can give + // warnings if you don't have a lot of things in transcode table. + $states[ $state ][ $type ] = 0; + } + } + foreach ( $this->transcodeStates as $state => $condition ) { + $cond = array( 'transcode_key' => $allTranscodes ); + $cond[] = $condition; + $res = $dbr->select( 'transcode', + array('COUNT(*) as count', 'transcode_key'), + $cond, + __METHOD__, + array( 'GROUP BY' => 'transcode_key' ) + ); + foreach( $res as $row ) { + $key = $row->transcode_key; + $states[ $state ][ $key ] = $row->count; + $states[ $state ][ 'total' ] += $states[ $state ][ $key ]; + } + } + $res = $dbr->select( 'transcode', + array( 'COUNT(*) as count', 'transcode_key' ), + array( 'transcode_key' => $allTranscodes ), + __METHOD__, + array( 'GROUP BY' => 'transcode_key' ) + ); + foreach( $res as $row ) { + $key = $row->transcode_key; + $states[ 'transcodes' ][ $key ] = $row->count; + $states[ 'transcodes' ][ $key ] -= $states[ 'queued' ][ $key ]; + $states[ 'transcodes' ][ 'total' ] += $states[ 'transcodes' ][ $key ]; + } + $wgMemc->add( $memcKey, $states, 60 ); + } + return $states; + } + + protected function getGroupName() { + return 'media'; + } +} diff --git a/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php b/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php new file mode 100644 index 00000000..70768479 --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaHandler.hooks.php @@ -0,0 +1,485 @@ +<?php + +/** + * Hooks for TimedMediaHandler extension + * + * @file + * @ingroup Extensions + */ + +class TimedMediaHandlerHooks { + + // Register TimedMediaHandler namespace IDs + // These are configurable due to Commons history: T123823 + // These need to be before registerhooks due to: T123695 + public static function onSetupAfterCache() { + global $wgEnableLocalTimedText, $wgExtraNamespaces, $wgTimedTextNS; + if ( $wgEnableLocalTimedText ) { + define( "NS_TIMEDTEXT", $wgTimedTextNS ); + define( "NS_TIMEDTEXT_TALK", $wgTimedTextNS +1 ); + + $wgExtraNamespaces[NS_TIMEDTEXT] = "TimedText"; + $wgExtraNamespaces[NS_TIMEDTEXT_TALK] = "TimedText_talk"; + } else { + $wgTimedTextNS = false; + } + return true; + } + + // Register TimedMediaHandler Hooks + public static function register() { + global $wgHooks, $wgJobClasses, $wgJobTypesExcludedFromDefaultQueue, $wgMediaHandlers, + $wgResourceModules, $wgExcludeFromThumbnailPurge, $wgParserOutputHooks, + $wgFileExtensions, $wgTmhEnableMp4Uploads, $wgExtensionAssetsPath, + $wgMwEmbedModuleConfig, $timedMediaDir, $wgEnableLocalTimedText, + $wgTmhFileExtensions, $wgTmhTheoraTwoPassEncoding, $wgTmhWebPlayer; + + // Remove mp4 if not enabled: + if( $wgTmhEnableMp4Uploads === false ){ + $index = array_search( 'mp4', $wgFileExtensions ); + if ( $index !== false ) { + array_splice( $wgFileExtensions, $index, 1 ); + } + } + + if( !class_exists( 'MwEmbedResourceManager' ) ) { + echo "TimedMediaHandler requires the MwEmbedSupport extension.\n"; + exit( 1 ); + } + + // Register the Timed Media Handler javascript resources ( MwEmbed modules ) + MwEmbedResourceManager::register( 'extensions/TimedMediaHandler/MwEmbedModules/EmbedPlayer' ); + MwEmbedResourceManager::register( 'extensions/TimedMediaHandler/MwEmbedModules/TimedText' ); + + // Set the default webPath for this embed player extension + $wgMwEmbedModuleConfig['EmbedPlayer.WebPath'] = $wgExtensionAssetsPath . + '/' . basename ( $timedMediaDir ) . '/MwEmbedModules/EmbedPlayer'; + + // Setup media Handlers: + $wgMediaHandlers['application/ogg'] = 'OggHandlerTMH'; + $wgMediaHandlers['audio/webm'] = 'WebMHandler'; + $wgMediaHandlers['video/webm'] = 'WebMHandler'; + $wgMediaHandlers['video/mp4'] = 'Mp4Handler'; + $wgMediaHandlers['audio/x-flac'] = 'FLACHandler'; + $wgMediaHandlers['audio/flac'] = 'FLACHandler'; + $wgMediaHandlers['audio/wav'] = 'WAVHandler'; + + // Add transcode job class: + $wgJobClasses['webVideoTranscode'] = 'WebVideoTranscodeJob'; + + // Transcode jobs must be explicitly requested from the job queue: + $wgJobTypesExcludedFromDefaultQueue[] = 'webVideoTranscode'; + + $baseExtensionResource = array( + 'localBasePath' => __DIR__, + 'remoteExtPath' => 'TimedMediaHandler', + ); + + // Add the PopUpMediaTransform module ( specific to timedMedia handler ( no support in mwEmbed modules ) + $wgResourceModules+= array( + 'mw.PopUpMediaTransform' => $baseExtensionResource + array( + 'scripts' => 'resources/mw.PopUpThumbVideo.js', + 'dependencies' => array( 'mw.MwEmbedSupport', 'mediawiki.Title' ), + ), + 'mw.PopUpMediaTransform.styles' => $baseExtensionResource + array( + 'position' => 'top', + 'styles' => 'resources/PopUpThumbVideo.css', + ), + 'mw.TMHGalleryHook.js' => $baseExtensionResource + array( + 'scripts' => 'resources/mw.TMHGalleryHook.js', + // position top needed as it needs to load before mediawiki.page.gallery + 'position' => 'top', + ), + 'embedPlayerIframeStyle'=> $baseExtensionResource + array( + 'styles' => 'resources/embedPlayerIframe.css', + ), + 'ext.tmh.transcodetable' => $baseExtensionResource + array( + 'scripts' => 'resources/ext.tmh.transcodetable.js', + 'styles' => 'resources/transcodeTable.css', + 'dependencies' => array( + 'mediawiki.api.edit', + 'mw.MwEmbedSupport', + ), + 'messages'=> array( + 'mwe-ok', + 'mwe-cancel', + 'timedmedia-reset-error', + 'timedmedia-reset', + 'timedmedia-reset-confirm' + ) + ), + 'ext.tmh.TimedTextSelector' => $baseExtensionResource + array( + 'scripts' => 'resources/ext.tmh.TimedTextSelector.js', + ), + "mw.MediaWikiPlayerSupport" => $baseExtensionResource + array( + 'scripts' => 'resources/mw.MediaWikiPlayerSupport.js', + 'dependencies'=> 'mw.Api', + ), + // adds support MediaWikiPlayerSupport player bindings + "mw.MediaWikiPlayer.loader" => $baseExtensionResource + array( + 'loaderScripts' => 'resources/mw.MediaWikiPlayer.loader.js', + ), + ); + + // Add OgvJs-related modules for Safari/IE/Edge Ogg playback + $wgResourceModules += array( + 'ext.tmh.OgvJsSupport' => $baseExtensionResource + array( + 'scripts' => array( + 'MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv-support.js', + 'resources/ext.tmh.OgvJsSupport.js', + ), + 'targets' => array( 'mobile', 'desktop' ), + ), + 'ext.tmh.OgvJs' => $baseExtensionResource + array( + 'scripts' => array( + 'MwEmbedModules/EmbedPlayer/binPlayers/ogv.js/ogv.js', + ), + 'dependencies' => 'ext.tmh.OgvJsSupport', + 'targets' => array( 'mobile', 'desktop' ), + ), + ); + + // Setup a hook for iframe embed handling: + $wgHooks['ArticleFromTitle'][] = 'TimedMediaIframeOutput::iframeHook'; + + // When an upload completes ( check clear any existing transcodes ) + $wgHooks['UploadComplete'][] = 'TimedMediaHandlerHooks::checkUploadComplete'; + + // When an image page is moved: + $wgHooks['TitleMove'][] = 'TimedMediaHandlerHooks::checkTitleMove'; + + // When image page is deleted so that we remove transcode settings / files. + $wgHooks['FileDeleteComplete'][] = 'TimedMediaHandlerHooks::onFileDeleteComplete'; + + // Add parser hook + $wgParserOutputHooks['TimedMediaHandler'] = array( 'TimedMediaHandler', 'outputHook' ); + + // Use a BeforePageDisplay hook to load the styles in pages that pull in media dynamically. + // (Special:Upload, for example, when there is an "existing file" warning.) + $wgHooks['BeforePageDisplay'][] = 'TimedMediaHandlerHooks::pageOutputHook'; + + // Make sure modules are loaded on image pages that don't have a media file in the wikitext. + $wgHooks['ImageOpenShowImageInlineBefore'][] = 'TimedMediaHandlerHooks::onImageOpenShowImageInlineBefore'; + + // Exclude transcoded assets from normal thumbnail purging + // ( a maintenance script could handle transcode asset purging) + if ( isset( $wgExcludeFromThumbnailPurge ) ) { + $wgExcludeFromThumbnailPurge = array_merge( $wgExcludeFromThumbnailPurge, $wgTmhFileExtensions ); + // Also add the .log file ( used in two pass encoding ) + // ( probably should move in-progress encodes out of web accessible directory ) + $wgExcludeFromThumbnailPurge[] = 'log'; + } + + $wgHooks['LoadExtensionSchemaUpdates'][] = 'TimedMediaHandlerHooks::loadExtensionSchemaUpdates'; + + // Add unit tests + $wgHooks['UnitTestsList'][] = 'TimedMediaHandlerHooks::registerUnitTests'; + + /** + * Add support for the "TimedText" NameSpace + */ + if ( $wgEnableLocalTimedText ) { + // Check for timed text page: + $wgHooks[ 'ArticleFromTitle' ][] = 'TimedMediaHandlerHooks::checkForTimedTextPage'; + $wgHooks[ 'ArticleContentOnDiff' ][] = 'TimedMediaHandlerHooks::checkForTimedTextDiff'; + } else { + // overwrite TimedText.ShowInterface for video with mw-provider=local + $wgMwEmbedModuleConfig['TimedText.ShowInterface.local'] = 'off'; + } + + // Add transcode status to video asset pages: + $wgHooks[ 'ImagePageAfterImageLinks' ][] = 'TimedMediaHandlerHooks::checkForTranscodeStatus'; + $wgHooks[ 'NewRevisionFromEditComplete' ][] = 'TimedMediaHandlerHooks::onNewRevisionFromEditComplete'; + $wgHooks[ 'ArticlePurge' ][] = 'TimedMediaHandlerHooks::onArticlePurge'; + + $wgHooks['LoadExtensionSchemaUpdates'][] = 'TimedMediaHandlerHooks::checkSchemaUpdates'; + $wgHooks['wgQueryPages'][] = 'TimedMediaHandlerHooks::onwgQueryPages'; + return true; + } + + /** + * @param $imagePage ImagePage + * @param $wgOut OutputPage + * @return bool + */ + public static function onImageOpenShowImageInlineBefore( $imagePage, $out ) { + $handler = $imagePage->getDisplayedFile()->getHandler(); + if ( $handler !== false && $handler instanceof TimedMediaHandler ) { + TimedMediaHandler::outputHook( $out, null, null ); + } + return true; + } + + /** + * @param $title Title + * @param $article Article + * @return bool + */ + public static function checkForTimedTextPage( &$title, &$article ){ + global $wgTimedTextNS; + if ( $title->getNamespace() === $wgTimedTextNS ) { + $article = new TimedTextPage( $title ); + } + return true; + } + + /** + * @param $diffEngine DifferenceEngine + * @param $output OutputPage + * @return bool + */ + public static function checkForTimedTextDiff( $diffEngine, $output ) { + global $wgTimedTextNS; + if ( $output->getTitle()->getNamespace() === $wgTimedTextNS ) { + $article = new TimedTextPage( $output->getTitle() ); + $article->renderOutput( $output ); + return false; + } + return true; + } + + /** + * Wraps the isTranscodableFile function + * @param $title Title + * @return bool + */ + public static function isTranscodableTitle( $title ){ + if( $title->getNamespace() != NS_FILE ){ + return false; + } + $file = wfFindFile( $title ); + return self::isTranscodableFile( $file ); + } + + /** + * Utility function to check if a given file can be "transcoded" + * @param $file File object + * @return bool + */ + public static function isTranscodableFile( & $file ){ + global $wgEnableTranscode, $wgEnabledAudioTranscodeSet; + + // don't show the transcode table if transcode is disabled + if( !$wgEnableTranscode && !$wgEnabledAudioTranscodeSet ){ + return false; + } + // Can't find file + if( !$file ){ + return false; + } + // We can only transcode local files + if( !$file->isLocal() ){ + return false; + } + + $handler = $file->getHandler(); + // Not able to transcode files without handler + if( !$handler ) { + return false; + } + $mediaType = $handler->getMetadataType( $file ); + // If ogg or webm format and not audio we can "transcode" this file + $isAudio = $handler instanceof TimedMediaHandler && $handler->isAudio( $file ); + if( ( $mediaType == 'webm' || $mediaType == 'ogg' || $mediaType =='mp4' ) + && !$isAudio + ){ + return true; + } + if( $isAudio && count( $wgEnabledAudioTranscodeSet ) ) { + return true; + } + return false; + } + + /** + * @param $article Article + * @param $html string + * @return bool + */ + public static function checkForTranscodeStatus( $article, &$html ){ + // load the file: + $file = wfFindFile( $article->getTitle() ); + if( self::isTranscodableFile( $file ) ){ + $html .= TranscodeStatusTable::getHTML( $file ); + } + return true; + } + + /** + * @param $image UploadBase + * @return bool + */ + public static function checkUploadComplete( $upload ){ + $file = $upload->getLocalFile(); + // Check that the file is a transcodable asset: + if( $file && self::isTranscodableFile( $file ) ){ + // Remove all the transcode files and db states for this asset + WebVideoTranscode::removeTranscodes( $file ); + WebVideoTranscode::startJobQueue( $file ); + } + return true; + } + /** + * Handle moved titles + * + * For now we just remove all the derivatives for the oldTitle. In the future we could + * look at moving the files, but right now thumbs are not moved, so I don't want to be + * inconsistent. + * @param $title Title + * @param $newTitle Title + * @param $user User + * @return bool + */ + public static function checkTitleMove( $title, $newTitle, $user ){ + if( self::isTranscodableTitle( $title ) ){ + // Remove all the transcode files and db states for this asset + // ( will be re-added the first time the asset is displayed with its new title ) + $file = wfFindFile( $title ); + WebVideoTranscode::removeTranscodes( $file ); + } + return true; + } + + /** + * Hook to FileDeleteComplete + * remove transcodes on delete + * @param $file File + * @param $oldimage + * @param $article Article + * @param $user User + * @param $reason string + * @return bool + */ + public static function onFileDeleteComplete( $file, $oldimage, $article, $user, $reason ) { + if ( !$oldimage ) { + if( self::isTranscodableFile( $file ) ){ + WebVideoTranscode::removeTranscodes( $file ); + } + } + return true; + } + + /* + * If file gets reverted to a previous version, reset transcodes. + */ + public static function onNewRevisionFromEditComplete( $article, Revision $rev, $baseID, User $user ) { + if ( $baseID !== false ) { + // Check if the article is a file and remove transcode files: + if( $article->getTitle()->getNamespace() == NS_FILE ) { + $file = wfFindFile( $article->getTitle() ); + if( self::isTranscodableFile( $file ) ){ + WebVideoTranscode::removeTranscodes( $file ); + WebVideoTranscode::startJobQueue( $file ); + } + } + } + return true; + } + + /** + * When a user asks for a purge, perhaps through our handy "update transcode status" + * link, make sure we've got the updated set of transcodes. This'll allow a user or + * automated process to see their status and reset them. + */ + public static function onArticlePurge( $article ) { + if( $article->getTitle()->getNamespace() == NS_FILE ) { + $file = wfFindFile( $article->getTitle() ); + if( self::isTranscodableFile( $file ) ){ + WebVideoTranscode::cleanupTranscodes( $file ); + } + } + return true; + } + + /** + * Adds the transcode sql + * @param $updater DatabaseUpdater + * @return bool + */ + public static function loadExtensionSchemaUpdates( $updater ){ + $updater->addExtensionTable( 'transcode', __DIR__ . '/TimedMediaHandler.sql' ); + return true; + } + + /** + * Hook to add list of PHPUnit test cases. + * @param $files Array of files + * @return bool + */ + public static function registerUnitTests( array &$files ) { + $testDir = __DIR__ . '/tests/phpunit/'; + $testFiles = array( + 'TestTimeParsing.php', + 'TestApiUploadVideo.php', + 'TestVideoThumbnail.php', + 'TestVideoTranscode.php', + 'TestOggHandler.php', + 'TestTimedMediaTransformOutput.php', + 'TestTimedMediaHandler.php' + ); + foreach( $testFiles as $fileName ){ + $files[] = $testDir . $fileName; + } + return true; + } + + /** + * Add JavaScript and CSS for special pages that may include timed media + * but which will not fire the parser hook. + * + * FIXME: There ought to be a better interface for determining whether the + * page is liable to contain timed media. + * + * @param $out OutputPage + * @param $sk + * @return bool + */ + static function pageOutputHook( &$out, &$sk ){ + global $wgTimedTextNS; + + $title = $out->getTitle(); + $namespace = $title->getNamespace(); + $addModules = false; + + if ( $namespace === NS_CATEGORY || $namespace === $wgTimedTextNS ) { + $addModules = true; + } + + if ( $title->isSpecialPage() ) { + list( $name, /* subpage */ ) = SpecialPageFactory::resolveAlias( $title->getDBkey() ); + if ( stripos( $name, 'file' ) !== false || stripos( $name, 'image' ) !== false + || $name === 'Search' || $name === 'GlobalUsage' ) { + $addModules = true; + } + } + + if ( $addModules ) { + $out->addModuleScripts( 'mw.PopUpMediaTransform' ); + $out->addModuleStyles( 'mw.PopUpMediaTransform.styles' ); + } + + return true; + } + + public static function checkSchemaUpdates( DatabaseUpdater $updater ) { + $base = __DIR__ ; + + switch ( $updater->getDB()->getType() ) { + case 'mysql': + case 'sqlite': + $updater->addExtensionTable( 'transcode', "$base/TimedMediaHandler.sql" ); // Initial install tables + $updater->addExtensionUpdate( array( 'addIndex', 'transcode', 'transcode_name_key', + "$base/archives/transcode_name_key.sql", true ) ); + break; + case 'postgres': + //TODO + break; + } + return true; + } + + public static function onwgQueryPages( $qp ) { + $qp[] = array( 'SpecialOrphanedTimedText', 'OrphanedTimedText' ); + return true; + } +} diff --git a/extensions/TimedMediaHandler/TimedMediaHandler.i18n.alias.php b/extensions/TimedMediaHandler/TimedMediaHandler.i18n.alias.php new file mode 100644 index 00000000..35c28ad8 --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaHandler.i18n.alias.php @@ -0,0 +1,76 @@ +<?php +/** + * Aliases for special pages for extension TimedMediaHandler + * + * @file + * @ingroup Extensions + */ +// @codingStandardsIgnoreFile + +$specialPageAliases = array(); + +/** English (English) */ +$specialPageAliases['en'] = array( + 'TimedMediaHandler' => array( 'TimedMediaHandler' ), + 'OrphanedTimedText' => array( 'OrphanedTimedText' ), +); + +/** Arabic (Ų§ŁŲ¹Ų±ŲØŁŲ©) */ +$specialPageAliases['ar'] = array( + 'TimedMediaHandler' => array( 'Ł
Ų¹Ų§ŁŲ¬_Ų§ŁŁ
ŁŲÆŁŲ§_Ų§ŁŲ²Ł
ŁŁŲ©' ), + 'OrphanedTimedText' => array( 'ŁŲµ_Ų²Ł
ŁŁ_ŁŲŖŁŁ
' ), +); + +/** Egyptian Arabic (Ł
ŲµŲ±Ł) */ +$specialPageAliases['arz'] = array( + 'TimedMediaHandler' => array( 'Ł
Ų¹Ų§ŁŲ¬_Ų§ŁŁ
ŁŲÆŁŲ§-Ų§ŁŲ²Ł
ŁŁŁ' ), +); + +/** German (Deutsch) */ +$specialPageAliases['de'] = array( + 'TimedMediaHandler' => array( 'TimedMedia-Steuerungsprogramm' ), + 'OrphanedTimedText' => array( 'Verwaister_TimedText' ), +); + +/** Zazaki (Zazaki) */ +$specialPageAliases['diq'] = array( + 'TimedMediaHandler' => array( 'MısnayoÄĆ©MedyayaZemanın' ), +); + +/** Estonian (eesti) */ +$specialPageAliases['et'] = array( + 'TimedMediaHandler' => array( 'Ajastatud_meediafailide_tƶƶtleja' ), +); + +/** Hebrew (×¢××Ø××Ŗ) */ +$specialPageAliases['he'] = array( + 'TimedMediaHandler' => array( '××××_××Ŗ×××× ×Ŗ' ), + 'OrphanedTimedText' => array( '×קה×_××Ŗ××××_××Ŗ××' ), +); + +/** Korean (ķźµģ“) */ +$specialPageAliases['ko'] = array( + 'TimedMediaHandler' => array( 'ģė§ėÆøėģ“ķøė¤ė¬' ), +); + +/** Macedonian (Š¼Š°ŠŗŠµŠ“Š¾Š½ŃŠŗŠø) */ +$specialPageAliases['mk'] = array( + 'TimedMediaHandler' => array( 'Š”ŠøŠ½Ń
ŃŠ¾Š½ŠøŠ·ŠøŃŠ°Š½ŠøŠ”Š½ŠøŠ¼ŠŗŠø' ), + 'OrphanedTimedText' => array( 'ŠŃŠ°Š¼ŠµŠ½ŠøŠ”ŠøŠ½Ń
ŃŠ¾Š½ŠøŠ·Š°ŃŠøŠø' ), +); + +/** Malayalam (ą“®ą“²ą“Æą“¾ą“³ą“) */ +$specialPageAliases['ml'] = array( + 'TimedMediaHandler' => array( 'ą“øą“®ą“Æą“¾ą“§ą“æą“·ąµą“ ą“æą“¤ą“®ąµą“”ą“æą“Æą“ąµą“ą“¾ą“°ąµą“Æąµą“Ŗą“ą“°ą“£ą“' ), +); + +/** Vietnamese (Tiįŗæng Viį»t) */ +$specialPageAliases['vi'] = array( + 'TimedMediaHandler' => array( 'Bį»_xį»_lĆ½_phĘ°Ę”ng_tiį»n_Äį»ng_bį»', 'Bį»_xį»_lĆ_phĘ°Ę”ng_tiį»n_Äį»ng_bį»' ), +); + +/** Simplified Chinese (äøęļ¼ē®ä½ļ¼ā) */ +$specialPageAliases['zh-hans'] = array( + 'TimedMediaHandler' => array( 'å®ę¶åŖä½å¤ēåØ' ), + 'OrphanedTimedText' => array( 'å¤ē«å®ę¶ęę¬' ), +);
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/TimedMediaHandler.i18n.magic.php b/extensions/TimedMediaHandler/TimedMediaHandler.i18n.magic.php new file mode 100644 index 00000000..878ceb17 --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaHandler.i18n.magic.php @@ -0,0 +1,86 @@ +<?php +/** + * Internationalisation file for extension TimedMediaHandler. + * + * @file + * @ingroup Extensions + */ + +$magicWords = array(); + +$magicWords['en'] = array( + 'timedmedia_noplayer' => array( 0, 'noplayer' ), + 'timedmedia_noicon' => array( 0, 'noicon' ), + 'timedmedia_thumbtime' => array( 0, 'thumbtime=$1' ), + 'timedmedia_starttime' => array( 0, 'start=$1'), + 'timedmedia_endtime' => array( 0, 'end=$1'), + 'timedmedia_disablecontrols' => array( 0, 'disablecontrols=$1'), +); + +$magicWords['af'] = array( + 'timedmedia_noplayer' => array( '0', 'geenspeler', 'noplayer' ), + 'timedmedia_noicon' => array( '0', 'geenikoon', 'noicon' ), + 'timedmedia_starttime' => array( '0', 'begin=$1', 'start=$1' ), + 'timedmedia_endtime' => array( '0', 'einde=$1', 'end=$1' ), +); + +$magicWords['ar'] = array( + 'timedmedia_noplayer' => array( '0', 'ŁŲ§ŲØŲ±ŁŲ§Ł
Ų¬', 'noplayer' ), + 'timedmedia_noicon' => array( '0', 'ŁŲ§Ų£ŁŁŁŁŲ©', 'noicon' ), + 'timedmedia_thumbtime' => array( '0', 'ŁŁŲŖ_Ų§ŁŲŖŲµŲŗŁŲ±=$1', 'thumbtime=$1' ), + 'timedmedia_starttime' => array( '0', 'ŲØŲÆŲ§ŁŲ©=$1', 'start=$1' ), + 'timedmedia_endtime' => array( '0', 'ŁŁŲ§ŁŲ©=$1', 'end=$1' ), +); + +$magicWords['arc'] = array( + 'timedmedia_starttime' => array( '0', 'Ü«ÜÜŖÜÜ=', 'start=$1' ), + 'timedmedia_endtime' => array( '0', 'Ü«ÜÜ Ü”Ü=$1', 'end=$1' ), +); + +$magicWords['arz'] = array( + 'timedmedia_noplayer' => array( '0', 'ŁŲ§ŲØŲ±ŁŲ§Ł
Ų¬', 'noplayer' ), + 'timedmedia_noicon' => array( '0', 'ŁŲ§Ų£ŁŁŁŁŲ©', 'noicon' ), + 'timedmedia_thumbtime' => array( '0', 'ŁŁŲŖ_Ų§ŁŲŖŲµŲŗŁŲ±=$1', 'thumbtime=$1' ), + 'timedmedia_starttime' => array( '0', 'ŲØŲÆŲ§ŁŲ©=$1', 'start=$1' ), + 'timedmedia_endtime' => array( '0', 'ŁŁŲ§ŁŲ©=$1', 'end=$1' ), +); + +$magicWords['ko'] = array( + 'timedmedia_starttime' => array( '0', 'ģģ=$1', 'start=$1' ), + 'timedmedia_endtime' => array( '0', 'ė=$1', 'end=$1' ), +); + +$magicWords['ml'] = array( + 'timedmedia_noplayer' => array( '0', 'ą“Ŗąµą“²ąµą“Æą“±ą“æą“²ąµą“²', 'noplayer' ), + 'timedmedia_noicon' => array( '0', 'ą“ą“ąµą“£ą“æą“²ąµą“²', 'noicon' ), + 'timedmedia_thumbtime' => array( '0', 'ą“²ą“ąµą“°ąµą“Ŗą“øą“®ą“Æą“=$1', 'thumbtime=$1' ), + 'timedmedia_starttime' => array( '0', 'ą“¤ąµą“ą“ąµą“ąµą“=$1', 'start=$1' ), + 'timedmedia_endtime' => array( '0', 'ą“Øą“æąµ¼ą“¤ąµą“¤ąµą“=$1', 'end=$1' ), +); + +$magicWords['mr'] = array( + 'timedmedia_thumbtime' => array( '0', 'ą¤„ą¤ą¤¬ą¤ą¤¾ą¤ą¤®=$1', 'ą¤ą¤µą¤²ą¤¾ą¤µą„ą¤³=$1', 'thumbtime=$1' ), + 'timedmedia_starttime' => array( '0', 'ą¤øą„ą¤°ą¤µą¤¾ą¤¤=$1', 'start=$1' ), + 'timedmedia_endtime' => array( '0', 'ą¤¶ą„ą¤µą¤=$1', 'end=$1' ), +); + +$magicWords['nds-nl'] = array( + 'timedmedia_noplayer' => array( '0', 'gienspeuler', 'geenspeler', 'noplayer' ), + 'timedmedia_noicon' => array( '0', 'gienicoon', 'geenicoon', 'noicon' ), + 'timedmedia_thumbtime' => array( '0', 'miniatuurtied=$1', 'miniatuurtijd=$1', 'thumbtime=$1' ), + 'timedmedia_endtime' => array( '0', 'einde=$1', 'eind=$1', 'end=$1' ), +); + +$magicWords['nl'] = array( + 'timedmedia_noplayer' => array( '0', 'geenspeler', 'noplayer' ), + 'timedmedia_noicon' => array( '0', 'geenicoon', 'noicon' ), + 'timedmedia_thumbtime' => array( '0', 'miniatuurtijd=$1', 'thumbtime=$1' ), + 'timedmedia_endtime' => array( '0', 'eind=$1', 'end=$1' ), +); + +$magicWords['ru'] = array( + 'timedmedia_noplayer' => array( '0', 'Š½ŠµŃŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń', 'noplayer' ), + 'timedmedia_noicon' => array( '0', 'Š½ŠµŃŠ·Š½Š°ŃŠŗŠ°', 'noicon' ), + 'timedmedia_starttime' => array( '0', 'Š½Š°ŃŠ°Š»Š¾=$1', 'start=$1' ), + 'timedmedia_endtime' => array( '0', 'Š¾ŠŗŠ¾Š½ŃŠ°Š½ŠøŠµ=$1', 'end=$1' ), +); diff --git a/extensions/TimedMediaHandler/TimedMediaHandler.php b/extensions/TimedMediaHandler/TimedMediaHandler.php new file mode 100644 index 00000000..2c032e6a --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaHandler.php @@ -0,0 +1,306 @@ +<?php + +if ( !defined( 'MEDIAWIKI' ) ) { + echo "This is the TimedMediaHandler extension. Please see the README file for installation instructions.\n"; + exit( 1 ); +} + +// Set up the timed media handler dir: +$timedMediaDir = __DIR__; +// Include WebVideoTranscode (prior to config so that its defined transcode keys can be used in configuration) +$wgAutoloadClasses['WebVideoTranscode'] = "$timedMediaDir/WebVideoTranscode/WebVideoTranscode.php"; + +// Add the rest transcode right: +$wgAvailableRights[] = 'transcode-reset'; +$wgAvailableRights[] = 'transcode-status'; + + + +/*** MwEmbed module configuration: *********************************/ + +// Show a warning to the user if they are not using an html5 browser with high quality ogg support +$wgMwEmbedModuleConfig['EmbedPlayer.DirectFileLinkWarning'] = true; + +// Show the options menu: +$wgMwEmbedModuleConfig['EmbedPlayer.EnableOptionsMenu'] = true; + +$wgMwEmbedModuleConfig['EmbedPlayer.DisableHTML5FlashFallback' ] = true; + +// The text interface should always be shown +// ( even if there are no text tracks for that asset at render time ) +$wgMwEmbedModuleConfig['TimedText.ShowInterface'] = 'always'; + +// Show the add text link: +$wgMwEmbedModuleConfig['TimedText.ShowAddTextLink'] = true; + +/*** Timed Media Handler configuration ****************************/ + +// Which users can restart failed or expired transcode jobs: +$wgGroupPermissions['sysop']['transcode-reset'] = true; +$wgGroupPermissions['autoconfirmed']['transcode-reset'] = true; + +// Which users can see Special:TimedMediaHandler +$wgGroupPermissions['sysop']['transcode-status'] = true; + +// How long you have to wait between transcode resets for non-error transcodes +$wgWaitTimeForTranscodeReset = 3600; + +// The minimum size for an embed video player ( smaller than this size uses a pop-up player ) +$wgMinimumVideoPlayerSize = 200; + +// Set the supported ogg codecs: +$wgMediaVideoTypes = array( 'Theora', 'VP8' ); +$wgMediaAudioTypes = array( 'Vorbis', 'Speex', 'FLAC', 'Opus' ); + +// Default skin for mwEmbed player +$wgVideoPlayerSkinModule = 'mw.PlayerSkinKskin'; + +// Support iframe for remote embedding +$wgEnableIframeEmbed = true; + +// If transcoding is enabled for this wiki (if disabled, no transcode jobs are added and no +// transcode status is displayed). Note if remote embedding an asset we will still check if +// the remote repo has transcoding enabled and associated flavors for that media embed. +$wgEnableTranscode = true; + +// If the job runner should run transcode commands in a background thread and monitor the +// transcoding progress. This enables more fine grain control of the transcoding process, wraps +// encoding commands in a lower priority 'nice' call, and kills long running transcodes that are +// not making any progress. If set to false, the job runner will use the more compatible +// php blocking shell exec command. +$wgEnableNiceBackgroundTranscodeJobs = false; + +// The priority to be used with the nice transcode commands. +$wgTranscodeBackgroundPriority = 19; + +// The total amout of time a transcoding shell command can take: +$wgTranscodeBackgroundTimeLimit = 3600 * 8; +// Maximum amount of virtual memory available to transcoding processes in KB +$wgTranscodeBackgroundMemoryLimit = 2 * 1024 * 1024; // 2GB avconv, ffmpeg2theora mmap resources so virtual memory needs to be high enough +// Maximum file size transcoding processes can create, in KB +$wgTranscodeBackgroundSizeLimit = 3 * 1024 * 1024; // 3GB + +// Number of threads to use in avconv for transcoding +$wgFFmpegThreads = 1; + +// The location of ffmpeg2theora (transcoding) +// Set to false to use avconv/ffmpeg to produce Ogg Theora transcodes instead; +// beware this will disable Ogg skeleton metadata generation. +$wgFFmpeg2theoraLocation = '/usr/bin/ffmpeg2theora'; + +// Location of oggThumb binary ( used instead of ffmpeg ) +$wgOggThumbLocation = '/usr/bin/oggThumb'; + +// Location of the avconv/ffmpeg binary (used to encode WebM and for thumbnails) +$wgFFmpegLocation = '/usr/bin/avconv'; + +// The NS for TimedText (registered on MediaWiki.org) +// http://www.mediawiki.org/wiki/Extension_namespace_registration +// Note commons pre-dates TimedMediaHandler and should set $wgTimedTextNS = 102 in LocalSettings.php +$wgTimedTextNS = 710; + +// Set TimedText namespace for ForeignDBViaLBRepo on a per wikiID basis +// $wgTimedTextForeignNamespaces = array( 'commonswiki' => 102 ); +$wgTimedTextForeignNamespaces = array(); + +// Set to false to disable local TimedText, +// you still get subtitles for videos from foreign repos +// to disable all TimedText, set +// $wgMwEmbedModuleConfig['TimedText.ShowInterface'] = 'off'; +$wgEnableLocalTimedText = true; + +/** + * Default enabled transcodes + * + * -If set to empty array, no derivatives will be created + * -Derivative keys encode settings are defined in WebVideoTranscode.php + * + * -These transcodes are *in addition to* the source file. + * -Only derivatives with smaller width than the source asset size will be created + * -Regardless of source size at least one WebM and Ogg source will be created from the $wgEnabledTranscodeSet + * -Derivative jobs are added to the MediaWiki JobQueue the first time the asset is displayed + * -Derivative should be listed min to max + */ +$wgEnabledTranscodeSet = array( + + // WebM VP8/Vorbis + // primary free/open video format + // supported by Chrome/Firefox/Opera but not Safari/IE/Edge + + // Medium-bitrate web streamable WebM video + WebVideoTranscode::ENC_WEBM_360P, + + // Moderate-bitrate web streamable WebM video + WebVideoTranscode::ENC_WEBM_480P, + + // A high quality WebM stream + WebVideoTranscode::ENC_WEBM_720P, + + // A full-HD high quality WebM stream + WebVideoTranscode::ENC_WEBM_1080P, + + // A 4K full high quality WebM stream + // WebVideoTranscode::ENC_WEBM_2160P, + + + // Ogg Theora/Vorbis + // Fallback for Safari/IE/Edge with ogv.js + // + // Requires twice the bitrate for same quality as VP8, + // and JS decoder can be slow, so shift to smaller sizes. + + // Low-bitrate Ogg stream + WebVideoTranscode::ENC_OGV_160P, + + // Medium-bitrate Ogg stream + WebVideoTranscode::ENC_OGV_240P, + + // Moderate-bitrate Ogg stream + WebVideoTranscode::ENC_OGV_360P, + + // High-bitrate Ogg stream + WebVideoTranscode::ENC_OGV_480P, + +/* + // MP4 H.264/AAC + // Primary format for the Apple/Microsoft world + // + // Check patent licensing issues in your country before use! + // Similar to WebM in quality/bitrate + + // A least common denominator h.264 stream; first gen iPhone, iPods, early android etc. + WebVideoTranscode::ENC_H264_320P, + + // A mid range h.264 stream; mid range phones and low end tables + WebVideoTranscode::ENC_H264_480P, + + // An high quality HD stream; higher end phones, tablets, smart tvs + WebVideoTranscode::ENC_H264_720P, + + // A full-HD high quality stream; higher end phones, tablets, smart tvs + WebVideoTranscode::ENC_H264_1080P, + + // A 4K high quality stream; higher end phones, tablets, smart tvs + WebVideoTranscode::ENC_H264_2160P, +*/ +); + +$wgEnabledAudioTranscodeSet = array( + WebVideoTranscode::ENC_OGG_VORBIS, + + //opus support must be available in avconv + //WebVideoTranscode::ENC_OGG_OPUS, + + //avconv needs libmp3lame support + //WebVideoTranscode::ENC_MP3, + + //avconv needs libvo_aacenc support + //WebVideoTranscode::ENC_AAC, +); + +// If mp4 source assets can be ingested: +$wgTmhEnableMp4Uploads = false; + +/******************* CONFIGURATION ENDS HERE **********************/ + + +// List of extensions handled by Timed Media Handler since its referenced in a few places. +// you should not modify this variable + +$wgTmhFileExtensions = array( 'ogg', 'ogv', 'oga', 'flac', 'wav', 'webm', 'mp4' ); + +$wgFileExtensions = array_merge( $wgFileExtensions, $wgTmhFileExtensions ); + +// Timed Media Handler AutoLoad Classes: +$wgAutoloadClasses['TimedMediaHandler'] = "$timedMediaDir/TimedMediaHandler_body.php"; +$wgAutoloadClasses['TimedMediaHandlerHooks'] = "$timedMediaDir/TimedMediaHandler.hooks.php"; +$wgAutoloadClasses['TimedMediaTransformOutput'] = "$timedMediaDir/TimedMediaTransformOutput.php"; +$wgAutoloadClasses['TimedMediaIframeOutput'] = "$timedMediaDir/TimedMediaIframeOutput.php"; +$wgAutoloadClasses['TimedMediaThumbnail'] = "$timedMediaDir/TimedMediaThumbnail.php"; +// Transcode Page +$wgAutoloadClasses['TranscodeStatusTable'] = "$timedMediaDir/TranscodeStatusTable.php"; + +// Testing: +$wgAutoloadClasses['ApiTestCaseVideoUpload'] = "$timedMediaDir/tests/phpunit/ApiTestCaseVideoUpload.php"; + +// Ogg Handler +$wgAutoloadClasses['OggHandlerTMH'] = "$timedMediaDir/handlers/OggHandler/OggHandler.php"; +$wgAutoloadClasses['OggException'] = "$timedMediaDir/handlers/OggHandler/OggException.php"; +$wgAutoloadClasses['File_Ogg'] = "$timedMediaDir/handlers/OggHandler/File_Ogg/File/Ogg.php"; +$wgAutoloadClasses['File_Ogg_Bitstream'] = "$timedMediaDir/handlers/OggHandler/File_Ogg/File/Ogg/Bitstream.php"; +$wgAutoloadClasses['File_Ogg_Flac'] = "$timedMediaDir/handlers/OggHandler/File_Ogg/File/Ogg/Flac.php"; +$wgAutoloadClasses['File_Ogg_Media'] = "$timedMediaDir/handlers/OggHandler/File_Ogg/File/Ogg/Media.php"; +$wgAutoloadClasses['File_Ogg_Opus'] = "$timedMediaDir/handlers/OggHandler/File_Ogg/File/Ogg/Opus.php"; +$wgAutoloadClasses['File_Ogg_Speex'] = "$timedMediaDir/handlers/OggHandler/File_Ogg/File/Ogg/Speex.php"; +$wgAutoloadClasses['File_Ogg_Theora'] = "$timedMediaDir/handlers/OggHandler/File_Ogg/File/Ogg/Theora.php"; +$wgAutoloadClasses['File_Ogg_Vorbis'] = "$timedMediaDir/handlers/OggHandler/File_Ogg/File/Ogg/Vorbis.php"; + +// getID3 provides metadata for mp4 and webm files: +$wgAutoloadClasses['getID3'] = "$timedMediaDir/libs/getid3/getid3.php"; +$wgAutoloadClasses['getid3_exception'] = "$timedMediaDir/libs/getid3/getid3.php"; +$wgAutoloadClasses['getid3_handler'] = "$timedMediaDir/libs/getid3/getid3.php"; + +// ID3 Metadata Handler +$wgAutoloadClasses['ID3Handler'] = "$timedMediaDir/handlers/ID3Handler/ID3Handler.php"; +// Mp4 / h264 Handler +$wgAutoloadClasses['Mp4Handler'] = "$timedMediaDir/handlers/Mp4Handler/Mp4Handler.php"; +// WebM Handler +$wgAutoloadClasses['WebMHandler'] = "$timedMediaDir/handlers/WebMHandler/WebMHandler.php"; +// FLAC Handler +$wgAutoloadClasses['FLACHandler'] = "$timedMediaDir/handlers/FLACHandler/FLACHandler.php"; +// WAV Handler +$wgAutoloadClasses['WAVHandler'] = "$timedMediaDir/handlers/WAVHandler/WAVHandler.php"; + +// Text handler +$wgAutoloadClasses['ForeignApiQueryAllPages'] = "$timedMediaDir/handlers/TextHandler/TextHandler.php"; +$wgAutoloadClasses['TextHandler'] = "$timedMediaDir/handlers/TextHandler/TextHandler.php"; +$wgAutoloadClasses['TimedTextPage'] = "$timedMediaDir/TimedTextPage.php"; + +// Transcode support +$wgAutoloadClasses['WebVideoTranscodeJob'] = "$timedMediaDir/WebVideoTranscode/WebVideoTranscodeJob.php"; + +// API modules: +$wgAutoloadClasses['ApiQueryVideoInfo'] = "$timedMediaDir/ApiQueryVideoInfo.php"; +$wgAPIPropModules['videoinfo'] = 'ApiQueryVideoInfo'; + +$wgAutoloadClasses['ApiTranscodeStatus'] = "$timedMediaDir/ApiTranscodeStatus.php"; +$wgAPIPropModules['transcodestatus'] = 'ApiTranscodeStatus'; + +$wgAutoloadClasses['ApiTranscodeReset'] = "$timedMediaDir/ApiTranscodeReset.php"; +$wgAPIModules['transcodereset'] = 'ApiTranscodeReset'; + +// Localization +$wgMessagesDirs['TimedMediaHandler'] = __DIR__ . '/i18n'; +$wgExtensionMessagesFiles['TimedMediaHandlerMagic'] = "$timedMediaDir/TimedMediaHandler.i18n.magic.php"; +$wgExtensionMessagesFiles['TimedMediaHandlerAliases'] = "$timedMediaDir/TimedMediaHandler.i18n.alias.php"; +// Inlcude module locationlizations +$wgMessagesDirs['MwEmbed.EmbedPlayer'] = __DIR__ . '/MwEmbedModules/EmbedPlayer/i18n'; +$wgMessagesDirs['MwEmbed.TimedText'] = __DIR__ . '/MwEmbedModules/TimedText/i18n'; + +// Special Pages +$wgAutoloadClasses['SpecialTimedMediaHandler'] = "$timedMediaDir/SpecialTimedMediaHandler.php"; +$wgAutoloadClasses['SpecialOrphanedTimedText'] = "$timedMediaDir/SpecialOrphanedTimedText.php"; + +// This way if you set a variable like $wgTimedTextNS in LocalSettings.php +// after you include TimedMediaHandler we can still read the variable values +// See also T123695 and T123823 +$wgHooks['SetupAfterCache'][] = 'TimedMediaHandlerHooks::onSetupAfterCache'; + +// Register remaining Timed Media Handler hooks right after initial setup +$wgExtensionFunctions[] = 'TimedMediaHandlerHooks::register'; + +# add Special pages +$wgSpecialPages['OrphanedTimedText'] = 'SpecialOrphanedTimedText'; +$wgSpecialPages['TimedMediaHandler'] = 'SpecialTimedMediaHandler'; + +// Extension Credits +$wgExtensionCredits['media'][] = array( + 'path' => __FILE__, + 'name' => 'TimedMediaHandler', + 'namemsg' => 'extensionname-timedmedia', + 'author' => array( 'Michael Dale', 'Tim Starling', 'James Heinrich', 'Jan Gerber', 'Brion Vibber' ), + 'url' => 'https://www.mediawiki.org/wiki/Extension:TimedMediaHandler', + 'descriptionmsg' => 'timedmedia-desc', + 'version' => '0.4.0', + 'license-name' => 'GPL-2.0+', +); diff --git a/extensions/TimedMediaHandler/TimedMediaHandler.sql b/extensions/TimedMediaHandler/TimedMediaHandler.sql new file mode 100644 index 00000000..7bafe675 --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaHandler.sql @@ -0,0 +1,19 @@ +-- TimedMediaHandler.sql +-- 2011-04-05 <mdale@wikimedia.org> +-- +CREATE TABLE /*_*/transcode ( + transcode_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + transcode_image_name VARCHAR(255) NOT NULL, + transcode_key VARCHAR(48) NOT NULL, + transcode_error longtext NOT NULL, + transcode_time_addjob VARCHAR(14) NULL, + transcode_time_startwork VARCHAR(14) NULL, + transcode_time_success VARCHAR(14) NULL, + transcode_time_error VARCHAR(14) NULL, + transcode_final_bitrate INT NOT NULL +) /*$wgDBTableOptions*/; + +CREATE INDEX /*i*/transcode_time_inx ON /*_*/transcode( transcode_time_addjob ,transcode_time_startwork , transcode_time_success, transcode_time_error ); +CREATE INDEX /*i*/transcode_key_idx ON /*_*/transcode( transcode_key ); + +CREATE UNIQUE INDEX /*i*/transcode_name_key ON /*_*/transcode (transcode_image_name,transcode_key); diff --git a/extensions/TimedMediaHandler/TimedMediaHandler_body.php b/extensions/TimedMediaHandler/TimedMediaHandler_body.php new file mode 100644 index 00000000..cb689858 --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaHandler_body.php @@ -0,0 +1,483 @@ +<?php + +class TimedMediaHandler extends MediaHandler { + static $magicDone = false; + + /** + * @return bool + */ + function isEnabled() { + return true; + } + + /** + * Get an image size array like that returned by getimagesize(), or false if it + * can't be determined. + * @param $file File + * @param $path string + * @param $metadata bool + * @return array|bool + */ + function getImageSize( $file, $path, $metadata = false ) { + /* override by handler */ + return false; + } + + /** + * Get the list of supported wikitext embed params + * @return array + */ + function getParamMap() { + return array( + 'img_width' => 'width', + 'timedmedia_thumbtime' => 'thumbtime', + 'timedmedia_starttime' => 'start', + 'timedmedia_endtime' => 'end', + 'timedmedia_disablecontrols' => 'disablecontrols', + ); + } + + /** + * Validate a embed file parameters + * + * @param $name {String} Name of the param + * @param $value {Mixed} Value to validated + * @return bool + */ + function validateParam( $name, $value ) { + if ( $name == 'thumbtime' || $name == 'start' || $name == 'end' ) { + if ( $this->parseTimeString( $value ) === false ) { + return false; + } + } elseif ( $name == 'disablecontrols' ) { + $values = explode( ',', $value); + foreach($values as $v) { + if ( !in_array( $v, array( 'options', 'timedText', 'fullscreen' ) ) ) { + return false; + } + } + } elseif( $name === 'width' || $name === 'height' ) { + return $value > 0; + } + return true; + } + + /** + * TODO we should really have "$file" available here to validate the param string + * @param $params array + * @return string + */ + function makeParamString( $params ) { + // Add the width param string ( same as images {width}px ) + $paramString =''; + $paramString.= ( isset( $params['width'] ) )? $params['width'] . 'px' : ''; + $paramString.= ( $paramString != '' )? '-' : ''; + + // Get the raw thumbTime from thumbtime or start param + if ( isset ( $params['thumbtime'] ) ) { + $thumbTime = $params['thumbtime']; + } elseif ( isset ( $params['start'] ) ) { + $thumbTime = $params['start']; + } else { + $thumbTime = false; + } + + if ( $thumbTime !== false ) { + $time = $this->parseTimeString( $thumbTime ); + if ( $time !== false ) { + return $paramString. 'seek=' . $time; + } + } + + if ( !$paramString ) { + $paramString = 'mid'; + } + return $paramString ; + } + + /** + * Used by thumb.php to find url parameters + * + * @param $str string + * @return array|bool Array of thumbnail parameters, or false if string cannot be parsed + */ + function parseParamString( $str ) { + $params = array(); + if ( preg_match( '/^(mid|(\d*)px-)*(seek=([\d.]+))*$/', $str, $matches ) ) { + $size = $thumbtime = null; + if ( isset( $matches[2] ) ) { + $size = $matches[2]; + } + if ( isset( $matches[4] ) ) { + $thumbtime = $matches[4]; + } + + if ( !is_null( $size ) && $size !== '' ) { + $params['width'] = (int) $size; + } + if ( !is_null( $thumbtime ) ) { + $params['thumbtime'] = (float) $thumbtime; + } + return $params; // valid thumbnail URL + } else { + // invalid parameter string + return false; + } + } + + /** + * @param $image File + * @param $params array + * @return bool + */ + function normaliseParams( $image, &$params ) { + $timeParam = array( 'thumbtime', 'start', 'end' ); + // Parse time values if endtime or thumbtime can't be more than length -1 + foreach($timeParam as $pn){ + if ( isset( $params[$pn] ) && $params[$pn] !== false ) { + $length = $this->getLength( $image ); + $time = $this->parseTimeString( $params[$pn] ); + if ( $time === false ) { + return false; + } elseif ( $time > $length - 1 ) { + $params[$pn] = $length - 1; + } elseif ( $time <= 0 ) { + $params[$pn] = 0; + } + } + } + + if ( $this->isAudio( $image ) ) { + // Assume a default for audio files + $size = array( + 'width' => 220, + 'height' => 23, + ); + } else { + $size = array( + 'width' => $image->getWidth(), + 'height' => $image->getHeight(), + ); + } + // Make sure we don't try and up-scale the asset: + if( isset( $params['width'] ) && (int)$params['width'] > $size['width'] ){ + $params['width'] = $size['width']; + } + + if ( isset( $params['height'] ) && $params['height'] != -1 ) { + if( $params['width'] * $size['height'] > $params['height'] * $size['width'] ) { + $params['width'] = self::fitBoxWidth( $size['width'], $size['height'], $params['height'] ); + } + } + if ( isset( $params['width'] ) ) { + $params['height'] = File::scaleHeight( $size['width'], $size['height'], $params['width'] ); + } + + // Make sure start time is not > than end time + if( isset($params['start']) + && isset($params['end'] ) + && $params['start'] !== false + && $params['end'] !== false + ) { + if ( $this->parseTimeString( $params['start'] ) > $this->parseTimeString( $params['end'] ) ) { + return false; + } + } + + return true; + } + + /** + * @param $parser Parser + * @param $file File + */ + function parserTransformHook( $parser, $file ) { + $parserOutput = $parser->getOutput(); + if ( isset( $parserOutput->hasTimedMediaTransform ) ) { + return ; + } + $parserOutput->hasTimedMediaTransform = true; + $parserOutput->addOutputHook( 'TimedMediaHandler' ); + } + + /** + * Parser output hook only adds the PopUpMediaTransform + * + * The core embedPlayer module is part of a "loaderScript" so it does not need to + * be registered here. + * + * TODO move core loader to on-page script as to not include it on all pages. + * + * @param $outputPage OutputPage + * @param $parserOutput + * @param $data + */ + static function outputHook( $outputPage, $parserOutput, $data ) { + // Add the PopUpMediaTransform code + $outputPage->addModuleScripts( 'mw.PopUpMediaTransform' ); + $outputPage->addModuleStyles( 'mw.PopUpMediaTransform.styles' ); + $outputPage->addModules( 'mw.TMHGalleryHook.js' ); + if ( $parserOutput ) { + // Not present when run from outputpage hooks, like File/Category etc... + $parserOutput->setExtensionData( 'mw_ext_TMH_hasTimedMediaTransform', true ); + } + } + + /** + * Utility functions + * @param $timeString + * @param $length + * @return bool|int + */ + public static function parseTimeString( $timeString, $length = false ) { + $parts = explode( ':', $timeString ); + $time = 0; + // Check for extra :s + if( count( $parts ) > 3 ){ + return false; + } + for ( $i = 0; $i < count( $parts ); $i++ ) { + if ( !is_numeric( $parts[$i] ) ) { + return false; + } + $time += floatval( $parts[$i] ) * pow( 60, count( $parts ) - $i - 1 ); + } + + if ( $time < 0 ) { + wfDebug( __METHOD__.": specified negative time, using zero\n" ); + $time = 0; + } elseif ( $length !== false && $time > $length - 1 ) { + wfDebug( __METHOD__.": specified near-end or past-the-end time {$time}s, using end minus 1s\n" ); + $time = $length - 1; + } + return $time; + } + + /** + * @static + * @param $timePassed + * @return string + */ + public static function getTimePassedMsg( $timePassed ){ + $t = array(); + $t['days'] = floor($timePassed/60/60/24); + $t['hours'] = floor($timePassed/60/60)%24; + $t['minutes'] = floor($timePassed/60)%60; + $t['seconds'] = $timePassed%60; + + foreach( $t as $k => $v ){ + if($v == 0 ){ + unset( $t[$k] ); + } else { + // Give grep a chance to find the usages: + // timedmedia-days, timedmedia-hours, timedmedia-minutes,timedmedia-seconds + $t[$k] = wfMessage( 'timedmedia-' . $k, $v )->text(); + } + } + if( count( $t ) == 0 ){ + $t = array( wfMessage( 'timedmedia-seconds', 0 )->text() ) ; + } + + global $wgLang; + return $wgLang->commaList( $t ); + } + + /** + * Converts seconds to Normal play time (NPT) time format: + * consist of hh:mm:ss.ms + * also see: http://www.ietf.org/rfc/rfc2326.txt section 3.6 + * + * @param $time Number Seconds to be converted to npt time format + * @return bool|string + */ + public static function seconds2npt( $time ){ + if ( !is_numeric( $time ) ) { + wfDebug( __METHOD__.": trying to get npt time on NaN:" + $time); + return false; + } + if( $time < 0 ){ + wfDebug( __METHOD__.": trying to time on negative value:" + $time); + return false; + } + $hours = floor( $time / 3600 ); + $min = floor( ( $time / 60 ) % 60 ); + $sec = ($time % 60 ); + $ms = ( $time - round( $time, 3) != 0 ) ? '.' .( $time - round( $time, 3) ) : ''; + + return "{$hours}:{$min}:{$sec}{$ms}"; + } + + /** + * @param $metadata + * @return bool|mixed + */ + function unpackMetadata( $metadata ) { + wfSuppressWarnings(); + $unser = unserialize( $metadata ); + wfRestoreWarnings(); + if ( isset( $unser['version'] ) ) { + return $unser; + } else { + return false; + } + } + + /** + * @param $image + * @param $metadata + * @return bool + */ + function isMetadataValid( $image, $metadata ) { + return $this->unpackMetadata( $metadata ) !== false; + } + + /** + * @param $ext + * @param $mime + * @param null $params + * @return array + */ + function getThumbType( $ext, $mime, $params = null ) { + return array( 'jpg', 'image/jpeg' ); + } + + /** + * checks if a given file is an audio file + * @param $file File + * @return bool + */ + function isAudio( $file ){ + return ( $file->getWidth() == 0 && $file->getHeight() == 0 ); + } + + /** + * @param $file File + * @param $dstPath String + * @param $dstUrl String + * @param $params array + * @param $flags int + * @return bool|MediaTransformError|MediaTransformOutput|TimedMediaTransformOutput + */ + function doTransform( $file, $dstPath, $dstUrl, $params, $flags = 0 ) { + # Important or height handling is wrong. + if ( !$this->normaliseParams( $file, $params ) ) { + return new TransformParameterError( $params ); + } + + $srcWidth = $file->getWidth(); + $srcHeight = $file->getHeight(); + + // Audio should not be transformed by size, give it a default width and height + if( $this->isAudio( $file ) ){ + $srcWidth = 220; + $srcHeight = 23; + } + + $params['width'] = isset( $params['width'] ) ? $params['width'] : $srcWidth; + + // if height overtakes width use height as max: + $targetWidth = $params['width']; + $targetHeight = $srcWidth == 0 ? $srcHeight : round( $params['width'] * $srcHeight / $srcWidth ); + if( isset( $params['height'] ) && $targetHeight > $params['height'] ){ + $targetHeight = $params['height']; + $targetWidth = round( $params['height'] * $srcWidth / $srcHeight ); + } + $options = array( + 'file' => $file, + 'length' => $this->getLength( $file ), + 'offset' => $this->getOffset( $file ), + 'width' => $targetWidth, + 'height' => $targetHeight, + 'isVideo' => !$this->isAudio( $file ), + 'thumbtime' => isset( $params['thumbtime'] ) ? $params['thumbtime'] : intval( $file->getLength() / 2 ), + 'start' => isset( $params['start'] ) ? $params['start'] : false, + 'end' => isset( $params['end'] ) ? $params['end'] : false, + 'fillwindow' => isset( $params['fillwindow'] ) ? $params['fillwindow'] : false, + 'disablecontrols' => isset ( $params['disablecontrols'] ) ? $params['disablecontrols'] : false + ); + + // No thumbs for audio + if( !$options['isVideo'] ){ + return new TimedMediaTransformOutput( $options ); + } + + // Setup pointer to thumb arguments + $options[ 'thumbUrl' ] = $dstUrl; + $options[ 'dstPath' ] = $dstPath; + $options[ 'path' ] = $dstPath; + + // Check if transform is deferred: + if ( $flags & self::TRANSFORM_LATER ) { + return new TimedMediaTransformOutput($options); + } + + // Generate thumb: + $thumbStatus = TimedMediaThumbnail::get( $options ); + if( $thumbStatus !== true ){ + return $thumbStatus; + } + + return new TimedMediaTransformOutput( $options ); + } + + /** + * @param $file + * @return bool + */ + function canRender( $file ) { return true; } + + /** + * @param $file + * @return bool + */ + function mustRender( $file ) { return true; } + + /** + * Get a stream offset time + * @param $file + * @return int + */ + function getOffset( $file ){ + return 0; + } + + /** + * Get length of a file + * @param $file + * @return int + */ + function getLength( $file ){ + return $file->getLength(); + } + + /** + * @param $file File + * @return String + */ + function getDimensionsString( $file ) { + global $wgLang; + + if ( $file->getWidth() ) { + return wfMessage( 'video-dims', $wgLang->formatTimePeriod( $this->getLength( $file ) ) ) + ->numParams( $file->getWidth(), $file->getHeight() )->text(); + } else { + return $wgLang->formatTimePeriod( $this->getLength( $file ) ); + } + } + + public function filterThumbnailPurgeList( &$files, $options ) { + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet; + + $transcodeSet = array_merge($wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet); + + //dont remove derivatives on normal purge + foreach(array_slice($files, 1) as $key => $file) { + foreach( $transcodeSet as $transcodeKey ) { + if ( preg_match('/' . preg_quote($transcodeKey) . '$/', $file) ) { + unset($files[$key]); + break; + } + } + } + } +} diff --git a/extensions/TimedMediaHandler/TimedMediaIframeOutput.php b/extensions/TimedMediaHandler/TimedMediaIframeOutput.php new file mode 100644 index 00000000..a0e2920b --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaIframeOutput.php @@ -0,0 +1,152 @@ +<?php +/** + * Adds iframe output ( bug 25862 ) + * + * This enables iframe based embeds of the wikimeia player with the following syntax: + * + * <iframe src="http://commons.wikimedia.org/wiki/File:Folgers.ogv?embedplayer=yes" + * width="240" height="180" frameborder="0" ></iframe> + * + */ + +class TimedMediaIframeOutput { + /** + * The iframe hook check file pages embedplayer=yes + * @param $title Title + * @param $article Article + * @param bool $doOutput + * @return bool + */ + static function iframeHook( &$title, &$article, $doOutput = true ) { + global $wgRequest, $wgOut, $wgEnableIframeEmbed; + if( !$wgEnableIframeEmbed ) + return true; //continue normal output iframes are "off" (maybe throw a warning in the future) + + // Make sure we are in the right namespace and iframe=true was called: + if( is_object( $title ) && $title->getNamespace() == NS_FILE && + $wgRequest->getVal('embedplayer') == 'yes' && + $wgEnableIframeEmbed && + $doOutput ){ + + if ( self::outputIframe( $title ) ) { + // Turn off output of anything other than the iframe + $wgOut->disable(); + } + } + + return true; + } + + /** + * Output an iframe + * @param $title Title + * @throws Exception + */ + static function outputIframe( $title ) { + global $wgEnableIframeEmbed, $wgOut, $wgUser, $wgBreakFrames; + + if( !$wgEnableIframeEmbed ){ + return false; + } + + // Setup the render parm + $file = wfFindFile( $title ); + if ( !$file ) { + // file was removed, show wiki page with warning + return false; + } + $params = array( + 'fillwindow' => true + ); + $videoTransform = $file->transform( $params ); + + // Definitely do not want to break frames + $wgBreakFrames = false; + $wgOut->allowClickjacking(); + + $wgOut->addModules( array( 'embedPlayerIframeStyle', 'mw.EmbedPlayer' ) ); + $wgOut->sendCacheControl(); + ?> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta charset="UTF-8" /> +<title><?php echo $title->getText() ?></title> + <?php + echo Html::element( 'meta', array( 'name' => 'ResourceLoaderDynamicStyles', 'content' => '' ) ); + ?> + <?php + echo implode( "\n", $wgOut->getHeadLinksArray() ); + echo implode( "\n", $wgOut->getHeadLinksArray() ); + ?> + <style type="text/css"> + html, body { + height: 100%; + width: 100%; + margin: 0; + padding: 0; + overflow:hidden; + } + img#bgimage { + position:fixed; + top:0; + left:0; + width:100%; + height:100%; + } + .videoHolder { + position:relative; + } + </style> + <?php echo $wgOut->getHeadScripts(); ?> + <script> + window.RLQ = window.RLQ || []; + window.RLQ.push( function() { + mw.loader.using( 'mw.MwEmbedSupport', function() { + mw.setConfig('EmbedPlayer.RewriteSelector', ''); + } ); + // Turn off rewrite selector. This prevents automatic conversion of + // <video> tags, since we are going to do that ourselves later. + } ); + </script> + </head> +<body> + <img src="<?php echo $videoTransform->getUrl() ?>" id="bgimage" ></img> + <div id="videoContainer" style="visibility:hidden"> + <?php echo $videoTransform->toHtml(); ?> + </div> + <?php echo $wgOut->getBottomScripts(); ?> + <script> + window.RLQ.push( function() { + mw.loader.using( 'mw.MwEmbedSupport', function() { + // only enable fullscreen if enabled in iframe + mw.setConfig('EmbedPlayer.EnableFullscreen', document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || false ); + $('#bgimage').remove(); + + mw.setConfig( 'EmbedPlayer.IsIframeServer', true ); + + // rewrite player + $( '#<?php echo TimedMediaTransformOutput::PLAYER_ID_PREFIX . '0' ?>' ).embedPlayer(function(){ + + // Bind window resize to reize the player: + var fitPlayer = function(){ + $( '#<?php echo TimedMediaTransformOutput::PLAYER_ID_PREFIX . '0' ?>' ) + [0].updateLayout(); + } + + $( window ).resize( fitPlayer ); + $('#videoContainer').css({ + 'visibility':'visible' + } ); + fitPlayer(); + } ); + } ); + } ); + </script> +</body> +</html> + <?php + return true; + } + +} diff --git a/extensions/TimedMediaHandler/TimedMediaThumbnail.php b/extensions/TimedMediaHandler/TimedMediaThumbnail.php new file mode 100644 index 00000000..77757440 --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaThumbnail.php @@ -0,0 +1,240 @@ +<?php +class TimedMediaThumbnail { + + /** + * @param $options array() + * @return bool|MediaTransformError + */ + static function get( $options ){ + if( !is_dir( dirname( $options['dstPath'] ) ) ){ + wfMkdirParents( dirname( $options['dstPath'] ), null, __METHOD__ ); + } + + wfDebug( "Creating video thumbnail at " . $options['dstPath'] . "\n" ); + if( + isset( $options['width'] ) && isset( $options['height'] ) && + $options['width'] != $options['file']->getWidth() && + $options['height'] != $options['file']->getHeight() + ){ + return self::resizeThumb( $options ); + } + // try OggThumb, and fallback to ffmpeg + $result = self::tryOggThumb( $options ); + if ( $result === false ) { + return self::tryFfmpegThumb( $options ); + } + return $result; + } + + /** + * Run oggThumb to generate a still image from a video file, using a frame + * close to the given number of seconds from the start. + * + * @param $options array + * @return bool|MediaTransformError + * + */ + static function tryOggThumb( $options ) { + global $wgOggThumbLocation; + + // Check that the file is 'ogg' format + if( $options['file']->getHandler()->getMetadataType( $options['file'] ) != 'ogg' ){ + return false; + } + + // Check for $wgOggThumbLocation + if( !$wgOggThumbLocation || !is_file( $wgOggThumbLocation ) ){ + return false; + } + + $time = self::getThumbTime( $options ); + $dstPath = $options['dstPath']; + $videoPath = $options['file']->getLocalRefPath(); + + $cmd = wfEscapeShellArg( $wgOggThumbLocation ) + . ' -t ' . floatval( $time ); + // Set the output size if set in options: + if( isset( $options['width'] ) && isset( $options['height'] ) ){ + $cmd.= ' -s '. intval( $options['width'] ) . 'x' . intval( $options['height'] ); + } + $cmd .= ' -n ' . wfEscapeShellArg( $dstPath ) . + ' ' . wfEscapeShellArg( $videoPath ) . ' 2>&1'; + $retval = 0; + $returnText = wfShellExec( $cmd, $retval ); + + if ( $options['file']->getHandler()->removeBadFile( $dstPath, $retval ) || $retval ) { + // oggThumb spams both stderr and stdout with useless progress + // messages, and then often forgets to output anything when + // something actually does go wrong. So interpreting its output is + // a challenge. + $lines = explode( "\n", str_replace( "\r\n", "\n", $returnText ) ); + if ( count( $lines ) > 0 + && preg_match( '/invalid option -- \'n\'$/', $lines[0] ) ) + { + $returnText = wfMessage( 'timedmedia-oggThumb-version', '0.9' )->inContentLanguage()->text(); + } else { + $returnText = wfMessage( 'timedmedia-oggThumb-failed' )->inContentLanguage()->text(); + } + return new MediaTransformError( 'thumbnail_error', + $options['width'], $options['height'], $returnText ); + } + return true; + } + + /** + * @param $options array + * @return bool|MediaTransformError + */ + static function tryFfmpegThumb( $options ){ + global $wgFFmpegLocation, $wgMaxShellMemory; + + if( !$wgFFmpegLocation || !is_file( $wgFFmpegLocation ) ){ + return false; + } + + $cmd = wfEscapeShellArg( $wgFFmpegLocation ) . ' -threads 1 '; + + $offset = intval( self::getThumbTime( $options ) ); + /* + This is a workaround until ffmpegs ogg demuxer properly seeks to keyframes. + Seek N seconds before offset and seek in decoded stream after that. + -ss before input seeks without decode + -ss after input seeks in decoded stream + + N depends on framerate of input, keyframe interval defaults + to 64 for most encoders, seeking a bit before that + */ + + $framerate = $options['file']->getHandler()->getFramerate( $options['file'] ); + if ( $framerate > 0 ) { + $seekoffset = 1 + intval( 64 / $framerate ); + } else { + $seekoffset = 3; + } + + if($offset > $seekoffset) { + $cmd .= ' -ss ' . floatval($offset - $seekoffset); + $offset = $seekoffset; + } + + //try to get temorary local url to file + $backend = $options['file']->getRepo()->getBackend(); + // getFileHttpUrl was only added in mw 1.21, dont fail if it does not exist + if ( method_exists( $backend, 'getFileHttpUrl' ) ) { + $src = $backend->getFileHttpUrl( array( + 'src' => $options['file']->getPath() + ) ); + } else { + $src = null; + } + if ( $src == null ) { + $src = $options['file']->getLocalRefPath(); + } + + $cmd .= ' -y -i ' . wfEscapeShellArg( $src ); + $cmd .= ' -ss ' . $offset . ' '; + + // Set the output size if set in options: + if( isset( $options['width'] ) && isset( $options['height'] ) ){ + $cmd.= ' -s '. intval( $options['width'] ) . 'x' . intval( $options['height'] ); + } + + # MJPEG, that's the same as JPEG except it's supported by the windows build of ffmpeg + # No audio, one frame + $cmd .= ' -f mjpeg -an -vframes 1 ' . + wfEscapeShellArg( $options['dstPath'] ) . ' 2>&1'; + + $retval = 0; + $returnText = wfShellExec( $cmd, $retval ); + // Check if it was successful + if ( !$options['file']->getHandler()->removeBadFile( $options['dstPath'], $retval ) ) { + return true; + } + $returnText = $cmd . "\nwgMaxShellMemory: $wgMaxShellMemory\n" . $returnText; + // Return error box + return new MediaTransformError( 'thumbnail_error', $options['width'], $options['height'], $returnText ); + } + + /** + * @param $options array + * @return bool|MediaTransformError + */ + static function resizeThumb( $options ) { + $file = $options['file']; + $params = array(); + foreach( array( 'start', 'thumbtime' ) as $key ) { + if( isset( $options[ $key ] ) ) { + $params[ $key ] = $options[ $key ]; + } + } + $params["width"] = $file->getWidth(); + $params["height"] = $file->getHeight(); + + $poolKey = $file->getRepo()->getSharedCacheKey( 'file', md5( $file->getName() ) ); + $posOptions = array_flip( array( 'start', 'thumbtime' ) ); + $poolKey = wfAppendQuery( $poolKey, array_intersect_key( $options, $posOptions ) ); + + if ( class_exists( 'PoolCounterWorkViaCallback' ) ) { + $work = new PoolCounterWorkViaCallback( 'TMHTransformFrame', + '_tmh:frame:' . $poolKey, + array( 'doWork' => function() use ($file, $params) { + return $file->transform( $params, File::RENDER_NOW ); + } ) ); + $thumb = $work->execute(); + } else { + $thumb = $file->transform( $params, File::RENDER_NOW ); + } + + if ( !$thumb || $thumb->isError() ) { + return $thumb; + } + $src = $thumb->getStoragePath(); + if ( !$src ) { + return false; + } + $thumbFile = new UnregisteredLocalFile( $file->getTitle(), + RepoGroup::singleton()->getLocalRepo(), $src, false ); + $thumbParams = array( + "width" => $options['width'], + "height" => $options['height'] + ); + $handler = $thumbFile->getHandler(); + if ( !$handler ) { + return false; + } + $scaledThumb = $handler->doTransform( + $thumbFile, + $options['dstPath'], + $options['dstPath'], + $thumbParams + ); + + if ( !$scaledThumb || $scaledThumb->isError() ) { + return $scaledThumb; + } + return true; + } + + /** + * @param $options array + * @return bool|float|int + */ + static function getThumbTime( $options ){ + $length = $options['file']->getLength(); + + // If start time param isset use that for the thumb: + if( isset( $options['start'] ) ) { + $thumbtime = TimedMediaHandler::parseTimeString( $options['start'], $length ); + if( $thumbtime !== false ) + return $thumbtime; + } + // else use thumbtime + if ( isset( $options['thumbtime'] ) ) { + $thumbtime = TimedMediaHandler::parseTimeString( $options['thumbtime'], $length ); + if( $thumbtime !== false ) + return $thumbtime; + } + // Seek to midpoint by default, it tends to be more interesting than the start + return $length / 2; + } +} diff --git a/extensions/TimedMediaHandler/TimedMediaTransformOutput.php b/extensions/TimedMediaHandler/TimedMediaTransformOutput.php new file mode 100644 index 00000000..36532093 --- /dev/null +++ b/extensions/TimedMediaHandler/TimedMediaTransformOutput.php @@ -0,0 +1,486 @@ +<?php + +class TimedMediaTransformOutput extends MediaTransformOutput { + static $serial = 0; + + // Video file sources object lazy init in getSources() + var $sources = null; + var $textTracks = null; + var $hashTime = null; + var $textHandler = null; // lazy init in getTextHandler + var $disablecontrols = null; + + var $start, $end, $fillwindow; + + // The prefix for player ids + const PLAYER_ID_PREFIX = 'mwe_player_'; + + function __construct( $conf ){ + $options = array( 'file', 'dstPath', 'sources', 'thumbUrl', 'start', 'end', + 'width', 'height', 'length', 'offset', 'isVideo', 'path', 'fillwindow', + 'sources', 'disablecontrols' ); + foreach ( $options as $key ) { + if( isset( $conf[ $key ]) ){ + $this->$key = $conf[$key]; + } else { + $this->$key = false; + } + } + } + + /** + * @return TextHandler + */ + function getTextHandler(){ + if( !$this->textHandler ){ + // Init an associated textHandler + $this->textHandler = new TextHandler( $this->file ); + } + return $this->textHandler; + } + + /** + * Get the media transform thumbnail + * @return string + */ + function getUrl( $sizeOverride = false ){ + global $wgVersion, $wgResourceBasePath, $wgStylePath; + // Needs to be 1.24c because version_compare() works in confusing ways + if ( version_compare( $wgVersion, '1.24c', '>=' ) ) { + $url = "$wgResourceBasePath/resources/assets/file-type-icons/fileicon-ogg.png"; + } else { + $url = "$wgStylePath/common/images/icons/fileicon-ogg.png"; + } + + if ( $this->isVideo ) { + if ( $this->thumbUrl ) { + $url = $this->thumbUrl; + } + + // Update the $posterUrl to $sizeOverride ( if not an old file ) + if( !$this->file->isOld() && $sizeOverride && + $sizeOverride[0] && intval( $sizeOverride[0] ) != intval( $this->width ) ){ + $apiUrl = $this->getPoster( $sizeOverride[0] ); + if( $apiUrl ){ + $url = $apiUrl; + } + } + } + return $url; + } + + /** + * TODO get the local path + * @return mixed + */ + function getPath(){ + return $this->dstPath; + } + + /** + * @return int + */ + function getPlayerHeight(){ + // Check if "video" tag output: + if ( $this->isVideo ) { + return intval( $this->height ); + } else { + // Give sound files a height of 23px + return 23; + } + } + + /** + * @return int + */ + function getPlayerWidth(){ + // Check if "video" tag output: + if ( $this->isVideo ) { + return intval( $this->width ); + } else { + // Give sound files a width of 300px ( if unsized ) + if( $this->width == 0 ){ + return 300; + } + // else give the target size down to 35 px wide + return ( $this->width < 35 ) ? 35 : intval( $this->width ) ; + } + } + + /** + * @return string + */ + function getTagName(){ + return ( $this->isVideo ) ? 'video' : 'audio'; + } + + /** + * @param $options array + * @return string + * @throws Exception + */ + function toHtml( $options = array() ) { + if ( count( func_get_args() ) == 2 ) { + throw new Exception( __METHOD__ .' called in the old style' ); + } + + $oldHeight = $this->height; + $oldWidth = $this->width; + if ( isset( $options['override-height'] ) ) { + $this->height = $options['override-height']; + } + if ( isset( $options['override-width'] ) ) { + $this->width = $options['override-width']; + } + + if ( $this->useImagePopUp() ) { + $res = $this->getImagePopUp(); + } else { + $res = $this->getHtmlMediaTagOutput(); + } + $this->width = $oldWidth; + $this->height = $oldHeight; + return $res; + } + + /** + * Helper to determine if to use pop up dialog for videos + * + * @return boolean + */ + private function useImagePopUp() { + global $wgMinimumVideoPlayerSize; + // Check if the video is too small to play inline ( instead do a pop-up dialog ) + // If we're filling the window (e.g. during an iframe embed) one probably doesn't want the pop up. + // Also the pop up is broken in that case. + return $this->isVideo + && !$this->fillwindow + && $this->getPlayerWidth() < $wgMinimumVideoPlayerSize + // Do not do pop-up if its going to be the same size as inline player anyways + && $this->getPlayerWidth() < $this->getPopupPlayerWidth(); + } + + /** + * XXX migrate this to the mediawiki Html class as 'tagSet' helper function + * @param $tagName + * @param $tagSet + * @return string + */ + static function htmlTagSet( $tagName, $tagSet ){ + if( empty( $tagSet ) ){ + return ''; + } + $s = ''; + foreach( $tagSet as $attr ){ + $s .= Html::element( $tagName, $attr); + } + return $s; + } + + /** + * @return string + */ + function getImagePopUp(){ + // pop up videos set the autoplay attribute to true: + $autoPlay = true; + return Xml::tags( 'div' , array( + 'id' => self::PLAYER_ID_PREFIX . TimedMediaTransformOutput::$serial++, + 'class' => 'PopUpMediaTransform', + 'style' => "width:" . $this->getPlayerWidth() . "px;", + 'videopayload' => $this->getHtmlMediaTagOutput( $this->getPopupPlayerSize(), $autoPlay ), + ), + Xml::tags( 'img', array( + 'alt' => $this->file->getTitle(), + 'style' => "width:" . $this->getPlayerWidth() . "px;height:" . + $this->getPlayerHeight() . "px", + 'src' => $this->getUrl(), + ),'') + . + // For javascript disabled browsers provide a link to the asset: + Xml::tags( 'a', array( + 'href'=> $this->file->getUrl(), + 'title' => wfMessage( 'timedmedia-play-media' )->escaped(), + 'target' => 'new' + ), + Xml::tags( 'span', array( + 'class' => 'play-btn-large' + ), + // Have some sort of text for lynx & screen readers. + Html::element( + 'span', + array( 'class' => 'mw-tmh-playtext' ), + wfMessage( 'timedmedia-play-media' )->text() + ) + ) + ) + ); + } + + /** + * Get target popup player size + */ + function getPopupPlayerSize(){ + // Get the max width from the enabled transcode settings: + $maxImageSize = WebVideoTranscode::getMaxSizeWebStream(); + return WebVideoTranscode::getMaxSizeTransform( $this->file, $maxImageSize); + } + + /** + * Helper function to get pop up width + * + * Silly function because array index operations aren't allowed + * on function calls before php 5.4 + */ + private function getPopupPlayerWidth() { + list( $popUpWidth ) = $this->getPopupPlayerSize(); + return $popUpWidth; + } + + /** + * Sort media by bandwidth, but with things not wide enough at end + * + * The list should be in preferred source order, so we want the file + * with the lowest bitrate (to save bandwidth) first, but we also want + * appropriate resolution files before the 160p transcodes. + */ + private function sortMediaByBandwidth( $a, $b ) { + $width = $this->getPlayerWidth(); + $maxWidth = $this->getPopupPlayerWidth(); + if ( $this->useImagePopUp() || $width > $maxWidth ) { + // If its a pop-up player than we should use the pop up player size + // if its a normal player, but has a bigger width than the pop-up + // player, then we use the pop-up players width as the target width + // as that is equivalent to the max transcode size. Otherwise this + // will suggest the original file as the best source, which seems like + // a potentially bad idea, as it could be anything size wise. + $width = $maxWidth; + } + + if ( $a['width'] < $width && $b['width'] >= $width ) { + // $a is not wide enough but $b is + // so we consider $a > $b as we want $b before $a + return 1; + } + if ( $a['width'] >= $width && $b['width'] < $width ) { + // $b not wide enough, so $a must be preferred. + return -1; + } + if ( $a['width'] < $width && $b['width'] < $width && $a['width'] != $b['width'] ) { + // both are too small. Go with the one closer to the target width + return ( $a['width'] < $b['width'] ) ? -1 : 1; + } + // Both are big enough, or both equally too small. Go with the one + // that has a lower bit-rate (as it will be faster to download). + if ( isset( $a['bandwidth'] ) && isset( $b['bandwidth'] ) ) { + return ( $a['bandwidth'] < $b['bandwidth'] ) ? -1 : 1; + } + + // We have no firm basis for a comparison, so consider them equal. + return 0; + } + + /** + * Call mediaWiki xml helper class to build media tag output from + * supplied arrays + * @param $sizeOverride array + * @param $autoPlay boolean sets the autoplay attribute + * @return string + */ + function getHtmlMediaTagOutput( $sizeOverride = array(), $autoPlay = false ){ + // Try to get the first source src attribute ( usually this should be the source file ) + $mediaSources = $this->getMediaSources(); + reset( $mediaSources ); // do not rely on auto-resetting of arrays under HHVM + $firstSource = current( $mediaSources ); + + if( !$firstSource['src'] ){ + // XXX media handlers don't seem to work with exceptions.. + return 'Error missing media source'; + }; + + // Sort sources by bandwidth least to greatest ( so default selection on resource constrained + // browsers ( without js? ) go with minimal source. + usort( $mediaSources, array( $this, 'sortMediaByBandwidth' ) ); + + // We prefix some source attributes with data- to pass along to the javascript player + $prefixedSourceAttr = Array( 'width', 'height', 'title', 'shorttitle', 'bandwidth', 'framerate', 'disablecontrols' ); + foreach( $mediaSources as &$source ){ + foreach( $source as $attr => $val ){ + if( in_array( $attr, $prefixedSourceAttr ) ){ + $source[ 'data-' . $attr ] = $val; + unset( $source[ $attr ] ); + } + } + } + + $width = $sizeOverride ? $sizeOverride[0] : $this->getPlayerWidth(); + if( $this->fillwindow ){ + $width = '100%'; + } else { + $width .= 'px'; + } + // Build the video tag output: + $s = Xml::tags( 'div' , array( + 'class' => 'mediaContainer', + 'style' => 'position:relative;display:block;width:'. $width + ), + Html::rawElement( $this->getTagName(), $this->getMediaAttr( $sizeOverride, $autoPlay ), + // The set of media sources: + self::htmlTagSet( 'source', $mediaSources ) . + + // Timed text: + self::htmlTagSet( 'track', + $this->file ? $this->getTextHandler()->getTracks() : null ) . + + // Fallback text displayed for browsers without js and without video tag support: + /// XXX note we may want to replace this with an image and download link play button + wfMessage( 'timedmedia-no-player-js', $firstSource['src'] )->text() + ) + ); + return $s; + } + + /** + * Get poster. + * @param $width Integer width of poster. Should not equal $this->width. + * @throws Exception If $width is same as $this->width. + * @return String|bool url for poster or false + */ + function getPoster ( $width ) { + if ( intval( $width ) === intval( $this->width ) ) { + // Prevent potential loop + throw new Exception( "Asked for poster in current size. Potential loop." ); + } + $params = array( "width" => intval( $width ) ); + $mto = $this->file->transform( $params ); + if ( $mto ) { + return $mto->getUrl(); + } else { + return false; + } + } + + /** + * Get the media attributes + * @param $sizeOverride Array|bool of width and height + * @return array + */ + function getMediaAttr( $sizeOverride = false, $autoPlay = false ){ + global $wgVideoPlayerSkin ; + // Normalize values + $length = floatval( $this->length ); + $offset = floatval( $this->offset ); + + $width = $sizeOverride ? $sizeOverride[0] : $this->getPlayerWidth(); + $height = $sizeOverride ? $sizeOverride[1]: $this->getPlayerHeight(); + + // The poster url: + $posterUrl = $this->getUrl( $sizeOverride ); + + if( $this->fillwindow ){ + $width = '100%'; + $height = '100%'; + } else{ + $width .= 'px'; + $height .= 'px'; + } + + $mediaAttr = array( + 'id' => self::PLAYER_ID_PREFIX . TimedMediaTransformOutput::$serial++, + 'style' => "width:{$width}", + // Get the correct size: + 'poster' => $posterUrl, + + // Note we set controls to true ( for no-js players ) when mwEmbed rewrites the interface + // it updates the controls attribute of the embed video + 'controls'=> 'true', + // Since we will reload the item with javascript, + // tell browser to not load the video before + 'preload'=>'none', + ); + + if ( $this->isVideo ) { + $mediaAttr['style'] .= ";height:{$height}"; + } + + if( $autoPlay === true ){ + $mediaAttr['autoplay'] = 'true'; + } + + // MediaWiki uses the kSkin class + $mediaAttr['class'] = 'kskin'; + + if ( $this->file ) { + // Custom data-attributes + $mediaAttr += array( + 'data-durationhint' => $length, + 'data-startoffset' => $offset, + 'data-mwtitle' => $this->file->getTitle()->getDBkey() + ); + + // Add api provider: + if( $this->file->isLocal() ){ + $apiProviderName = 'local'; + } else { + // Set the api provider name to "wikimediacommons" for shared ( instant commons convention ) + // (provider names should have identified the provider instead of the provider type "shared") + $apiProviderName = $this->file->getRepoName(); + if( $apiProviderName == 'shared' ) { + $apiProviderName = 'wikimediacommons'; + } + } + // XXX Note: will probably migrate mwprovider to an escaped api url. + $mediaAttr[ 'data-mwprovider' ] = $apiProviderName; + } else { + if ( $length ) { + $mediaAttr[ 'data-durationhint' ] = $length; + } + if ( $offset ) { + $mediaAttr[ 'data-startoffset' ] = $offset; + } + } + if ( $this->disablecontrols ) { + $mediaAttr[ 'data-disablecontrols' ] = $this->disablecontrols; + } + return $mediaAttr; + } + + /** + * @return null + */ + function getMediaSources(){ + if( !$this->sources ){ + // Generate transcode jobs ( and get sources that are already transcoded) + // At a minimum this should return the source video file. + $this->sources = WebVideoTranscode::getSources( $this->file ); + // Check if we have "start or end" times and append the temporal url fragment hash + foreach( $this->sources as &$source ){ + $source['src'].= $this->getTemporalUrlHash(); + } + } + return $this->sources; + } + + function getTemporalUrlHash(){ + if( $this->hashTime ){ + return $this->hashTime; + } + $hash =''; + if( $this->start ){ + $startSec = TimedMediaHandler::parseTimeString( $this->start ); + if( $startSec !== false ){ + $hash.= '#t=' . TimedMediaHandler::seconds2npt( $startSec ); + } + } + if( $this->end ){ + if( $hash == '' ){ + $hash .= '#t=0'; + } + $endSec = TimedMediaHandler::parseTimeString( $this->end ); + if( $endSec !== false ){ + $hash.= ',' . TimedMediaHandler::seconds2npt( $endSec ); + } + } + $this->hashTime = $hash; + return $this->hashTime; + } +} diff --git a/extensions/TimedMediaHandler/TimedTextPage.php b/extensions/TimedMediaHandler/TimedTextPage.php new file mode 100644 index 00000000..361c2eb9 --- /dev/null +++ b/extensions/TimedMediaHandler/TimedTextPage.php @@ -0,0 +1,187 @@ +<?php +/** + * TimedText page display the current video with subtitles to the right. + * + * Future features for this page" + * @todo add srt download links + * @todo parse and validate srt files + * @todo link-in or include the universal subtitles editor + */ +class TimedTextPage extends Article { + // The width of the video plane: + static private $videoWidth = 400; + static private $knownTimedTextExtensions = array( 'srt', 'vtt' ); + + public function view() { + $request = $this->getContext()->getRequest(); + $out = $this->getContext()->getOutput(); + $user = $this->getContext()->getUser(); + + $diff = $request->getVal( 'diff' ); + + if ( $this->getTitle()->getNamespace() != NS_TIMEDTEXT || isset( $diff ) ) { + parent::view(); + return; + } + $this->renderOutput( $out ); + } + + /** + * Render TimedText to given output + * @param $out OutputPage + */ + public function renderOutput( $out ){ + // parse page title: + $titleParts = explode( '.', $this->getTitle()->getDBkey() ); + $timedTextExtension = array_pop( $titleParts ); + $languageKey = array_pop( $titleParts ); + + $oldid = $this->getOldID(); + # Are we looking at an old revision + if ( $oldid && $this->mRevision ) { + $this->fetchContentObject(); + $out->setRevisionId( $this->getRevIdFetched() ); + $this->setOldSubtitle( $oldid ); + + if ( !$this->showDeletedRevisionHeader() ) { + wfDebug( __METHOD__ . ": cannot view deleted revision\n" ); + return; + } + } + + // Check for File name without text extension: + // i.e TimedText:myfile.ogg + $fileTitle = Title::newFromText( $this->getTitle()->getDBkey(), NS_FILE ); + $file = wfFindFile( $fileTitle ); + // Check for a valid srt page, present redirect form for the full title match: + if( !in_array( $timedTextExtension, self::$knownTimedTextExtensions ) && $file && $file->exists() ){ + if( $file->isLocal() ){ + $this->doRedirectToPageForm( $fileTitle ); + } else { + $this->doLinkToRemote( $file ); + } + return; + } + + // Check for File name with text extension ( from remaning parts of title ) + // i.e TimedText:myfile.ogg.en.srt + + $videoTitle = Title::newFromText( implode('.', $titleParts ), NS_FILE ); + + // Check for remote file + $basefile = wfFindFile( $videoTitle ); + if ( !$basefile ) { + $out->addHTML( wfMessage( 'timedmedia-subtitle-no-video' )->escaped() ); + return; + } + + if( !$basefile->isLocal() ){ + $this->doLinkToRemote( $basefile ); + return; + } + + // Look up the language name: + $language = $out->getLanguage()->getCode(); + $languages = Language::fetchLanguageNames( $language, 'all' ); + if( isset( $languages[ $languageKey ] ) ) { + $languageName = $languages[ $languageKey ]; + } else { + $languageName = $languageKey; + } + + // Set title + $message = $this->exists() ? + 'mwe-timedtext-language-subtitles-for-clip' : + 'mwe-timedtext-language-no-subtitles-for-clip'; + $out->setPageTitle( wfMessage($message, $languageName, $videoTitle ) ); + + // Get the video with with a max of 600 pixel page + $out->addHTML( + xml::tags( 'table', array( 'style'=> 'border:none' ), + xml::tags( 'tr', null, + xml::tags( 'td', array( 'valign' => 'top', 'width' => self::$videoWidth ), + $this->getVideoHTML( $videoTitle ) + ) . + xml::tags( 'td', array( 'valign' => 'top' ) , $this->getTimedTextHTML( $languageName ) ) + ) + ) + ); + } + + /** + * Timed text or file is hosted on remote repo, Add a short description and link to foring repo + * @param $file File the base file + */ + function doLinkToRemote( $file ){ + $output = $this->getContext()->getOutput(); + $output->setPageTitle( wfMessage( 'timedmedia-subtitle-remote', + $file->getRepo()->getDisplayName() ) ); + $output->addHTML( wfMessage( 'timedmedia-subtitle-remote-link', + $file->getDescriptionUrl(), $file->getRepo()->getDisplayName() ) ); + } + + function doRedirectToPageForm(){ + $lang = $this->getContext()->getLanguage(); + $out = $this->getContext()->getOutput(); + + // Set the page title: + $out->setPageTitle( wfMessage( 'timedmedia-subtitle-new' ) ); + + // Look up the language name: + $language = $out->getLanguage()->getCode(); + $attrs = array( 'id' => 'timedmedia-tt-input' ); + $langSelect = Xml::languageSelector( $language, false, null, $attrs, null ); + + $out->addHTML( + Xml::tags('div', array( 'style' => 'text-align:center' ), + Xml::tags( 'div', null, + wfMessage( 'timedmedia-subtitle-new-desc', $lang->getCode() )->parse() + ) . + $langSelect[1] . + Xml::tags( 'button', + array( 'id' => 'timedmedia-tt-go' ), + wfMessage( 'timedmedia-subtitle-new-go' )->escaped() + ) + ) + ); + $out->addModules( 'ext.tmh.TimedTextSelector' ); + } + + /** + * Gets the video HTML ( with the current language set as default ) + * @param $videoTitle string + * @return String + */ + private function getVideoHTML( $videoTitle ){ + // Get the video embed: + $file = wfFindFile( $videoTitle ); + if( !$file ){ + return wfMessage( 'timedmedia-subtitle-no-video' )->escaped(); + } else { + $videoTransform= $file->transform( + array( + 'width' => self::$videoWidth + ) + ); + return $videoTransform->toHTML(); + } + } + + /** + * Gets an HTML representation of the Timed Text + * + * @param $languageName string + * @return Message|string + */ + private function getTimedTextHTML( $languageName ){ + if( !$this->exists() ){ + return wfMessage( 'timedmedia-subtitle-no-subtitles', $languageName ); + } + return Xml::element( + 'pre', + array( 'style' => 'margin-top: 0px;' ), + $this->getContent(), + false + ); + } +} diff --git a/extensions/TimedMediaHandler/TranscodeStatusTable.php b/extensions/TimedMediaHandler/TranscodeStatusTable.php new file mode 100644 index 00000000..2220fc72 --- /dev/null +++ b/extensions/TimedMediaHandler/TranscodeStatusTable.php @@ -0,0 +1,236 @@ +<?php +/** + * TranscodeStatusTable outputs a "transcode" status table to the ImagePage + * + * If logged in as autoconfirmed users can reset transcode states + * via the transcode api entry point + * + */ +class TranscodeStatusTable { + /** + * @param $file File + * @return string + */ + public static function getHTML( $file ){ + global $wgUser, $wgOut; + + // Add transcode table css and javascript: + $wgOut->addModules( array( 'ext.tmh.transcodetable' ) ); + + $o = '<h2 id="transcodestatus">' . wfMessage( 'timedmedia-status-header' )->escaped() . '</h2>'; + // Give the user a purge page link + $o.= Linker::link( + $file->getTitle(), + wfMessage('timedmedia-update-status')->escaped(), + array(), + array( 'action'=> 'purge' ) + ); + + $o.= Xml::openElement( 'table', array( 'class' => 'wikitable mw-filepage-transcodestatus' ) ) . "\n" + . '<tr>' + . '<th>' . wfMessage( 'timedmedia-transcodeinfo' )->escaped() . '</th>' + . '<th>' . wfMessage( 'timedmedia-transcodebitrate' )->escaped() . '</th>' + . '<th>' . wfMessage( 'timedmedia-direct-link' )->escaped() . '</th>'; + + if( $wgUser->isAllowed( 'transcode-reset' ) ) { + $o.= '<th>' . wfMessage( 'timedmedia-actions' )->escaped() . '</th>'; + } + + $o.= '<th>' . wfMessage( 'timedmedia-status' )->escaped() . '</th>'; + $o.= '<th>' . wfMessage( 'timedmedia-transcodeduration' )->escaped() . '</th>'; + $o.= "</tr>\n"; + + $o.= self::getTranscodeRows( $file ); + + $o.= Xml::closeElement( 'table' ); + return $o; + } + + /** + * Get the video or audio codec for the defined transcode, + * for grouping/sorting purposes. + */ + public static function codecFromTranscodeKey( $key ) { + if ( isset( WebVideoTranscode::$derivativeSettings[$key] ) ) { + $settings = WebVideoTranscode::$derivativeSettings[$key]; + if ( isset( $settings['videoCodec'] ) ) { + return $settings['videoCodec']; + } else if ( isset( $settings['audioCodec'] ) ) { + return $settings['audioCodec']; + } else { + // this this shouldn't happen... + // fall through + } + } else { + // derivative type no longer defined or invalid def? + // fall through + } + return $key; + } + + /** + * @param $file File + * @return string + */ + public static function getTranscodeRows( $file ){ + global $wgUser, $wgLang; + $o=''; + + $transcodeRows = WebVideoTranscode::getTranscodeState( $file ); + + uksort( $transcodeRows, function( $a, $b ) { + $formatOrder = array( 'vp9', 'vp8', 'h264', 'theora', 'opus', 'vorbis', 'aac' ); + + $aFormat = self::codecFromTranscodeKey( $a ); + $bFormat = self::codecFromTranscodeKey( $b ); + $aIndex = array_search( $aFormat, $formatOrder ); + $bIndex = array_search( $bFormat, $formatOrder ); + + if ( $aIndex === false && $bIndex === false ) { + return -strnatcmp( $a, $b ); + } else if ( $aIndex === false ) { + return 1; + } else if ( $bIndex === false ) { + return -1; + } else if ( $aIndex === $bIndex ) { + return -strnatcmp( $a, $b ); + } else { + return ( $aIndex - $bIndex ); + } + } ); + + foreach( $transcodeRows as $transcodeKey => $state ){ + $o.='<tr>'; + // Encode info: + $o.='<td>' . wfMessage('timedmedia-derivative-' . $transcodeKey )->escaped() . '</td>'; + $o.='<td>' . self::getTranscodeBitrate( $file, $state ) . '</td>'; + + // Download file + $o.='<td>'; + $o.= ( !is_null( $state['time_success'] ) ) ? + '<a href="'.self::getSourceUrl( $file, $transcodeKey ) .'" title="'.wfMessage + ('timedmedia-download' )->escaped() .'"><div class="download-btn"><span>' . + wfMessage('timedmedia-download' )->escaped(). '</span></div></a></td>' : + wfMessage('timedmedia-not-ready' )->escaped(); + $o.='</td>'; + + // Check if we should include actions: + if( $wgUser->isAllowed( 'transcode-reset' ) ){ + // include reset transcode action buttons + $o.='<td class="mw-filepage-transcodereset"><a href="#" data-transcodekey="' . + htmlspecialchars( $transcodeKey ). '">' . wfMessage('timedmedia-reset')->escaped() . + '</a></td>'; + } + + // Status: + $o.='<td>' . self::getStatusMsg( $file, $state ) . '</td>'; + $o.='<td>' . self::getTranscodeDuration( $file, $state ) . '</td>'; + + $o.='</tr>'; + } + return $o; + } + + /** + * @param $file File + * @param $transcodeKey string + * @return string + */ + public static function getSourceUrl( $file, $transcodeKey ){ + return WebVideoTranscode::getTranscodedUrlForFile( $file, $transcodeKey ); + } + + /** + * @param $file File + * @param $state + * @return string + */ + public static function getTranscodeDuration( $file, $state ) { + global $wgLang; + if( !is_null( $state['time_success'] ) ) { + $startTime = wfTimestamp( TS_UNIX, $state['time_startwork'] ); + $endTime = wfTimestamp( TS_UNIX, $state['time_success'] ); + $delta = $endTime - $startTime; + $duration = $wgLang->formatTimePeriod( $delta ); + return $duration; + } else { + return ''; + } + } + + /** + * @param $file File + * @param $state + * @return string + */ + public static function getTranscodeBitrate( $file, $state ) { + global $wgLang; + if( !is_null( $state['time_success'] ) ) { + return $wgLang->formatBitrate( $state['final_bitrate'] ); + } else { + return ''; + } + } + + /** + * @param $file File + * @param $state + * @return string + */ + public static function getStatusMsg( $file, $state ){ + global $wgContLang; + // Check for success: + if( !is_null( $state['time_success'] ) ) { + return wfMessage( 'timedmedia-completed-on', + $wgContLang->timeAndDate( $state[ 'time_success' ] ) )->escaped(); + } + // Check for error: + if( !is_null( $state['time_error'] ) ){ + $attribs = array(); + if( !is_null( $state['error'] ) ){ + $attribs = array( + 'class' => 'mw-tmh-pseudo-error-link', + 'data-error' => $state['error'], + ); + } + + return Html::rawElement( 'span', $attribs, + wfMessage( 'timedmedia-error-on', + $wgContLang->timeAndDate( $state['time_error'] ) )->escaped() + ); + } + + //$db = wfGetDB( DB_SLAVE ); + // Check for started encoding + if( !is_null( $state['time_startwork'] ) ){ + $timePassed = time() - wfTimestamp ( TS_UNIX, $state['time_startwork'] ); + // Get the rough estimate of time done: ( this is not very costly considering everything else + // that happens in an action=purge video page request ) + /*$filePath = WebVideoTranscode::getTargetEncodePath( $file, $state['key'] ); + if( is_file( $filePath ) ){ + $targetSize = WebVideoTranscode::getProjectedFileSize( $file, $state['key'] ); + if( $targetSize === false ){ + $doneMsg = wfMessage( 'timedmedia-unknown-target-size', $wgLang->formatSize( filesize( $filePath ) ) )->escaped(); + } else { + $doneMsg = wfMessage('timedmedia-percent-done', round( filesize( $filePath ) / $targetSize, 2 ) )->escaped(); + } + } */ + // Predicting percent done is not working well right now ( disabled for now ) + $doneMsg = ''; + return wfMessage( + 'timedmedia-started-transcode', + TimedMediaHandler::getTimePassedMsg( $timePassed ), $doneMsg + )->escaped(); + } + // Check for job added ( but not started encoding ) + if( !is_null( $state['time_addjob'] ) ){ + $timePassed = time() - wfTimestamp ( TS_UNIX, $state['time_addjob'] ); + return wfMessage( + 'timedmedia-in-job-queue', + TimedMediaHandler::getTimePassedMsg( $timePassed ) + )->escaped(); + } + // Return unknown status error: + return wfMessage('timedmedia-status-unknown')->escaped(); + } +} diff --git a/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php b/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php new file mode 100644 index 00000000..e4d02556 --- /dev/null +++ b/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscode.php @@ -0,0 +1,1192 @@ +<?php +/** + * WebVideoTranscode provides: + * encode keys + * encode settings + * + * extends api to return all the streams + * extends video tag output to provide all the available sources + */ + +/** + * Main WebVideoTranscode Class hold some constants and config values + */ +class WebVideoTranscode { + /** + * Key constants for the derivatives, + * this key is appended to the derivative file name + * + * If you update the wgDerivativeSettings for one of these keys + * and want to re-generate the video you should also update the + * key constant. ( Or just run a maintenance script to delete all + * the assets for a given profile ) + * + * Msg keys for derivatives are set as follows: + * $messages['timedmedia-derivative-200_200kbs.ogv'] => 'Ogg 200'; + */ + + // Ogg Profiles + const ENC_OGV_160P = '160p.ogv'; + const ENC_OGV_240P = '240p.ogv'; + const ENC_OGV_360P = '360p.ogv'; + const ENC_OGV_480P = '480p.ogv'; + const ENC_OGV_720P = '720p.ogv'; + const ENC_OGV_1080P = '1080p.ogv'; + + // WebM VP8/Vorbis profiles: + const ENC_WEBM_160P = '160p.webm'; + const ENC_WEBM_360P = '360p.webm'; + const ENC_WEBM_480P = '480p.webm'; + const ENC_WEBM_720P = '720p.webm'; + const ENC_WEBM_1080P = '1080p.webm'; + const ENC_WEBM_2160P = '2160p.webm'; + + // WebM VP9/Opus profiles: + const ENC_VP9_360P = '360p.vp9.webm'; + const ENC_VP9_480P = '480p.vp9.webm'; + const ENC_VP9_720P = '720p.vp9.webm'; + const ENC_VP9_1080P = '1080p.vp9.webm'; + const ENC_VP9_2160P = '2160p.vp9.webm'; + + // mp4 profiles: + const ENC_H264_320P = '320p.mp4'; + const ENC_H264_480P = '480p.mp4'; + const ENC_H264_720P = '720p.mp4'; + const ENC_H264_1080P = '1080p.mp4'; + const ENC_H264_2160P = '2160p.mp4'; + + const ENC_OGG_VORBIS = 'ogg'; + const ENC_OGG_OPUS = 'opus'; + const ENC_MP3 = 'mp3'; + const ENC_AAC = 'm4a'; + + // Static cache of transcode state per instantiation + public static $transcodeState = array() ; + + /** + * Encoding parameters are set via firefogg encode api + * + * For clarity and compatibility with passing down + * client side encode settings at point of upload + * + * http://firefogg.org/dev/index.html + */ + public static $derivativeSettings = array( + WebVideoTranscode::ENC_OGV_160P => + array( + 'maxSize' => '288x160', + 'videoBitrate' => '160', + 'framerate' => '15', + 'audioQuality' => '-1', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + //'twopass' => 'true', // temporarily disabled for broken ffmpeg2theora + 'optimize' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'theora', + 'type' => 'video/ogg; codecs="theora, vorbis"', + ), + WebVideoTranscode::ENC_OGV_240P => + array( + 'maxSize' => '426x240', + 'videoBitrate' => '512', + 'audioQuality' => '0', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + //'twopass' => 'true', // temporarily disabled for broken ffmpeg2theora + 'optimize' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'theora', + 'type' => 'video/ogg; codecs="theora, vorbis"', + ), + WebVideoTranscode::ENC_OGV_360P => + array( + 'maxSize' => '640x360', + 'videoBitrate' => '1024', + 'audioQuality' => '1', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + //'twopass' => 'true', // temporarily disabled for broken ffmpeg2theora + 'optimize' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'theora', + 'type' => 'video/ogg; codecs="theora, vorbis"', + ), + WebVideoTranscode::ENC_OGV_480P => + array( + 'maxSize' => '854x480', + 'videoBitrate' => '2048', + 'audioQuality' => '2', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + //'twopass' => 'true', // temporarily disabled for broken ffmpeg2theora + 'optimize' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'theora', + 'type' => 'video/ogg; codecs="theora, vorbis"', + ), + + WebVideoTranscode::ENC_OGV_720P => + array( + 'maxSize' => '1280x720', + 'videoQuality' => 6, + 'audioQuality' => 3, + 'noUpscaling' => 'true', + //'twopass' => 'true', // temporarily disabled for broken ffmpeg2theora + 'optimize' => 'true', + 'keyframeInterval' => '128', + 'videoCodec' => 'theora', + 'type' => 'video/ogg; codecs="theora, vorbis"', + ), + + WebVideoTranscode::ENC_OGV_1080P => + array( + 'maxSize' => '1920x1080', + 'videoQuality' => 6, + 'audioQuality' => 3, + 'noUpscaling' => 'true', + //'twopass' => 'true', // temporarily disabled for broken ffmpeg2theora + 'optimize' => 'true', + 'keyframeInterval' => '128', + 'videoCodec' => 'theora', + 'type' => 'video/ogg; codecs="theora, vorbis"', + ), + + // WebM transcode: + WebVideoTranscode::ENC_WEBM_160P => + array( + 'maxSize' => '288x160', + 'videoBitrate' => '256', + 'audioQuality' => '-1', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + 'twopass' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'vp8', + 'type' => 'video/webm; codecs="vp8, vorbis"', + ), + WebVideoTranscode::ENC_WEBM_360P => + array( + 'maxSize' => '640x360', + 'videoBitrate' => '512', + 'audioQuality' => '1', + 'samplerate' => '44100', + 'noUpscaling' => 'true', + 'twopass' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'vp8', + 'type' => 'video/webm; codecs="vp8, vorbis"', + ), + WebVideoTranscode::ENC_WEBM_480P => + array( + 'maxSize' => '854x480', + 'videoBitrate' => '1024', + 'audioQuality' => '2', + 'samplerate' => '44100', + 'noUpscaling' => 'true', + 'twopass' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'vp8', + 'type' => 'video/webm; codecs="vp8, vorbis"', + ), + WebVideoTranscode::ENC_WEBM_720P => + array( + 'maxSize' => '1280x720', + 'videoQuality' => 7, + 'audioQuality' => 3, + 'noUpscaling' => 'true', + 'videoCodec' => 'vp8', + 'type' => 'video/webm; codecs="vp8, vorbis"', + ), + WebVideoTranscode::ENC_WEBM_1080P => + array( + 'maxSize' => '1920x1080', + 'videoQuality' => 7, + 'audioQuality' => 3, + 'noUpscaling' => 'true', + 'videoCodec' => 'vp8', + 'type' => 'video/webm; codecs="vp8, vorbis"', + ), + WebVideoTranscode::ENC_WEBM_2160P => + array( + 'maxSize' => '4096x2160', + 'videoQuality' => 7, + 'audioQuality' => 3, + 'noUpscaling' => 'true', + 'videoCodec' => 'vp8', + 'type' => 'video/webm; codecs="vp8, vorbis"', + ), + + // WebM VP9 transcode: + WebVideoTranscode::ENC_VP9_360P => + array( + 'maxSize' => '640x360', + 'videoBitrate' => '256', + 'samplerate' => '48000', + 'noUpscaling' => 'true', + 'twopass' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'vp9', + 'audioCodec' => 'opus', + 'type' => 'video/webm; codecs="vp9, opus"', + ), + WebVideoTranscode::ENC_VP9_480P => + array( + 'maxSize' => '854x480', + 'videoBitrate' => '512', + 'samplerate' => '48000', + 'noUpscaling' => 'true', + 'twopass' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'vp9', + 'audioCodec' => 'opus', + 'type' => 'video/webm; codecs="vp9, opus"', + ), + WebVideoTranscode::ENC_VP9_720P => + array( + 'maxSize' => '1280x720', + 'videoBitrate' => '1024', + 'samplerate' => '48000', + 'noUpscaling' => 'true', + 'twopass' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'vp9', + 'audioCodec' => 'opus', + 'tileColumns' => '2', + 'type' => 'video/webm; codecs="vp9, opus"', + ), + WebVideoTranscode::ENC_VP9_1080P => + array( + 'maxSize' => '1920x1080', + 'videoBitrate' => '2048', + 'samplerate' => '48000', + 'noUpscaling' => 'true', + 'twopass' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'vp9', + 'audioCodec' => 'opus', + 'tileColumns' => '4', + 'type' => 'video/webm; codecs="vp9, opus"', + ), + WebVideoTranscode::ENC_VP9_2160P => + array( + 'maxSize' => '4096x2160', + 'videoBitrate' => '8192', + 'samplerate' => '48000', + 'noUpscaling' => 'true', + 'twopass' => 'true', + 'keyframeInterval' => '128', + 'bufDelay' => '256', + 'videoCodec' => 'vp9', + 'audioCodec' => 'opus', + 'tileColumns' => '4', + 'type' => 'video/webm; codecs="vp9, opus"', + ), + + // Losly defined per PCF guide to mp4 profiles: + // https://develop.participatoryculture.org/index.php/ConversionMatrix + // and apple HLS profile guide: + // https://developer.apple.com/library/ios/#documentation/networkinginternet/conceptual/streamingmediaguide/UsingHTTPLiveStreaming/UsingHTTPLiveStreaming.html#//apple_ref/doc/uid/TP40008332-CH102-DontLinkElementID_24 + + WebVideoTranscode::ENC_H264_320P => + array( + 'maxSize' => '480x320', + 'videoCodec' => 'h264', + 'preset' => 'ipod320', + 'videoBitrate' => '400k', + 'audioCodec' => 'aac', + 'channels' => '2', + 'audioBitrate' => '40k', + 'type' => 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', + ), + + WebVideoTranscode::ENC_H264_480P => + array( + 'maxSize' => '640x480', + 'videoCodec' => 'h264', + 'preset' => 'ipod640', + 'videoBitrate' => '1200k', + 'audioCodec' => 'aac', + 'channels' => '2', + 'audioBitrate' => '64k', + 'type' => 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', + ), + + WebVideoTranscode::ENC_H264_720P => + array( + 'maxSize' => '1280x720', + 'videoCodec' => 'h264', + 'preset' => '720p', + 'videoBitrate' => '2500k', + 'audioCodec' => 'aac', + 'channels' => '2', + 'audioBitrate' => '128k', + 'type' => 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', + ), + + WebVideoTranscode::ENC_H264_1080P => + array( + 'maxSize' => '1920x1080', + 'videoCodec' => 'h264', + 'videoBitrate' => '5000k', + 'audioCodec' => 'aac', + 'channels' => '2', + 'audioBitrate' => '128k', + 'type' => 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', + ), + WebVideoTranscode::ENC_H264_2160P => + array( + 'maxSize' => '4096x2160', + 'videoCodec' => 'h264', + 'videoBitrate' => '16384k', + 'audioCodec' => 'aac', + 'channels' => '2', + 'audioBitrate' => '128k', + 'type' => 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"', + ), + + //Audio profiles + WebVideoTranscode::ENC_OGG_VORBIS => + array( + 'audioCodec' => 'vorbis', + 'audioQuality' => '1', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + 'novideo' => 'true', + 'type' => 'audio/ogg; codecs="vorbis"', + ), + WebVideoTranscode::ENC_OGG_OPUS => + array( + 'audioCodec' => 'opus', + 'audioQuality' => '1', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + 'novideo' => 'true', + 'type' => 'audio/ogg; codecs="opus"', + ), + WebVideoTranscode::ENC_MP3 => + array( + 'audioCodec' => 'mp3', + 'audioQuality' => '1', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + 'novideo' => 'true', + 'type' => 'audio/mpeg', + ), + WebVideoTranscode::ENC_AAC => + array( + 'audioCodec' => 'aac', + 'audioQuality' => '1', + 'samplerate' => '44100', + 'channels' => '2', + 'noUpscaling' => 'true', + 'novideo' => 'true', + 'type' => 'audio/mp4; codecs="mp4a.40.5"', + ), + ); + + /** + * @param $file File + * @param $transcodeKey string + * @return string + */ + static public function getDerivativeFilePath( $file, $transcodeKey ) { + return $file->getTranscodedPath( self::getTranscodeFileBaseName( $file, $transcodeKey ) ); + } + + /** + * Get the name to use as the base name for the transcode. + * + * Swift has problems where the url-encoded version of + * the path (ie 'filename.ogv/filename.ogv.720p.webm' ) + * is greater that > 1024 bytes, so shorten in that case. + * + * Future versions might respect FileRepo::$abbrvThreshold. + * + * @param File $file + * @param String $suffix Optional suffix (e.g. transcode key). + * @return String File name, or the string transcode. + */ + static public function getTranscodeFileBaseName( $file, $suffix = '' ) { + $name = $file->getName(); + if ( strlen( urlencode( $name ) ) * 2 + 12 > 1024 ) { + return 'transcode' . '.' . $suffix; + } else { + return $name . '.' . $suffix; + } + } + + /** + * Get url for a transcode. + * + * @param $file File + * @param $suffix string Transcode key + * @return string + */ + static public function getTranscodedUrlForFile( $file, $suffix = '' ) { + return $file->getTranscodedUrl( self::getTranscodeFileBaseName( $file, $suffix ) ); + } + + /** + * Get temp file at target path for video encode + * + * @param $file File + * @param $transcodeKey String + * + * @return TempFSFile at target encode path + */ + static public function getTargetEncodeFile( &$file, $transcodeKey ){ + $filePath = self::getDerivativeFilePath( $file, $transcodeKey ); + $ext = strtolower( pathinfo( "$filePath", PATHINFO_EXTENSION ) ); + + // Create a temp FS file with the same extension + $tmpFile = TempFSFile::factory( 'transcode_' . $transcodeKey, $ext); + if ( !$tmpFile ) { + return False; + } + return $tmpFile; + } + + /** + * Get the max size of the web stream ( constant bitrate ) + * @return int + */ + static public function getMaxSizeWebStream(){ + global $wgEnabledTranscodeSet; + $maxSize = 0; + foreach( $wgEnabledTranscodeSet as $transcodeKey ){ + if( isset( self::$derivativeSettings[$transcodeKey]['videoBitrate'] ) ){ + $currentSize = self::$derivativeSettings[$transcodeKey]['maxSize']; + if( $currentSize > $maxSize ){ + $maxSize = $currentSize; + } + } + } + return $maxSize; + } + + /** + * Give a rough estimate on file size + * Note this is not always accurate.. especially with variable bitrate codecs ;) + * @param $file File + * @param $transcodeKey string + * @return number + */ + static public function getProjectedFileSize( $file, $transcodeKey ){ + $settings = self::$derivativeSettings[$transcodeKey]; + if( $settings[ 'videoBitrate' ] && $settings['audioBitrate'] ){ + return $file->getLength() * 8 * ( + self::$derivativeSettings[$transcodeKey]['videoBitrate'] + + + self::$derivativeSettings[$transcodeKey]['audioBitrate'] + ); + } + // Else just return the size of the source video ( we have no idea how large the actual derivative size will be ) + return $file->getLength() * $file->getHandler()->getBitrate( $file ) * 8; + } + + /** + * Static function to get the set of video assets + * Checks if the file is local or remote and grabs respective sources + * @param $file File + * @param $options array + * @return array|mixed + */ + static public function getSources( &$file , $options = array() ){ + if( $file->isLocal() || $file->repo instanceof ForeignDBViaLBRepo ){ + return self::getLocalSources( $file , $options ); + } else { + return self::getRemoteSources( $file , $options ); + } + } + + /** + * Grabs sources from the remote repo via ApiQueryVideoInfo.php entry point. + * + * TODO: This method could use some rethinking. See comments on PS1 of + * <https://gerrit.wikimedia.org/r/#/c/117916/> + * + * Because this works with commons regardless of whether TimedMediaHandler is installed or not + * @param $file File + * @param $options array + * @return array|mixed + */ + static public function getRemoteSources(&$file , $options = array() ){ + global $wgMemc; + // Setup source attribute options + $dataPrefix = in_array( 'nodata', $options )? '': 'data-'; + + // Use descriptionCacheExpiry as our expire for timed text tracks info + if ( $file->repo->descriptionCacheExpiry > 0 ) { + wfDebug("Attempting to get sources from cache..."); + $key = $file->repo->getLocalCacheKey( 'WebVideoSources', 'url', $file->getName() ); + $sources = $wgMemc->get($key); + if ( $sources ) { + wfDebug("Success found sources in local cache\n"); + return $sources; + } + wfDebug("source cache miss\n"); + } + + wfDebug("Get Video sources from remote api for " . $file->getName() . "\n"); + $query = array( + 'action' => 'query', + 'prop' => 'videoinfo', + 'viprop' => 'derivatives', + 'titles' => MWNamespace::getCanonicalName( NS_FILE ) .':'. $file->getTitle()->mTextform + ); + + $data = $file->repo->fetchImageQuery( $query ); + + if( isset( $data['warnings'] ) && isset( $data['warnings']['query'] ) + && $data['warnings']['query']['*'] == "Unrecognized value for parameter 'prop': videoinfo" ) + { + // Commons does not yet have TimedMediaHandler. + // Use the normal file repo system single source: + return array( self::getPrimarySourceAttributes( $file, array( $dataPrefix ) ) ); + } + $sources = array(); + // Generate the source list from the data response: + if( isset( $data['query'] ) && $data['query']['pages'] ){ + $vidResult = array_shift( $data['query']['pages'] ); + if( isset( $vidResult['videoinfo'] ) ) { + $derResult = array_shift( $vidResult['videoinfo'] ); + $derivatives = $derResult['derivatives']; + foreach( $derivatives as $derivativeSource ){ + $sources[] = $derivativeSource; + } + } + } + + // Update the cache: + if ( $sources && $file->repo->descriptionCacheExpiry > 0 ) { + $wgMemc->set( $key, $sources, $file->repo->descriptionCacheExpiry ); + } + + return $sources; + + } + + /** + * Based on the $wgEnabledTranscodeSet set of enabled derivatives we + * return sources that are ready. + * + * This will not automatically update or queue anything! + * + * @param $file File object + * @param $options array Options, a set of options: + * 'nodata' Strips the data- attribute, useful when your output is not html + * @return array an associative array of sources suitable for <source> tag output + */ + static public function getLocalSources( &$file , $options=array() ){ + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet, $wgEnableTranscode; + $sources = array(); + + // Add the original file: + $sources[] = self::getPrimarySourceAttributes( $file, $options ); + + // If $wgEnableTranscode is false don't look for or add other local sources: + if( $wgEnableTranscode === false && + !($file->repo instanceof ForeignDBViaLBRepo) ){ + return $sources; + } + + // If an "oldFile" don't look for other sources: + if( $file->isOld() ){ + return $sources; + } + + // Now Check for derivatives + if( $file->getHandler()->isAudio( $file ) ){ + $transcodeSet = $wgEnabledAudioTranscodeSet; + } else { + $transcodeSet = $wgEnabledTranscodeSet; + } + foreach( $transcodeSet as $transcodeKey ){ + if ( self::isTranscodeEnabled( $file, $transcodeKey ) ) { + // Try and add the source + self::addSourceIfReady( $file, $sources, $transcodeKey, $options ); + } + } + + return $sources; + } + + /** + * Get the transcode state for a given filename and transcodeKey + * + * @param $fileName string + * @param $transcodeKey string + * @return bool + */ + public static function isTranscodeReady( $file, $transcodeKey ){ + + // Check if we need to populate the transcodeState cache: + $transcodeState = self::getTranscodeState( $file ); + + // If no state is found the cache for this file is false: + if( !isset( $transcodeState[ $transcodeKey ] ) ) { + return false; + } + // Else return boolean ready state ( if not null, then ready ): + return !is_null( $transcodeState[ $transcodeKey ]['time_success'] ); + } + + /** + * Clear the transcode state cache: + * @param String $fileName Optional fileName to clear transcode cache for + */ + public static function clearTranscodeCache( $fileName = null){ + if( $fileName ){ + unset( self::$transcodeState[ $fileName ] ); + } else { + self::$transcodeState = array(); + } + } + + /** + * Populates the transcode table with the current DB state of transcodes + * if transcodes are not found in the database their state is set to "false" + * + * @param {Object} File object + */ + public static function getTranscodeState( $file, $db = false ){ + global $wgTranscodeBackgroundTimeLimit; + $fileName = $file->getName(); + if( ! isset( self::$transcodeState[$fileName] ) ){ + if ( $db === false ) { + $db = $file->repo->getSlaveDB(); + } + // initialize the transcode state array + self::$transcodeState[ $fileName ] = array(); + $res = $db->select( 'transcode', + '*', + array( 'transcode_image_name' => $fileName ), + __METHOD__, + array( 'LIMIT' => 100 ) + ); + $overTimeout = array(); + $over = $db->timestamp(time() - (2 * $wgTranscodeBackgroundTimeLimit)); + // Populate the per transcode state cache + foreach ( $res as $row ) { + // strip the out the "transcode_" from keys + $trascodeState = array(); + foreach( $row as $k => $v ){ + $trascodeState[ str_replace( 'transcode_', '', $k ) ] = $v; + } + self::$transcodeState[ $fileName ][ $row->transcode_key ] = $trascodeState; + if ( $row->transcode_time_startwork != NULL + && $row->transcode_time_startwork < $over + && $row->transcode_time_success == NULL + && $row->transcode_time_error == NULL ) { + $overTimeout[] = $row->transcode_key; + } + } + if ( $overTimeout ) { + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( + 'transcode', + array( + 'transcode_time_error' => $dbw->timestamp(), + 'transcode_error' => 'timeout' + ), + array( + 'transcode_image_name' => $fileName, + 'transcode_key' => $overTimeout + ), + __METHOD__, + array( 'LIMIT' => count( $overTimeout ) ) + ); + } + } + $sorted = self::$transcodeState[ $fileName ]; + uksort( $sorted, 'strnatcmp' ); + return $sorted; + } + + /** + * Remove any transcode files and db states associated with a given $file + * Note that if you want to see them again, you must re-queue them by calling + * startJobQueue() or updateJobQueue(). + * + * also remove the transcode files: + * @param $file File Object + * @param $transcodeKey String Optional transcode key to remove only this key + */ + public static function removeTranscodes( &$file, $transcodeKey = false ){ + + // if transcode key is non-false, non-null: + if( $transcodeKey ){ + // only remove the requested $transcodeKey + $removeKeys = array( $transcodeKey ); + } else { + // Remove any existing files ( regardless of their state ) + $res = $file->repo->getMasterDB()->select( 'transcode', + array( 'transcode_key' ), + array( 'transcode_image_name' => $file->getName() ) + ); + $removeKeys = array(); + foreach( $res as $transcodeRow ){ + $removeKeys[] = $transcodeRow->transcode_key; + } + } + + // Remove files by key: + $urlsToPurge = array(); + foreach ( $removeKeys as $tKey ) { + $urlsToPurge[] = self::getTranscodedUrlForFile( $file, $tKey ); + $filePath = self::getDerivativeFilePath( $file, $tKey ); + if( $file->repo->fileExists( $filePath ) ){ + wfSuppressWarnings(); + $res = $file->repo->quickPurge( $filePath ); + wfRestoreWarnings(); + if( !$res ){ + wfDebug( "Could not delete file $filePath\n" ); + } + } + } + + SquidUpdate::purge( $urlsToPurge ); + + // Build the sql query: + $dbw = wfGetDB( DB_MASTER ); + $deleteWhere = array( 'transcode_image_name' => $file->getName() ); + // Check if we are removing a specific transcode key + if( $transcodeKey !== false ){ + $deleteWhere['transcode_key'] = $transcodeKey; + } + // Remove the db entries + $dbw->delete( 'transcode', $deleteWhere, __METHOD__ ); + + // Purge the cache for pages that include this video: + $titleObj = $file->getTitle(); + self::invalidatePagesWithFile( $titleObj ); + + // Remove from local WebVideoTranscode cache: + self::clearTranscodeCache( $titleObj->getDBkey() ); + } + + /** + * @param $titleObj Title + */ + public static function invalidatePagesWithFile( &$titleObj ){ + wfDebug("WebVideoTranscode:: Invalidate pages that include: " . $titleObj->getDBkey() . "\n" ); + // Purge the main image page: + $titleObj->invalidateCache(); + + // TODO if the video is used in over 500 pages add to 'job queue' + // TODO interwiki invalidation ? + $limit = 500; + $dbr = wfGetDB( DB_SLAVE ); + $res = $dbr->select( + array( 'imagelinks', 'page' ), + array( 'page_namespace', 'page_title' ), + array( 'il_to' => $titleObj->getDBkey(), 'il_from = page_id' ), + __METHOD__, + array( 'LIMIT' => $limit + 1 ) + ); + foreach ( $res as $page ) { + $title = Title::makeTitle( $page->page_namespace, $page->page_title ); + $title->invalidateCache(); + } + } + + /** + * Add a source to the sources list if the transcode job is ready + * + * If the source is not found, it will not be used yet... + * Missing transcodes should be added by write tasks, not read tasks! + */ + public static function addSourceIfReady( &$file, &$sources, $transcodeKey, $dataPrefix = '' ){ + // Check if the transcode is ready: + if( self::isTranscodeReady( $file, $transcodeKey ) ){ + $sources[] = self::getDerivativeSourceAttributes( $file, $transcodeKey, $dataPrefix ); + } + } + + /** + * Get the primary "source" asset used for other derivatives + * @param $file File + * @param $options array + * @return array + */ + static public function getPrimarySourceAttributes( $file, $options = array() ){ + global $wgLang; + $src = in_array( 'fullurl', $options)? wfExpandUrl( $file->getUrl() ) : $file->getUrl(); + + $bitrate = $file->getHandler()->getBitrate( $file ); + $metadataType = $file->getHandler()->getMetadataType( $file ); + + // Give grep a chance to find the usages: timedmedia-ogg, timedmedia-webm, + // timedmedia-mp4, timedmedia-flac, timedmedia-wav + if( $file->getHandler()->isAudio( $file ) ){ + $title = wfMessage( 'timedmedia-source-audio-file-desc', + wfMessage( 'timedmedia-' . $metadataType )->text() ) + ->params( $wgLang->formatBitrate( $bitrate ) )->text(); + } else { + $title = wfMessage( 'timedmedia-source-file-desc', + wfMessage( 'timedmedia-' . $metadataType )->text() ) + ->numParams( $file->getWidth(), $file->getHeight() ) + ->params( $wgLang->formatBitrate( $bitrate ) )->text(); + } + + // Give grep a chance to find the usages: timedmedia-ogg, timedmedia-webm, + // timedmedia-mp4, timedmedia-flac, timedmedia-wav + $source = array( + 'src' => $src, + 'type' => $file->getHandler()->getWebType( $file ), + 'title' => $title, + "shorttitle" => wfMessage( + 'timedmedia-source-file', + wfMessage( 'timedmedia-' . $metadataType )->text() + )->text(), + "width" => intval( $file->getWidth() ), + "height" => intval( $file->getHeight() ), + ); + + if( $bitrate ){ + $source["bandwidth"] = round ( $bitrate ); + } + + // For video include framerate: + if( !$file->getHandler()->isAudio( $file ) ){ + $framerate = $file->getHandler()->getFramerate( $file ); + if( $framerate ){ + $source[ "framerate" ] = floatval( $framerate ); + } + } + return $source; + } + + /** + * Get derivative "source" attributes + * @param $file File + * @param $transcodeKey string + * @param $options array + * @return array + */ + static public function getDerivativeSourceAttributes($file, $transcodeKey, $options = array() ){ + $fileName = $file->getTitle()->getDbKey(); + + $src = self::getTranscodedUrlForFile( $file, $transcodeKey ); + + if( $file->getHandler()->isAudio( $file ) ){ + $width = $height = 0; + } else { + list( $width, $height ) = WebVideoTranscode::getMaxSizeTransform( + $file, + self::$derivativeSettings[$transcodeKey]['maxSize'] + ); + } + + $framerate = ( isset( self::$derivativeSettings[$transcodeKey]['framerate'] ) )? + self::$derivativeSettings[$transcodeKey]['framerate'] : + $file->getHandler()->getFramerate( $file ); + // Setup the url src: + $src = in_array( 'fullurl', $options) ? wfExpandUrl( $src ) : $src; + $fields = array( + 'src' => $src, + 'title' => wfMessage( 'timedmedia-derivative-desc-' . $transcodeKey )->text(), + 'type' => self::$derivativeSettings[ $transcodeKey ][ 'type' ], + "shorttitle" => wfMessage( 'timedmedia-derivative-' . $transcodeKey )->text(), + "transcodekey" => $transcodeKey, + + // Add data attributes per emerging DASH / webTV adaptive streaming attributes + // eventually we will define a manifest xml entry point. + "width" => intval( $width ), + "height" => intval( $height ), + ); + + // a "ready" transcode should have a bitrate: + if ( isset( self::$transcodeState[$fileName] ) ) { + $fields["bandwidth"] = intval( + self::$transcodeState[$fileName][ $transcodeKey ]['final_bitrate'] + ); + } + + if ( !$file->getHandler()->isAudio( $file ) ) { + $fields += array( "framerate" => floatval( $framerate ) ); + } + return $fields; + } + + /** + * Queue up all enabled transcodes if missing. + * @param $file File object + */ + public static function startJobQueue( File $file ) { + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet; + $keys = array_merge( $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet ); + + // 'Natural sort' puts the transcodes in ascending order by resolution, + // which roughly gives us fastest-to-slowest order. + natsort($keys); + + foreach ( $keys as $tKey ) { + // Note the job queue will de-duplicate and handle various errors, so we + // can just blast out the full list here. + self::updateJobQueue( $file, $tKey ); + } + } + + /** + * Make sure all relevant transcodes for the given file are tracked in the + * transcodes table; add entries for any missing ones. + * + * @param $file File object + */ + public static function cleanupTranscodes( File $file ) { + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet; + + $fileName = $file->getTitle()->getDbKey(); + $db = $file->repo->getMasterDB(); + + $transcodeState = self::getTranscodeState( $file, $db ); + + $keys = array_merge( $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet ); + foreach ( $keys as $transcodeKey ) { + if ( !self::isTranscodeEnabled( $file, $transcodeKey ) ) { + // This transcode is no longer enabled or erroneously included... + // Leave it in place, allowing it to be removed manually; + // it won't be used in playback and should be doing no harm. + continue; + } + if ( !isset( $transcodeState[ $transcodeKey ] ) ) { + $db->insert( + 'transcode', + array( + 'transcode_image_name' => $fileName, + 'transcode_key' => $transcodeKey, + 'transcode_time_addjob' => null, + 'transcode_error' => "", + 'transcode_final_bitrate' => 0 + ), + __METHOD__, + array( 'IGNORE' ) + ); + } + } + } + + /** + * Check if the given transcode key is appropriate for the file. + * + * @param $file File object + * @param $transcodeKey String transcode key + * @return boolean + */ + public static function isTranscodeEnabled( File $file, $transcodeKey ) { + global $wgEnabledTranscodeSet, $wgEnabledAudioTranscodeSet; + + $audio = $file->getHandler()->isAudio( $file ); + if ( $audio ) { + $keys = $wgEnabledAudioTranscodeSet; + } else { + $keys = $wgEnabledTranscodeSet; + } + + if ( in_array( $transcodeKey, $keys ) ) { + $settings = self::$derivativeSettings[$transcodeKey]; + if ( $audio ) { + $sourceCodecs = $file->getHandler()->getStreamTypes( $file ); + $sourceCodec = $sourceCodecs ? strtolower( $sourceCodecs[0] ) : ''; + return ( $sourceCodec !== $settings['audioCodec'] ); + } else if ( self::isTargetLargerThanFile( $file, $settings['maxSize'] ) ) { + // Are we the smallest enabled transcode for this type? + // Then go ahead and make a wee little transcode for compat. + return self::isSmallestTranscodeForCodec( $transcodeKey ); + } else { + return true; + } + } else { + // Transcode key is invalid or has been disabled. + return false; + } + } + + /** + * Update the job queue if the file is not already in the job queue: + * @param $file File object + * @param $transcodeKey String transcode key + */ + public static function updateJobQueue( &$file, $transcodeKey ){ + $fileName = $file->getTitle()->getDbKey(); + $db = $file->repo->getMasterDB(); + + $transcodeState = self::getTranscodeState( $file, $db ); + + if ( !self::isTranscodeEnabled( $file, $transcodeKey ) ) { + return; + } + + // If the job hasn't been added yet, attempt to do so + if ( !isset( $transcodeState[ $transcodeKey ] ) ) { + $db->insert( + 'transcode', + array( + 'transcode_image_name' => $fileName, + 'transcode_key' => $transcodeKey, + 'transcode_time_addjob' => $db->timestamp(), + 'transcode_error' => "", + 'transcode_final_bitrate' => 0 + ), + __METHOD__, + array( 'IGNORE' ) + ); + + if ( !$db->affectedRows() ) { + // There is already a row for that job added by another request, no need to continue + return; + } + + $job = new WebVideoTranscodeJob( $file->getTitle(), array( + 'transcodeMode' => 'derivative', + 'transcodeKey' => $transcodeKey, + ) ); + + if ( $job->insert() ) { + // Clear the state cache ( now that we have updated the page ) + self::clearTranscodeCache( $fileName ); + } else { + // Adding job failed, update transcode row + $db->update( + 'transcode', + array( + 'transcode_time_error' => $db->timestamp(), + 'transcode_error' => "Failed to insert Job." + ), + array( + 'transcode_image_name' => $fileName, + 'transcode_key' => $transcodeKey, + ), + __METHOD__, + array( 'LIMIT' => 1 ) + ); + } + } + } + + /** + * Transforms the size per a given "maxSize" + * if maxSize is > file, file size is used + * @param $file File + * @param $targetMaxSize int + * @return array + */ + public static function getMaxSizeTransform( &$file, $targetMaxSize ){ + $maxSize = self::getMaxSize( $targetMaxSize ); + $sourceWidth = intval( $file->getWidth() ); + $sourceHeight = intval( $file->getHeight() ); + if ( $sourceHeight === 0 ) { + // Audio file + return array( 0, 0 ); + } + $sourceAspect = $sourceWidth / $sourceHeight; + $targetWidth = $sourceWidth; + $targetHeight = $sourceHeight; + if ( $sourceAspect <= $maxSize['aspect'] ) { + if ( $sourceHeight > $maxSize['height'] ) { + $targetHeight = $maxSize['height']; + $targetWidth = intval( $targetHeight * $sourceAspect ); + } + } else { + if ( $sourceWidth > $maxSize['width'] ) { + $targetWidth = $maxSize['width']; + $targetHeight = intval( $targetWidth / $sourceAspect ); + //some players do not like uneven frame sizes + } + } + //some players do not like uneven frame sizes + $targetWidth += $targetWidth%2; + $targetHeight += $targetHeight%2; + return array( $targetWidth, $targetHeight ); + } + + /** + * Test if a given transcode target is larger than the source file + * + * @param $file File object + * @param $targetMaxSize string + * @return bool + */ + public static function isTargetLargerThanFile( &$file, $targetMaxSize ){ + $maxSize = self::getMaxSize( $targetMaxSize ); + $sourceWidth = $file->getWidth(); + $sourceHeight = $file->getHeight(); + $sourceAspect = intval( $sourceWidth ) / intval( $sourceHeight ); + if ( $sourceAspect <= $maxSize['aspect'] ) { + return ( $maxSize['height'] > $sourceHeight ); + } else { + return ( $maxSize['width'] > $sourceWidth ); + } + } + + /** + * Is the given transcode key the smallest configured transcode for + * its video codec? + */ + public static function isSmallestTranscodeForCodec( $transcodeKey ) { + global $wgEnabledTranscodeSet; + + $settings = self::$derivativeSettings[$transcodeKey]; + $vcodec = $settings['videoCodec']; + $maxSize = self::getMaxSize( $settings['maxSize'] ); + + foreach ( $wgEnabledTranscodeSet as $tKey ) { + $tsettings = self::$derivativeSettings[$tKey]; + if ( $tsettings['videoCodec'] === $vcodec ) { + $tmaxSize = self::getMaxSize( $tsettings['maxSize'] ); + if ( $tmaxSize['width'] < $maxSize['width'] ) { + return false; + } + if ( $tmaxSize['height'] < $maxSize['height'] ) { + return false; + } + } + } + + return true; + } + + /** + * Return maxSize array for given maxSize setting + * + * @param $targetMaxSize string + * @return array + */ + public static function getMaxSize( $targetMaxSize ){ + $maxSize = array(); + $targetMaxSize = explode( 'x', $targetMaxSize ); + $maxSize['width'] = intval( $targetMaxSize[0] ); + if ( count( $targetMaxSize ) == 1 ) { + $maxSize['height'] = intval( $targetMaxSize[0] ); + } else { + $maxSize['height'] = intval( $targetMaxSize[1] ); + } + // check for zero size ( audio ) + if( $maxSize['width'] === 0 || $maxSize['height'] == 0 ){ + return 0; + } + $maxSize['aspect'] = $maxSize['width'] / $maxSize['height']; + return $maxSize; + } +} diff --git a/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php b/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php new file mode 100644 index 00000000..d437d9c7 --- /dev/null +++ b/extensions/TimedMediaHandler/WebVideoTranscode/WebVideoTranscodeJob.php @@ -0,0 +1,965 @@ +<?php +/** + * Job for transcode jobs + * + * @file + * @ingroup JobQueue + */ + +/** + * Job for web video transcode + * + * Support two modes + * 1) non-free media transcode ( delays the media file being inserted, adds note to talk page once ready) + * 2) derivatives for video ( makes new sources for the asset ) + * + * @ingroup JobQueue + */ + +class WebVideoTranscodeJob extends Job { + var $targetEncodeFile = null; + var $sourceFilePath = null; + + /** + * @var File + */ + var $file; + + public function __construct( $title, $params, $id = 0 ) { + parent::__construct( 'webVideoTranscode', $title, $params, $id ); + $this->removeDuplicates = true; + } + + /** + * Local function to debug output ( jobs don't have access to the maintenance output class ) + * @param $msg string + */ + private function output( $msg ){ + print $msg . "\n"; + } + + /** + * @return File + */ + private function getFile() { + if( !$this->file ){ + $this->file = wfLocalFile( $this->title ); + } + return $this->file; + } + + /** + * @return string + */ + private function getTargetEncodePath(){ + if( !$this->targetEncodeFile ){ + $file = $this->getFile(); + $transcodeKey = $this->params[ 'transcodeKey' ]; + $this->targetEncodeFile = WebVideoTranscode::getTargetEncodeFile( $file, $transcodeKey ); + $this->targetEncodeFile->bind( $this ); + } + return $this->targetEncodeFile->getPath(); + } + /** + * purge temporary encode target + */ + private function purgeTargetEncodeFile () { + if ( $this->targetEncodeFile ) { + $this->targetEncodeFile->purge(); + $this->targetEncodeFile = null; + } + } + + /** + * @return string|bool + */ + private function getSourceFilePath(){ + if( !$this->sourceFilePath ){ + $file = $this->getFile(); + $this->source = $file->repo->getLocalReference( $file->getPath() ); + if ( !$this->source ) { + $this->sourceFilePath = false; + } else { + $this->sourceFilePath = $this->source->getPath(); + } + } + return $this->sourceFilePath; + } + + /** + * Update the transcode table with failure time and error + * @param $transcodeKey string + * @param $error string + * + */ + private function setTranscodeError( $transcodeKey, $error ){ + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( + 'transcode', + array( + 'transcode_time_error' => $dbw->timestamp(), + 'transcode_error' => $error + ), + array( + 'transcode_image_name' => $this->getFile()->getName(), + 'transcode_key' => $transcodeKey + ), + __METHOD__ + ); + $this->setLastError( $error ); + } + + /** + * Run the transcode request + * @return boolean success + */ + public function run() { + global $wgVersion, $wgFFmpeg2theoraLocation; + // get a local pointer to the file + $file = $this->getFile(); + + // Validate the file exists: + if( !$file ){ + $this->output( $this->title . ': File not found ' ); + return false; + } + + // Validate the transcode key param: + $transcodeKey = $this->params['transcodeKey']; + // Build the destination target + if( ! isset( WebVideoTranscode::$derivativeSettings[ $transcodeKey ] )){ + $error = "Transcode key $transcodeKey not found, skipping"; + $this->output( $error ); + $this->setLastError( $error ); + return false; + } + + // Validate the source exists: + if( !$this->getSourceFilePath() || !is_file( $this->getSourceFilePath() ) ){ + $status = $this->title . ': Source not found ' . $this->getSourceFilePath(); + $this->output( $status ); + $this->setTranscodeError( $transcodeKey, $status ); + return false; + } + + $options = WebVideoTranscode::$derivativeSettings[ $transcodeKey ]; + + if ( isset( $options[ 'novideo' ] ) ) { + $this->output( "Encoding to audio codec: " . $options['audioCodec'] ); + } else { + $this->output( "Encoding to codec: " . $options['videoCodec'] ); + } + + $dbw = wfGetDB( DB_MASTER ); + + // Check if we have "already started" the transcode ( possible error ) + $dbStartTime = $dbw->selectField( 'transcode', 'transcode_time_startwork', + array( + 'transcode_image_name' => $this->getFile()->getName(), + 'transcode_key' => $transcodeKey + ), + __METHOD__ + ); + if( ! is_null( $dbStartTime ) ){ + $error = 'Error, running transcode job, for job that has already started'; + $this->output( $error ); + return true; + } + + // Update the transcode table letting it know we have "started work": + $jobStartTimeCache = $dbw->timestamp(); + $dbw->update( + 'transcode', + array( 'transcode_time_startwork' => $jobStartTimeCache ), + array( + 'transcode_image_name' => $this->getFile()->getName(), + 'transcode_key' => $transcodeKey + ), + __METHOD__ + ); + // Avoid contention and "server has gone away" errors as + // the transcode will take a very long time in some cases + $dbw->commit( __METHOD__, 'flush' ); + + // Check the codec see which encode method to call; + if ( isset( $options[ 'novideo' ] ) ) { + $status = $this->ffmpegEncode( $options ); + } elseif( $options['videoCodec'] == 'theora' && $wgFFmpeg2theoraLocation !== false ){ + $status = $this->ffmpeg2TheoraEncode( $options ); + } elseif( $options['videoCodec'] == 'vp8' || $options['videoCodec'] == 'vp9' || $options['videoCodec'] == 'h264' || ( $options['videoCodec'] == 'theora' && $wgFFmpeg2theoraLocation === false ) ){ + // Check for twopass: + if( isset( $options['twopass'] ) ){ + // ffmpeg requires manual two pass + $status = $this->ffmpegEncode( $options, 1 ); + if( $status && !is_string($status) ){ + $status = $this->ffmpegEncode( $options, 2 ); + } + } else { + $status = $this->ffmpegEncode( $options ); + } + } else { + wfDebug( 'Error unknown codec:' . $options['videoCodec'] ); + $status = 'Error unknown target encode codec:' . $options['videoCodec']; + } + + // Remove any log files all useful info should be in status and or we are done with 2 passs encoding + $this->removeFffmpgeLogFiles(); + + // Do a quick check to confirm the job was not restarted or removed while we were transcoding + // Confirm the in memory $jobStartTimeCache matches db start time + $dbStartTime = $dbw->selectField( 'transcode', 'transcode_time_startwork', + array( + 'transcode_image_name' => $this->getFile()->getName(), + 'transcode_key' => $transcodeKey + ) + ); + + // Check for ( hopefully rare ) issue of or job restarted while transcode in progress + if( $dbw->timestamp( $jobStartTimeCache ) != $dbw->timestamp( $dbStartTime ) ){ + $this->output('Possible Error, transcode task restarted, removed, or completed while transcode was in progress'); + // if an error; just error out, we can't remove temp files or update states, because the new job may be doing stuff. + if( $status !== true ){ + $this->setTranscodeError( $transcodeKey, $status ); + return false; + } + // else just continue with db updates, and when the new job comes around it won't start because it will see + // that the job has already been started. + } + + // If status is oky and target does not exist, reset status + if( $status === true && !is_file( $this->getTargetEncodePath() ) ) { + $status = 'Target does not exist: ' . $this->getTargetEncodePath(); + } + // If status is ok and target is larger than 0 bytes + if( $status === true && filesize( $this->getTargetEncodePath() ) > 0 ){ + $file = $this->getFile(); + $storeOptions = null; + if ( version_compare( $wgVersion, '1.23c', '>' ) && + strpos( $options['type'], '/ogg' ) !== false && + $file->getLength() + ) { + // Ogg files need a duration header for firefox + $storeOptions['headers']['X-Content-Duration'] = floatval( $file->getLength() ); + } + + // Copy derivative from the FS into storage at $finalDerivativeFilePath + $result = $file->getRepo()->quickImport( + $this->getTargetEncodePath(), // temp file + WebVideoTranscode::getDerivativeFilePath( $file, $transcodeKey ), // storage + $storeOptions + ); + if ( !$result->isOK() ) { + // no need to invalidate all pages with video. Because all pages remain valid ( no $transcodeKey derivative ) + // just clear the file page ( so that the transcode table shows the error ) + $this->title->invalidateCache(); + $this->setTranscodeError( $transcodeKey, $result->getWikiText() ); + $status = false; + } else { + $bitrate = round( intval( filesize( $this->getTargetEncodePath() ) / $file->getLength() ) * 8 ); + //wfRestoreWarnings(); + // Update the transcode table with success time: + $dbw->update( + 'transcode', + array( + 'transcode_error' => '', + 'transcode_time_success' => $dbw->timestamp(), + 'transcode_final_bitrate' => $bitrate + ), + array( + 'transcode_image_name' => $this->getFile()->getName(), + 'transcode_key' => $transcodeKey, + ), + __METHOD__ + ); + $dbw->commit( __METHOD__, 'flush' ); + WebVideoTranscode::invalidatePagesWithFile( $this->title ); + } + } else { + // Update the transcode table with failure time and error + $this->setTranscodeError( $transcodeKey, $status ); + // no need to invalidate all pages with video. Because all pages remain valid ( no $transcodeKey derivative ) + // just clear the file page ( so that the transcode table shows the error ) + $this->title->invalidateCache(); + } + //done with encoding target, clean up + $this->purgeTargetEncodeFile(); + + // Clear the webVideoTranscode cache ( so we don't keep out dated table cache around ) + WebVideoTranscode::clearTranscodeCache( $this->title->getDBkey() ); + + $url = WebVideoTranscode::getTranscodedUrlForFile( $file, $transcodeKey ); + SquidUpdate::purge( array( $url ) ); + + if ($status !== true) { + $this->setLastError( $status ); + } + return $status === true; + } + + function removeFffmpgeLogFiles(){ + $path = $this->getTargetEncodePath(); + $dir = dirname( $path ); + if ( is_dir( $dir ) ) { + $dh = opendir( $dir ); + if ( $dh ) { + while ( ($file = readdir($dh)) !== false ) { + $log_path = "$dir/$file"; + $ext = strtolower( pathinfo( $log_path, PATHINFO_EXTENSION ) ); + if( $ext == 'log' && substr( $log_path, 0 , strlen($path) ) == $path ){ + wfSuppressWarnings(); + unlink( $log_path ); + wfRestoreWarnings(); + } + } + closedir( $dh ); + } + } + } + + /** + * Utility helper for ffmpeg and ffmpeg2theora mapping + * @param $options array + * @param $pass int + * @return bool|string + */ + function ffmpegEncode( $options, $pass=0 ){ + global $wgFFmpegLocation, $wgTranscodeBackgroundMemoryLimit; + + if( !is_file( $this->getSourceFilePath() ) ) { + return "source file is missing, " . $this->getSourceFilePath() . ". Encoding failed."; + } + + // Set up the base command + $cmd = wfEscapeShellArg( $wgFFmpegLocation ) . ' -y -i ' . wfEscapeShellArg( $this->getSourceFilePath() ); + + + if( isset( $options['vpre'] ) ){ + $cmd.= ' -vpre ' . wfEscapeShellArg( $options['vpre'] ); + } + + if ( isset( $options['novideo'] ) ) { + $cmd.= " -vn "; + } elseif( $options['videoCodec'] == 'vp8' || $options['videoCodec'] == 'vp9' ){ + $cmd.= $this->ffmpegAddWebmVideoOptions( $options, $pass ); + } elseif( $options['videoCodec'] == 'h264'){ + $cmd.= $this->ffmpegAddH264VideoOptions( $options, $pass ); + } elseif( $options['videoCodec'] == 'theora'){ + $cmd.= $this->ffmpegAddTheoraVideoOptions( $options, $pass ); + } + // Add size options: + $cmd .= $this->ffmpegAddVideoSizeOptions( $options ) ; + + // Check for start time + if( isset( $options['starttime'] ) ){ + $cmd.= ' -ss ' . wfEscapeShellArg( $options['starttime'] ); + } else { + $options['starttime'] = 0; + } + // Check for end time: + if( isset( $options['endtime'] ) ){ + $cmd.= ' -t ' . intval( $options['endtime'] ) - intval($options['starttime'] ) ; + } + + if ( $pass == 1 || isset( $options['noaudio'] ) ) { + $cmd.= ' -an'; + } else { + $cmd.= $this->ffmpegAddAudioOptions( $options, $pass ); + } + + if ( $pass != 0 ) { + $cmd.=" -pass " .wfEscapeShellArg( $pass ) ; + $cmd.=" -passlogfile " . wfEscapeShellArg( $this->getTargetEncodePath() .'.log' ); + } + // And the output target: + if ($pass == 1) { + $cmd.= ' /dev/null'; + } else{ + $cmd.= " " . $this->getTargetEncodePath(); + } + + $this->output( "Running cmd: \n\n" .$cmd . "\n" ); + + // Right before we output remove the old file + $retval = 0; + $shellOutput = $this->runShellExec( $cmd, $retval ); + + if( $retval != 0 ){ + return $cmd . + "\n\nExitcode: $retval\nMemory: $wgTranscodeBackgroundMemoryLimit\n\n" . + $shellOutput; + } + return true; + } + + /** + * Adds ffmpeg shell options for h264 + * + * @param $options + * @param $pass + * @return string + */ + function ffmpegAddH264VideoOptions( $options, $pass ){ + global $wgFFmpegThreads; + // Set the codec: + $cmd= " -threads " . intval( $wgFFmpegThreads ) . " -vcodec libx264"; + // Check for presets: + if( isset( $options['preset'] ) ){ + // Add the two vpre types: + switch( $options['preset'] ){ + case 'ipod320': + $cmd .= " -profile:v baseline -preset slow -coder 0 -bf 0 -weightb 1 -level 13 -maxrate 768k -bufsize 3M"; + break; + case '720p': + case 'ipod640': + $cmd .= " -profile:v baseline -preset slow -coder 0 -bf 0 -refs 1 -weightb 1 -level 31 -maxrate 10M -bufsize 10M"; + break; + default: + // in the default case just pass along the preset to ffmpeg + $cmd.= " -vpre " . wfEscapeShellArg( $options['preset'] ); + break; + } + } + if( isset( $options['videoBitrate'] ) ){ + $cmd.= " -b " . wfEscapeShellArg ( $options['videoBitrate'] ); + } + // Output mp4 + $cmd.=" -f mp4"; + return $cmd; + } + + function ffmpegAddVideoSizeOptions( $options ){ + $cmd = ''; + // Get a local pointer to the file object + $file = $this->getFile(); + + // Check for aspect ratio ( we don't do anything with this right now) + if ( isset( $options['aspect'] ) ) { + $aspectRatio = $options['aspect']; + } else { + $aspectRatio = $file->getWidth() . ':' . $file->getHeight(); + } + if (isset( $options['maxSize'] )) { + // Get size transform ( if maxSize is > file, file size is used: + + list( $width, $height ) = WebVideoTranscode::getMaxSizeTransform( $file, $options['maxSize'] ); + $cmd.= ' -s ' . intval( $width ) . 'x' . intval( $height ); + } elseif ( + (isset( $options['width'] ) && $options['width'] > 0 ) + && + (isset( $options['height'] ) && $options['height'] > 0 ) + ){ + $cmd.= ' -s ' . intval( $options['width'] ) . 'x' . intval( $options['height'] ); + } + + // Handle crop: + $optionMap = array( + 'cropTop' => '-croptop', + 'cropBottom' => '-cropbottom', + 'cropLeft' => '-cropleft', + 'cropRight' => '-cropright' + ); + foreach( $optionMap as $name => $cmdArg ){ + if( isset($options[$name]) ){ + $cmd.= " $cmdArg " . wfEscapeShellArg( $options[$name] ); + } + } + return $cmd; + } + /** + * Adds ffmpeg shell options for webm + * + * @param $options + * @param $pass + * @return string + */ + function ffmpegAddWebmVideoOptions( $options, $pass ){ + global $wgFFmpegThreads; + + // Get a local pointer to the file object + $file = $this->getFile(); + + $cmd =' -threads ' . intval( $wgFFmpegThreads ); + + // check for presets: + if( isset($options['preset']) ){ + if ($options['preset'] == "360p") { + $cmd.= " -vpre libvpx-360p"; + } elseif ( $options['preset'] == "720p" ) { + $cmd.= " -vpre libvpx-720p"; + } elseif ( $options['preset'] == "1080p" ) { + $cmd.= " -vpre libvpx-1080p"; + } + } + + // Add the boiler plate vp8 ffmpeg command: + $cmd.=" -skip_threshold 0 -bufsize 6000k -rc_init_occupancy 4000"; + + // Check for video quality: + if ( isset( $options['videoQuality'] ) && $options['videoQuality'] >= 0 ) { + // Map 0-10 to 63-0, higher values worse quality + $quality = 63 - intval( intval( $options['videoQuality'] )/10 * 63 ); + $cmd .= " -qmin " . wfEscapeShellArg( $quality ); + $cmd .= " -qmax " . wfEscapeShellArg( $quality ); + } + + // Check for video bitrate: + if ( isset( $options['videoBitrate'] ) ) { + $cmd.= " -qmin 1 -qmax 51"; + $cmd.= " -vb " . wfEscapeShellArg( $options['videoBitrate'] * 1000 ); + } + // Set the codec: + if ( $options['videoCodec'] === 'vp9' ) { + $cmd.= " -vcodec libvpx-vp9"; + if ( isset( $options['tileColumns'] ) ) { + $cmd.= ' -tile-columns ' . wfEscapeShellArg( $options['tileColumns'] ); + } + } else { + $cmd.= " -vcodec libvpx"; + } + + // Check for keyframeInterval + if( isset( $options['keyframeInterval'] ) ){ + $cmd.= ' -g ' . wfEscapeShellArg( $options['keyframeInterval'] ); + $cmd.= ' -keyint_min ' . wfEscapeShellArg( $options['keyframeInterval'] ); + } + if( isset( $options['deinterlace'] ) ){ + $cmd.= ' -deinterlace'; + } + + // Output WebM + $cmd.=" -f webm"; + + return $cmd; + } + + /** + * Adds ffmpeg/avconv shell options for ogg + * + * Used only when $wgFFmpeg2theoraLocation set to false. + * Warning: does not create Ogg skeleton metadata track. + * + * @param $options + * @param $pass + * @return string + */ + function ffmpegAddTheoraVideoOptions( $options, $pass ){ + global $wgFFmpegThreads; + + // Get a local pointer to the file object + $file = $this->getFile(); + + $cmd =' -threads ' . intval( $wgFFmpegThreads ); + + // Check for video quality: + if ( isset( $options['videoQuality'] ) && $options['videoQuality'] >= 0 ) { + // Map 0-10 to 63-0, higher values worse quality + $quality = 63 - intval( intval( $options['videoQuality'] )/10 * 63 ); + $cmd .= " -qmin " . wfEscapeShellArg( $quality ); + $cmd .= " -qmax " . wfEscapeShellArg( $quality ); + } + + // Check for video bitrate: + if ( isset( $options['videoBitrate'] ) ) { + $cmd.= " -qmin 1 -qmax 51"; + $cmd.= " -vb " . wfEscapeShellArg( $options['videoBitrate'] * 1000 ); + } + // Set the codec: + $cmd.= " -vcodec theora"; + + // Check for keyframeInterval + if( isset( $options['keyframeInterval'] ) ){ + $cmd.= ' -g ' . wfEscapeShellArg( $options['keyframeInterval'] ); + $cmd.= ' -keyint_min ' . wfEscapeShellArg( $options['keyframeInterval'] ); + } + if( isset( $options['deinterlace'] ) ){ + $cmd.= ' -deinterlace'; + } + if( isset( $options['framerate'] ) ) { + $cmd.= ' -r ' . wfEscapeShellArg( $options['framerate'] ); + } + + // Output Ogg + $cmd.=" -f ogg"; + + return $cmd; + } + + /** + * @param $options array + * @param $pass + * @return string + */ + function ffmpegAddAudioOptions( $options, $pass ){ + $cmd =''; + if( isset( $options['audioQuality'] ) ){ + $cmd.= " -aq " . wfEscapeShellArg( $options['audioQuality'] ); + } + if( isset( $options['audioBitrate'] )){ + $cmd.= ' -ab ' . intval( $options['audioBitrate'] ) * 1000; + } + if( isset( $options['samplerate'] ) ){ + $cmd.= " -ar " . wfEscapeShellArg( $options['samplerate'] ); + } + if( isset( $options['channels'] ) ){ + $cmd.= " -ac " . wfEscapeShellArg( $options['channels'] ); + } + + if( isset( $options['audioCodec'] ) ){ + $encoders = array( + 'vorbis' => 'libvorbis', + 'opus' => 'libopus', + 'mp3' => 'libmp3lame', + ); + if ( isset( $encoders[ $options['audioCodec'] ] ) ) { + $codec = $encoders[ $options['audioCodec'] ]; + } else { + $codec = $options['audioCodec']; + } + $cmd.= " -acodec " . wfEscapeShellArg( $codec ); + if ( $codec === 'aac' ) { + // the aac encoder is currently "experimental" in libav 9? :P + $cmd .= ' -strict experimental'; + } + } else { + // if no audio codec set use vorbis : + $cmd.= " -acodec libvorbis "; + } + return $cmd; + } + + /** + * ffmpeg2Theora mapping is much simpler since it is the basis of the the firefogg API + * @param $options array + * @return bool|string + */ + function ffmpeg2TheoraEncode( $options ){ + global $wgFFmpeg2theoraLocation, $wgTranscodeBackgroundMemoryLimit; + + if( !is_file( $this->getSourceFilePath() ) ) { + return "source file is missing, " . $this->getSourceFilePath() . ". Encoding failed."; + } + + // Set up the base command + $cmd = wfEscapeShellArg( $wgFFmpeg2theoraLocation ) . ' ' . wfEscapeShellArg( $this->getSourceFilePath() ); + + $file = $this->getFile(); + + if( isset( $options['maxSize'] ) ){ + list( $width, $height ) = WebVideoTranscode::getMaxSizeTransform( $file, $options['maxSize'] ); + $options['width'] = $width; + $options['height'] = $height; + $options['aspect'] = $width . ':' . $height; + unset( $options['maxSize'] ); + } + + // Add in the encode settings + foreach( $options as $key => $val ){ + if( isset( self::$foggMap[$key] ) ){ + if( is_array( self::$foggMap[$key] ) ){ + $cmd.= ' '. implode(' ', self::$foggMap[$key] ); + } elseif ($val == 'true' || $val === true){ + $cmd.= ' '. self::$foggMap[$key]; + } elseif ($val == 'false' || $val === false){ + //ignore "false" flags + } else { + //normal get/set value + $cmd.= ' '. self::$foggMap[$key] . ' ' . wfEscapeShellArg( $val ); + } + } + } + + // Add the output target: + $outputFile = $this->getTargetEncodePath(); + $cmd.= ' -o ' . wfEscapeShellArg ( $outputFile ); + + $this->output( "Running cmd: \n\n" .$cmd . "\n" ); + + $retval = 0; + $shellOutput = $this->runShellExec( $cmd, $retval ); + + // ffmpeg2theora returns 0 status on some errors, so also check for file + if( $retval != 0 || !is_file( $outputFile ) || filesize( $outputFile ) === 0 ){ + return $cmd . + "\n\nExitcode: $retval\nMemory: $wgTranscodeBackgroundMemoryLimit\n\n" . + $shellOutput; + } + return true; + } + + /** + * Runs the shell exec command. + * if $wgEnableBackgroundTranscodeJobs is enabled will mannage a background transcode task + * else it just directly passes off to wfShellExec + * + * @param $cmd String Command to be run + * @param $retval String, refrence variable to return the exit code + * @return string + */ + public function runShellExec( $cmd, &$retval ){ + global $wgTranscodeBackgroundTimeLimit, + $wgTranscodeBackgroundMemoryLimit, + $wgTranscodeBackgroundSizeLimit, + $wgEnableNiceBackgroundTranscodeJobs; + + // For profiling + $caller = wfGetCaller(); + + // Check if background tasks are enabled + if( $wgEnableNiceBackgroundTranscodeJobs === false ){ + // Directly execute the shell command: + $limits = array( + "filesize" => $wgTranscodeBackgroundSizeLimit, + "memory" => $wgTranscodeBackgroundMemoryLimit, + "time" => $wgTranscodeBackgroundTimeLimit + ); + return wfShellExec( $cmd . ' 2>&1', $retval , array(), $limits, + array( 'profileMethod' => $caller ) ); + } + + $encodingLog = $this->getTargetEncodePath() . '.stdout.log'; + $retvalLog = $this->getTargetEncodePath() . '.retval.log'; + // Check that we can actually write to these files + //( no point in running the encode if we can't write ) + wfSuppressWarnings(); + if( ! touch( $encodingLog) || ! touch( $retvalLog ) ){ + wfRestoreWarnings(); + $retval = 1; + return "Error could not write to target location"; + } + wfRestoreWarnings(); + + // Fork out a process for running the transcode + $pid = pcntl_fork(); + if ($pid == -1) { + $errorMsg = '$wgEnableNiceBackgroundTranscodeJobs enabled but failed pcntl_fork'; + $retval = 1; + $this->output( $errorMsg); + return $errorMsg; + } elseif ( $pid == 0) { + // we are the child + $this->runChildCmd( $cmd, $retval, $encodingLog, $retvalLog, $caller ); + // dont remove any temp files in the child process, this is done + // once the parent is finished + $this->targetEncodeFile->preserve(); + if ( $this->source instanceof TempFSFile ) { + $this->source->preserve(); + } + // exit with the same code as the transcode: + exit( $retval ); + } else { + // we are the parent monitor and return status + return $this->monitorTranscode($pid, $retval, $encodingLog, $retvalLog); + } + } + + /** + * @param $cmd + * @param $retval + * @param $encodingLog + * @param $retvalLog + * @param string $caller The calling method + */ + public function runChildCmd( $cmd, &$retval, $encodingLog, $retvalLog, $caller ){ + global $wgTranscodeBackgroundTimeLimit, + $wgTranscodeBackgroundMemoryLimit, + $wgTranscodeBackgroundSizeLimit; + // In theory we should use pcntl_exec but not sure how to get the stdout, ensure + // we don't max php memory with the same protections provided by wfShellExec. + + // pcntl_exec requires a direct path to the exe and arguments as an array: + //$cmd = explode(' ', $cmd ); + //$baseCmd = array_shift( $cmd ); + //print "run:" . $baseCmd . " args: " . print_r( $cmd, true ); + //$status = pcntl_exec($baseCmd , $cmd ); + + // Directly execute the shell command: + //global $wgTranscodeBackgroundPriority; + //$status = wfShellExec( 'nice -n ' . $wgTranscodeBackgroundPriority . ' '. $cmd . ' 2>&1', $retval ); + $limits = array( + "filesize" => $wgTranscodeBackgroundSizeLimit, + "memory" => $wgTranscodeBackgroundMemoryLimit, + "time" => $wgTranscodeBackgroundTimeLimit + ); + $status = wfShellExec( $cmd . ' 2>&1', $retval , array(), $limits, + array( 'profileMethod' => $caller ) ); + + // Output the status: + wfSuppressWarnings(); + file_put_contents( $encodingLog, $status ); + // Output the retVal to the $retvalLog + file_put_contents( $retvalLog, $retval ); + wfRestoreWarnings(); + } + + /** + * @param $pid + * @param $retval + * @param $encodingLog + * @param $retvalLog + * @return string + */ + public function monitorTranscode( $pid, &$retval, $encodingLog, $retvalLog ){ + global $wgTranscodeBackgroundTimeLimit, $wgLang; + $errorMsg = ''; + $loopCount = 0; + $oldFileSize = 0; + $startTime = time(); + $fileIsNotGrowing = false; + + $this->output( "Encoding with pid: $pid \npcntl_waitpid: " . pcntl_waitpid( $pid, $status, WNOHANG OR WUNTRACED) . + "\nisProcessRunning: " . self::isProcessRunningKillZombie( $pid ) . "\n" ); + + // Check that the child process is still running ( note this does not work well with pcntl_waitpid + // for some reason :( + while( self::isProcessRunningKillZombie( $pid ) ) { + //$this->output( "$pid is running" ); + + // Check that the target file is growing ( every 5 seconds ) + if( $loopCount == 10 ){ + // only run check if we are outputing to target file + // ( two pass encoding does not output to target on first pass ) + clearstatcache(); + $newFileSize = is_file( $this->getTargetEncodePath() ) ? filesize( $this->getTargetEncodePath() ) : 0; + // Don't start checking for file growth until we have an initial positive file size: + if( $newFileSize > 0 ){ + $this->output( $wgLang->formatSize( $newFileSize ). ' Total size, encoding ' . + $wgLang->formatSize( ( $newFileSize - $oldFileSize ) / 5 ) . ' per second' ); + if( $newFileSize == $oldFileSize ){ + if( $fileIsNotGrowing ){ + $errorMsg = "Target File is not increasing in size, kill process."; + $this->output( $errorMsg ); + // file is not growing in size, kill proccess + $retval = 1; + + //posix_kill( $pid, 9); + self::killProcess( $pid ); + break; + } + // Wait an additional 5 seconds of the file not growing to confirm + // the transcode is frozen. + $fileIsNotGrowing = true; + } else { + $fileIsNotGrowing = false; + } + $oldFileSize = $newFileSize; + } + // reset the loop counter + $loopCount = 0; + } + + // Check if we have global job run-time has been exceeded: + if ( $wgTranscodeBackgroundTimeLimit && time() - $startTime > $wgTranscodeBackgroundTimeLimit ){ + $errorMsg = "Encoding exceeded max job run time ( " + . TimedMediaHandler::seconds2npt( $wgTranscodeBackgroundTimeLimit ) . " ), kill process."; + $this->output( $errorMsg ); + // File is not growing in size, kill proccess + $retval = 1; + //posix_kill( $pid, 9); + self::killProcess( $pid ); + break; + } + + // Sleep for one second before repeating loop + $loopCount++; + sleep( 1 ); + } + + $returnPcntl = pcntl_wexitstatus( $status ); + // check status + wfSuppressWarnings(); + $returnCodeFile = file_get_contents( $retvalLog ); + wfRestoreWarnings(); + //$this->output( "TranscodeJob:: Child pcntl return:". $returnPcntl . ' Log file exit code:' . $returnCodeFile . "\n" ); + + // File based exit code seems more reliable than pcntl_wexitstatus + $retval = $returnCodeFile; + + // return the encoding log contents ( will be inserted into error table if an error ) + // ( will be ignored and removed if success ) + if( $errorMsg!= '' ){ + $errorMsg.="\n\n"; + } + return $errorMsg . file_get_contents( $encodingLog ); + } + + /** + * check if proccess is running and not a zombie + * @param $pid int + * @return bool + */ + public static function isProcessRunningKillZombie( $pid ){ + exec( "ps $pid", $processState ); + if( !isset( $processState[1] ) ){ + return false; + } + if( strpos( $processState[1], '<defunct>' ) !== false ){ + // posix kill does not seem to work + //posix_kill( $pid, 9); + self::killProcess( $pid ); + return false; + } + return true; + } + + /** + * Kill Application PID + * + * @param $pid int + * @return bool + */ + public static function killProcess( $pid ){ + exec( "kill -9 $pid" ); + exec( "ps $pid", $processState ); + if( isset( $processState[1] ) ){ + return false; + } + return true; + } + + /** + * Mapping between firefogg api and ffmpeg2theora command line + * + * This lets us share a common api between firefogg and WebVideoTranscode + * also see: http://firefogg.org/dev/index.html + */ + public static $foggMap = array( + // video + 'width' => "--width", + 'height' => "--height", + 'maxSize' => "--max_size", + 'noUpscaling' => "--no-upscaling", + 'videoQuality'=> "-v", + 'videoBitrate' => "-V", + 'twopass' => "--two-pass", + 'optimize' => "--optimize", + 'framerate' => "-F", + 'aspect' => "--aspect", + 'starttime' => "--starttime", + 'endtime' => "--endtime", + 'cropTop' => "--croptop", + 'cropBottom' => "--cropbottom", + 'cropLeft' => "--cropleft", + 'cropRight' => "--cropright", + 'keyframeInterval'=> "--keyint", + 'denoise' => array("--pp", "de"), + 'deinterlace' => "--deinterlace", + 'novideo' => array("--novideo", "--no-skeleton"), + 'bufDelay' => "--buf-delay", + // audio + 'audioQuality' => "-a", + 'audioBitrate' => "-A", + 'samplerate' => "-H", + 'channels' => "-c", + 'noaudio' => "--noaudio", + // metadata + 'artist' => "--artist", + 'title' => "--title", + 'date' => "--date", + 'location' => "--location", + 'organization' => "--organization", + 'copyright' => "--copyright", + 'license' => "--license", + 'contact' => "--contact" + ); + +} diff --git a/extensions/TimedMediaHandler/archives/transcode_name_key.sql b/extensions/TimedMediaHandler/archives/transcode_name_key.sql new file mode 100644 index 00000000..85b00858 --- /dev/null +++ b/extensions/TimedMediaHandler/archives/transcode_name_key.sql @@ -0,0 +1,3 @@ +-- Add unique constrain on name/key +DROP INDEX /*i*/transcode_name_inx ON /*_*/transcode; +CREATE UNIQUE INDEX /*i*/transcode_name_key ON /*_*/transcode (transcode_image_name,transcode_key); diff --git a/extensions/TimedMediaHandler/composer.json b/extensions/TimedMediaHandler/composer.json new file mode 100644 index 00000000..3d55a97d --- /dev/null +++ b/extensions/TimedMediaHandler/composer.json @@ -0,0 +1,10 @@ +{ + "require-dev": { + "jakub-onderka/php-parallel-lint": "0.9.*" + }, + "scripts": { + "test": [ + "parallel-lint . --exclude vendor" + ] + } +} diff --git a/extensions/TimedMediaHandler/gitinfo.json b/extensions/TimedMediaHandler/gitinfo.json new file mode 100644 index 00000000..d26a9734 --- /dev/null +++ b/extensions/TimedMediaHandler/gitinfo.json @@ -0,0 +1 @@ +{"headSHA1": "7cab54e2e482d51df69e4b9c880182b23cabf0bc\n", "head": "7cab54e2e482d51df69e4b9c880182b23cabf0bc\n", "remoteURL": "https://gerrit.wikimedia.org/r/mediawiki/extensions/TimedMediaHandler", "branch": "7cab54e2e482d51df69e4b9c880182b23cabf0bc\n", "headCommitDate": "1453929642"}
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/handlers/FLACHandler/FLACHandler.php b/extensions/TimedMediaHandler/handlers/FLACHandler/FLACHandler.php new file mode 100644 index 00000000..f08c9b90 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/FLACHandler/FLACHandler.php @@ -0,0 +1,74 @@ +<?php +/** + * FLAC handler + */ +class FLACHandler extends ID3Handler { + + /** + * @param $file File + * @return string + */ + function getMetadataType( $file ) { + return 'flac'; + } + + /** + * @param $file File + * @return String + */ + function getWebType( $file ) { + return 'audio/flac'; + } + + /** + * @param $file File + * @return array|bool + */ + function getStreamTypes( $file ) { + $streamTypes = array(); + $metadata = $this->unpackMetadata( $file->getMetadata() ); + + if ( !$metadata || isset( $metadata['error'] ) ) { + return false; + } + + if( isset( $metadata['audio'] ) && $metadata['audio']['dataformat'] == 'flac' ){ + $streamTypes[] = 'FLAC'; + } + + return $streamTypes; + } + + /** + * @param $file File + * @return String + */ + function getShortDesc( $file ) { + global $wgLang; + + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getShortDesc( $file ); + } + return wfMessage( 'timedmedia-flac-short-audio', + $wgLang->formatTimePeriod( $this->getLength( $file ) ) )->text(); + } + + /** + * @param $file File + * @return String + */ + function getLongDesc( $file ) { + global $wgLang; + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getLongDesc( $file ); + } + return wfMessage('timedmedia-flac-long-audio', + $wgLang->formatTimePeriod( $this->getLength($file) ), + $wgLang->formatBitrate( $this->getBitRate( $file ) ) + )->text(); + + } + +} diff --git a/extensions/TimedMediaHandler/handlers/ID3Handler/ID3Handler.php b/extensions/TimedMediaHandler/handlers/ID3Handler/ID3Handler.php new file mode 100644 index 00000000..1e3ae4fb --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/ID3Handler/ID3Handler.php @@ -0,0 +1,107 @@ +<?php +/** + * getID3 Metadata handler + */ +class ID3Handler extends TimedMediaHandler { + // XXX match GETID3_VERSION ( too bad version is not a getter ) + const METADATA_VERSION = 2; + + /** + * @param $path string + * @return array + */ + protected function getID3( $path ) { + // Create new id3 object: + $getID3 = new getID3(); + + // Don't grab stuff we don't use: + $getID3->option_tag_id3v1 = false; // Read and process ID3v1 tags + $getID3->option_tag_id3v2 = false; // Read and process ID3v2 tags + $getID3->option_tag_lyrics3 = false; // Read and process Lyrics3 tags + $getID3->option_tag_apetag = false; // Read and process APE tags + $getID3->option_tags_process = false; // Copy tags to root key 'tags' and encode to $this->encoding + $getID3->option_tags_html = false; // Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities + + // Analyze file to get metadata structure: + $id3 = $getID3->analyze( $path ); + + // remove file paths + unset( $id3['filename'] ); + unset( $id3['filepath'] ); + unset( $id3['filenamepath']); + + // Update the version + $id3['version'] = self::METADATA_VERSION; + + return $id3; + } + + /** + * @param $file File + * @param $path string + * @return string + */ + function getMetadata( $file, $path ) { + $id3 = $this->getID3( $path ); + return serialize( $id3 ); + } + + /** + * @param $metadata + * @return bool|mixed + */ + function unpackMetadata( $metadata ) { + wfSuppressWarnings(); + $unser = unserialize( $metadata ); + wfRestoreWarnings(); + if ( isset( $unser['version'] ) && $unser['version'] == self::METADATA_VERSION ) { + return $unser; + } else { + return false; + } + } + + /** + * @param $file File + * @return mixed + */ + function getBitrate( $file ){ + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) || !isset( $metadata['bitrate'] ) ) { + return 0; + } else { + return $metadata['bitrate']; + } + } + + /** + * @param $file File + * @return int + */ + function getLength( $file ) { + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) || !isset( $metadata['playtime_seconds'] ) ) { + return 0; + } else { + return $metadata['playtime_seconds']; + } + } + + /** + * @param $file File + * @return bool|int + */ + function getFramerate( $file ){ + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) ) { + return 0; + } else { + // return the frame rate of the first found video stream: + if( isset( $metadata['video'] ) + && isset( $metadata['video']['frame_rate'] ) ) { + return $metadata['video']['frame_rate']; + } + return false; + } + } +} diff --git a/extensions/TimedMediaHandler/handlers/Mp4Handler/Mp4Handler.php b/extensions/TimedMediaHandler/handlers/Mp4Handler/Mp4Handler.php new file mode 100644 index 00000000..897e1017 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/Mp4Handler/Mp4Handler.php @@ -0,0 +1,139 @@ +<?php +/** + * MP4 handler + */ +class Mp4Handler extends ID3Handler { + + /** + * @param $path string + * @return array + */ + protected function getID3( $path ) { + $id3 = parent::getID3( $path ); + // Unset some parts of id3 that are too detailed and matroska specific: + unset( $id3['quicktime'] ); + return $id3; + } + + /** + * Get the "media size" + * @param $file File + * @param $path string + * @param $metadata bool + * @return array|bool + */ + function getImageSize( $file, $path, $metadata = false ) { + // Just return the size of the first video stream + if ( $metadata === false ) { + $metadata = $file->getMetadata(); + } + $metadata = $this->unpackMetadata( $metadata ); + if ( isset( $metadata['error'] ) ) { + return false; + } + if( isset( $metadata['video']['resolution_x']) + && + isset( $metadata['video']['resolution_y']) + ){ + return array ( + $metadata['video']['resolution_x'], + $metadata['video']['resolution_y'] + ); + } + return array( false, false ); + } + + /** + * @param $image + * @return string + */ + function getMetadataType( $image ) { + return 'mp4'; + } + /** + * @param $file File + */ + function getWebType( $file ) { + /** + * h.264 profile types: + H.264 Simple baseline profile video (main and extended video compatible) level 3 and Low-Complexity AAC audio in MP4 container: + type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' + + H.264 Extended profile video (baseline-compatible) level 3 and Low-Complexity AAC audio in MP4 container: + type='video/mp4; codecs="avc1.58A01E, mp4a.40.2"' + + H.264 Main profile video level 3 and Low-Complexity AAC audio in MP4 container + type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"' + + H.264 āHighā profile video (incompatible with main, baseline, or extended profiles) level 3 and Low-Complexity AAC audio in MP4 container + type='video/mp4; codecs="avc1.64001E, mp4a.40.2"' + */ + // all h.264 encodes are currently simple profile + return 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'; + } + /** + * @param $file File + * @return array|bool + */ + function getStreamTypes( $file ) { + $streamTypes = array(); + $metadata = self::unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) ) { + return false; + } + if( isset( $metadata['audio'] ) && $metadata['audio']['dataformat'] == 'mp4' ){ + if( isset( $metadata['audio']['codec'] ) + && + strpos( $metadata['audio']['codec'] , 'AAC' ) !== false + ){ + $streamTypes[] = 'AAC'; + } else { + $streamTypes[] = $metadata['audio']['codec']; + } + } + // id3 gives 'V_VP8' for what we call VP8 + if( $metadata['video']['dataformat'] == 'quicktime' ){ + $streamTypes[] = 'h.264'; + } + + return $streamTypes; + } + + /** + * @param $file File + * @return String + */ + function getShortDesc( $file ) { + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getShortDesc( $file ); + } + return wfMessage( 'timedmedia-mp4-short-video', implode( '/', $streamTypes ) + )->timeperiodParams( + $this->getLength( $file ) + )->text(); + } + + /** + * @param $file File + * @return String + */ + function getLongDesc( $file ) { + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getLongDesc( $file ); + } + return wfMessage('timedmedia-mp4-long-video', + implode( '/', $streamTypes ) + )->timeperiodParams( + $this->getLength( $file ) + )->bitrateParams( + $this->getBitRate( $file ) + )->numParams( + $file->getWidth(), + $file->getHeight() + )->text(); + + } + +} diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg.php b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg.php new file mode 100644 index 00000000..ca281e22 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg.php @@ -0,0 +1,631 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------------+ +// | File_Ogg PEAR Package for Accessing Ogg Bitstreams | +// | Copyright (c) 2005-2007 | +// | David Grant <david@grant.org.uk> | +// | Tim Starling <tstarling@wikimedia.org> | +// +----------------------------------------------------------------------------+ +// | This library is free software; you can redistribute it and/or | +// | modify it under the terms of the GNU Lesser General Public | +// | License as published by the Free Software Foundation; either | +// | version 2.1 of the License, or (at your option) any later version. | +// | | +// | This library 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 | +// | Lesser General Public License for more details. | +// | | +// | You should have received a copy of the GNU Lesser General Public | +// | License along with this library; if not, write to the Free Software | +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +// +----------------------------------------------------------------------------+ + +/** + * @author David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @category File + * @copyright David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @license http://www.gnu.org/copyleft/lesser.html GNU LGPL + * @link http://pear.php.net/package/File_Ogg + * @package File_Ogg + * @version CVS: $Id: Ogg.php,v 1.14 2005/11/19 09:06:30 djg Exp $ + */ + +/** + * @access public + */ +define("OGG_STREAM_VORBIS", 1); +/** + * @access public + */ +define("OGG_STREAM_THEORA", 2); +/** + * @access public + */ +define("OGG_STREAM_SPEEX", 3); +/** + * @access public + */ +define("OGG_STREAM_FLAC", 4); +/** + * @access public + */ +define("OGG_STREAM_OPUS", 5); + +/** + * Capture pattern to determine if a file is an Ogg physical stream. + * + * @access private + */ +define("OGG_CAPTURE_PATTERN", "OggS"); +/** + * Maximum size of an Ogg stream page plus four. This value is specified to allow + * efficient parsing of the physical stream. The extra four is a paranoid measure + * to make sure a capture pattern is not split into two parts accidentally. + * + * @access private + */ +define("OGG_MAXIMUM_PAGE_SIZE", 65311); +/** + * Capture pattern for an Ogg Vorbis logical stream. + * + * @access private + */ +define("OGG_STREAM_CAPTURE_VORBIS", "vorbis"); +/** + * Capture pattern for an Ogg Speex logical stream. + * @access private + */ +define("OGG_STREAM_CAPTURE_SPEEX", "Speex "); +/** + * Capture pattern for an Ogg FLAC logical stream. + * + * @access private + */ +define("OGG_STREAM_CAPTURE_FLAC", "FLAC"); +/** + * Capture pattern for an Ogg Theora logical stream. + * + * @access private + */ +define("OGG_STREAM_CAPTURE_THEORA", "theora"); +/** + * Capture pattern for an Ogg Opus logical stream. + * @access private + */ +define("OGG_STREAM_CAPTURE_OPUS", "OpusHead"); +/** + * Error thrown if the file location passed is nonexistant or unreadable. + * + * @access private + */ +define("OGG_ERROR_INVALID_FILE", 1); +/** + * Error thrown if the user attempts to extract an unsupported logical stream. + * + * @access private + */ +define("OGG_ERROR_UNSUPPORTED", 2); +/** + * Error thrown if the user attempts to extract an logical stream with no + * corresponding serial number. + * + * @access private + */ +define("OGG_ERROR_BAD_SERIAL", 3); +/** + * Error thrown if the stream appears to be corrupted. + * + * @access private + */ +define("OGG_ERROR_UNDECODABLE", 4); + + +/** + * Class for parsing a ogg bitstream. + * + * This class provides a means to access several types of logical bitstreams (e.g. Vorbis) + * within a Ogg physical bitstream. + * + * @link http://www.xiph.org/ogg/doc/ + * @package File_Ogg + */ +class File_Ogg +{ + /** + * File pointer to Ogg container. + * + * This is the file pointer used for extracting data from the Ogg stream. It is + * the result of a standard fopen call. + * + * @var pointer + * @access private + */ + var $_filePointer; + + /** + * The container for all logical streams. + * + * List of all of the unique streams in the Ogg physical stream. The key + * used is the unique serial number assigned to the logical stream by the + * encoding application. + * + * @var array + * @access private + */ + var $_streamList = array(); + var $_streams = array(); + + /** + * Length in seconds of each stream group + */ + var $_groupLengths = array(); + + /** + * Total length in seconds of the entire file + */ + var $_totalLength; + var $_startOffset = false; + + /** + * Maximum number of pages to store detailed metadata for, per stream. + * We can't store every page because there could be millions, causing an OOM. + * This must be big enough so that all the codecs can get the metadata they + * need without re-reading the file. + */ + var $_maxPageCacheSize = 4; + + /** + * Returns an interface to an Ogg physical stream. + * + * This method takes the path to a local file and examines it for a physical + * ogg bitsream. After instantiation, the user should query the object for + * the logical bitstreams held within the ogg container. + * + * @access public + * @param string $fileLocation The path of the file to be examined. + */ + function __construct($fileLocation) + { + clearstatcache(); + if (! file_exists($fileLocation)) { + throw new OggException("Couldn't Open File. Check File Path.", OGG_ERROR_INVALID_FILE); + } + + // Open this file as a binary, and split the file into streams. + $this->_filePointer = fopen($fileLocation, "rb"); + if (!is_resource($this->_filePointer)) + throw new OggException("Couldn't Open File. Check File Permissions.", OGG_ERROR_INVALID_FILE); + + // Check for a stream at the start + $magic = fread($this->_filePointer, strlen(OGG_CAPTURE_PATTERN)); + if ($magic !== OGG_CAPTURE_PATTERN) { + throw new OggException("Couldn't read file: Incorrect magic number.", OGG_ERROR_UNDECODABLE); + } + fseek($this->_filePointer, 0, SEEK_SET); + + $this->_splitStreams(); + fclose($this->_filePointer); + } + + /** + * Little-endian equivalent for bin2hex + * @static + */ + static function _littleEndianBin2Hex( $bin ) { + $bigEndian = bin2hex( $bin ); + // Reverse entire string + $reversed = strrev( $bigEndian ); + // Swap nibbles back + for ( $i = 0; $i < strlen( $bigEndian ); $i += 2 ) { + $temp = $reversed[$i]; + $reversed[$i] = $reversed[$i+1]; + $reversed[$i+1] = $temp; + } + return $reversed; + } + + + /** + * Read a binary structure from a file. An array of unsigned integers are read. + * Large integers are upgraded to floating point on overflow. + * + * Format is big-endian as per Theora bit packing convention, this function + * won't work for Vorbis. + * + * @param resource $file + * @param array $fields Associative array mapping name to length in bits + */ + static function _readBigEndian($file, $fields) + { + $bufferLength = ceil(array_sum($fields) / 8); + $buffer = fread($file, $bufferLength); + if (strlen($buffer) != $bufferLength) { + throw new OggException('Unexpected end of file', OGG_ERROR_UNDECODABLE); + } + $bytePos = 0; + $bitPos = 0; + $byteValue = ord($buffer[0]); + $output = array(); + foreach ($fields as $name => $width) { + if ($width % 8 == 0 && $bitPos == 0) { + // Byte aligned case + $bytes = $width / 8; + $endBytePos = $bytePos + $bytes; + $value = 0; + while ($bytePos < $endBytePos) { + $value = ($value * 256) + ord($buffer[$bytePos]); + $bytePos++; + } + if ($bytePos < strlen($buffer)) { + $byteValue = ord($buffer[$bytePos]); + } + } else { + // General case + $bitsRemaining = $width; + $value = 0; + while ($bitsRemaining > 0) { + $bitsToRead = min($bitsRemaining, 8 - $bitPos); + $byteValue <<= $bitsToRead; + $overflow = ($byteValue & 0xff00) >> 8; + $byteValue &= $byteValue & 0xff; + + $bitPos += $bitsToRead; + $bitsRemaining -= $bitsToRead; + $value += $overflow * pow(2, $bitsRemaining); + + if ($bitPos >= 8) { + $bitPos = 0; + $bytePos++; + if ($bitsRemaining <= 0) { + break; + } + $byteValue = ord($buffer[$bytePos]); + } + } + } + $output[$name] = $value; + assert($bytePos <= $bufferLength); + } + return $output; + } + + /** + * Read a binary structure from a file. An array of unsigned integers are read. + * Large integers are upgraded to floating point on overflow. + * + * Format is little-endian as per Vorbis bit packing convention. + * + * @param resource $file + * @param array $fields Associative array mapping name to length in bits + */ + static function _readLittleEndian( $file, $fields ) { + $bufferLength = ceil(array_sum($fields) / 8); + $buffer = fread($file, $bufferLength); + if (strlen($buffer) != $bufferLength) { + throw new OggException('Unexpected end of file', OGG_ERROR_UNDECODABLE); + } + + $bytePos = 0; + $bitPos = 0; + $byteValue = ord($buffer[0]) << 8; + $output = array(); + foreach ($fields as $name => $width) { + if ($width % 8 == 0 && $bitPos == 0) { + // Byte aligned case + $bytes = $width / 8; + $value = 0; + for ($i = 0; $i < $bytes; $i++, $bytePos++) { + $value += pow(256, $i) * ord($buffer[$bytePos]); + } + if ($bytePos < strlen($buffer)) { + $byteValue = ord($buffer[$bytePos]) << 8; + } + } else { + // General case + $bitsRemaining = $width; + $value = 0; + while ($bitsRemaining > 0) { + $bitsToRead = min($bitsRemaining, 8 - $bitPos); + $byteValue >>= $bitsToRead; + $overflow = ($byteValue & 0xff) >> (8 - $bitsToRead); + $byteValue &= 0xff00; + + $value += $overflow * pow(2, $width - $bitsRemaining); + $bitPos += $bitsToRead; + $bitsRemaining -= $bitsToRead; + + if ($bitPos >= 8) { + $bitPos = 0; + $bytePos++; + if ($bitsRemaining <= 0) { + break; + } + $byteValue = ord($buffer[$bytePos]) << 8; + } + } + } + $output[$name] = $value; + assert($bytePos <= $bufferLength); + } + return $output; + } + + + /** + * @access private + */ + function _decodePageHeader($pageData, $pageOffset, $groupId) + { + // Extract the various bits and pieces found in each packet header. + if (substr($pageData, 0, 4) != OGG_CAPTURE_PATTERN) + return (false); + + $stream_version = unpack("C1data", substr($pageData, 4, 1)); + if ($stream_version['data'] != 0x00) + return (false); + + $header_flag = unpack("Cdata", substr($pageData, 5, 1)); + + // Exact granule position + $abs_granule_pos = self::_littleEndianBin2Hex( substr($pageData, 6, 8)); + + // Approximate (floating point) granule position + $pos = unpack("Va/Vb", substr($pageData, 6, 8)); + $approx_granule_pos = $pos['a'] + $pos['b'] * pow(2, 32); + + // Serial number for the current datastream. + $stream_serial = unpack("Vdata", substr($pageData, 14, 4)); + $page_sequence = unpack("Vdata", substr($pageData, 18, 4)); + $checksum = unpack("Vdata", substr($pageData, 22, 4)); + $page_segments = unpack("Cdata", substr($pageData, 26, 1)); + $segments_total = 0; + for ($i = 0; $i < $page_segments['data']; ++$i) { + $segment_length = unpack("Cdata", substr($pageData, 26 + ($i + 1), 1)); + $segments_total += $segment_length['data']; + } + $pageFinish = $pageOffset + 27 + $page_segments['data'] + $segments_total; + $page = array( + 'stream_version' => $stream_version['data'], + 'header_flag' => $header_flag['data'], + 'abs_granule_pos' => $abs_granule_pos, + 'approx_granule_pos' => $approx_granule_pos, + 'checksum' => sprintf("%u", $checksum['data']), + 'segments' => $page_segments['data'], + 'head_offset' => $pageOffset, + 'body_offset' => $pageOffset + 27 + $page_segments['data'], + 'body_finish' => $pageFinish, + 'data_length' => $pageFinish - $pageOffset, + 'group' => $groupId, + ); + if ( !isset( $this->_streamList[$stream_serial['data']] ) ) { + $this->_streamList[$stream_serial['data']] = array( + 'pages' => array(), + 'data_length' => 0, + 'first_granule_pos' => null, + 'last_granule_pos' => null, + ); + } + $stream =& $this->_streamList[$stream_serial['data']]; + if ( count( $stream['pages'] ) < $this->_maxPageCacheSize ) { + $stream['pages'][$page_sequence['data']] = $page; + } + $stream['last_page'] = $page; + $stream['data_length'] += $page['data_length']; + + # Reject -1 as a granule pos, that means no segment finished in the packet + if ( $abs_granule_pos !== 'ffffffffffffffff' ) { + if ( $stream['first_granule_pos'] === null ) { + $stream['first_granule_pos'] = $abs_granule_pos; + } + $stream['last_granule_pos'] = $abs_granule_pos; + } + + $pageData = null; + return $page; + } + + /** + * @access private + */ + function _splitStreams() + { + // Loop through the physical stream until there are no more pages to read. + $groupId = 0; + $openStreams = 0; + $this_page_offset = 0; + while (!feof($this->_filePointer)) { + $pageData = fread($this->_filePointer, 282); + if (strval($pageData) === '') { + break; + } + $page = $this->_decodePageHeader($pageData, $this_page_offset, $groupId); + if ($page === false) { + throw new OggException("Cannot decode Ogg file: Invalid page at offset $this_page_offset", OGG_ERROR_UNDECODABLE); + } + + // Keep track of multiplexed groups + if ($page['header_flag'] & 2/*bos*/) { + $openStreams++; + } elseif ($page['header_flag'] & 4/*eos*/) { + $openStreams--; + if (!$openStreams) { + // End of group + $groupId++; + } + } + if ($openStreams < 0) { + throw new OggException("Unexpected end of stream", OGG_ERROR_UNDECODABLE); + } + + $this_page_offset = $page['body_finish']; + fseek( $this->_filePointer, $this_page_offset, SEEK_SET ); + } + // Loop through the streams, and find out what type of stream is available. + $groupLengths = array(); + foreach ($this->_streamList as $stream_serial => $streamData) { + fseek($this->_filePointer, $streamData['pages'][0]['body_offset'], SEEK_SET); + $pattern = fread($this->_filePointer, 8); + if (preg_match("/" . OGG_STREAM_CAPTURE_VORBIS . "/", $pattern)) { + $this->_streamList[$stream_serial]['stream_type'] = OGG_STREAM_VORBIS; + $stream = new File_Ogg_Vorbis($stream_serial, $streamData, $this->_filePointer); + } elseif (preg_match("/" . OGG_STREAM_CAPTURE_SPEEX . "/", $pattern)) { + $this->_streamList[$stream_serial]['stream_type'] = OGG_STREAM_SPEEX; + $stream = new File_Ogg_Speex($stream_serial, $streamData, $this->_filePointer); + } elseif (preg_match("/" . OGG_STREAM_CAPTURE_FLAC . "/", $pattern)) { + $this->_streamList[$stream_serial]['stream_type'] = OGG_STREAM_FLAC; + $stream = new File_Ogg_Flac($stream_serial, $streamData, $this->_filePointer); + } elseif (preg_match("/" . OGG_STREAM_CAPTURE_THEORA . "/", $pattern)) { + $this->_streamList[$stream_serial]['stream_type'] = OGG_STREAM_THEORA; + $stream = new File_Ogg_Theora($stream_serial, $streamData, $this->_filePointer); + } elseif (preg_match("/" . OGG_STREAM_CAPTURE_OPUS . "/", $pattern)) { + $this->_streamList[$stream_serial]['stream_type'] = OGG_STREAM_OPUS; + $stream = new File_Ogg_Opus($stream_serial, $streamData, $this->_filePointer); + } else { + $streamData['stream_type'] = "unknown"; + $stream = false; + } + + if ($stream) { + $this->_streams[$stream_serial] = $stream; + $group = $streamData['pages'][0]['group']; + if (isset($groupLengths[$group])) { + $groupLengths[$group] = max($groupLengths[$group], $stream->getLength()); + } else { + $groupLengths[$group] = $stream->getLength(); + } + //just store the startOffset for the first stream: + if( $this->_startOffset === false ){ + $this->_startOffset = $stream->getStartOffset(); + } + + } + } + $this->_groupLengths = $groupLengths; + $this->_totalLength = array_sum( $groupLengths ); + unset($this->_streamList); + } + + /** + * Returns the overead percentage used by the Ogg headers. + * + * This function returns the percentage of the total stream size + * used for Ogg headers. + * + * @return float + */ + function getOverhead() { + $header_size = 0; + $stream_size = 0; + foreach ($this->_streams as $serial => $stream) { + foreach ($stream->_streamList as $offset => $stream_data) { + $header_size += $stream_data['body_offset'] - $stream_data['head_offset']; + $stream_size = $stream_data['body_finish']; + } + } + return sprintf("%0.2f", ($header_size / $stream_size) * 100); + } + + /** + * Returns the appropriate logical bitstream that corresponds to the provided serial. + * + * This function returns a logical bitstream contained within the Ogg physical + * stream, corresponding to the serial used as the offset for that bitstream. + * The returned stream may be Vorbis, Speex, FLAC or Theora, although the only + * usable bitstream is Vorbis. + * + * @return File_Ogg_Bitstream + */ + function &getStream($streamSerial) + { + if (! array_key_exists($streamSerial, $this->_streams)) + throw new OggException("The stream number is invalid.", OGG_ERROR_BAD_SERIAL); + + return $this->_streams[$streamSerial]; + } + + /** + * This function returns true if a logical bitstream of the requested type can be found. + * + * This function checks the contents of this ogg physical bitstream for of logical + * bitstream corresponding to the supplied type. If one is found, the function returns + * true, otherwise it return false. + * + * @param int $streamType + * @return boolean + */ + function hasStream($streamType) + { + foreach ($this->_streams as $stream) { + if ($stream['stream_type'] == $streamType) + return (true); + } + return (false); + } + + /** + * Returns an array of logical streams inside this physical bitstream. + * + * This function returns an array of logical streams found within this physical + * bitstream. If a filter is provided, only logical streams of the requested type + * are returned, as an array of serial numbers. If no filter is provided, this + * function returns a two-dimensional array, with the stream type as the primary key, + * and a value consisting of an array of stream serial numbers. + * + * @param int $filter + * @return array + */ + function listStreams($filter = null) + { + $streams = array(); + // Loops through the streams and assign them to an appropriate index, + // ready for filtering the second part of this function. + foreach ($this->_streams as $serial => $stream) { + $stream_type = 0; + switch (get_class($stream)) { + case "file_ogg_flac": + $stream_type = OGG_STREAM_FLAC; + break; + case "file_ogg_speex": + $stream_type = OGG_STREAM_SPEEX; + break; + case "file_ogg_theora": + $stream_type = OGG_STREAM_THEORA; + break; + case "file_ogg_vorbis": + $stream_type = OGG_STREAM_VORBIS; + break; + } + if (! isset($streams[$stream_type])) + // Initialise the result list for this stream type. + $streams[$stream_type] = array(); + + $streams[$stream_type][] = $serial; + } + + // Perform filtering. + if (is_null($filter)) + return ($streams); + elseif (isset($streams[$filter])) + return ($streams[$filter]); + else + return array(); + } + /** + * getStartOffset + * + * @return unknown + */ + function getStartOffset(){ + if( $this->_startOffset === false) + return 0; + return $this->_startOffset; + } + /** + * Get the total length of the group of streams + */ + function getLength() { + return $this->_totalLength; + } +} +?> diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Bitstream.php b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Bitstream.php new file mode 100644 index 00000000..1a462232 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Bitstream.php @@ -0,0 +1,125 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------------+ +// | File_Ogg PEAR Package for Accessing Ogg Bitstreams | +// | Copyright (c) 2005-2007 | +// | David Grant <david@grant.org.uk> | +// | Tim Starling <tstarling@wikimedia.org> | +// +----------------------------------------------------------------------------+ +// | This library is free software; you can redistribute it and/or | +// | modify it under the terms of the GNU Lesser General Public | +// | License as published by the Free Software Foundation; either | +// | version 2.1 of the License, or (at your option) any later version. | +// | | +// | This library 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 | +// | Lesser General Public License for more details. | +// | | +// | You should have received a copy of the GNU Lesser General Public | +// | License along with this library; if not, write to the Free Software | +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +// +----------------------------------------------------------------------------+ + + +/** + * @author David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @category File + * @copyright David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @license http://www.gnu.org/copyleft/lesser.html GNU LGPL + * @link http://pear.php.net/package/File_Ogg + * @package File_Ogg + * @version CVS: $Id: Bitstream.php,v 1.3 2005/11/08 19:36:18 djg Exp $ + */ +class File_Ogg_Bitstream +{ + /** + * The serial number of this logical stream. + * + * @var int + * @access private + */ + var $_streamSerial; + /** + * @access private + */ + var $_streamData; + /** + * @access private + */ + var $_filePointer; + /** + * The number of bits used in this stream. + * + * @var int + * @access private + */ + var $_streamSize; + + /** + * The last granule position in the stream + * @var int + * @access private + */ + var $_lastGranulePos; + + /** + * Constructor for a generic logical stream. + * + * @param int $streamSerial Serial number of the logical stream. + * @param array $streamData Data for the requested logical stream. + * @param string $filePath Location of a file on the filesystem. + * @param pointer $filePointer File pointer for the current physical stream. + * @access private + */ + function __construct($streamSerial, $streamData, $filePointer) + { + $this->_streamSerial = $streamSerial; + $this->_streamData = $streamData; + $this->_filePointer = $filePointer; + $this->_firstGranulePos = $streamData['first_granule_pos']; + $this->_lastGranulePos = $streamData['last_granule_pos']; + $this->_streamSize = $streamData['data_length']; + $this->_group = $streamData['pages'][0]['group']; + } + + /** + * Gives the serial number of this stream. + * + * The stream serial number is of fairly academic importance, as it makes little + * difference to the end user. The serial number is used by the Ogg physical + * stream to distinguish between concurrent logical streams. + * + * @return int + * @access public + */ + function getSerial() + { + return ($this->_streamSerial); + } + + /** + * Gives the size (in bits) of this stream. + * + * This function returns the size of the Vorbis stream within the Ogg + * physical stream. + * + * @return int + * @access public + */ + function getSize() + { + return ($this->_streamSize); + } + + /** + * Get the multiplexed group ID + */ + function getGroup() + { + return $this->_group; + } + +} + +?> diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Flac.php b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Flac.php new file mode 100644 index 00000000..6838ba68 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Flac.php @@ -0,0 +1,133 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------------+ +// | File_Ogg PEAR Package for Accessing Ogg Bitstreams | +// | Copyright (c) 2005-2007 | +// | David Grant <david@grant.org.uk> | +// | Tim Starling <tstarling@wikimedia.org> | +// +----------------------------------------------------------------------------+ +// | This library is free software; you can redistribute it and/or | +// | modify it under the terms of the GNU Lesser General Public | +// | License as published by the Free Software Foundation; either | +// | version 2.1 of the License, or (at your option) any later version. | +// | | +// | This library 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 | +// | Lesser General Public License for more details. | +// | | +// | You should have received a copy of the GNU Lesser General Public | +// | License along with this library; if not, write to the Free Software | +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +// +----------------------------------------------------------------------------+ + + +/** + * @author David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @category File + * @copyright David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @license http://www.gnu.org/copyleft/lesser.html GNU LGPL + * @link http://pear.php.net/package/File_Ogg + * @link http://flac.sourceforge.net/documentation.html + * @package File_Ogg + * @version CVS: $Id: Flac.php,v 1.9 2005/11/16 20:43:27 djg Exp $ + */ +class File_Ogg_Flac extends File_Ogg_Media +{ + /** + * @access private + */ + function __construct($streamSerial, $streamData, $filePointer) + { + parent::__construct($streamSerial, $streamData, $filePointer); + $this->_decodeHeader(); + $this->_decodeCommentsHeader(); + $this->_streamLength = $this->_streamInfo['total_samples'] + / $this->_streamInfo['sample_rate']; + } + + /** + * Get a short string describing the type of the stream + * @return string + */ + function getType() { + return 'FLAC'; + } + + /** + * @access private + * @param int $packetType + * @param int $pageOffset + */ + function _decodeHeader() + { + fseek($this->_filePointer, $this->_streamData['pages'][0]['body_offset'], SEEK_SET); + // Check if this is the correct header. + $packet = unpack("Cdata", fread($this->_filePointer, 1)); + if ($packet['data'] != 0x7f) + throw new OggException("Stream Undecodable", OGG_ERROR_UNDECODABLE); + + // The following four characters should be "FLAC". + if (fread($this->_filePointer, 4) != 'FLAC') + throw new OggException("Stream is undecodable due to a malformed header.", OGG_ERROR_UNDECODABLE); + + $version = unpack("Cmajor/Cminor", fread($this->_filePointer, 2)); + $this->_version = "{$version['major']}.{$version['minor']}"; + if ($version['major'] > 1) { + throw new OggException("Cannot decode a version {$version['major']} FLAC stream", OGG_ERROR_UNDECODABLE); + } + $h = File_Ogg::_readBigEndian( $this->_filePointer, + array( + // Ogg-specific + 'num_headers' => 16, + 'flac_native_sig' => 32, + // METADATA_BLOCK_HEADER + 'is_last' => 1, + 'type' => 7, + 'length' => 24, + )); + + // METADATA_BLOCK_STREAMINFO + // The variable names are canonical, and come from the FLAC source (format.h) + $this->_streamInfo = File_Ogg::_readBigEndian( $this->_filePointer, + array( + 'min_blocksize' => 16, + 'max_blocksize' => 16, + 'min_framesize' => 24, + 'max_framesize' => 24, + 'sample_rate' => 20, + 'channels' => 3, + 'bits_per_sample' => 5, + 'total_samples' => 36, + )); + $this->_streamInfo['md5sum'] = bin2hex(fread($this->_filePointer, 16)); + } + + /** + * Get an associative array containing header information about the stream + * @access public + * @return array + */ + function getHeader() + { + return $this->_streamInfo; + } + + function _decodeCommentsHeader() + { + fseek($this->_filePointer, $this->_streamData['pages'][1]['body_offset'], SEEK_SET); + $blockHeader = File_Ogg::_readBigEndian( $this->_filePointer, + array( + 'last_block' => 1, + 'block_type' => 7, + 'length' => 24 + ) + ); + if ($blockHeader['block_type'] != 4) { + throw new OggException("Stream Undecodable", OGG_ERROR_UNDECODABLE); + } + + $this->_decodeBareCommentsHeader(); + } +} +?> diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Media.php b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Media.php new file mode 100644 index 00000000..67ddaece --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Media.php @@ -0,0 +1,262 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------------+ +// | File_Ogg PEAR Package for Accessing Ogg Bitstreams | +// | Copyright (c) 2005-2007 | +// | David Grant <david@grant.org.uk> | +// | Tim Starling <tstarling@wikimedia.org> | +// +----------------------------------------------------------------------------+ +// | This library is free software; you can redistribute it and/or | +// | modify it under the terms of the GNU Lesser General Public | +// | License as published by the Free Software Foundation; either | +// | version 2.1 of the License, or (at your option) any later version. | +// | | +// | This library 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 | +// | Lesser General Public License for more details. | +// | | +// | You should have received a copy of the GNU Lesser General Public | +// | License along with this library; if not, write to the Free Software | +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +// +----------------------------------------------------------------------------+ + + +/** + * Parent class for media bitstreams + * Contains some functions common to various media formats + */ +abstract class File_Ogg_Media extends File_Ogg_Bitstream +{ + /** + * Maximum size of header comment to parse. + * Set to 1 MB by default. Make sure this is less than your PHP memory_limit. + */ + const COMMENT_MAX_SIZE = 1000000; + + /** + * Array to hold each of the comments. + * + * @access private + * @var array + */ + var $_comments = array(); + + /** + * Vendor string for the stream. + * + * @access private + * @var string + */ + var $_vendor; + + /** + * Length of the stream in seconds + */ + var $_streamLength; + + /* Start offset of the stream in seconds */ + var $_startOffset = 0; + + /** + * Get a short string describing the type of the stream + * @return string + */ + abstract function getType(); + + /** + * Get the 6-byte identification string expected in the common header + * @return string + */ + function getIdentificationString() + { + return ''; + } + + /** + * @access private + * @param int $packetType + * @param int $pageOffset + */ + function _decodeCommonHeader($packetType, $pageOffset) + { + fseek($this->_filePointer, $this->_streamData['pages'][$pageOffset]['body_offset'], SEEK_SET); + if ($packetType !== false) { + // Check if this is the correct header. + $packet = unpack("Cdata", fread($this->_filePointer, 1)); + if ($packet['data'] != $packetType) + throw new OggException("Stream Undecodable", OGG_ERROR_UNDECODABLE); + + // The following six characters should be equal to getIdentificationString() + $id = $this->getIdentificationString(); + if ($id !== '' && fread($this->_filePointer, strlen($id)) !== $id) + throw new OggException("Stream is undecodable due to a malformed header.", OGG_ERROR_UNDECODABLE); + } // else seek only, no common header + } + + /** + * Parse a Vorbis-style comments header. + * + * This function parses the comments header. The comments header contains a series of + * UTF-8 comments related to the audio encoded in the stream. This header also contains + * a string to identify the encoding software. More details on the comments header can + * be found at the following location: http://xiph.org/vorbis/doc/v-comment.html + * + * @access private + */ + function _decodeBareCommentsHeader() + { + // Decode the vendor string length as a 32-bit unsigned integer. + $vendor_len = unpack("Vdata", fread($this->_filePointer, 4)); + if ( $vendor_len['data'] > 0 ) { + // Retrieve the vendor string from the stream. + $this->_vendor = fread($this->_filePointer, $vendor_len['data']); + } else { + $this->_vendor = ''; + } + // Decode the size of the comments list as a 32-bit unsigned integer. + $comment_list_length = unpack("Vdata", fread($this->_filePointer, 4)); + // Iterate through the comments list. + for ($i = 0; $i < $comment_list_length['data']; ++$i) { + // Unpack the length of this comment. + $comment_length = unpack("Vdata", fread($this->_filePointer, 4)); + + // If the comment length is greater than specified limit, skip it. + if ( $comment_length['data'] > self::COMMENT_MAX_SIZE ) { + continue; + } + + // Comments are in the format 'ARTIST=Super Furry Animals', so split it on the equals character. + // NOTE: Equals characters are strictly prohibited in either the COMMENT or DATA parts. + $comment = explode("=", fread($this->_filePointer, $comment_length['data'])); + $comment_title = (string) $comment[0]; + $comment_value = (string) $comment[1]; + + // Check if the comment type (e.g. ARTIST) already exists. If it does, + // take the new value, and the existing value (or array) and insert it + // into a new array. This is important, since each comment type may have + // multiple instances (e.g. ARTIST for a collaboration) and we should not + // overwrite the previous value. + if (isset($this->_comments[$comment_title])) { + if (is_array($this->_comments[$comment_title])) + $this->_comments[$comment_title][] = $comment_value; + else + $this->_comments[$comment_title] = array($this->_comments[$comment_title], $comment_value); + } else + $this->_comments[$comment_title] = $comment_value; + } + } + + /** + * Number of channels used in this stream + * + * This function returns the number of channels used in this stream. This + * can range from 1 to 255, but will likely be 2 (stereo) or 1 (mono). + * + * @access public + * @return int + * @see File_Ogg_Vorbis::isMono() + * @see File_Ogg_Vorbis::isStereo() + * @see File_Ogg_Vorbis::isQuadrophonic() + */ + function getChannels() + { + return ($this->_channels); + } + + /** + * Provides a list of the comments extracted from the Vorbis stream. + * + * It is recommended that the user fully inspect the array returned by this function + * rather than blindly requesting a comment in false belief that it will always + * be present. Whilst the Vorbis specification dictates a number of popular + * comments (e.g. TITLE, ARTIST, etc.) for use in Vorbis streams, they are not + * guaranteed to appear. + * + * @access public + * @return array + */ + function getCommentList() + { + return (array_keys($this->_comments)); + } + + /** + * Provides an interface to the numerous comments located with a Vorbis stream. + * + * A Vorbis stream may contain one or more instances of each comment, so the user + * should check the variable type before printing out the result of this method. + * The situation in which multiple instances of a comment occurring are not as + * rare as one might think, since they are conceivable at least for ARTIST comments + * in the situation where a track is a duet. + * + * @access public + * @param string $commentTitle Comment title to search for, e.g. TITLE. + * @param string $separator String to separate multiple values. + * @return string + */ + function getField($commentTitle, $separator = ", ") + { + if (isset($this->_comments[$commentTitle])) { + if (is_array($this->_comments[$commentTitle])) + return (implode($separator, $this->_comments[$commentTitle])); + else + return ($this->_comments[$commentTitle]); + } else + // The comment doesn't exist in this file. The user should've called getCommentList first. + return (""); + } + + /** + * Get the entire comments array. + * May return an empty array if the bitstream does not support comments. + * + * @access public + * @return array + */ + function getComments() { + return $this->_comments; + } + + /** + * Vendor of software used to encode this stream. + * + * Gives the vendor string for the software used to encode this stream. + * It is common to find libVorbis here. The majority of encoders appear + * to use libvorbis from Xiph.org. + * + * @access public + * @return string + */ + function getVendor() + { + return ($this->_vendor); + } + + /** + * Get an associative array containing header information about the stream + * @access public + * @return array + */ + function getHeader() + { + return array(); + } + + /** + * Get the length of the stream in seconds + * @return float + */ + function getLength() + { + return $this->_streamLength; + } + /** + * Get the start offset of the stream in seconds + * + * @return float + */ + function getStartOffset(){ + return $this->_startOffset; + } +} diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Opus.php b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Opus.php new file mode 100644 index 00000000..2c23d928 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Opus.php @@ -0,0 +1,126 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------------+ +// | File_Ogg PEAR Package for Accessing Ogg Bitstreams | +// | Copyright (c) 2013 | +// | Jan Gerber <jgerber@wikimedia.org> | +// +----------------------------------------------------------------------------+ +// | This library is free software; you can redistribute it and/or | +// | modify it under the terms of the GNU Lesser General Public | +// | License as published by the Free Software Foundation; either | +// | version 2.1 of the License, or (at your option) any later version. | +// | | +// | This library 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 | +// | Lesser General Public License for more details. | +// | | +// | You should have received a copy of the GNU Lesser General Public | +// | License along with this library; if not, write to the Free Software | +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +// +----------------------------------------------------------------------------+ + + +define( 'OGG_OPUS_COMMENTS_PAGE_OFFSET', 1 ); + +/** + * @author Jan Gerber <jgerber@wikimedia.org> + * @category File + * @copyright Jan Gerber <jgerber@wikimedia.org> + * @license http://www.gnu.org/copyleft/lesser.html GNU LGPL + * @link http://pear.php.net/package/File_Ogg + * @link http://www.opus-codec.org/ + * @package File_Ogg + * @version 1 + */ +class File_Ogg_Opus extends File_Ogg_Media +{ + /** + * @access private + */ + function __construct($streamSerial, $streamData, $filePointer) + { + parent::__construct($streamSerial, $streamData, $filePointer); + $this->_decodeHeader(); + $this->_decodeCommentsHeader(); + + $endSec = $this->getSecondsFromGranulePos( $this->_lastGranulePos ); + $startSec = $this->getSecondsFromGranulePos( $this->_firstGranulePos ); + + if( $startSec > 1){ + $this->_streamLength = $endSec - $startSec; + $this->_startOffset = $startSec; + }else{ + $this->_streamLength = $endSec; + } + $this->_avgBitrate = $this->_streamLength ? ($this->_streamSize * 8) / $this->_streamLength : 0; + } + + function getSecondsFromGranulePos( $granulePos ){ + return (( '0x' . substr( $granulePos, 0, 8 ) ) * pow(2, 32) + + ( '0x' . substr( $granulePos, 8, 8 ) ) + - $this->_header['pre_skip']) + / 48000; + } + + /** + * Get a short string describing the type of the stream + * @return string + */ + function getType() + { + return 'Opus'; + } + + /** + * Decode the stream header + * @access private + */ + function _decodeHeader() + { + fseek($this->_filePointer, $this->_streamData['pages'][0]['body_offset'], SEEK_SET); + // The first 8 characters should be "OpusHead". + if (fread($this->_filePointer, 8) != 'OpusHead') + throw new OggException("Stream is undecodable due to a malformed header.", OGG_ERROR_UNDECODABLE); + + $this->_header = File_Ogg::_readLittleEndian($this->_filePointer, array( + 'opus_version' => 8, + 'nb_channels' => 8, + 'pre_skip' => 16, + 'audio_sample_rate' => 32, + 'output_gain' => 16, + 'channel_mapping_family'=> 8, + )); + $this->_channels = $this->_header['nb_channels']; + } + + /** + * Get an associative array containing header information about the stream + * @access public + * @return array + */ + function getHeader() { + return $this->_header; + } + + function getSampleRate() + { + //Opus always outputs 48kHz, the header only lists + //the samplerate of the source as reference + return 48000; + } + + /** + * Decode the comments header + * @access private + */ + function _decodeCommentsHeader() + { + $id = 'OpusTags'; + $this->_decodeCommonHeader(false, OGG_OPUS_COMMENTS_PAGE_OFFSET); + if(fread($this->_filePointer, strlen($id)) !== $id) + throw new OggException("Stream is undecodable due to a malformed header.", OGG_ERROR_UNDECODABLE); + $this->_decodeBareCommentsHeader(); + } +} +?> diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Speex.php b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Speex.php new file mode 100644 index 00000000..42f9b0eb --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Speex.php @@ -0,0 +1,122 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------------+ +// | File_Ogg PEAR Package for Accessing Ogg Bitstreams | +// | Copyright (c) 2005-2007 | +// | David Grant <david@grant.org.uk> | +// | Tim Starling <tstarling@wikimedia.org> | +// +----------------------------------------------------------------------------+ +// | This library is free software; you can redistribute it and/or | +// | modify it under the terms of the GNU Lesser General Public | +// | License as published by the Free Software Foundation; either | +// | version 2.1 of the License, or (at your option) any later version. | +// | | +// | This library 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 | +// | Lesser General Public License for more details. | +// | | +// | You should have received a copy of the GNU Lesser General Public | +// | License along with this library; if not, write to the Free Software | +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +// +----------------------------------------------------------------------------+ + + +/** + * @author David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @category File + * @copyright David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @license http://www.gnu.org/copyleft/lesser.html GNU LGPL + * @link http://pear.php.net/package/File_Ogg + * @link http://www.speex.org/docs.html + * @package File_Ogg + * @version CVS: $Id: Speex.php,v 1.10 2005/11/16 20:43:27 djg Exp $ + */ +class File_Ogg_Speex extends File_Ogg_Media +{ + /** + * @access private + */ + function __construct($streamSerial, $streamData, $filePointer) + { + parent::__construct($streamSerial, $streamData, $filePointer); + $this->_decodeHeader(); + $this->_decodeCommentsHeader(); + $endSec = + (( '0x' . substr( $this->_lastGranulePos, 0, 8 ) ) * pow(2, 32) + + ( '0x' . substr( $this->_lastGranulePos, 8, 8 ) )) + / $this->_header['rate']; + + $startSec = + (( '0x' . substr( $this->_firstGranulePos, 0, 8 ) ) * pow(2, 32) + + ( '0x' . substr( $this->_firstGranulePos, 8, 8 ) )) + / $this->_header['rate']; + + //make sure the offset is worth taking into account oggz_chop related hack + if( $startSec > 1){ + $this->_streamLength = $endSec - $startSec; + $this->_startOffset = $startSec; + }else{ + $this->_streamLength = $endSec; + } + } + + /** + * Get a short string describing the type of the stream + * @return string + */ + function getType() + { + return 'Speex'; + } + + /** + * Decode the stream header + * @access private + */ + function _decodeHeader() + { + fseek($this->_filePointer, $this->_streamData['pages'][0]['body_offset'], SEEK_SET); + // The first 8 characters should be "Speex ". + if (fread($this->_filePointer, 8) != 'Speex ') + throw new OggException("Stream is undecodable due to a malformed header.", OGG_ERROR_UNDECODABLE); + + $this->_version = fread($this->_filePointer, 20); + $this->_header = File_Ogg::_readLittleEndian($this->_filePointer, array( + 'speex_version_id' => 32, + 'header_size' => 32, + 'rate' => 32, + 'mode' => 32, + 'mode_bitstream_version'=> 32, + 'nb_channels' => 32, + 'bitrate' => 32, + 'frame_size' => 32, + 'vbr' => 32, + 'frames_per_packet' => 32, + 'extra_headers' => 32, + 'reserved1' => 32, + 'reserved2' => 32 + )); + $this->_header['speex_version'] = $this->_version; + } + + /** + * Get an associative array containing header information about the stream + * @access public + * @return array + */ + function getHeader() { + return $this->_header; + } + + /** + * Decode the comments header + * @access private + */ + function _decodeCommentsHeader() + { + fseek($this->_filePointer, $this->_streamData['pages'][1]['body_offset'], SEEK_SET); + $this->_decodeBareCommentsHeader(); + } +} +?> diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Theora.php b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Theora.php new file mode 100644 index 00000000..b801ea26 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Theora.php @@ -0,0 +1,240 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------------+ +// | File_Ogg PEAR Package for Accessing Ogg Bitstreams | +// | Copyright (c) 2005-2007 | +// | David Grant <david@grant.org.uk> | +// | Tim Starling <tstarling@wikimedia.org> | +// +----------------------------------------------------------------------------+ +// | This library is free software; you can redistribute it and/or | +// | modify it under the terms of the GNU Lesser General Public | +// | License as published by the Free Software Foundation; either | +// | version 2.1 of the License, or (at your option) any later version. | +// | | +// | This library 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 | +// | Lesser General Public License for more details. | +// | | +// | You should have received a copy of the GNU Lesser General Public | +// | License along with this library; if not, write to the Free Software | +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +// +----------------------------------------------------------------------------+ + + +define( 'OGG_THEORA_IDENTIFICATION_HEADER', 0x80 ); +define( 'OGG_THEORA_COMMENTS_HEADER', 0x81 ); +define( 'OGG_THEORA_IDENTIFICATION_PAGE_OFFSET', 0 ); +define( 'OGG_THEORA_COMMENTS_PAGE_OFFSET', 1 ); + + +/** + * @author David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @category File + * @copyright David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @license http://www.gnu.org/copyleft/lesser.html GNU LGPL + * @link http://pear.php.net/package/File_Ogg + * @link http://www.xiph.org/theora/ + * @package File_Ogg + * @version CVS: $Id: Theora.php,v 1.9 2005/11/16 20:43:27 djg Exp $ + */ +class File_Ogg_Theora extends File_Ogg_Media +{ + /** + * @access private + */ + function __construct($streamSerial, $streamData, $filePointer) + { + parent::__construct($streamSerial, $streamData, $filePointer); + $this->_decodeIdentificationHeader(); + $this->_decodeCommentsHeader(); + $endSec = $this->getSecondsFromGranulePos( $this->_lastGranulePos ); + + $startSec = $this->getSecondsFromGranulePos( $this->_firstGranulePos ); + + //make sure the offset is worth taking into account oggz_chop related hack + if( $startSec > 1){ + $this->_streamLength = $endSec - $startSec; + $this->_startOffset = $startSec; + }else{ + $this->_streamLength = $endSec; + } + + $this->_avgBitrate = $this->_streamLength ? ($this->_streamSize * 8) / $this->_streamLength : 0; + } + function getSecondsFromGranulePos($granulePos){ + // Calculate GranulePos seconds + // First make some "numeric strings" + // These might not fit into PHP's integer type, but they will fit into + // the 53-bit mantissa of a double-precision number + $topWord = floatval( base_convert( substr( $granulePos, 0, 8 ), 16, 10 ) ); + $bottomWord = floatval( base_convert( substr( $granulePos, 8, 8 ), 16, 10 ) ); + // Calculate the keyframe position by shifting right by KFGSHIFT + // We don't use PHP's shift operators because they're terribly broken + // This is made slightly simpler by the fact that KFGSHIFT < 32 + $keyFramePos = $topWord / pow(2, $this->_kfgShift - 32) + + floor( $bottomWord / pow(2, $this->_kfgShift) ); + // Calculate the frame offset by masking off the top 64-KFGSHIFT bits + // This requires a bit of floating point trickery + $offset = fmod( $bottomWord, pow(2, $this->_kfgShift) ); + // They didn't teach you that one at school did they? + // Now put it together with the frame rate to calculate time in seconds + return ( $keyFramePos + $offset ) / $this->_frameRate; + } + /** + * Get the 6-byte identification string expected in the common header + */ + function getIdentificationString() + { + return OGG_STREAM_CAPTURE_THEORA; + } + + /** + * Parse the identification header in a Theora stream. + * @access private + */ + function _decodeIdentificationHeader() + { + $this->_decodeCommonHeader(OGG_THEORA_IDENTIFICATION_HEADER, OGG_THEORA_IDENTIFICATION_PAGE_OFFSET); + $h = File_Ogg::_readBigEndian( $this->_filePointer, array( + 'VMAJ' => 8, + 'VMIN' => 8, + 'VREV' => 8, + 'FMBW' => 16, + 'FMBH' => 16, + 'PICW' => 24, + 'PICH' => 24, + 'PICX' => 8, + 'PICY' => 8, + 'FRN' => 32, + 'FRD' => 32, + 'PARN' => 24, + 'PARD' => 24, + 'CS' => 8, + 'NOMBR' => 24, + 'QUAL' => 6, + 'KFGSHIFT' => 5, + 'PF' => 2)); + if ( !$h ) { + throw new OggException("Stream is undecodable due to a truncated header.", OGG_ERROR_UNDECODABLE); + } + + // Theora version + // Seems overly strict but this is what the spec says + // VREV is for backwards-compatible changes, apparently + if ( $h['VMAJ'] != 3 || $h['VMIN'] != 2 ) { + throw new OggException("Stream is undecodable due to an invalid theora version.", OGG_ERROR_UNDECODABLE); + } + $this->_theoraVersion = "{$h['VMAJ']}.{$h['VMIN']}.{$h['VREV']}"; + + // Frame height/width + if ( !$h['FMBW'] || !$h['FMBH'] ) { + throw new OggException("Stream is undecodable because it has frame size of zero.", OGG_ERROR_UNDECODABLE); + } + $this->_frameWidth = $h['FMBW'] * 16; + $this->_frameHeight = $h['FMBH'] * 16; + + // Picture height/width + if ( $h['PICW'] > $this->_frameWidth || $h['PICH'] > $this->_frameHeight ) { + throw new OggException("Stream is undecodable because the picture width is greater than the frame width.", OGG_ERROR_UNDECODABLE); + } + $this->_pictureWidth = $h['PICW']; + $this->_pictureHeight = $h['PICH']; + + // Picture offset + $this->_offsetX = $h['PICX']; + $this->_offsetY = $h['PICY']; + // Frame rate + $this->_frameRate = $h['FRD'] == 0 ? 0 : $h['FRN'] / $h['FRD']; + // Physical aspect ratio + if ( !$h['PARN'] || !$h['PARD'] ) { + $this->_physicalAspectRatio = 1; + } else { + $this->_physicalAspectRatio = $h['PARN'] / $h['PARD']; + } + + // Color space + $colorSpaces = array( + 0 => 'Undefined', + 1 => 'Rec. 470M', + 2 => 'Rec. 470BG', + ); + if ( isset( $colorSpaces[$h['CS']] ) ) { + $this->_colorSpace = $colorSpaces[$h['CS']]; + } else { + $this->_colorSpace = 'Unknown (reserved)'; + } + + $this->_nomBitrate = $h['NOMBR']; + + $this->_quality = $h['QUAL']; + $this->_kfgShift = $h['KFGSHIFT']; + + $pixelFormats = array( + 0 => '4:2:0', + 1 => 'Unknown (reserved)', + 2 => '4:2:2', + 3 => '4:4:4', + ); + $this->_pixelFormat = $pixelFormats[$h['PF']]; + + switch ( $h['PF'] ) { + case 0: + $h['NSBS'] = + floor( ($h['FMBW'] + 1) / 2 ) * + floor( ($h['FMBH'] + 1) / 2 ) + 2 * + floor( ($h['FMBW'] + 3) / 4 ) * + floor( ($h['FMBH'] + 3) / 4 ); + $h['NBS'] = 6 * $h['FMBW'] * $h['FMBH']; + break; + case 2: + $h['NSBS'] = + floor( ($h['FMBW'] + 1) / 2 ) * + floor( ($h['FMBH'] + 1) / 2 ) + 2 * + floor( ($h['FMBW'] + 3) / 4 ) * + floor( ($h['FMBH'] + 1) / 2 ); + $h['NBS'] = 8 * $h['FMBW'] * $h['FMBH']; + break; + case 3: + $h['NSBS'] = + 3 * floor( ($h['FMBW'] + 1) / 2 ) * + floor( ($h['FMBH'] + 1) / 2 ); + $h['NBS'] = 12 * $h['FMBW'] * $h['FMBH']; + break; + default: + $h['NSBS'] = $h['NBS'] = 0; + } + $h['NMBS'] = $h['FMBW'] * $h['FMBH']; + + $this->_idHeader = $h; + } + + /** + * Get an associative array containing header information about the stream + * @access public + * @return array + */ + function getHeader() { + return $this->_idHeader; + } + + /** + * Get a short string describing the type of the stream + * @return string + */ + function getType() { + return 'Theora'; + } + + /** + * Decode the comments header + * @access private + */ + function _decodeCommentsHeader() + { + $this->_decodeCommonHeader(OGG_THEORA_COMMENTS_HEADER, OGG_THEORA_COMMENTS_PAGE_OFFSET); + $this->_decodeBareCommentsHeader(); + } + +} +?> diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Vorbis.php b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Vorbis.php new file mode 100644 index 00000000..06c2c180 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/Ogg/Vorbis.php @@ -0,0 +1,790 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------------+ +// | File_Ogg PEAR Package for Accessing Ogg Bitstreams | +// | Copyright (c) 2005-2007 | +// | David Grant <david@grant.org.uk> | +// | Tim Starling <tstarling@wikimedia.org> | +// +----------------------------------------------------------------------------+ +// | This library is free software; you can redistribute it and/or | +// | modify it under the terms of the GNU Lesser General Public | +// | License as published by the Free Software Foundation; either | +// | version 2.1 of the License, or (at your option) any later version. | +// | | +// | This library 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 | +// | Lesser General Public License for more details. | +// | | +// | You should have received a copy of the GNU Lesser General Public | +// | License along with this library; if not, write to the Free Software | +// | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | +// +----------------------------------------------------------------------------+ + + +/** + * Check number for the first header in a Vorbis stream. + * + * @access private + */ +define("OGG_VORBIS_IDENTIFICATION_HEADER", 1); +/** + * Check number for the second header in a Vorbis stream. + * + * @access private + */ +define("OGG_VORBIS_COMMENTS_HEADER", 3); +/** + * Check number for the third header in a Vorbis stream. + * + * @access private + */ +define("OGG_VORBIS_SETUP_HEADER", 5); +/** + * Error thrown if the stream appears to be corrupted. + * + * @access private + */ +define("OGG_VORBIS_ERROR_UNDECODABLE", OGG_ERROR_UNDECODABLE); +/** + * Error thrown if the user attempts to extract a comment using a comment key + * that does not exist. + * + * @access private + */ +define("OGG_VORBIS_ERROR_INVALID_COMMENT", 2); + +define("OGG_VORBIS_IDENTIFICATION_PAGE_OFFSET", 0); +define("OGG_VORBIS_COMMENTS_PAGE_OFFSET", 1); + +/** + * Error thrown if the user attempts to write a comment containing an illegal + * character + * + * @access private + */ +define("OGG_VORBIS_ERROR_ILLEGAL_COMMENT", 3); + +/** + * Extract the contents of a Vorbis logical stream. + * + * This class provides an interface to a Vorbis logical stream found within + * a Ogg stream. A variety of information may be extracted, including comment + * tags, running time, and bitrate. For more information, please see the following + * links. + * + * @author David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @category File + * @copyright David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org> + * @license http://www.gnu.org/copyleft/lesser.html GNU LGPL + * @link http://pear.php.net/package/File_Ogg + * @link http://www.xiph.org/vorbis/doc/ + * @package File_Ogg + * @version CVS: $Id: Vorbis.php,v 1.13 2005/11/19 09:06:32 djg Exp $ + */ +class File_Ogg_Vorbis extends File_Ogg_Media +{ + + /** + * Version of vorbis specification used. + * + * @access private + * @var int + */ + var $_version; + + /** + * Number of channels in the vorbis stream. + * + * @access private + * @var int + */ + var $_channels; + + /** + * Number of samples per second in the vorbis stream. + * + * @access private + * @var int + */ + var $_sampleRate; + + /** + * Minimum bitrate for the vorbis stream. + * + * @access private + * @var int + */ + var $_minBitrate; + + /** + * Maximum bitrate for the vorbis stream. + * + * @access private + * @var int + */ + var $_maxBitrate; + + /** + * Nominal bitrate for the vorbis stream. + * + * @access private + * @var int + */ + var $_nomBitrate; + + /** + * Average bitrate for the vorbis stream. + * + * @access private + * @var float + */ + var $_avgBitrate; + + /** + * The length of this stream in seconds. + * + * @access private + * @var int + */ + var $_streamLength; + + /** + * the start offset of this stream in seconds + */ + var $_startOffset; + /** + * Constructor for accessing a Vorbis logical stream. + * + * This method is the constructor for the native-PHP interface to a Vorbis logical + * stream, embedded within an Ogg physical stream. + * + * @param int $streamSerial Serial number of the logical stream. + * @param array $streamData Data for the requested logical stream. + * @param string $filePath Location of a file on the filesystem. + * @param pointer $filePointer File pointer for the current physical stream. + * @access private + */ + function __construct($streamSerial, $streamData, $filePointer) + { + parent::__construct($streamSerial, $streamData, $filePointer); + $this->_decodeIdentificationHeader(); + $this->_decodeCommentsHeader(OGG_VORBIS_COMMENTS_HEADER, OGG_VORBIS_COMMENTS_PAGE_OFFSET); + + $endSec = $this->getSecondsFromGranulePos( $this->_lastGranulePos ); + $startSec = $this->getSecondsFromGranulePos( $this->_firstGranulePos ); + + //make sure the offset is worth taking into account oggz_chop related hack + if( $startSec > 1){ + $this->_streamLength = $endSec - $startSec; + $this->_startOffset = $startSec; + }else{ + $this->_streamLength = $endSec; + } + + $this->_avgBitrate = $this->_streamLength ? ($this->_streamSize * 8) / $this->_streamLength : 0; + } + function getSecondsFromGranulePos( $granulePos ){ + return (( '0x' . substr( $granulePos, 0, 8 ) ) * pow(2, 32) + + ( '0x' . substr( $granulePos, 8, 8 ) )) + / $this->_idHeader['audio_sample_rate']; + } + /** + * Get a short string describing the type of the stream + */ + function getType() + { + return 'Vorbis'; + } + + /** + * Parse the identification header (the first of three headers) in a Vorbis stream. + * + * This function parses the identification header. The identification header + * contains simple audio characteristics, such as sample rate and number of + * channels. There are a number of error-checking provisions laid down in the Vorbis + * specification to ensure the stream is pure. + * + * @access private + */ + function _decodeIdentificationHeader() + { + $this->_decodeCommonHeader(OGG_VORBIS_IDENTIFICATION_HEADER, OGG_VORBIS_IDENTIFICATION_PAGE_OFFSET); + + $h = File_Ogg::_readLittleEndian($this->_filePointer, array( + 'vorbis_version' => 32, + 'audio_channels' => 8, + 'audio_sample_rate' => 32, + 'bitrate_maximum' => 32, + 'bitrate_nominal' => 32, + 'bitrate_minimum' => 32, + 'blocksize_0' => 4, + 'blocksize_1' => 4, + 'framing_flag' => 1 + )); + + // The Vorbis stream version must be 0. + if ($h['vorbis_version'] == 0) + $this->_version = $h['vorbis_version']; + else + throw new OggException("Stream is undecodable due to an invalid vorbis stream version.", OGG_VORBIS_ERROR_UNDECODABLE); + + // The number of channels MUST be greater than 0. + if ($h['audio_channels'] == 0) + throw new OggException("Stream is undecodable due to zero channels.", OGG_VORBIS_ERROR_UNDECODABLE); + else + $this->_channels = $h['audio_channels']; + + // The sample rate MUST be greater than 0. + if ($h['audio_sample_rate'] == 0) + throw new OggException("Stream is undecodable due to a zero sample rate.", OGG_VORBIS_ERROR_UNDECODABLE); + else + $this->_sampleRate = $h['audio_sample_rate']; + + // Extract the various bitrates + $this->_maxBitrate = $h['bitrate_maximum']; + $this->_nomBitrate = $h['bitrate_nominal']; + $this->_minBitrate = $h['bitrate_minimum']; + + // Powers of two between 6 and 13 inclusive. + $valid_block_sizes = array(64, 128, 256, 512, 1024, 2048, 4096, 8192); + + // blocksize_0 MUST be a valid blocksize. + $blocksize_0 = pow(2, $h['blocksize_0']); + if (FALSE == in_array($blocksize_0, $valid_block_sizes)) + throw new OggException("Stream is undecodable because blocksize_0 is $blocksize_0, which is not a valid size.", OGG_VORBIS_ERROR_UNDECODABLE); + + // Extract bits 5 to 8 from the character data. + // blocksize_1 MUST be a valid blocksize. + $blocksize_1 = pow(2, $h['blocksize_1']); + if (FALSE == in_array($blocksize_1, $valid_block_sizes)) + throw new OggException("Stream is undecodable because blocksize_1 is not a valid size.", OGG_VORBIS_ERROR_UNDECODABLE); + + // blocksize 0 MUST be less than or equal to blocksize 1. + if ($blocksize_0 > $blocksize_1) + throw new OggException("Stream is undecodable because blocksize_0 is not less than or equal to blocksize_1.", OGG_VORBIS_ERROR_UNDECODABLE); + + // The framing bit MUST be set to mark the end of the identification header. + // Some encoders are broken though -- TS + /* + if ($h['framing_flag'] == 0) + throw new OggException("Stream in undecodable because the framing bit is not non-zero.", OGG_VORBIS_ERROR_UNDECODABLE); + */ + + $this->_idHeader = $h; + } + + /** + * Decode the comments header + * @access private + * @param int $packetType + * @param int $pageOffset + */ + function _decodeCommentsHeader($packetType, $pageOffset) + { + $this->_decodeCommonHeader($packetType, $pageOffset); + $this->_decodeBareCommentsHeader(); + // The framing bit MUST be set to mark the end of the comments header. + $framing_bit = unpack("Cdata", fread($this->_filePointer, 1)); + if ($framing_bit['data'] != 1) + throw new OggException("Stream Undecodable", OGG_VORBIS_ERROR_UNDECODABLE); + } + + /** + * Get the 6-byte identification string expected in the common header + */ + function getIdentificationString() { + return OGG_STREAM_CAPTURE_VORBIS; + } + + /** + * Version of the Vorbis specification referred to in the encoding of this stream. + * + * This method returns the version of the Vorbis specification (currently 0 (ZERO)) + * referred to by the encoder of this stream. The Vorbis specification is well- + * defined, and thus one does not expect this value to change on a frequent basis. + * + * @access public + * @return int + */ + function getEncoderVersion() + { + return ($this->_version); + } + + /** + * Samples per second. + * + * This function returns the number of samples used per second in this + * recording. Probably the most common value here is 44,100. + * + * @return int + * @access public + */ + function getSampleRate() + { + return ($this->_sampleRate); + } + + /** + * Various bitrate measurements + * + * Gives an array of the values of four different types of bitrates for this + * stream. The nominal, maximum and minimum values are found within the file, + * whereas the average value is computed. + * + * @access public + * @return array + */ + function getBitrates() + { + return (array("nom" => $this->_nomBitrate, "max" => $this->_maxBitrate, "min" => $this->_minBitrate, "avg" => $this->_avgBitrate)); + } + + /** + * Gives the most accurate bitrate measurement from this stream. + * + * This function returns the most accurate bitrate measurement for this + * recording, depending on values set in the stream header. + * + * @access public + * @return float + */ + function getBitrate() + { + if ($this->_avgBitrate != 0) + return ($this->_avgBitrate); + elseif ($this->_nomBitrate != 0) + return ($this->_nomBitrate); + else + return (($this->_minBitrate + $this->_maxBitrate) / 2); + } + + /** + * Gives the length (in seconds) of this stream. + * + * @access public + * @return int + */ + function getLength() + { + return ($this->_streamLength); + } + /** + * Get the start offset of the stream in seconds + * @access public + * @return int + */ + function getStartOffset(){ + return ($this->_startOffset); + } + /** + * States whether this logical stream was encoded in mono. + * + * @access public + * @return boolean + */ + function isMono() + { + return ($this->_channels == 1); + } + + /** + * States whether this logical stream was encoded in stereo. + * + * @access public + * @return boolean + */ + function isStereo() + { + return ($this->_channels == 2); + } + + /** + * States whether this logical stream was encoded in quadrophonic sound. + * + * @access public + * @return boolean + */ + function isQuadrophonic() + { + return ($this->_channels == 4); + } + + /** + * The title of this track, e.g. "What's Up Pussycat?". + * + * @access public + * @return string + */ + function getTitle() + { + return ($this->getField("TITLE")); + } + + /** + * Set the title of this track. + * + * @access public + * @param string $title + * @param boolean $replace + */ + function setTitle($title, $replace = true) + { + $this->setField("TITLE", $title, $replace); + } + + /** + * The version of the track, such as a remix. + * + * @access public + * @return string + */ + function getVersion() + { + return $this->getField("VERSION"); + } + + /** + * Set the version of this track. + * + * @access public + * @param string $version + * @param boolean $replace + */ + function setVersion($version, $replace = true) + { + $this->setField("VERSION", $version, $replace); + } + + /** + * The album or collection from which this track comes. + * + * @access public + * @return string + */ + function getAlbum() + { + return ($this->getField("ALBUM")); + } + + /** + * Set the album or collection for this track. + * + * @access public + * @param string $album + * @param boolean $replace + */ + function setAlbum($album, $replace = true) + { + $this->setField("ALBUM", $album, $replace); + } + + /** + * The number of this track if it is part of a larger collection. + * + * @access public + * @return string + */ + function getTrackNumber() + { + return ($this->getField("TRACKNUMBER")); + } + + /** + * Set the number of this relative to the collection. + * + * @access public + * @param int $number + * @param boolean $replace + */ + function setTrackNumber($number, $replace = true) + { + $this->setField("TRACKNUMBER", $number, $replace); + } + + /** + * The artist responsible for this track. + * + * This function returns the name of the artist responsible for this + * recording, which may be either a solo-artist, duet or group. + * + * @access public + * @return string + */ + function getArtist() + { + return ($this->getField("ARTIST")); + } + + /** + * Set the artist of this track. + * + * @access public + * @param string $artist + * @param boolean $replace + */ + function setArtist($artist, $replace = true) + { + $this->setField("ARTIST", $artist, $replace = true); + } + + /** + * The performer of this track, such as an orchestra + * + * @access public + * @return string + */ + function getPerformer() + { + return ($this->getField("PERFORMER")); + } + + /** + * Set the performer of this track. + * + * @access public + * @param string $performer + * @param boolean $replace + */ + function setPerformer($performer, $replace = true) + { + $this->setField("PERFORMER", $performer, $replace); + } + + /** + * The copyright attribution for this track. + * + * @access public + * @return string + */ + function getCopyright() + { + return ($this->getField("COPYRIGHT")); + } + + /** + * Set the copyright attribution for this track. + * + * @access public + * @param string $copyright + * @param boolean $replace + */ + function setCopyright($copyright, $replace = true) + { + $this->setField("COPYRIGHT", $copyright, $replace); + } + + /** + * The rights of distribution for this track. + * + * This funtion returns the license for this track, and may include + * copyright information, or a creative commons statement. + * + * @access public + * @return string + */ + function getLicense() + { + return ($this->getField("LICENSE")); + } + + /** + * Set the distribution rights for this track. + * + * @access public + * @param string $license + * @param boolean $replace + */ + function setLicense($license, $replace = true) + { + $this->setField("LICENSE", $license, $replace); + } + + /** + * The organisation responsible for this track. + * + * This function returns the name of the organisation responsible for + * the production of this track, such as the record label. + * + * @access public + * @return string + */ + function getOrganization() + { + return ($this->getField("ORGANIZATION")); + } + + /** + * Set the organisation responsible for this track. + * + * @access public + * @param string $organization + * @param boolean $replace + */ + function setOrganziation($organization, $replace = true) + { + $this->setField("ORGANIZATION", $organization, $replace); + } + + /** + * A short description of the contents of this track. + * + * This function returns a short description of this track, which might + * contain extra information that doesn't fit anywhere else. + * + * @access public + * @return string + */ + function getDescription() + { + return ($this->getField("DESCRIPTION")); + } + + /** + * Set the description of this track. + * + * @access public + * @param string $description + * @param boolean $replace + */ + function setDescription($description, $replace = true) + { + $this->setField("DESCRIPTION", $replace); + } + + /** + * The genre of this recording (e.g. Rock) + * + * This function returns the genre of this recording. There are no pre- + * defined genres, so this is completely up to the tagging software. + * + * @access public + * @return string + */ + function getGenre() + { + return ($this->getField("GENRE")); + } + + /** + * Set the genre of this track. + * + * @access public + * @param string $genre + * @param boolean $replace + */ + function setGenre($genre, $replace = true) + { + $this->setField("GENRE", $genre, $replace); + } + + /** + * The date of the recording of this track. + * + * This function returns the date on which this recording was made. There + * is no specification for the format of this date. + * + * @access public + * @return string + */ + function getDate() + { + return ($this->getField("DATE")); + } + + /** + * Set the date of recording for this track. + * + * @access public + * @param string $date + * @param boolean $replace + */ + function setDate($date, $replace = true) + { + $this->setField("DATE", $date, $replace); + } + + /** + * Where this recording was made. + * + * This function returns where this recording was made, such as a recording + * studio, or concert venue. + * + * @access public + * @return string + */ + function getLocation() + { + return ($this->getField("LOCATION")); + } + + /** + * Set the location of the recording of this track. + * + * @access public + * @param string $location + * @param boolean $replace + */ + function setLocation($location, $replace = true) + { + $this->setField("LOCATION", $location, $replace); + } + + /** + * @access public + * @return string + */ + function getContact() + { + return ($this->getField("CONTACT")); + } + + /** + * Set the contact information for this track. + * + * @access public + * @param string $contact + * @param boolean $replace + */ + function setContact($contact, $replace = true) + { + $this->setField("CONTACT", $contact, $replace); + } + + /** + * International Standard Recording Code. + * + * Returns the International Standard Recording Code. This code can be + * validated using the Validate_ISPN package. + * + * @access public + * @return string + */ + function getIsrc() + { + return ($this->getField("ISRC")); + } + + /** + * Set the ISRC for this track. + * + * @access public + * @param string $isrc + * @param boolean $replace + */ + function setIsrc($isrc, $replace = true) + { + $this->setField("ISRC", $isrc, $replace); + } + + /** + * Get an associative array containing header information about the stream + * @access public + * @return array + */ + function getHeader() { + return $this->_idHeader; + } +} +?> diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/README b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/README new file mode 100644 index 00000000..963ca07c --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/File_Ogg/File/README @@ -0,0 +1,2 @@ +This was originally a fork of the File_Ogg package in PEAR. + diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/OggException.php b/extensions/TimedMediaHandler/handlers/OggHandler/OggException.php new file mode 100644 index 00000000..a09d36da --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/OggException.php @@ -0,0 +1,4 @@ +<?php + +class OggException extends Exception { +} diff --git a/extensions/TimedMediaHandler/handlers/OggHandler/OggHandler.php b/extensions/TimedMediaHandler/handlers/OggHandler/OggHandler.php new file mode 100644 index 00000000..83e1a0e7 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/OggHandler/OggHandler.php @@ -0,0 +1,379 @@ +<?php +/** + * ogg handler + */ +class OggHandlerTMH extends TimedMediaHandler { + const METADATA_VERSION = 2; + + /** + * @param $image File + * @param $path string + * @return string + */ + function getMetadata( $image, $path ) { + $metadata = array( 'version' => self::METADATA_VERSION ); + + try { + $f = new File_Ogg( $path ); + $streams = array(); + foreach ( $f->listStreams() as $streamIDs ) { + foreach ( $streamIDs as $streamID ) { + $stream = $f->getStream( $streamID ); + $streams[$streamID] = array( + 'serial' => $stream->getSerial(), + 'group' => $stream->getGroup(), + 'type' => $stream->getType(), + 'vendor' => $stream->getVendor(), + 'length' => $stream->getLength(), + 'size' => $stream->getSize(), + 'header' => $stream->getHeader(), + 'comments' => $stream->getComments() + ); + } + } + $metadata['streams'] = $streams; + $metadata['length'] = $f->getLength(); + // Get the offset of the file (in cases where the file is a segment copy) + $metadata['offset'] = $f->getStartOffset(); + } catch ( OggException $e ) { + // File not found, invalid stream, etc. + $metadata['error'] = array( + 'message' => $e->getMessage(), + 'code' => $e->getCode() + ); + } + return serialize( $metadata ); + } + + /** + * Display metadata box on file description page. + * + * This is pretty basic, it puts data from all the streams together, + * and only outputs a couple of the most commonly used ogg "comments", + * with comments from all the streams combined + * + * @param File $file + * @param bool|IContextSource $context Context to use (optional) + * @return array|bool + */ + public function formatMetadata( $file, $context = false ) { + $meta = $this->getCommonMetaArray( $file ); + if ( count( $meta ) === 0 ) { + return false; + } + return $this->formatMetadataHelper( $meta, $context ); + } + + /** + * Get some basic metadata properties that are common across file types. + * + * @param File $file + * @return array Array of metadata. See MW's FormatMetadata class for format. + */ + public function getCommonMetaArray( File $file ) { + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) || !isset( $metadata['streams'] ) ) { + return array(); + } + + // See http://www.xiph.org/vorbis/doc/v-comment.html + // http://age.hobba.nl/audio/mirroredpages/ogg-tagging.html + $metadataMap = array( + 'title' => 'ObjectName', + 'artist' => 'Artist', + 'performer' => 'Artist', + 'description' => 'ImageDescription', + 'license' => 'UsageTerms', + 'copyright' => 'Copyright', + 'organization' => 'dc-publisher', + 'date' => 'DateTimeDigitized', + 'location' => 'LocationDest', + 'contact' => 'Contact', + 'encoded_using' => 'Software', + 'encoder' => 'Software', + // OpenSubtitles.org hash. Identifies source video. + 'source_ohash' => 'OriginalDocumentID', + 'comment' => 'UserComment', + 'language' => 'LanguageCode', + ); + + $props = array(); + + foreach( $metadata['streams'] as $stream ) { + if ( isset( $stream['vendor'] ) ) { + if ( !isset( $props['Software'] ) ) { + $props['Software'] = array(); + } + $props['Software'][] = trim( $stream['vendor'] ); + } + if ( !isset( $stream['comments'] ) ) { + continue; + } + foreach( $stream['comments'] as $name => $rawValue ) { + // $value will be an array if the file has + // a multiple tags with the same name. Otherwise it + // is a string. + foreach( (array) $rawValue as $value ) { + $trimmedValue = trim( $value ); + if ( $trimmedValue === '' ) { + continue; + } + $lowerName = strtolower( $name ); + if ( isset( $metadataMap[$lowerName] ) ) { + $convertedName = $metadataMap[$lowerName]; + if ( !isset( $props[$convertedName] ) ) { + $props[$convertedName] = array(); + } + $props[$convertedName][] = $trimmedValue; + } + } + } + + } + // properties might be duplicated across streams + foreach( $props as &$type ) { + $type = array_unique( $type ); + $type = array_values( $type ); + } + + return $props; + } + + /** + * Get the "media size" + * + * @param $file File + * @param $path string + * @param $metadata bool + * @return array|bool + */ + function getImageSize( $file, $path, $metadata = false ) { + global $wgMediaVideoTypes; + // Just return the size of the first video stream + if ( $metadata === false ) { + $metadata = $file->getMetadata(); + } + $metadata = $this->unpackMetadata( $metadata ); + if ( isset( $metadata['error'] ) || !isset( $metadata['streams'] ) ) { + return false; + } + foreach ( $metadata['streams'] as $stream ) { + if ( in_array( $stream['type'], $wgMediaVideoTypes ) ) { + $pictureWidth = $stream['header']['PICW']; + $parNumerator = $stream['header']['PARN']; + $parDenominator = $stream['header']['PARD']; + if( $parNumerator && $parDenominator ) { + // Compensate for non-square pixel aspect ratios + $pictureWidth = $pictureWidth * $parNumerator / $parDenominator; + } + return array( + intval( $pictureWidth ), + intval( $stream['header']['PICH'] ) + ); + } + } + return array( false, false ); + } + + /** + * @param $metadata + * @return bool|mixed + */ + function unpackMetadata( $metadata ) { + wfSuppressWarnings(); + $unser = unserialize( $metadata ); + wfRestoreWarnings(); + if ( isset( $unser['version'] ) && $unser['version'] == self::METADATA_VERSION ) { + return $unser; + } else { + return false; + } + } + + /** + * @param $image + * @return string + */ + function getMetadataType( $image ) { + return 'ogg'; + } + /** + * @param $file File + */ + function getWebType( $file ) { + $baseType = ( $file->getWidth() == 0 && $file->getHeight() == 0 )? 'audio' : 'video'; + $baseType .= '/ogg'; + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return $baseType; + } + $codecs = strtolower( implode( ", ", $streamTypes ) ); + return $baseType . '; codecs="' . $codecs . '"'; + } + /** + * @param $file File + * @return array|bool + */ + function getStreamTypes( $file ) { + $streamTypes = array(); + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) ) { + return false; + } + foreach ( $metadata['streams'] as $stream ) { + $streamTypes[] = $stream['type']; + } + return array_unique( $streamTypes ); + } + + /** + * @param $file File + * @return int + */ + function getOffset( $file ){ + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) || !isset( $metadata['offset']) ) { + return 0; + } else { + return $metadata['offset']; + } + } + + /** + * @param $file File + * @return int + */ + function getLength( $file ) { + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) ) { + return 0; + } else { + return $metadata['length']; + } + } + + /** + * Get useful response headers for GET/HEAD requests for a file with the given metadata + * @param $metadata mixed Result this handlers getMetadata() for a file + * @return Array + */ + public function getStreamHeaders( $metadata ) { + $metadata = $this->unpackMetadata( $metadata ); + if ( $metadata && !isset( $metadata['error'] ) && isset( $metadata['length'] ) ) { + return array( 'X-Content-Duration' => floatval( $metadata[ 'length' ] ) ); + } + return array(); + } + + /** + * @param $file File + * @return float|int + */ + function getFramerate( $file ){ + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) ) { + return 0; + } else { + // Return the first found theora stream framerate: + foreach ( $metadata['streams'] as $stream ) { + if( $stream['type'] == 'Theora' ){ + return $stream['header']['FRN'] / $stream['header']['FRD']; + } + } + return 0; + } + } + + /** + * @param $file File + * @return String + */ + function getShortDesc( $file ) { + global $wgLang, $wgMediaAudioTypes, $wgMediaVideoTypes; + + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getShortDesc( $file ); + } + if ( array_intersect( $streamTypes, $wgMediaVideoTypes ) ) { + // Count multiplexed audio/video as video for short descriptions + $msg = 'timedmedia-ogg-short-video'; + } elseif ( array_intersect( $streamTypes, $wgMediaAudioTypes ) ) { + $msg = 'timedmedia-ogg-short-audio'; + } else { + $msg = 'timedmedia-ogg-short-general'; + } + return wfMessage( $msg, implode( '/', $streamTypes ), + $wgLang->formatTimePeriod( $this->getLength( $file ) ) )->text(); + } + + /** + * @param $file File + * @return String + */ + function getLongDesc( $file ) { + global $wgLang, $wgMediaVideoTypes, $wgMediaAudioTypes; + + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + $unpacked = $this->unpackMetadata( $file->getMetadata() ); + if ( isset( $unpacked['error']['message'] ) ) { + return wfMessage( 'timedmedia-ogg-long-error', $unpacked['error']['message'] )->text(); + } else { + return wfMessage( 'timedmedia-ogg-long-no-streams' )->text(); + } + } + if ( array_intersect( $streamTypes,$wgMediaVideoTypes ) ) { + if ( array_intersect( $streamTypes, $wgMediaAudioTypes ) ) { + $msg = 'timedmedia-ogg-long-multiplexed'; + } else { + $msg = 'timedmedia-ogg-long-video'; + } + } elseif ( array_intersect( $streamTypes, $wgMediaAudioTypes ) ) { + $msg = 'timedmedia-ogg-long-audio'; + } else { + $msg = 'timedmedia-ogg-long-general'; + } + $size = 0; + $unpacked = $this->unpackMetadata( $file->getMetadata() ); + if ( !$unpacked || isset( $metadata['error'] ) ) { + $length = 0; + } else { + $length = $this->getLength( $file ); + foreach ( $unpacked['streams'] as $stream ) { + if( isset( $stream['size'] ) ) + $size += $stream['size']; + } + } + return wfMessage( + $msg, + implode( '/', $streamTypes ), + $wgLang->formatTimePeriod( $length ), + $wgLang->formatBitrate( $this->getBitRate( $file ) ) + )->numParams( + $file->getWidth(), + $file->getHeight() + )->text(); + } + + /** + * @param $file File + * @return float|int + */ + function getBitRate( &$file ){ + $size = 0; + $unpacked = $this->unpackMetadata( $file->getMetadata() ); + if ( !$unpacked || isset( $unpacked['error'] ) ) { + $length = 0; + } else { + $length = $this->getLength( $file ); + if ( isset( $unpacked['streams'] ) ) { + foreach ( $unpacked['streams'] as $stream ) { + if( isset( $stream['size'] ) ) + $size += $stream['size']; + } + } + } + return $length == 0 ? 0 : $size / $length * 8; + } +} diff --git a/extensions/TimedMediaHandler/handlers/TextHandler/TextHandler.php b/extensions/TimedMediaHandler/handlers/TextHandler/TextHandler.php new file mode 100644 index 00000000..3c229d5f --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/TextHandler/TextHandler.php @@ -0,0 +1,305 @@ +<?php +/** + * Timed Text handling for mediaWiki + * + * Timed text support is presently fairly limited. Unlike Ogg and WebM handlers, + * timed text does not extend the TimedMediaHandler class. + * + * TODO On "new" timedtext language save purge all pages where file exists + */ + + +/** + * Subclass ApiMain but query other db + */ +class ForeignApiQueryAllPages extends ApiQueryAllPages { + public function __construct( $mDb, $query, $moduleName ) { + global $wgTimedTextForeignNamespaces; + + $this->foreignDb = $mDb; + + $wikiID = $this->foreignDb->getWikiID(); + if ( isset( $wgTimedTextForeignNamespaces[ $wikiID ] ) ) { + $this->foreignNs = $wgTimedTextForeignNamespaces[ $wikiID ]; + } else { + $this->foreignNs = NS_TIMEDTEXT; + } + parent::__construct( $query, $moduleName, 'ap' ); + } + + protected function getDB() { + return $this->foreignDb; + } + + protected function parseMultiValue( $valueName, $value, $allowMultiple, $allowedValues ) { + // foreignnNs might not be defined localy, + // catch the undefined error here + if ( $valueName == 'apnamespace' + && $value == $this->foreignNs + && $allowMultiple == false + ) { + return $this->foreignNs; + } + return parent::parseMultiValue( $valueName, $value, $allowMultiple, $allowedValues ); + } + + /** + * An alternative to titleToKey() that doesn't trim trailing spaces + * + * + * @FIXME: I'M A BIG HACK + * + * @param string $titlePart Title part with spaces + * @return string Title part with underscores + */ + public function titlePartToKey( $titlePart, $defaultNamespace = NS_MAIN ) { + return substr( $this->titleToKey( $titlePart . 'x' ), 0, -1 ); + } +} + +class TextHandler { + var $remoteNs = null;//lazy init remote Namespace number + + /** + * @var File + */ + protected $file; + + function __construct( $file ){ + $this->file = $file; + } + + /** + * Get the timed text tracks elements as an associative array + * @return array|mixed + */ + function getTracks(){ + if( $this->file->isLocal() ){ + return $this->getLocalTextSources(); + } elseif ( $this->file->getRepo() instanceof ForeignDBViaLBRepo ){ + return $this->getForeignDBTextSources(); + } else { + return $this->getRemoteTextSources(); + } + } + + /** + * @return bool|int|null + */ + function getTimedTextNamespace(){ + global $wgEnableLocalTimedText; + if( $this->file->isLocal() ) { + if ( $wgEnableLocalTimedText ) { + return NS_TIMEDTEXT; + } else { + return false; + } + } elseif( $this->file->repo instanceof ForeignDBViaLBRepo ){ + global $wgTimedTextForeignNamespaces; + $wikiID = $this->file->getRepo()->getSlaveDB()->getWikiID(); + if ( isset( $wgTimedTextForeignNamespaces[ $wikiID ] ) ) { + return $wgTimedTextForeignNamespaces[ $wikiID ]; + } + // failed to get namespace via ForeignDBViaLBRepo, return NS_TIMEDTEXT + return NS_TIMEDTEXT; + } else { + if( $this->remoteNs !== null ){ + return $this->remoteNs; + } + // Get the namespace data from the image api repo: + // fetchImageQuery query caches results + $data = $this->file->getRepo()->fetchImageQuery( array( + 'meta' =>'siteinfo', + 'siprop' => 'namespaces' + )); + + if( isset( $data['query'] ) && isset( $data['query']['namespaces'] ) ){ + // get the ~last~ timed text namespace defined + foreach( $data['query']['namespaces'] as $ns ){ + if( $ns['*'] == 'TimedText' ){ + $this->remoteNs = $ns['id']; + } + } + } + // Return the remote Ns + return $this->remoteNs; + } + } + + /** + * @return array|bool + */ + function getTextPagesQuery(){ + $ns = $this->getTimedTextNamespace(); + if( $ns === false ){ + wfDebug("Repo: " . $this->file->repo->getName() . " does not have a TimedText namesapce \n"); + // No timed text namespace, don't try to look up timed text tracks + return false; + } + return array( + 'action' => 'query', + 'list' => 'allpages', + 'apnamespace' => $ns, + 'aplimit' => 300, + 'apprefix' => $this->file->getTitle()->getDBkey() + ); + } + + /** + * @return array|mixed + */ + function getRemoteTextSources(){ + global $wgMemc; + // Use descriptionCacheExpiry as our expire for timed text tracks info + if ( $this->file->getRepo()->descriptionCacheExpiry > 0 ) { + wfDebug("Attempting to get text tracks from cache..."); + $key = $this->file->getRepo()->getLocalCacheKey( 'RemoteTextTracks', 'url', $this->file->getName() ); + $obj = $wgMemc->get($key); + if ($obj) { + wfDebug("success!\n"); + return $obj; + } + wfDebug("miss\n"); + } + wfDebug("Get text tracks from remote api \n"); + $query = $this->getTextPagesQuery(); + + // Error in getting timed text namespace return empty array; + if( $query === false ){ + return array(); + } + $data = $this->file->getRepo()->fetchImageQuery( $query ); + $textTracks = $this->getTextTracksFromData( $data ); + if ( $data && $this->file->repo->descriptionCacheExpiry > 0 ) { + $wgMemc->set( $key, $textTracks, $this->file->repo->descriptionCacheExpiry ); + } + return $textTracks; + } + + /** + * @return array + */ + function getLocalTextSources(){ + global $wgEnableLocalTimedText; + if ( $wgEnableLocalTimedText ) { + // Init $this->textTracks + $params = new FauxRequest( $this->getTextPagesQuery() ); + $api = new ApiMain( $params ); + $api->execute(); + if ( defined( 'ApiResult::META_CONTENT' ) ) { + $data = $api->getResult()->getResultData( null, array( 'Strip' => 'all' ) ); + } else { + $data = $api->getResultData(); + } + wfDebug(print_r($data, true)); + // Get the list of language Names + return $this->getTextTracksFromData( $data ); + } else { + return array(); + } + } + + /** + * @return array|mixed + */ + function getForeignDBTextSources(){ + // Init $this->textTracks + $params = new FauxRequest( $this->getTextPagesQuery() ); + $api = new ApiMain( $params ); + $api->profileIn(); + $query = new ApiQuery( $api, 'foo', 'bar' ); + $query->profileIn(); + $module = new ForeignApiQueryAllPages( $this->file->getRepo()->getSlaveDB(), $query, 'allpages' ); + $module->profileIn(); + $module->execute(); + $module->profileOut(); + $query->profileOut(); + $api->profileOut(); + + if ( defined( 'ApiResult::META_CONTENT' ) ) { + $data = $module->getResult()->getResultData( null, array( 'Strip' => 'all' ) ); + } else { + $data = $module->getResultData(); + } + // Get the list of language Names + return $this->getTextTracksFromData( $data ); + } + + /** + * @param $data + * @return array + */ + function getTextTracksFromData( $data ){ + $textTracks = array(); + $providerName = $this->file->repo->getName(); + // commons is called shared in production. normalize it to wikimediacommons + if( $providerName == 'shared' ){ + $providerName = 'wikimediacommons'; + } + // Provider name should be the same as the interwiki map + // @@todo more testing with this: + + $langNames = Language::fetchLanguageNames( null, 'mw' ); + if( $data['query'] && $data['query']['allpages'] ){ + foreach( $data['query']['allpages'] as $page ){ + $subTitle = Title::newFromText( $page['title'] ) ; + $tileParts = explode( '.', $page['title'] ); + if( count( $tileParts) >= 3 ){ + $timedTextExtension = array_pop( $tileParts ); + $languageKey = array_pop( $tileParts ); + $contentType = $this->getContentType( $timedTextExtension ); + } else { + continue; + } + // If there is no valid language continue: + if( !isset( $langNames[ $languageKey ] ) ){ + continue; + } + $namespacePrefix = "TimedText:"; + $textTracks[] = array( + 'kind' => 'subtitles', + 'data-mwtitle' => $namespacePrefix . $subTitle->getDBkey(), + 'data-mwprovider' => $providerName, + 'type' => $contentType, + // @todo Should eventually add special entry point and output proper WebVTT format: + // http://www.whatwg.org/specs/web-apps/current-work/webvtt.html + 'src' => $this->getFullURL( $page['title'], $contentType ), + 'srclang' => $languageKey, + 'data-dir' => Language::factory( $languageKey )->getDir(), + 'label' => wfMessage('timedmedia-subtitle-language', + $langNames[ $languageKey ], + $languageKey )->text() + ); + } + } + return $textTracks; + } + + function getContentType( $timedTextExtension ) { + if ( $timedTextExtension === 'srt' ) { + return 'text/x-srt'; + } else if ( $timedTextExtension === 'vtt' ) { + return 'text/vtt'; + } + return ''; + } + + function getFullURL( $pageTitle, $contentType ){ + if( $this->file->isLocal() ) { + $subTitle = Title::newFromText( $pageTitle ) ; + return $subTitle->getFullURL( array( + 'action' => 'raw', + 'ctype' => $contentType + )); + //} elseif( $this->file->repo instanceof ForeignDBViaLBRepo ){ + } else { + $query = 'title=' . wfUrlencode( $pageTitle ) . '&'; + $query .= wfArrayToCgi( array( + 'action' => 'raw', + 'ctype' => $contentType + ) ); + // Note: This will return false if scriptDirUrl is not set for repo. + return $this->file->repo->makeUrl( $query ); + } + } +} diff --git a/extensions/TimedMediaHandler/handlers/WAVHandler/WAVHandler.php b/extensions/TimedMediaHandler/handlers/WAVHandler/WAVHandler.php new file mode 100644 index 00000000..9fae12b8 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/WAVHandler/WAVHandler.php @@ -0,0 +1,87 @@ +<?php +/** + * WAV handler + */ +class WAVHandler extends ID3Handler { + + /** + * @param $file File + * @return string + */ + function getMetadataType( $file ) { + return 'wav'; + } + + /** + * @param $file File + * @return String + */ + function getWebType( $file ) { + return 'audio/wav'; + } + + function verifyUpload( $filename ) { + $metadata = $this->getID3( $filename ); + + if( + isset( $metadata['audio'] ) + && $metadata['audio']['dataformat'] == 'wav' + && ( $metadata['audio']['codec'] == 'Pulse Code Modulation (PCM)' || $metadata['audio']['codec'] == 'IEEE Float' ) + ){ + return Status::newGood(); + } + + return Status::newFatal( 'timedmedia-wav-pcm-required' ); + } + /** + * @param $file File + * @return array|bool + */ + function getStreamTypes( $file ) { + $streamTypes = array(); + $metadata = $this->unpackMetadata( $file->getMetadata() ); + + if ( !$metadata || isset( $metadata['error'] ) ) { + return false; + } + + if( isset( $metadata['audio'] ) && $metadata['audio']['dataformat'] == 'wav' ){ + $streamTypes[] = 'WAV'; + } + + return $streamTypes; + } + + /** + * @param $file File + * @return String + */ + function getShortDesc( $file ) { + global $wgLang; + + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getShortDesc( $file ); + } + return wfMessage( 'timedmedia-wav-short-audio', + $wgLang->formatTimePeriod( $this->getLength( $file ) ) )->text(); + } + + /** + * @param $file File + * @return String + */ + function getLongDesc( $file ) { + global $wgLang; + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getLongDesc( $file ); + } + return wfMessage('timedmedia-wav-long-audio', + $wgLang->formatTimePeriod( $this->getLength($file) ), + $wgLang->formatBitrate( $this->getBitRate( $file ) ) + )->text(); + + } + +} diff --git a/extensions/TimedMediaHandler/handlers/WebMHandler/WebMHandler.php b/extensions/TimedMediaHandler/handlers/WebMHandler/WebMHandler.php new file mode 100644 index 00000000..ebdad0d1 --- /dev/null +++ b/extensions/TimedMediaHandler/handlers/WebMHandler/WebMHandler.php @@ -0,0 +1,175 @@ +<?php +/** + * WebM handler + */ +class WebMHandler extends ID3Handler { + + /** + * @param $path string + * @return array + */ + protected function getID3( $path ) { + $id3 = parent::getID3( $path ); + // Unset some parts of id3 that are too detailed and matroska specific: + unset( $id3['matroska'] ); + return $id3; + } + + /** + * Get the "media size" + * @param $file File + * @param $path string + * @param $metadata bool + * @return array|bool + */ + function getImageSize( $file, $path, $metadata = false ) { + // Just return the size of the first video stream + if ( $metadata === false ) { + $metadata = $file->getMetadata(); + } + $metadata = $this->unpackMetadata( $metadata ); + if ( isset( $metadata['error'] ) ) { + return false; + } + + $size = array( false, false ); + // display_x/display_y is only set if DisplayUnit + // is pixels, otherwise display_aspect_ratio is set + if ( isset( $metadata['video']['display_x'] ) + && + isset( $metadata['video']['display_y'] ) + ){ + $size = array ( + $metadata['video']['display_x'], + $metadata['video']['display_y'] + ); + } + elseif ( isset( $metadata['video']['resolution_x'] ) + && + isset( $metadata['video']['resolution_y'] ) + ){ + $size = array ( + $metadata['video']['resolution_x'], + $metadata['video']['resolution_y'] + ); + if ( isset($metadata['video']['crop_top']) ) { + $size[1] -= $metadata['video']['crop_top']; + } + if ( isset($metadata['video']['crop_bottom']) ) { + $size[1] -= $metadata['video']['crop_bottom']; + } + if ( isset($metadata['video']['crop_left']) ) { + $size[0] -= $metadata['video']['crop_left']; + } + if ( isset($metadata['video']['crop_right']) ) { + $size[0] -= $metadata['video']['crop_right']; + } + } + if ( $size[0] && $size[1] && isset( $metadata['video']['display_aspect_ratio'] ) ) { + //for wide images (i.e. 16:9) take native height as base + if ( $metadata['video']['display_aspect_ratio'] >= 1 ) { + $size[0] = intval( $size[1] * $metadata['video']['display_aspect_ratio'] ); + } else { //for tall images (i.e. 9:16) take width as base + $size[1] = intval( $size[0] / $metadata['video']['display_aspect_ratio'] ); + } + } + return $size; + } + + /** + * @param $file + * @return string + */ + function getMetadataType( $file ) { + return 'webm'; + } + + /** + * @param $file File + * @return String + */ + function getWebType( $file ) { + $baseType = ( $file->getWidth() == 0 && $file->getHeight() == 0 )? 'audio' : 'video'; + + $streams = $this->getStreamTypes( $file ); + if ( !$streams ) { + return $baseType . '/webm'; + } + + $codecs = strtolower( implode( ', ', $streams ) ); + + return $baseType . '/webm; codecs="' . $codecs . '"'; + } + + /** + * @param $file File + * @return array|bool + */ + function getStreamTypes( $file ) { + $streamTypes = array(); + $metadata = $this->unpackMetadata( $file->getMetadata() ); + if ( !$metadata || isset( $metadata['error'] ) ) { + return false; + } + // id3 gives 'V_VP8' for what we call VP8 + if( isset( $metadata['video'] ) && $metadata['video']['dataformat'] == 'vp8' ){ + $streamTypes[] = 'VP8'; + } elseif( isset( $metadata['video'] ) && + ( $metadata['video']['dataformat'] === 'vp9' + || $metadata['video']['dataformat'] === 'V_VP9' + ) ) { + // Currently getID3 calls it V_VP9. That will probably change to vp9 + // once getID3 actually gets support for the codec. + $streamTypes[] = 'VP9'; + } + if( isset( $metadata['audio'] ) && $metadata['audio']['dataformat'] == 'vorbis' ){ + $streamTypes[] = 'Vorbis'; + } elseif ( isset( $metadata['audio'] ) && + ( $metadata['audio']['dataformat'] == 'opus' + || $metadata['audio']['dataformat'] == 'A_OPUS' + ) ) { + // Currently getID3 calls it A_OPUS. That will probably change to 'opus' + // once getID3 actually gets support for the codec. + $streamTypes[] = 'Opus'; + } + + return $streamTypes; + } + + /** + * @param $file File + * @return String + */ + function getShortDesc( $file ) { + global $wgLang; + + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getShortDesc( $file ); + } + return wfMessage( 'timedmedia-webm-short-video', implode( '/', $streamTypes ), + $wgLang->formatTimePeriod( $this->getLength( $file ) ) )->text(); + } + + /** + * @param $file File + * @return String + */ + function getLongDesc( $file ) { + global $wgLang; + $streamTypes = $this->getStreamTypes( $file ); + if ( !$streamTypes ) { + return parent::getLongDesc( $file ); + } + return wfMessage('timedmedia-webm-long-video', + implode( '/', $streamTypes ), + $wgLang->formatTimePeriod( $this->getLength($file) ), + $wgLang->formatBitrate( $this->getBitRate( $file ) ) + )->numParams( + $file->getWidth(), + $file->getHeight() + )->text(); + + } + +} diff --git a/extensions/TimedMediaHandler/i18n/ady-cyrl.json b/extensions/TimedMediaHandler/i18n/ady-cyrl.json new file mode 100644 index 00000000..a76e7faa --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ady-cyrl.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "GR44 Luc", + "TheRossatron" + ] + }, + "timedmedia-no-player-js": "ŠŃŃŃŃŃŠ³ŃŃŠ³ŃŃ, Šµ ŃŠø Š±ŃŠ¾ŃŠ·ŠµŃŃŠ¼ Šø JavaScript Š³ŃŃŠŗIŠ¾ŃŠ°Š³ŃŃ, Šµ Š³ŃŃŠ»ŃŃŠ³ŃŃŠ°Š»ŃŃ ŃŃŃŃŠ· ŃŠµŃŃŠæ.<br />\n<a href=\"$1\">ŠŠ»ŠøŠæŃŃ ŠŗŃŠøŠæŃŃŠ½</a> Šµ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š³ŃŃŠ»ŃŃŠ³ŃŃŠ°Š»ŃŃ ŃŠµŠ±Š³ŃŃŃŃŠ¾Š½</a> ŠæŠ»ŃŃŠŗIŃŃŃ, ŃŠø Š±ŃŠ¾ŃŠ·ŠµŃŃŠ¼ ŃŃŠµŠæŠ»ŃŃŠ½ŃŃ.", + "timedmedia-source-file": "ŠŃŠ°ŠæŃŃŃ $1", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š» $1-ŃŠ°Š¹Š»ŃŃ ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/aeb-latn.json b/extensions/TimedMediaHandler/i18n/aeb-latn.json new file mode 100644 index 00000000..65d57191 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/aeb-latn.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Csisc" + ] + }, + "timedmedia-source-file": "$1 is-sÅ«rs", + "timedmedia-source-audio-file-desc": "FicyÄy $1 aÅlÄ« ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/af.json b/extensions/TimedMediaHandler/i18n/af.json new file mode 100644 index 00000000..7708e9ae --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/af.json @@ -0,0 +1,25 @@ +{ + "@metadata": { + "authors": [ + "Naudefj", + "SPQRobin", + "Arnobarnard" + ] + }, + "timedmedia-desc": "Hanteer Ogg Theora- en Vorbis-lĆŖers met 'n JavaScript-mediaspeler", + "timedmedia-ogg-short-audio": "Ogg $1 klanklĆŖer, $2", + "timedmedia-ogg-short-video": "Ogg $1 video lĆŖer, $2", + "timedmedia-ogg-short-general": "Ogg $1 medialĆŖer, $2", + "timedmedia-ogg-long-audio": "Ogg $1 klanklĆŖer, lengte $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videolĆŖer, lengte $2, $4Ć$5 pixels, $3", + "timedmedia-ogg-long-general": "Ogg medialĆŖer, lengte $2, $3", + "timedmedia-ogg-long-error": "Ongeldige Ogg-lĆŖer: $1", + "timedmedia-no-player-js": "Jammer, u blaaier het of JavaScript gedeaktiveer of het nie enige ondersteunde speler nie.<br />\nU kan <a href=\"$1\">die knipsel aflaai</a> of <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">'n speler aflaai</a> om die knipsel te speel in u blaaier.", + "timedmedia-more": "Meerā¦", + "timedmedia-dismiss": "Sluit", + "timedmedia-download": "Laai lĆŖer af", + "timedmedia-desc-link": "Aangaande die lĆŖer", + "timedmedia-minutes": "{{PLURAL:$1|$1 minuut|$1 minute}}", + "timedmedia-source-file": "Bron van $1", + "timedmedia-source-audio-file-desc": "Oorspronklike $1-lĆŖer ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/akz.json b/extensions/TimedMediaHandler/i18n/akz.json new file mode 100644 index 00000000..641c0b9f --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/akz.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Ulohnanne" + ] + }, + "timedmedia-more": "MaatĆ asasi..." +} diff --git a/extensions/TimedMediaHandler/i18n/aln.json b/extensions/TimedMediaHandler/i18n/aln.json new file mode 100644 index 00000000..67645c86 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/aln.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Mdupont" + ] + }, + "timedmedia-desc": "MbajtĆ«s pĆ«r mediat nĆ« kohĆ«n e duhur (video, audio, timedText) me transcoding tĆ« ZQM Theora / Vorbis", + "timedmedia-ogg-short-audio": "Ogg tingull $1 fotografi, $2", + "timedmedia-ogg-short-video": "video file Ogg $1, $2", + "timedmedia-ogg-short-general": "Ogg $1 media file, $2", + "timedmedia-ogg-long-audio": "ZQM file $1 shĆ«ndoshĆ«, gjatĆ« $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 video file, gjatĆ« $2, $4 Ć $5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "ZQM multiplexed audio / video file, $1, gjatĆ« $2, $4 Ć $5 pixels, $3 e pĆ«rgjithshme", + "timedmedia-ogg-long-general": "Ogg media file, gjatĆ« $2, $3", + "timedmedia-ogg-long-error": "E pavlefshme Ogg file: $1", + "timedmedia-no-player-js": "Na vjen keq, browser-i juaj ose ka JavaScript paaftĆ« ose nuk ka asnjĆ« lojtar tĆ« mbĆ«shtetur. <br /> Ju mund tĆ« <a href=\"$1\">shkarkoni clip</a> ose <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">shkarkoni njĆ« lojtar</a> pĆ«r tĆ« luajtur clip nĆ« shfletuesin tuaj.", + "timedmedia-more": "MĆ« shumĆ« ...", + "timedmedia-dismiss": "AfĆ«r", + "timedmedia-download": "Shkarko file", + "timedmedia-desc-link": "PĆ«r kĆ«tĆ« fotografi", + "timedmedia-oggThumb-version": "OggHandler kĆ«rkon version oggThumb $1 ose mĆ« vonĆ«.", + "timedmedia-oggThumb-failed": "oggThumb dĆ«shtuar pĆ«r tĆ« krijuar tablo." +} diff --git a/extensions/TimedMediaHandler/i18n/an.json b/extensions/TimedMediaHandler/i18n/an.json new file mode 100644 index 00000000..8bee5529 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/an.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Juanpabl" + ] + }, + "timedmedia-desc": "Maneyador de fichers sincronizatos (vidio, son y texto sincronizato) con transcodificaciĆ³n Ogg Theora/Vorbis", + "timedmedia-ogg-short-audio": "Fichero de son ogg $1, $2", + "timedmedia-ogg-short-video": "Fichero de vidio ogg $1, $2", + "timedmedia-ogg-short-general": "Fichero multimedia ogg $1, $2", + "timedmedia-ogg-long-audio": "Fichero de son ogg $1, durada $2, $3", + "timedmedia-ogg-long-video": "Fichero de vidio ogg $1, durada $2, $4Ć$5 pĆxels, $3", + "timedmedia-ogg-long-multiplexed": "fichero ogg multiplexato audio/vidio, $1, durada $2, $4Ć$5 pĆxels, $3 total", + "timedmedia-ogg-long-general": "fichero ogg multimedia durada $2, $3", + "timedmedia-ogg-long-error": "Fichero ogg no conforme: $1", + "timedmedia-more": "MĆ”sā¦", + "timedmedia-dismiss": "Zarrar", + "timedmedia-download": "Escargar fichero", + "timedmedia-desc-link": "InformaciĆ³n sobre este fichero" +} diff --git a/extensions/TimedMediaHandler/i18n/ang.json b/extensions/TimedMediaHandler/i18n/ang.json new file mode 100644 index 00000000..077e8718 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ang.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Gott wisst" + ] + }, + "timedmedia-source-file": "$1 fruma", + "timedmedia-source-audio-file-desc": "Frumlicu $1 ymele ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/ar.json b/extensions/TimedMediaHandler/i18n/ar.json new file mode 100644 index 00000000..bcb7c11c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ar.json @@ -0,0 +1,67 @@ +{ + "@metadata": { + "authors": [ + "Alnokta", + "Asaifm", + "Meno25", + "OsamaK", + "Ų±ŁŲ®Ł", + "Abanima" + ] + }, + "timedmedia-desc": "Ł
ŲÆŲ§ŁŁ ŁŁŲµŁŲŖŁŲ§ŲŖ ŁŲ§ŁŁ
Ų±Ų¦ŁŲ§ŲŖ ŁŲ§ŁŁŲµŁŲµ Ų§ŁŁ
Ų¤ŁŲŖŲ© ŁŲ§ŁŲ°Ł ŁŲÆŁŁ Ų§ŁŁŲÆŲ±Ų© Ų¹ŁŁ ŲÆŲ¹Ł
Ł
ŁŁŲ§ŲŖ ŲØŲµŁŲŗŲ© WebM ŁOgg Theora ŁVorbis Łsrt", + "timedmedia-ogg-short-audio": "Ogg $1 Ł
ŁŁ ŲµŁŲŖŲ $2", + "timedmedia-ogg-short-video": "Ogg $1 Ł
ŁŁ ŁŁŲÆŁŁŲ $2", + "timedmedia-ogg-short-general": "Ogg $1 Ł
ŁŁ Ł
ŁŲÆŁŲ§Ų $2", + "timedmedia-ogg-long-audio": "Ogg $1 Ł
ŁŁ ŲµŁŲŖŲ Ų§ŁŲ·ŁŁ $2Ų $3", + "timedmedia-ogg-long-video": "Ogg $1 Ł
ŁŁ ŁŁŲÆŁŁŲ Ų§ŁŲ·ŁŁ $2Ų $4Ć$5 ŲØŁŲ³ŁŲ $3", + "timedmedia-ogg-long-multiplexed": "Ł
ŁŁ Ogg Ł
Ų§ŁŲŖŁ ŲØŁŁŁŲ³ŲÆ Ų£ŁŲÆŁŁ/ŁŁŲÆŁŁŲ $1Ų Ų§ŁŲ·ŁŁ $2Ų $4Ć$5 ŲØŁŲ³ŁŲ $3 Ų„Ų¬Ł
Ų§ŁŁ", + "timedmedia-ogg-long-general": "Ł
ŁŁ Ł
ŁŲÆŁŲ§ OggŲ Ų§ŁŲ·ŁŁ $2Ų $3", + "timedmedia-ogg-long-error": "Ł
ŁŁ Ogg ŲŗŁŲ± ŲµŲŁŲ: $1", + "timedmedia-webm-short-video": "ŁŲ³Ł WebMŲ $1 Ł
ŁŁ ŁŁŲÆŁŁ $2", + "timedmedia-webm-long-video": "Ł
ŁŁ ŲµŁŲŖ/ŁŁŲÆŁŁ ŲØŁŲ³Ł WebM , $1, Ų§ŁŲ·ŁŁ $2, $4Ć$5 ŲØŁŲ³ŁŲ $3 Ų„Ų¬Ł
Ų§ŁŲ§", + "timedmedia-no-player-js": "Ų¹Ų°Ų±Ų§Ų Ł
ŲŖŲµŁŲŁ Ų„Ł
Ų§ Ų§ŁŁ ŁŲ§ ŁŲÆŲ¹Ł
Ų§ŁŲ¬Ų§ŁŲ§ Ų³ŁŲ±ŁŲØŲŖ Ų£Ł Ų§ŁŁŲ§ Ł
Ų¹Ų·ŁŲ©.<br />\nŲŖŲ³ŲŖŲ·ŁŲ¹ <a href=\"$1\">ŲŖŲŁ
ŁŁ Ų§ŁŁ
ŁŲ·Ų¹</a> Ų£Ł <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŲŖŲŁ
ŁŁ Ł
Ų“ŲŗŁ</a> ŁŲ³ŲŖŲ·ŁŲ¹ ŲŖŲ“ŲŗŁŁ Ų§ŁŁ
ŁŲ·Ų¹ Ų¹ŁŁ Ł
ŲŖŲµŁŲŁ.", + "timedmedia-more": "Ų§ŁŁ
Ų²ŁŲÆ...", + "timedmedia-dismiss": "Ų£ŲŗŁŁ", + "timedmedia-download": "ŁŲ²Ł Ų§ŁŁ
ŁŁ", + "timedmedia-play-media": "ŲŖŲ“ŲŗŁŁ Ų§ŁŁŲ³Ų§Ų¦Ų·", + "timedmedia-desc-link": "Ų¹Ł ŁŲ°Ų§ Ų§ŁŁ
ŁŁ", + "timedmedia-status": "Ų§ŁŲŲ§ŁŲ©", + "timedmedia-status-unknown": "ŲŲ§ŁŲ© ŲŗŁŲ± Ł
Ų¹Ų±ŁŁŲ©", + "timedmedia-actions": "Ų§ŁŲ„Ų¬Ų±Ų§Ų”Ų§ŲŖ", + "timedmedia-direct-link": "ŲŖŲŁ
ŁŁ Ų§ŁŁ
Ų“ŲŖŁ", + "timedmedia-not-ready": "ŲŗŁŲ± Ų¬Ų§ŁŲ²", + "timedmedia-percent-done": "ŁŲµŁ ŁŁŲ³ŲØŲ© $1% Ų§ŁŲŖŁŁ", + "timedmedia-in-job-queue": "ŲŖŁ
ŲŖ Ų§ŁŲ„Ų¶Ų§ŁŲ© Ų„ŁŁ Ų·Ų§ŲØŁŲ± Ų§ŁŁ
ŁŲ§Ł
Ł
ŁŲ° $1", + "timedmedia-days": "{{PLURAL:$1|ŁŁŁ
ŁŲ§ŲŲÆ|ŁŁŁ
ŁŁ|$1 Ų£ŁŲ§Ł
|$1 ŁŁŁ
Ų§Ł|$1 ŁŁŁ
}}", + "timedmedia-hours": "{{PLURAL:$1|Ų³Ų§Ų¹Ų© ŁŲ§ŲŲÆŲ©|Ų³Ų§Ų¹ŲŖŁŁ|$1 Ų³Ų§Ų¹Ų§ŲŖ|$1 Ų³Ų§Ų¹Ų©}}", + "timedmedia-minutes": "{{PLURAL:$1|ŲÆŁŁŁŲ© ŁŲ§ŲŲÆŲ©|ŲÆŁŁŁŲŖŁŁ|$1 ŲÆŁŲ§Ų¦Ł|$1 ŲÆŁŁŁŲ©}}", + "timedmedia-seconds": "{{PLURAL:$1|Ų«Ų§ŁŁŲ© ŁŲ§ŲŲÆŲ©|Ų«Ų§ŁŁŲŖŁŁ|$1 Ų«ŁŲ§Ł|$1 Ų«Ų§ŁŁŲ©}}", + "timedmedia-ogg": "Ų£Ł Ų¬Ł Ų¬Ł", + "timedmedia-source-file": "$1 Ł
ŲµŲÆŲ±", + "timedmedia-source-file-desc": "Ų§ŁŲ£ŲµŁ Ł
ŁŁ $1Ų $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Ų§ŁŁ
ŁŁ $1 Ų§ŁŲ£ŲµŁŁ ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ų§ŁŲ®ŁŲ§Ų¶ Ų¹Ų±Ų¶ Ų§ŁŁŲ·Ų§Ł Ų§ŁŲŖŲ±ŲÆŲÆŁ Ų£ŁŲ¬ ŁŁŲÆŁŁ (160P)", + "timedmedia-derivative-desc-720p.ogv": "ŲŖŲŁ
ŁŁ Ų£ŁŲ¬ ŁŁŲÆŁŁ ŲØŲ¬ŁŲÆŲ© Ų¹Ų§ŁŁŲ© (720P)", + "timedmedia-subtitle-new": "Ų£ŁŲ“Ų¦ ŲŖŲ±Ų¬Ł
Ų© Ų¬ŲÆŁŲÆŲ© Ų£Ł ŲŲ±Ų± ŲŖŲ±Ų¬Ł
Ų© Ł
ŁŲ¬ŁŲÆŲ©", + "timedmedia-subtitle-new-desc": "ŁŁ
ŲØŲ„Ų®ŲŖŁŲ§Ų± Ų§ŁŁŲŗŲ© ŁŲ„Ų¶ŲŗŲ· Ų¹ŁŁ Ų²Ų± '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Ų§Ų°ŁŲØ", + "timedmedia-subtitle-language": "$1 ($2) ŲŖŲ±Ų¬Ł
Ų§ŲŖ", + "timedmedia-subtitle-no-video": "ŁŲ§ ŁŁŲ¬ŲÆ ŁŁŲÆŁŁ Ł
ŁŲŖŲ±Ł ŲØŲµŁŲŲ© ŲŖŲ±Ų¬Ł
Ų© Ų£Ł ŁŲµŁŲµ Ų§ŁŁŁŲÆŁŁ Ų§ŁŲŲ§ŁŁŲ©.", + "timedmedia-subtitle-no-subtitles": "ŁŲ§ ŲŖŁŲ¬ŲÆ ŁŲµŁŲµ Ų£Ł ŲŖŲ±Ų¬Ł
Ų§ŲŖ ŁŁ $1 ŁŁŲ°Ų§ Ų§ŁŁŁŲÆŁŁŲ ŁŁ
ŁŁŁ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ŲŖŲ¹ŲÆŁŁ ŁŲ°Ł Ų§ŁŲµŁŲŲ©] ŁŲ„Ų¶Ų§ŁŲŖŁŁ
.", + "timedmedia-subtitle-remote-link": "ŁŁ
ŁŁŁ [$1 Ł
Ų·Ų§ŁŲ¹Ų© ŲµŁŲŲ© Ų§ŁŁŲµŁ] ŁŁŲ°Ų§ Ų§ŁŁ
ŁŁ Ų¹ŁŁ $2", + "timedmediahandler": "Ł
Ų¹Ų§ŁŲ¬ Ų§ŁŁ
ŁŲÆŁŲ§ Ų§ŁŲ²Ł
ŁŁŲ©", + "timedmedia-videos": "{{PLURAL:$1|Ł
ŁŁ ŁŁŲÆŁŁ ŁŲ§ŲŲÆ|Ł
ŁŁŲ§ ŁŁŲÆŁŁ|$1 Ł
ŁŁŲ§ŲŖ ŁŁŲÆŁŁ|$1 Ł
ŁŁ ŁŁŲÆŁŁ}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|Ł
ŁŁ|Ł
ŁŁŲ§|$1 Ł
ŁŁŲ§ŲŖ|$1 Ł
ŁŁ}} ŁŁŲÆŁŁ Ogg", + "timedmedia-webm-videos": "{{PLURAL:$1|Ł
ŁŁ|Ł
ŁŁŲ§|$1 Ł
ŁŁŲ§ŲŖ|$1 Ł
ŁŁ}} ŁŁŲÆŁŁ WebM", + "timedmedia-file": "Ł
ŁŁ", + "timedmedia-audios": "{{PLURAL:$1|Ł
ŁŁ ŲµŁŲŖŁ ŁŲ§ŲŲÆ|$1 Ł
ŁŁ ŲµŁŲŖŁ}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|Ł
ŁŁ ŲµŁŲŖŁ ŁŲ§ŲŲÆ ŲØŲµŁŲŗŲ© Ų£ŁŲŗ|$1 Ł
ŁŁ ŲµŁŲŖŁ ŲØŲµŁŲŗŲ© Ų£ŁŲŗ}}", + "timedmedia-flac-audios": "{{PLURAL:$1|Ł
ŁŁ|Ł
ŁŁŲ§|$1 Ł
ŁŁŲ§ŲŖ|$1 Ł
ŁŁ}} ŲµŁŲŖŁ FLAC", + "timedmedia-wav-audios": "{{PLURAL:$1|Ł
ŁŁ|Ł
ŁŁŲ§|$1 Ł
ŁŁŲ§ŲŖ|$1 Ł
ŁŁ}} ŲµŁŲŖŁ WAV", + "orphanedtimedtext": "ŲµŁŲŲ§ŲŖ TimedText ŁŲŖŁŁ
Ų©", + "orphanedtimedtext-summary": "ŁŲ§Ų¦Ł
Ų© ŲØŲµŁŲŲ§ŲŖ [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] Ų§ŁŲŖŁ ŁŁŲ³ ŁŲÆŁŁŲ§ Ł
ŁŁ Ł
ŁŲ§ŁŁ.", + "orphanedtimedtext-unsupported": "ŁŲ°Ł Ų§ŁŲµŁŲŲ© Ų§ŁŲ®Ų§ŲµŲ© ŁŲ§ ŲŖŲÆŲ¹Ł
ŁŲ§ Ų„ŁŲ§ ŁŁŲ§Ų¹ŲÆ ŲØŁŲ§ŁŲ§ŲŖ MySQL", + "orphanedtimedtext-notimedtext": "TimedText ŲŗŁŲ± Ł
ŁŲ¹Ł Ų¹ŁŁ ŁŲ°Ų§ Ų§ŁŁŁŁŁ", + "apihelp-transcodereset-param-title": "Ų¹ŁŁŲ§Ł Ł
ŁŁ Ų§ŁŁ
ŁŲÆŁŲ§." +} diff --git a/extensions/TimedMediaHandler/i18n/arc.json b/extensions/TimedMediaHandler/i18n/arc.json new file mode 100644 index 00000000..7f2df877 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/arc.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Basharh" + ] + }, + "timedmedia-more": "ÜܬÜÜŖā¦" +} diff --git a/extensions/TimedMediaHandler/i18n/arq.json b/extensions/TimedMediaHandler/i18n/arq.json new file mode 100644 index 00000000..a4b24de3 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/arq.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Oldstoneage" + ] + }, + "timedmedia-no-player-js": "Ų§Ų¹ŲÆŁŲ±ŁŲ§Ų Ų§ŁŁŁŁŲ§Ł ŁŁŁ JavaScript Ł
ŲŲØŁŲ³ ŁŁŲ§ Ł
Ų§ ŁŁŁ ŲŲŖŲ§ ŁŲ±ŁŲ§Ł Ł
ŁŲ§ŁŁ
.<br />\nŲŖŁŲ¬Ł
<a href=\"$1\">ŲŖŲŖŁŁŁŲ“Ų§Ų±Ų¬Ł Ų§ŁŁŁŲÆŁŁ</a> ŁŁŲ§ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŁŲ²ŁŁ Ų¹ŁŲÆŁ ŁŲ±ŁŲ§Ł ŁŁŁŁ Ł
ŁŲ§ŁŁ
</a> ŲØŲ§Ų“ ŲŖŁŁŁŲŖ Ų§ŁŁŁŲÆŁŁ ŁŁ ŁŁŁŲ§Ł ŲŖŲ§Ų¹Ł.", + "timedmedia-source-file": "$1 Ł
ŲµŲÆŲ±", + "timedmedia-source-audio-file-desc": "ŁŁŲ“Ł $1 Ų£ŲµŁŁ ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/arz.json b/extensions/TimedMediaHandler/i18n/arz.json new file mode 100644 index 00000000..db3b7f88 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/arz.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Ghaly", + "Meno25", + "Ramsis II" + ] + }, + "timedmedia-desc": "Ł
ŲŖŲŁŁ
ŁŁ
ŁŁŲ§ŲŖ Ų£Ł Ų¬Ł Ų¬Ł Ų«ŁŁŲ±Ų§ Ł ŁŁŲ±ŲØŁŲ³Ų Ł
Ų¹ ŲØŁŲ§ŁŲ± Ų¬Ų§ŁŲ§Ų³ŁŲ±ŁŲØŲŖ", + "timedmedia-ogg-short-audio": "Ogg $1 Ł
ŁŁ ŲµŁŲŖŲ $2", + "timedmedia-ogg-short-video": "Ogg $1 Ł
ŁŁ ŁŁŲÆŁŁ, $2", + "timedmedia-ogg-short-general": "Ogg $1 Ł
ŁŁ Ł
ŁŲÆŁŲ§Ų $2", + "timedmedia-ogg-long-audio": "Ogg $1 Ł
ŁŁ ŲµŁŲŖŲ Ų§ŁŲ·ŁŁ $2Ų $3", + "timedmedia-ogg-long-video": "Ogg $1 Ł
ŁŁ ŁŁŲÆŁŁŲ Ų§ŁŲ·ŁŁ $2Ų $4Ć$5 ŲØŁŲ³ŁŲ $3", + "timedmedia-ogg-long-multiplexed": "Ł
ŁŁ Ogg Ł
Ų§ŁŲŖŁ ŲØŁŁŁŲ³ŲÆ Ų£ŁŲÆŁŁ/ŁŁŲÆŁŁŲ $1Ų Ų§ŁŲ·ŁŁ $2Ų $4Ć$5 ŲØŁŲ³ŁŲ $3 Ų„Ų¬Ł
Ų§ŁŁ", + "timedmedia-ogg-long-general": "Ł
ŁŁ Ł
ŁŲÆŁŲ§ OggŲ Ų§ŁŲ·ŁŁ $2Ų $3", + "timedmedia-ogg-long-error": "Ł
ŁŁ ogg Ł
Ų“ ŲµŲŁŲ: $1", + "timedmedia-more": "Ų£ŁŲŖŲ±...", + "timedmedia-dismiss": "Ų§ŁŁŁ", + "timedmedia-download": "ŁŲ²Ł Ų§ŁŁ
ŁŁ", + "timedmedia-desc-link": "Ų¹Ł Ų§ŁŁ
ŁŁ ŲÆŲ§", + "timedmedia-source-file": "$1 Ł
ŲµŲÆŲ±", + "timedmedia-source-audio-file-desc": "Ų§ŁŁ
ŁŁ $1 Ų§ŁŲ£ŲµŁ ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/as.json b/extensions/TimedMediaHandler/i18n/as.json new file mode 100644 index 00000000..519fccc6 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/as.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "IKHazarika" + ] + }, + "timedmedia-no-player-js": "ą¦¦ą§ą¦ą¦ą¦æą¦¤, ą¦ą¦Ŗą§ą¦Øą¦¾ą§° ą¦¬ą§ą§°ą¦¾ą¦ą¦ą¦¾ą§°ą¦¤ ą¦Øą¦¾ą¦ą¦¬ą¦¾ ą¦ą¦¾ą¦ą¦¾-ą¦øą§ą¦ą§ą§°ą¦æą¦Ŗą§ą¦ ą¦Øą¦æą¦·ą§ą¦ą§ą§°ą¦æą¦Æą¦¼ ą¦ą§°ą¦¾ ą¦¹ą§ ą¦ą¦ą§ ą¦
ą¦„ą¦¬ą¦¾ ą¦ą§ą¦Øą§ ą¦øą¦®ą§°ą§ą¦„ą¦æą¦¤ ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą§° ą¦Øą¦¾ą¦ą„¤ </br>\ną¦ą¦Ŗą§ą¦Øą¦¾ą§° ą¦¬ą§ą§°ą¦¾ą¦ą¦ą¦¾ą§°ą¦¤ ą¦ą§ą¦²ą¦æą¦Ŗą¦ą§ ą¦Ŗą§ą¦²ą§' ą¦ą§°ą¦æą¦¬ą¦²ą§ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¦Ŗą§ą¦²ą§'ą¦Æą¦¼ą¦¾ą§° ą¦ą¦ą¦¾ ą¦”ą¦¾ą¦ą¦Øą¦²'ą¦” ą¦ą§°ą¦</a> ą¦
ą¦„ą¦¬ą¦¾ <a href=\"$1\">ą¦ą§ą¦²ą¦æą¦Ŗą¦ą§ ą¦”ą¦¾ą¦ą¦Øą¦²'ą¦” ą¦ą§°ą¦</a> ą„¤", + "timedmedia-source-file": "$1 ą¦ą§ą¦ø", + "timedmedia-source-audio-file-desc": "ą¦Ŗą§ą§°ą¦ą§ą¦¤ $1 ą¦«ą¦¾ą¦ą¦² ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/ast.json b/extensions/TimedMediaHandler/i18n/ast.json new file mode 100644 index 00000000..2ff3d0af --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ast.json @@ -0,0 +1,122 @@ +{ + "@metadata": { + "authors": [ + "Esbardu", + "Xuacu" + ] + }, + "timedmedia-desc": "Remanador de sonĆu, videu y testu cronometrĆ”u, con sofitu pa los formatos WebM, Ogg Theora, Vorbis y srt", + "timedmedia-ogg-short-audio": "Archivu de sonĆu ogg $1, $2", + "timedmedia-ogg-short-video": "Archivu de videu ogg $1, $2", + "timedmedia-ogg-short-general": "Archivu multimedia ogg $1, $2", + "timedmedia-ogg-long-audio": "Archivu de sonĆu ogg $1, llonxitĆŗ $2, $3", + "timedmedia-ogg-long-video": "Archivu de videu ogg $1, llonxitĆŗ $2, $4Ć$5 pĆxeles, $3", + "timedmedia-ogg-long-multiplexed": "Ficheru de sonĆu/videu ogg multiplexĆ”u, $1, llonxitĆŗ $2, $4Ć$5 pĆxeles, $3", + "timedmedia-ogg-long-general": "Archivu multimedia ogg, llonxitĆŗ $2, $3", + "timedmedia-ogg-long-error": "Ficheru Ogg invĆ”lidu: $1", + "timedmedia-ogg-long-no-streams": "Ficheru multimedia Ogg. AtenciĆ³n: Nun se reconociĆ³ nengĆŗn codec de los usaos nesti ficheru.", + "timedmedia-webm-short-video": "Ficheru de videu WebM $1, $2", + "timedmedia-webm-long-video": "Ficheru de sonĆu/videu WebM, $1, llonxitĆŗ $2, $4 Ć $5 pixels, $3 total", + "timedmedia-flac-short-audio": "Ficheru de sonĆu FLAC, $1", + "timedmedia-flac-long-audio": "Ficheru de sonĆu FLAC, duraciĆ³n $1, $2 total", + "timedmedia-wav-short-audio": "Ficheru de sonĆu WAV, $1", + "timedmedia-wav-long-audio": "Ficheru de sonĆu WAV, duraciĆ³n $1, $2 total", + "timedmedia-wav-pcm-required": "NamĆ”i pue xubir WAV tipu PCM (Pulse Code Modulation).", + "timedmedia-mp4-short-video": "Archivu de videu MP4 $1, $2", + "timedmedia-mp4-long-video": "Ficheru de sonĆu/videu MP4, $1, llonxitĆŗ $2, $4 Ć $5 pixels, $3 total", + "timedmedia-no-player-js": "Sentimoslo, o'l to navegador tien desactivĆ”u JavaScript o nun tienes un reproductor compatible.<br />\nPues <a href=\"$1\">descargar el clip</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">descargar un reproductor</a> pa reproducir el clip nel to navegador.", + "timedmedia-more": "MĆ”s...", + "timedmedia-dismiss": "Zarrar", + "timedmedia-download": "Descargar archivu", + "timedmedia-play-media": "Reproducir el mediu", + "timedmedia-desc-link": "Tocante a esti archivu", + "timedmedia-oggThumb-version": "OggHandler requier oggThumb version $1 o mayor.", + "timedmedia-oggThumb-failed": "oggThumb nun pudo crear la miniatura.", + "timedmedia-status-header": "EstĆ”u de trescodificaciĆ³n", + "timedmedia-update-status": "Anovar l'estĆ”u de trescodificaciĆ³n", + "timedmedia-status": "EstĆ”u", + "timedmedia-status-unknown": "EstĆ”u desconocĆu", + "timedmedia-transcodebitrate": "Tasa de bits", + "timedmedia-transcodeduration": "Tiempu de codificaciĆ³n", + "timedmedia-transcodeinfo": "Formatu", + "timedmedia-actions": "Aiciones", + "timedmedia-direct-link": "Descargar", + "timedmedia-not-ready": "Nun ta preparĆ”u", + "timedmedia-completed-on": "Completada a les $1", + "timedmedia-error-on": "Error a les $1", + "timedmedia-started-transcode": "PrincipiĆ³ hai $1. $2", + "timedmedia-percent-done": "Fecho alredor del $1%", + "timedmedia-in-job-queue": "AmestĆ”u a la cola de trabayos hai $1", + "timedmedia-unknown-target-size": "TamaƱu del destĆn desconocĆu; $1 codificĆ”u", + "timedmedia-days": "{{PLURAL:$1|1 dĆa|$1 dĆes}}", + "timedmedia-hours": "{{PLURAL:$1|1 hora|$1 hores}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minutu|$1 minutos}}", + "timedmedia-seconds": "{{PLURAL:$1|1 segundu|$1 segundos}}", + "timedmedia-reset": "Reaniciar la trescodificaciĆ³n", + "timedmedia-reset-confirm": "Al reaniciar esta trescodificaciĆ³n desaniciarĆ” tolos ficheros esistentes (si los hai), y volverĆ” a amestar la trescodificaciĆ³n a la cola de trabayos. LlevarĆ” un tiempu volver a trescodificar.<br /><br />\nĀæTa seguru de que quier siguir?", + "timedmedia-reset-error": "Error al reaniciar el trabayu de trescodificaciĆ³n.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Fonte $1", + "timedmedia-source-file-desc": "Ficheru $1 orixinal, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Ficheru $1 orixinal ($2)", + "timedmedia-derivative-desc-160p.ogv": "Videu Ogg d'anchu de banda baxu (160P)", + "timedmedia-derivative-desc-240p.ogv": "Videu Ogg tresmitible pela web (240P)", + "timedmedia-derivative-desc-360p.ogv": "Videu Ogg tresmitible pela web (360P)", + "timedmedia-derivative-desc-480p.ogv": "Videu Ogg tresmitible pela web (480P)", + "timedmedia-derivative-desc-720p.ogv": "Videu Ogg descargable d'alta calida (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Videu Ogg descargable'n Full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "Videu WebM tresmitible pela web (160P)", + "timedmedia-derivative-desc-360p.webm": "Videu WebM tresmitible pela web (360P)", + "timedmedia-derivative-desc-480p.webm": "Videu WebM tresmitible pela web (480P)", + "timedmedia-derivative-desc-720p.webm": "Videu WebM descargable d'alta calida (720P)", + "timedmedia-derivative-desc-1080p.webm": "WebM descargable'n Full HD (1080P)", + "timedmedia-derivative-desc-2160p.webm": "WebM descargable'n Full 4K (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "WebM VP9 tresmitible pela web (360P)", + "timedmedia-derivative-desc-480p.vp9.webm": "WebM VP9 tresmitible pela web (480P)", + "timedmedia-derivative-desc-720p.vp9.webm": "WebM VP9 tresmitible'n HD (720P)", + "timedmedia-derivative-desc-1080p.vp9.webm": "WebM VP9 tresmitible'n Full HD (1080P)", + "timedmedia-derivative-desc-2160p.vp9.webm": "WebM VP9 tresmitible'n Full 4K (2160P)", + "timedmedia-derivative-desc-320p.mp4": "MP4 compatible colos preseos (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 tresmitible pela web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 de calidĆ” HD (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4 de calidĆ” Full HD (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "MP4 de calidĆ” Full 4K (2160P)", + "timedmedia-subtitle-new": "Crear una traducciĆ³n nueva o editar la esistente", + "timedmedia-subtitle-new-desc": "Seleicione la llingua y calque nel botĆ³n '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Dir", + "timedmedia-subtitle-language": "SubtĆtulos en $1 ($2)", + "timedmedia-subtitle-no-video": "Nun hai nengĆŗn videu asociĆ”u cola pĆ”xina de subtĆtulos actual", + "timedmedia-subtitle-no-subtitles": "AnguaƱo nun hai subtĆtulos en $1 pa esti videu, pue [{{fullurl:{{FULLPAGENAME}}|action=edit}} editar esta pĆ”xina] p'amestalos", + "timedmedia-subtitle-remote": "El testu cronometrĆ”u d'esti ficheru ta agospiĆ”u en $1", + "timedmedia-subtitle-remote-link": "Pue [$1 ver la pĆ”xina de descripciĆ³n] d'esti ficheru en $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 videu|$1 videos}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 videu|$1 videos}} Ogg", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 videu|$1 videos}} WebM", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 trescodificaciĆ³n|$1 trescodificaciones}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 trescodificaciĆ³n activa|$1 trescodificaciones actives}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 trescodificaciĆ³n|$1 trescodificaciones}} na cola", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 trescodificaciĆ³n fallida|$1 trescodificaciones fallĆes}}", + "timedmedia-file": "Ficheru", + "timedmedia-audios": "{{PLURAL:$1|$1 ficheru de sonĆu|$1 ficheros de sonĆu}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 ficheru de sonĆu Ogg|$1 ficheros de sonĆu Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 ficheru de sonĆu FLAC|$1 ficheros de sonĆu FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 ficheru de sonĆu WAV|$1 ficheros de sonĆu WAV}}", + "right-transcode-reset": "Reaniciar los videos fallĆos o trescodificaos pa que vuelvan a ponese na cola de trabayos.", + "right-transcode-status": "Ver [[Special:TimedMediaHandler|informaciĆ³n sobre l'actividĆ” de trescodificaciĆ³n actual]]", + "action-transcode-status": "ver l'estĆ”u actual de la trescodificaciĆ³n", + "orphanedtimedtext": "PĆ”xines gĆ¼Ć©rfanes de TimedText", + "orphanedtimedtext-summary": "Llista de pĆ”xines de [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] que nun tienen el correspondiente ficheru.", + "orphanedtimedtext-unsupported": "Esta pĆ”xina especial sĆ³lo tien sofitu con bases de datos MySQL.", + "orphanedtimedtext-notimedtext": "TimedText nun ta activĆ”u nesta wiki.", + "apihelp-query+transcodestatus-description": "Recibir l'estĆ”u de transcode pa una pĆ”xina de ficheru determinada.", + "apihelp-query+transcodestatus-example-1": "Recibir l'estĆ”u de transcode pa [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "Estende imageinfo pa incluir la informaciĆ³n de fonte de videu (derivaos)", + "apihelp-query+videoinfo-param-prop": "Que informaciĆ³n de videu algamar:\n;timestamp:Amiesta la marca d'hora de la versiĆ³n xubida.\n;user:Amiesta l'usuariu que xubiĆ³ la versiĆ³n del videu.\n;userid:Amiesta la ID del usuariu que xubiĆ³ la versiĆ³n del videu.\n;comment:Comentariu de la versiĆ³n.\n;parsedcomment:Comentariu analizĆ”u na versiĆ³n.\n;canonicaltitle:Amiesta'l tĆtulu canĆ³nicu del ficheru de videu.\n;url:Da la URL del videu y la pĆ”xina de descripciĆ³n.\n;size:Amiesta'l tamaƱu del videu en bytes, l'altor y anchor. Si ye aplicable, amiĆ©stase la cuenta de pĆ”xines y duraciĆ³n.\n;dimensions:AlcuƱu pa \"size\".\n;sha1:Amiesta'l hash SHA-1 del videu.\n;mime:Amiesta'l tipu MIME del videu.\n;thumbmime:Amiesta'l tipu MIME de la miniatura del videu (rique url y parĆ”metru $1urlwidth).\n;mediatype:Amiesta'l tipu de mediu del videu.\n;metadata:Llista de metadatos Exif de la versiĆ³n del videu.\n;commonmetadata:Llista de metadatos xenĆ©ricos del formatu de ficheru de la versiĆ³n del videu.\n;extmetadata:Llista de metadatos con formatu combinaos dende fontes diverses. Los resultaos tĆ”n en formatu HTML.\n;archivename:Amiesta'l nome de la versiĆ³n d'archivu pa versiones distintes de la Ćŗltima.\n;bitdepth:Amiesta la fondura de bit de la versiĆ³n.\n;uploadwarning:UsĆ”u pola pĆ”xina [[Special:Upload]] p'algamar informaciĆ³n d'un ficheru esistente. Nun ta previstu pa usase fuera del nucleu de MediaWiki.\n;derivatives:Amiesta una tabla colos diferentes formatos y calidaes disponibles d'un ficheru de sonĆu o videu.", + "apihelp-query+videoinfo-example-1": "Buscar informaciĆ³n tocante a [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "Los usuarios col permisu 'transcode-reset' pueden reaniciar y volver a executar un trabayu transcode.", + "apihelp-transcodereset-param-title": "TĆtulu del ficheru de multimedia.", + "apihelp-transcodereset-param-transcodekey": "La clave del transcode que quies reaniciar. CuĆ©yela de [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "Reaniciar tolos transcodes de [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "Reaniciar la clave transcode '360_560kbs.webm' de [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/av.json b/extensions/TimedMediaHandler/i18n/av.json new file mode 100644 index 00000000..2a3131e3 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/av.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Gazimagomedov" + ] + }, + "timedmedia-source-file": "$1 ŠøŃŃ", + "timedmedia-source-audio-file-desc": "ŠŃŠ»ŠøŃŠ± $1-ŃŠ°Š¹Š» ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/avk.json b/extensions/TimedMediaHandler/i18n/avk.json new file mode 100644 index 00000000..313cd0c9 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/avk.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Sab" + ] + }, + "timedmedia-download": "Iyeltakkalvajara", + "timedmedia-desc-link": "Icde bat iyeltak" +} diff --git a/extensions/TimedMediaHandler/i18n/awa.json b/extensions/TimedMediaHandler/i18n/awa.json new file mode 100644 index 00000000..fe0c3d1a --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/awa.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "1AnuraagPandey" + ] + }, + "timedmedia-no-player-js": "ą¤ą„ą¤·ą¤®ą¤¾ ą¤ą¤°ą„ą¤, ą¤ą¤Ŗą¤ą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤¼ą¤° ą¤®ą„ą¤ ą¤Æą¤¾ ą¤¤ą„ ą¤ą¤¾ą¤µą¤¾ą¤øą„ą¤ą„ą¤°ą¤æą¤Ŗą„ą¤ ą¤
ą¤ą„ą¤·ą¤® ą¤¹ą„ ą¤Æą¤¾ ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤Øą¤¹ą„ą¤ ą¤¹ą„ą„¤<br />\ną¤ą¤Ŗ <a href=\"$1\">ą¤ą„ą¤²ą¤æą¤Ŗ ą¤ą„ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤° ą¤øą¤ą¤¤ą„ ą¤¹ą„ą¤ ą¤
ą¤„ą¤µą¤¾ ą¤ą„ą¤²ą¤æą¤Ŗ ą¤ą„ ą¤
ą¤Ŗą¤Øą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤¼ą¤° ą¤®ą„ą¤ ą¤ą¤²ą¤¾ą¤Øą„ ą¤ą„ ą¤²ą¤æą¤ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¤ą¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤° ą¤øą¤ą¤¤ą„ ą¤¹ą„ą¤ą„¤", + "timedmedia-source-file": "$1 ą¤øą„ą¤°ą„ą¤¤", + "timedmedia-source-audio-file-desc": "ą¤®ą„ą¤² $1 ą¤«ą¤¼ą¤¾ą¤ą¤² ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/az.json b/extensions/TimedMediaHandler/i18n/az.json new file mode 100644 index 00000000..f54d2aed --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/az.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Cekli829", + "DaÄlı95", + "Wertuose" + ] + }, + "timedmedia-no-player-js": "BaÄıÅlayın, sizin veb brauzeriniz JavaScript texnologiyasını dÉstÉklÉmir vÉ ya bu ÉlavÉ deaktiv edilib.\nSiz dinlÉmÉk istÉdiyiniz faylı <a href=\"$1\">yĆ¼klÉyÉ</a> vÉ ya brauzerinizÉ, <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">lazımlı ÉlavÉni</a> quraÅdıra bilÉrsiz.", + "timedmedia-status": "Status", + "timedmedia-source-file": "$1 mÉnbÉyi", + "timedmedia-source-audio-file-desc": "Orijinal $1-fayl ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/azb.json b/extensions/TimedMediaHandler/i18n/azb.json new file mode 100644 index 00000000..d0c5b700 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/azb.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Amir a57", + "KoroÄlu" + ] + }, + "timedmedia-no-player-js": "Ų§ŁŲ²ŚÆŁŁŁŁŚ©āŁŁŲ Ų³ŪŲ²ŪŁ ŲÆŲ§Ų±Ų§ŪŪŲ¬ŪāŁŪŲ²ŪŁ Ų¬Ų§ŁŲ§ Ų§ŪŲ³Ś©Ų±ŪŁ¾ŲŖ ŪŲ§Ų²ŪŁŪŁ
Ū ŚŲ§ŁŪŲ“Ł
Ų§ŪŪŲ±Ų ŪŲ§ ŲÆŲ§ Ų³ŪŲ²ŪŁ ŲÆŲ§Ų±ŪŪŲ¬ŪāŁŪŲ² ŲØŁ ŪŲ§Ų²ŪŁŪŁ
āŲÆŲ§Ł Ų¢Ų±ŲÆŲ§ŲŗŁŲ§Ł
ŪŲ±.<br />\nŲ³ŪŲ² <a href=\"$1\">ŲØŁ ŁŪŲÆŪŁŁŁ Ų§ŪŁŲÆŪŲ±ŪŲØ</a> ŪŲ§ ŲÆŲ§ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŲØŪŲ± Ų§ŁŪŁŲ§ŲÆŪŲ¬Ū</a> Ų§ŪŁŲÆŪŲ±ŁāŲØŪŁŲ±Ų³ŪŁŪŲ².", + "timedmedia-source-file": "$1 Ś©ŁŚ©", + "timedmedia-source-audio-file-desc": "Ų§ŲµŁŪ $1 ŁŲ§ŪŁ ( $2 )" +} diff --git a/extensions/TimedMediaHandler/i18n/ba.json b/extensions/TimedMediaHandler/i18n/ba.json new file mode 100644 index 00000000..10f406c5 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ba.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Haqmar", + "Š ŃŃŃŠ°Š¼ ŠŃŃŃŠµŠ²" + ] + }, + "timedmedia-days": "{{PLURAL:$1|1=$1 ŠŗÓ©Š½|$1 ŠŗÓ©Š½}}", + "timedmedia-hours": "{{PLURAL:$1|1=$1 ŃÓŅÓŃ|$1 ŃÓŅÓŃ}}", + "timedmedia-minutes": "{{PLURAL:$1|1=$1 Š¼ŠøŠ½ŃŃ|$1 Š¼ŠøŠ½ŃŃ}}", + "timedmedia-seconds": "{{PLURAL:$1|1=$1 ŃŠµŠŗŃŠ½Š“|$1 ŃŠµŠŗŃŠ½Š“}}", + "timedmedia-source-file": "$1 ŃŃŅŠ°Š½Š°Ņ”", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š» $1-ŃŠ°Š¹Š» ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/bcc.json b/extensions/TimedMediaHandler/i18n/bcc.json new file mode 100644 index 00000000..11fbd1a8 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/bcc.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Mostafadaneshvar", + "Baloch Afghanistan" + ] + }, + "timedmedia-desc": "ŲÆŲ³ŚÆŪŲ±Ł Ł¾Ł ŁŲ§ŪŁŲ§Ł Ogg Theora Ł Vorbis, ŚÆŁŁ Ł¾Ų®Ų“ Ś©ŁŁŚ© Ų¬Ų§ŁŲ§ Ų§Ų³Ś©Ų±Ų³ŪŁ¾ŲŖ", + "timedmedia-ogg-short-audio": "ŁŲ§ŪŁ ŲµŁŲŖŪ Ogg $1Ų $2", + "timedmedia-ogg-short-video": "ŁŲ§ŪŁ ŲŖŲµŁŪŲ±Ū Ogg $1Ų $2", + "timedmedia-ogg-short-general": "ŁŲ§ŪŁ Ł
ŲÆŪŲ§ Ogg $1Ų $2", + "timedmedia-ogg-long-audio": "Ų§ŁŲ¬Ū Ų¬Ū $1 ŁŲ§ŪŁ ŲµŁŲŖŪ, Ų·ŁŁ $2, $3", + "timedmedia-ogg-long-video": "Ų§ŁŲ¬Ū Ų¬Ū $1 ŁŲ§ŪŁ ŁŪŲÆŪŁ, Ų·ŁŁ $2, $4Ć$5 Ł¾ŪŚ©Ų³Ł, $3", + "timedmedia-ogg-long-multiplexed": "Ų§ŁŲ¬Ū Ų¬Ū ŚŁŲÆ ŲÆŲ§ŲØŪ ŁŲ§ŪŁ ŲµŁŲŖ/ŲŖŲµŁŪŲ±, $1, Ų·ŁŁ $2, $4Ć$5 Ł¾ŪŚ©Ų³Ł, $3 Ś©Ł", + "timedmedia-ogg-long-general": "Ų§ŁŲ¬Ū Ų¬Ū ŁŲ§ŪŁ Ł
ŲÆŪŲ§, Ų·ŁŁ $2, $3", + "timedmedia-ogg-long-error": "ŁŲ§Ł
Ų¹ŲŖŲØŲ±ŪŁ ŁŲ§ŪŁ Ų§ŁŲ¬Ū Ų¬Ū: $1", + "timedmedia-more": "ŚÆŪŲ“ŲŖŪŲ±...", + "timedmedia-dismiss": "ŲØŲ³ŲŖŪŁ", + "timedmedia-download": "Ų¦ŪŲ± Ś©ŁŲ±ŲŖŪŁ Ł¾Ų§ŪŁŪ", + "timedmedia-desc-link": "Ų§Ū ŁŲ§ŪŁ ŲØŲ§Ų±Ł", + "timedmedia-subtitle-new-go": "ŲØŲ±Ų§", + "orphanedtimedtext": "ŪŲŖŪŁ
TimedText ŲÆŪŁ
Ų§Ł", + "orphanedtimedtext-summary": "ŁŲ§ ŲÆŪŁ
Ų§ŁŪ ŁŪŲ³ŲŖ Ś©Ł [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] Ł
ŲŖŁŲ§ŲøŲ±ŪŁ Ł¾Ų§ŪŁ ŁŲÆŲ§Ų±ŁŲŖ ." +} diff --git a/extensions/TimedMediaHandler/i18n/bcl.json b/extensions/TimedMediaHandler/i18n/bcl.json new file mode 100644 index 00000000..36042848 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/bcl.json @@ -0,0 +1,90 @@ +{ + "@metadata": { + "authors": [ + "Filipinayzd", + "Geopoet" + ] + }, + "timedmedia-desc": "Parakapot para sa audio, bidyo asin pinag-orasan na teksto, na igwa nin pormat kan suporta para sa WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 sagunson nin tanog, $2", + "timedmedia-ogg-short-video": "Ogg $1 sagunson nin bidyo, $2", + "timedmedia-ogg-short-general": "Ogg $1 sagunson nin midya, $2", + "timedmedia-ogg-long-audio": "Ogg $1 sagunson nin tanog, an laba $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 sagunson nin bidyo, an laba $2, $4 x $5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg pinaghalong sagunson nin audio/bidyo, $1, an laba $2, $4 x $5 piksel, $3", + "timedmedia-ogg-long-general": "Ogg sagunson nin midya, an laba $2, $3", + "timedmedia-ogg-long-error": "Imbalidong sagunson nin Ogg: $1", + "timedmedia-webm-short-video": "Webm $1 sagunson nin bidyo, $2", + "timedmedia-webm-long-video": "WebM sagunson nin audio/bidyo, $1, an laba $2, $4 x $5 piksel, $3 sa bilog na kagabsan", + "timedmedia-flac-short-audio": "FLAC sagunson nin audio, $1", + "timedmedia-flac-long-audio": "FLAC sagunson nin audio, an laba $1, $2 sa bilog na kagabsan", + "timedmedia-wav-short-audio": "WAV sagunson nin audio, $1", + "timedmedia-wav-long-audio": "WAV sagunson nin audio, an laba $1, $2 sa bilog na kagabsan", + "timedmedia-wav-pcm-required": "Ika makakarga sana nin PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "MP$ $1 sagunson nin bidyo, $2", + "timedmedia-mp4-long-video": "MP4 sagunson nin audio/bidyo, $1, an laba $2, $4 x $5 piksel, $3 sa bilog na kagabsan", + "timedmedia-no-player-js": "Sori po, an saimong pangilyaw baya pinagpundo an JavaScript o mayo gayod nin arinmang pinagsuportaran na parapaandar. <br /> Ika <a href=\"$1\">makakapagkarga nin klip</a> o baya <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">magkarga nin sarong parapaandar</a> tanganing paandaron an klip kan saimong kilyawan.", + "timedmedia-more": "Dakolon pa..", + "timedmedia-dismiss": "Isara", + "timedmedia-download": "Ikarga an sagunson", + "timedmedia-play-media": "Paandaron an midya", + "timedmedia-desc-link": "Mapanungod kaining sagunson", + "timedmedia-oggThumb-version": "OggHandler minahagad sa oggThumb bersyon na $1 o kahurihi.", + "timedmedia-oggThumb-failed": "oggThumb nagpalya sa pagmukna kan sadit na ladawan", + "timedmedia-status-header": "Kamugtakan kan panggantaw na kodigo", + "timedmedia-update-status": "Sumpayan an kamugtakan kan panggantaw na kodigo", + "timedmedia-status": "Kamugtakan", + "timedmedia-status-unknown": "Bakong aram na kamugtakan", + "timedmedia-transcodeinfo": "Deribatibong deskripsyon kan panggantaw na kodigo", + "timedmedia-actions": "Mga aksyon", + "timedmedia-direct-link": "Ikarga an deribatibo", + "timedmedia-not-ready": "Dae pa handa", + "timedmedia-completed-on": "Pinagkumpletong panggantaw na kodigo $1", + "timedmedia-error-on": "Kasalaan sa panggantaw na kodigo sa $1", + "timedmedia-started-transcode": "An panggantaw na kodigo pinagpoonan mga $1 an nakaagi. $2", + "timedmedia-percent-done": "Haros $1% an tapos na", + "timedmedia-in-job-queue": "Pinagdugang sa haralatan nin Trabaho mga $1 an nakaagi", + "timedmedia-unknown-target-size": "Dae aram an sukol kan target, $1 pinagkodigo na", + "timedmedia-days": "{{PLURAL:$1|1 aldaw|$1 mga aldaw}}", + "timedmedia-hours": "{{PLURAL:$1|1 oras|$1 mga oras}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuto|$1 minutos}}", + "timedmedia-seconds": "{{PLURAL:$1|1 segundo|$1 segundos}}", + "timedmedia-reset": "Pakibaguha an panggantaw na kodigo", + "timedmedia-reset-confirm": "Sa pagbabago kaining panggantaw na kodigo magtatangkas nin arinman na eksistidong sagunson (kun yaon), asin magdudugang otro kan panggantaw na kodigo sa haralatan nin trabaho. Ini minakaipo nin nagkapirang oras tangani na otrong ipaggantaw an kodigo. <br /><br /> Segurado ka na muya mong magpadagos?", + "timedmedia-reset-error": "Kasalaan sa pagbabago kan trabaho nin panggantaw na kodigo.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 pinagkuanan", + "timedmedia-source-file-desc": "Orihinal $1 na sagunson, $2 x $3 ($4)", + "timedmedia-source-audio-file-desc": "Orihinal $1 na sagunson ($2)", + "timedmedia-derivative-desc-160p.ogv": "Hababaong kalawigan Ogg bidyo (160P)", + "timedmedia-derivative-desc-360p.ogv": "Maantabayanan sa Web na bidyo kan Ogg (360P)", + "timedmedia-derivative-desc-480p.ogv": "Maantabayanan sa Web na bidyo kan Ogg (480P)", + "timedmedia-derivative-desc-720p.ogv": "Halangkaw na kalidad na maikakargang bidyo kan Ogg (720P)", + "timedmedia-derivative-desc-160p.webm": "Maantabayanan sa Web na bidyo kan WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "Maantabayanan sa Web na bidyo kan WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "Maantabayanan sa Web na bidyo kan WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "Halangkaw na kalidad na maikakargang bidyo kan WebM (720P)", + "timedmedia-derivative-desc-320p.mp4": "Masayon sa aparato MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Maantabayanan sa Web na MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD na kalidad MP4 (720P)", + "timedmedia-subtitle-new": "Magmukna nin baguhong dakit-taramon o liwaton an eksistido na", + "timedmedia-subtitle-new-desc": "Magpili nin lengguwahe asin pinduton an '''{{int:Timedmedia-subtitle-new-go}}''' na dutdutan", + "timedmedia-subtitle-new-go": "Magduman", + "timedmedia-subtitle-language": "$1 ($2) mga sub-titulo", + "timedmedia-subtitle-no-video": "Mayo tabing bidyo na asosyado na igwa nin sa ngunyan na subtitulo kan pahina", + "timedmedia-subtitle-no-subtitles": "Mayo tabi nin sa ngunyan na mga subtitulo sa $1 para kaining bidyo, ika tabi [{{fullurl:{{FULLPAGENAME}}|action=edit}} makapagliwat kaining pahina] tanganing maidugang sinda", + "timedmedia-subtitle-remote": "Pinag-orasang teksto para kaining sagunson iyo an pinagbunsod sa $1", + "timedmedia-subtitle-remote-link": "Ika tabi [$1 makakatanaw sa pahina kan deskripsyon] para kaining sagunson sa $2", + "timedmediahandler": "Pinag-orasan na Parakapot kan Midya", + "timedmedia-videos": "{{PLURAL:$1|$1 bidyo|$1 mga bidyo}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg bidyo|$1 Ogg mga bidyo}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM bidyo|$1 WebM mga bidyo}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 panggantaw na kodigo|$1 panggantaw na mga kodigo}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 nagdadalagan na panggantaw na kodigo|$1 nagdadalagan na panggantaw na mga kodigo}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 pinaghahalat na panggantaw na kodigo|$1 pinaghahalat na panggantaw na mga kodigo}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 nagpalyang panggantaw na kodigo|$1 nagpalyang panggantaw na mga kodigo}}", + "timedmedia-file": "Sagunson", + "right-transcode-reset": "An pagbĆ”go nagpalya o an pinaggantaw na kodigong mga bidyo kaya sinda pinagsingit giraray sa haralatan kan trabaho.", + "right-transcode-status": "Patanaw [[Special:TimedMediaHandler|impormasyon mapanungod sa ngunyan na aktibidad kan panggantaw na kodigo]]", + "action-transcode-status": "tanawon an sa ngunyan na kamugtakan kan panggangtaw na kodigo" +} diff --git a/extensions/TimedMediaHandler/i18n/be-tarask.json b/extensions/TimedMediaHandler/i18n/be-tarask.json new file mode 100644 index 00000000..1bd50c1d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/be-tarask.json @@ -0,0 +1,71 @@ +{ + "@metadata": { + "authors": [ + "EugeneZelenko", + "Jim-by", + "Red Winged Duck", + "Wizardist" + ] + }, + "timedmedia-desc": "ŠŠæŃŠ°ŃŠ¾ŃŃŃŃŠŗ Š°ŃŠ“ŃŃ, Š²ŃŠ“ŃŠ° Ń ŃŃŠ±ŃŃŃŃŠ°Ń Ń ŃŠ°ŃŠ¼Š°ŃŠ°Ń
WebM, Ogg Theora, Vorbis Ń SRT", + "timedmedia-ogg-short-audio": "ŠŃŠ“ŃŃ-ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-video": "ŠŃŠ“ŃŠ°-ŃŠ°Š¹Š» Ń ŃŠ°ŃŠ¼Š°ŃŠµ Ogg $1, $2", + "timedmedia-ogg-short-general": "ŠŃŠ“ŃŃŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-long-audio": "Š°ŃŠ“ŃŃ-ŃŠ°Š¹Š» Ogg $1, Š“Š°ŃŠ¶ŃŠ½Ń $2, $3", + "timedmedia-ogg-long-video": "Š²ŃŠ“ŃŠ°-ŃŠ°Š¹Š» Ogg $1, Š“Š°ŃŠ¶ŃŠ½Ń $2, $4Ć$5 ŠæŃŠŗŃŃŠ»ŃŃ, $3", + "timedmedia-ogg-long-multiplexed": "Š¼ŃŠ»ŃŃŃŠæŠ»ŠµŠŗŃŠ½Ń Š°ŃŠ“ŃŃ/Š²ŃŠ“ŃŠ°-ŃŠ°Š¹Š» Ogg, $1, Š“Š°ŃŠ¶ŃŠ½Ń $2, $4Ć$5 ŠæŃŠŗŃŃŠ»ŃŃ, ŃŃŃŠ³Š¾ $3", + "timedmedia-ogg-long-general": "Š¼ŃŠ“ŃŃŃŠ°Š¹Š» Ogg, Š“Š°ŃŠ¶ŃŠ½Ń $2, $3", + "timedmedia-ogg-long-error": "ŠŃŃŠ»ŃŃŠ½Ń ŃŠ°Š¹Š» Ń ŃŠ°ŃŠ¼Š°ŃŠµ Ogg: $1", + "timedmedia-webm-short-video": "WebM $1 Š²ŃŠ“ŃŠ°ŃŠ°Š¹Š», $2", + "timedmedia-webm-long-video": "ŠŃŠ“ŃŃ/Š²ŃŠ“ŃŠ°-ŃŠ°Š¹Š» WebM, $1, ŠæŃŠ°ŃŃŠ³Š»Š°ŃŃŃŃ $2, $4Ć$5 ŠæŃŠŗŃŃŠ»Š°Ń, ŃŃŃŠ³Š¾ $3", + "timedmedia-flac-short-audio": "ŠŃŠ“ŃŃŃŠ°Š¹Š» FLAC, $1", + "timedmedia-flac-long-audio": "ŠŃŠ“ŃŃŃŠ°Š¹Š» FLAC, ŠæŃŠ°ŃŃŠ³Š»Š°ŃŃŃŃ $1, ŃŃŃŠ³Š¾ $2", + "timedmedia-mp4-short-video": "MP4 $1 Š²ŃŠ“ŃŠ°ŃŠ°Š¹Š», $2", + "timedmedia-no-player-js": "ŠŃŠ°Š±Š°ŃŃŠµ, Š°Š»Šµ Ń ŠŠ°ŃŃŠ¼ Š±ŃŠ°ŃŠ·ŃŃŃ Š°Š“ŠŗŠ»ŃŃŠ°Š½Ń JavaScript Š°Š»ŃŠ±Š¾ Š½ŃŠ¼Š° Š½ŠµŠ°Š±Ń
Š¾Š“Š½Š°Š³Š° ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗŠ°.<br />\nŠŃ Š¼Š¾Š¶Š°ŃŠµ <a href=\"$1\">Š·Š°Š³ŃŃŠ·ŃŃŃ ŠŗŠ»ŃŠæ</a> ŃŃ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š·Š°Š³ŃŃŠ·ŃŃŃ ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ</a> Š“Š»Ń ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š½ŃŠ½Ń ŠŗŠ»ŃŠæŃ Ń ŠŠ°ŃŃŠ¼ Š±ŃŠ°ŃŠ·ŃŃŃ.", + "timedmedia-more": "ŠŠ¾Š»ŠµŠ¹ā¦", + "timedmedia-dismiss": "ŠŠ°Š·Š°Š“", + "timedmedia-download": "ŠŠ°Š³ŃŃŠ·ŃŃŃ ŃŠ°Š¹Š»", + "timedmedia-play-media": "ŠŃŠ°Š¹Š³ŃŠ°ŃŃ", + "timedmedia-desc-link": "ŠŠ½ŃŠ°ŃŠ¼Š°ŃŃŃ ŠæŃŠ° Š³ŃŃŃ ŃŠ°Š¹Š»", + "timedmedia-oggThumb-version": "OggHandler ŠæŠ°ŃŃŠ°Š±ŃŠµ oggThumb Š²ŃŃŃŃŃ $1 ŃŃ Š±Š¾Š»ŃŃ ŠæŠ¾Š·ŃŠ½ŃŠ¹.", + "timedmedia-oggThumb-failed": "oggThumb Š½Šµ Š°ŃŃŃŠ¼Š°Š»Š°ŃŃ ŃŃŠ²Š°ŃŃŃŃ Š¼ŃŠ½ŃŃŃŃŃŃ.", + "timedmedia-status-header": "Š”ŃŠ°ŃŃŃ ŃŃŠ°Š½ŃŠŗŠ°Š“Š°Š²Š°Š½ŃŠ½Ń", + "timedmedia-update-status": "ŠŠ±Š½Š°Š²ŃŃŃ ŃŃŠ°ŃŃŃ ŃŃŠ°Š½ŃŠŗŠ°Š“Š°Š²Š°Š½ŃŠ½Ń", + "timedmedia-status": "Š”ŃŠ°ŃŃŃ", + "timedmedia-status-unknown": "Š”ŃŠ°ŃŃŃ Š½ŠµŠ²ŃŠ“Š¾Š¼Ń", + "timedmedia-transcodeinfo": "Š¤Š°ŃŠ¼Š°Ń", + "timedmedia-actions": "ŠŠ·ŠµŃŠ½ŃŠ½Ń", + "timedmedia-direct-link": "Š”ŠæŠ°Š¼ŠæŠ°Š²Š°ŃŃ", + "timedmedia-not-ready": "ŠŠµ Š³Š°ŃŠ¾Š²Ń", + "timedmedia-completed-on": "ŠŠ°Š²ŠµŃŃŠ°Š½Š° $1", + "timedmedia-error-on": "ŠŠ°Š¼ŃŠ»ŠŗŠ° Ń $1", + "timedmedia-started-transcode": "ŠŠ°ŃŠ°Š»Š¾ŃŃ $1 ŃŠ°Š¼Ń. $2", + "timedmedia-percent-done": "ŠŠ°ŃŠ¾Š²Š° ŠŗŠ°Š»Ń $1%", + "timedmedia-in-job-queue": "ŠŠ°Š“Š°Š“Š·ŠµŠ½Š° Ń ŃŠ°ŃŠ³Ń Š·Š°Š“Š°Š½ŃŠ½ŃŃ $1 ŃŠ°Š¼Ń", + "timedmedia-unknown-target-size": "ŠŃŠ½ŃŠŗŠ¾Š²Ń ŠæŠ°Š¼ŠµŃ Š½ŠµŠ²ŃŠ“Š¾Š¼Ń, $1 Š·Š°ŠŗŠ°Š“Š°Š²Š°Š½Š°", + "timedmedia-days": "$1 {{PLURAL:$1|Š“Š·ŠµŠ½Ń|Š“Š½Ń|Š“Š·ŃŠ½}}", + "timedmedia-hours": "$1 {{PLURAL:$1|Š³Š°Š“Š·ŃŠ½Ń|Š³Š°Š“Š·ŃŠ½Ń|Š³Š°Š“Š·ŃŠ½Š°Ń}}", + "timedmedia-minutes": "$1 {{PLURAL:$1|Ń
Š²ŃŠ»ŃŠ½Ń|Ń
Š²ŃŠ»ŃŠ½Ń|Ń
Š²ŃŠ»ŃŠ½Š°Ń}}", + "timedmedia-seconds": "$1 {{PLURAL:$1|ŃŃŠŗŃŠ½Š“Ń|ŃŃŠŗŃŠ½Š“Ń|ŃŃŠŗŃŠ½Š“Š°Ń}}", + "timedmedia-reset": "ŠŠµŃŠ°Š·Š°ŠæŃŃŃŃŃŃŃ ŃŃŠ°Š½ŃŠŗŠ°Š“Š°Š²Š°Š½ŃŠ½Šµ", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "ŠŃŃŠ½ŃŃŠ° $1", + "timedmedia-source-file-desc": "ŠŃŃŠ³ŃŠ½Š°Š» Ń $1, $2Ć$3 ($4)", + "timedmedia-source-audio-file-desc": "ŠŃŃŠ³ŃŠ½Š°Š» Ń $1 ($2)", + "timedmedia-derivative-desc-160p.ogv": "ŠŃŠ·ŠŗŠ°ŠæŠ°ŃŠ¾ŃŠ½Š°Šµ Ogg-Š²ŃŠ“ŃŠ° (160P)", + "timedmedia-derivative-desc-360p.ogv": "ŠŠ°ŃŠ¾ŃŠ½Š°Šµ Ogg-Š²ŃŠ“ŃŠ° (360 ŠæŠŗŃ)", + "timedmedia-derivative-desc-480p.ogv": "ŠŠ°ŃŠ¾ŃŠ½Š°Šµ Ogg-Š²ŃŠ“ŃŠ° (480 ŠæŠŗŃ)", + "timedmedia-derivative-desc-720p.ogv": "ŠŃŃŠ°ŠŗŠ°ŃŠŗŠ°ŃŠ½Š°Šµ Ogg-Š²ŃŠ“ŃŠ° Š“Š»Ń Š·Š°Š³ŃŃŠ·ŠŗŃ (720p)", + "timedmedia-derivative-desc-360p.webm": "ŠŠ°ŃŠ¾ŃŠ½Ń WebM (360p)", + "timedmedia-derivative-desc-480p.webm": "ŠŠ°ŃŠ¾ŃŠ½Ń WebM (480p)", + "timedmedia-derivative-desc-720p.webm": "ŠŃŃŠ°ŠŗŠ°ŃŠŗŠ°ŃŠ½Š°Šµ WebM-Š²ŃŠ“ŃŠ° Š“Š»Ń Š·Š°Š³ŃŃŠ·ŠŗŃ (720p)", + "timedmedia-derivative-desc-720p.mp4": "MP4 HD-ŃŠŗŠ°ŃŃŃŃ (720P)", + "timedmedia-subtitle-new": "Š”ŃŠ²Š°ŃŃŃŃ Š½Š¾Š²Ń ŠæŠµŃŠ°ŠŗŠ»Š°Š“ ŃŃ ŃŃŠ“Š°Š³Š°Š²Š°ŃŃ ŃŃŠ½ŃŃŃŃ", + "timedmedia-subtitle-new-go": "ŠŠ°ŃŠ°ŃŃ", + "timedmedia-subtitle-language": "Š”ŃŠ±ŃŃŃŃŃ ($2) Š½Š° $1", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1}} Š²ŃŠ“ŃŠ°", + "timedmedia-file": "Š¤Š°Š¹Š»", + "right-transcode-reset": "ŃŠŗŃŠ“Š°Š½ŃŠ½Šµ Š½ŃŃŠ“Š°Š»ŃŃ
Š°Š±Š¾ ŃŃŠ°Š½ŃŠŗŠ°Š“Š°Š²Š°Š½ŃŃ
Š²ŃŠ“ŃŠ°, ŠŗŠ°Š± ŃŠ½Ń ŃŠ·Š½Š¾Ń ŃŃŠ°ŠæŃŠ»Ń Ń ŃŠ°ŃŠ³Ń Š·Š°Š“Š°Š½ŃŠ½ŃŃ", + "right-transcode-status": "ŠæŃŠ°Š³Š»ŃŠ“ [[Special:TimedMediaHandler|Š·ŃŠ²ŠµŃŃŠ°Šŗ ŠæŃŠ° Š°ŠŗŃŃŠ°Š»ŃŠ½Ń ŃŃŠ°Š½ ŠæŠµŃŠ°ŠŗŠ°Š“Š°Š²Š°Š½ŃŠ½Ń]]" +} diff --git a/extensions/TimedMediaHandler/i18n/be.json b/extensions/TimedMediaHandler/i18n/be.json new file mode 100644 index 00000000..d24bc36e --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/be.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Š§Š°Ń
Š¾Š²ŃŃ Š£Š»Š°Š“Š·ŃŃŠ»Š°Ń" + ] + }, + "timedmedia-no-player-js": "ŠŠ° Š¶Š°Š»Ń, Ń Š²Š°ŃŃŠ¼ Š±ŃŠ°ŃŠ·ŠµŃŃ Š°Š“ŠŗŠ»ŃŃŠ°Š½Ń JavaScript, ŃŃ Š½Šµ Š¼Š°ŠµŃŃŠ° ŠæŠ°ŃŃŠ°Š±Š°Š²Š°Š½Š°Š³Š° ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗŠ°.<br />\nŠŃ Š¼Š¾Š¶Š°ŃŠµ <a href=\"$1\">Š·Š°Š³ŃŃŠ·ŃŃŃ ŃŠ¾Š»ŃŠŗ</a> ŃŃ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š·Š°Š³ŃŃŠ·ŃŃŃ ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š»ŃŠ½ŃŠŗ</a> Š“Š»Ń ŠæŃŠ°Š¹Š³ŃŠ°Š²Š°Š½Š½Ń ŃŠ¾Š»ŃŠŗŠ° Ń Š±ŃŠ°ŃŠ·ŠµŃŃ.", + "timedmedia-source-file": "ŠŃŃŠ½ŃŃŠ° $1", + "timedmedia-source-audio-file-desc": "ŠŃŃŠ³ŃŠ½Š°Š»ŃŠ½Ń $1-ŃŠ°Š¹Š» ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/bg.json b/extensions/TimedMediaHandler/i18n/bg.json new file mode 100644 index 00000000..0ef16819 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/bg.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Borislav", + "DCLXVI", + "Spiritia", + "StanProg" + ] + }, + "timedmedia-desc": "ŠŃŠøŠ»Š¾Š¶ŠµŠ½ŠøŠµ Š·Š° ŃŠ°Š¹Š»Š¾Š²Šµ ŃŠøŠæ Ogg Theora Šø Vorbis, Ń ŠæŠ»ŠµŠ¹ŃŃ Š½Š° JavaScript", + "timedmedia-ogg-short-audio": "Ogg $1 Š·Š²ŃŠŗŠ¾Š² ŃŠ°Š¹Š», $2", + "timedmedia-ogg-short-video": "Ogg $1 Š²ŠøŠ“ŠµŠ¾ ŃŠ°Š¹Š», $2", + "timedmedia-ogg-long-audio": "Ogg $1 Š·Š²ŃŠŗŠ¾Š² ŃŠ°Š¹Š», ŠæŃŠ¾Š“ŃŠ»Š¶ŠøŃŠµŠ»Š½Š¾ŃŃ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 Š²ŠøŠ“ŠµŠ¾ ŃŠ°Š¹Š», ŠæŃŠ¾Š“ŃŠ»Š¶ŠøŃŠµŠ»Š½Š¾ŃŃ $2, $4Ć$5 ŠæŠøŠŗŃŠµŠ»Š°, $3", + "timedmedia-ogg-long-general": "ŠŃŠ»ŃŠøŠ¼ŠµŠ“ŠøŠµŠ½ ŃŠ°Š¹Š» Š² ogg ŃŠ¾ŃŠ¼Š°Ń Ń Š“ŃŠ»Š¶ŠøŠ½Š° $2, $3", + "timedmedia-ogg-long-error": "ŠŠµŠ²Š°Š»ŠøŠ“ŠµŠ½ ogg ŃŠ°Š¹Š»: $1", + "timedmedia-no-player-js": "ŠŠ° ŃŃŠ¶Š°Š»ŠµŠ½ŠøŠµ, Š±ŃŠ°ŃŠ·ŃŃŠ° Š²Šø ŠøŠ¼Š° ŠøŠ·ŠŗŠ»ŃŃŠµŠ½ JavaScript ŠøŠ»Šø Š½Šµ ŃŠ°Š·ŠæŠ¾Š»Š°Š³Š° Ń Š½ŠµŠ¾Š±Ń
Š¾Š“ŠøŠ¼ŠøŃ ŠæŠ»ŠµŠ¹ŃŃ.<br />\nŠŠ¾Š¶ŠµŃŠµ Š“Š° <a href=\"$1\">ŠøŠ·ŃŠµŠ³Š»ŠøŃŠµ ŠŗŠ»ŠøŠæŠ°</a> ŠøŠ»Šø <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š“Š° ŠøŠ·ŃŠµŠ³Š»ŠøŃŠµ ŠæŠ»ŠµŠ¹ŃŃ</a> Š·Š° Š“Š° ŠæŃŃŠ½ŠµŃŠµ ŠŗŠ»ŠøŠæŠ° Š² Š±ŃŠ°ŃŠ·ŃŃŠ° ŃŠø.", + "timedmedia-more": "ŠŠ¾Š²ŠµŃŠµ...", + "timedmedia-dismiss": "ŠŠ°ŃŠ²Š°ŃŃŠ½Šµ", + "timedmedia-download": "ŠŠ·ŃŠµŠ³Š»ŃŠ½Šµ Š½Š° ŃŠ°Š¹Š»Š°", + "timedmedia-desc-link": "ŠŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŃ Š·Š° ŃŠ°Š¹Š»Š°", + "timedmedia-source-file": "ŠŠ·ŃŠ¾ŃŠ½ŠøŠŗ Š½Š° $1", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š»ŠµŠ½ $1-ŃŠ°Š¹Š» ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/bgn.json b/extensions/TimedMediaHandler/i18n/bgn.json new file mode 100644 index 00000000..da70a08d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/bgn.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Baloch Afghanistan", + "Ibrahim khashrowdi" + ] + }, + "timedmedia-no-player-js": "ŲØŲ®Ų“Ų§ŪŲŖ Ų§ŪŚŪŲ Ų“Ł
Ū ŲØŲ±ŁŲ²ŪŲ± Ų¦Ū Ų³Ų±Ų§ Ų¬Ų§ŁŲ§ Ų§Ų³Ś©Ų±ŪŁ¾ŲŖ Ų¦Ū Ų³Ų§ŁŁ¹ Ų§ŪŲ± Ł¾Ų¦Ų§Ł ŁŁ Ų§ŪŁŲŖ Ų Ł ŪŲ§ Ś©Ł Ų“Ł
Ū ŲØŲ±ŁŲ²ŪŲ± Ų“Ł Ų§Ū Ł¾ŁŲ±Ł
ŲŖ Ų¦Ų§ Ł¾ŁŲ“ŲŖŪŁŲ§ŁŪ Ų¦Ł ŁŁ Ś©ŁŲŖ .<br />\nŲ“Ł
Ų§ Ų¦Ł ŲŖŁŲ§ŁŪŲŖ <a href=\"$1\">Ś©Ł Ų§Ū ŁŪŚŪŁ Ų¦Ų§ Ų§Ų¦ŪŲ± ŲØŚ©ŁŪŲŖ</a> Ł ŪŲ§ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŪŚ© Ł¾Ų®Ų“ Ś©ŁŪŚ©</a> Ų¦Ū Ł¾Ł Ų§Ū ŁŪŚŪŁ ŪŪ Ų§Ų¬Ų±Ų§ Ų¦Ų§ Ų§Ų¦ŪŲ± ŲØŚ©ŁŪŲŖ.", + "timedmedia-source-file": "$1 Ų²ŁŁ", + "timedmedia-source-audio-file-desc": "Ų§ŁŲ±Ų¬ŪŁŲ§Ł $1 ŁŲ§ŪŁ ( $2 )" +} diff --git a/extensions/TimedMediaHandler/i18n/bho.json b/extensions/TimedMediaHandler/i18n/bho.json new file mode 100644 index 00000000..b562c221 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/bho.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "SatyamMishra" + ] + }, + "timedmedia-source-audio-file-desc": "ą¤ą¤°ą¤æą¤ą¤Øą¤² $1 ą¤«ą¤¾ą¤ą¤² ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/bn.json b/extensions/TimedMediaHandler/i18n/bn.json new file mode 100644 index 00000000..d69249bb --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/bn.json @@ -0,0 +1,48 @@ +{ + "@metadata": { + "authors": [ + "Bellayet", + "Zaheen", + "Aftab1995", + "Aftabuzzaman" + ] + }, + "timedmedia-ogg-short-audio": "ą¦
ą¦ $1 ą¦øą¦¾ą¦ą¦Øą§ą¦” ą¦«ą¦¾ą¦ą¦², $2", + "timedmedia-ogg-short-video": "ą¦
ą¦ $1 ą¦ą¦æą¦”ą¦æą¦ ą¦«ą¦¾ą¦ą¦², $2", + "timedmedia-ogg-short-general": "ą¦
ą¦ $1 ą¦®ą¦æą¦”ą¦æą¦Æą¦¼ą¦¾ ą¦«ą¦¾ą¦ą¦², $2", + "timedmedia-ogg-long-audio": "ą¦
ą¦ $1 ą¦øą¦¾ą¦ą¦Øą§ą¦” ą¦«ą¦¾ą¦ą¦², ą¦¦ą§ą¦°ą§ą¦ą§ą¦Æ $2, $3", + "timedmedia-ogg-long-video": "ą¦
ą¦ $1 ą¦ą¦æą¦”ą¦æą¦ ą¦«ą¦¾ą¦ą¦², ą¦¦ą§ą¦°ą§ą¦ą§ą¦Æ $2, $4Ć$5 ą¦Ŗą¦æą¦ą§ą¦øą§ą¦², $3", + "timedmedia-ogg-long-multiplexed": "ą¦
ą¦ ą¦®ą¦¾ą¦²ą§ą¦ą¦æą¦Ŗą§ą¦²ą§ą¦ą§ą¦øą¦ą§ą¦¤ ą¦
ą¦”ą¦æą¦/ą¦ą¦æą¦”ą¦æą¦ ą¦«ą¦¾ą¦ą¦², $1, ą¦¦ą§ą¦°ą§ą¦ą§ą¦Æ $2, $4Ć$5 ą¦Ŗą¦æą¦ą§ą¦øą§ą¦², $3 ą¦øą¦¾ą¦®ą¦ą§ą¦°ą¦æą¦", + "timedmedia-ogg-long-general": "ą¦
ą¦ ą¦®ą¦æą¦”ą¦æą¦Æą¦¼ą¦¾ ą¦«ą¦¾ą¦ą¦², ą¦¦ą§ą¦°ą§ą¦ą§ą¦Æ $2, $3", + "timedmedia-ogg-long-error": "ą¦
ą¦¬ą§ą¦§ ą¦
ą¦ ą¦«ą¦¾ą¦ą¦²: $1", + "timedmedia-mp4-short-video": "MP4 $1 ą¦ą¦æą¦”ą¦æą¦ ą¦«ą¦¾ą¦ą¦², $2", + "timedmedia-mp4-long-video": "MP4 ą¦
ą¦”ą¦æą¦/ą¦ą¦æą¦”ą¦æą¦ ą¦«ą¦¾ą¦ą¦², $1, ą¦¦ą§ą¦°ą§ą¦ą§ą¦Æ $2, $4 Ć $5 ą¦Ŗą¦æą¦ą§ą¦øą§ą¦², $3 ą¦øą¦¾ą¦®ą¦ą§ą¦°ą¦æą¦", + "timedmedia-no-player-js": "ą¦¦ą§ą¦ą¦ą¦æą¦¤, ą¦ą¦Ŗą¦Øą¦¾ą¦° ą¦¬ą§ą¦°ą¦¾ą¦ą¦ą¦¾ą¦°ą§ ą¦ą¦¾ą¦ą¦¾ą¦øą§ą¦ą§ą¦°ą¦æą¦Ŗą§ą¦ ą¦Øą¦æą¦·ą§ą¦ą§ą¦°ą¦æą¦Æą¦¼ ą¦ą¦°ą¦¾ ą¦ą¦ą§ ą¦
ą¦„ą¦¬ą¦¾ ą¦ą§ą¦Øą§ ą¦øą¦®ą¦°ą§ą¦„ą¦æą¦¤ ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦° ą¦Øą§ą¦ą„¤ <br />\ną¦ą¦Ŗą¦Øą¦æ ą¦ą¦Ŗą¦Øą¦¾ą¦° ą¦¬ą§ą¦°ą¦¾ą¦ą¦ą¦¾ą¦°ą§ ą¦ą§ą¦²ą¦æą¦Ŗą¦ą¦æ ą¦ą¦¾ą¦²ą¦¾ą¦Øą§ą¦° ą¦ą¦Øą§ą¦Æ <a href=\"$1\">ą¦ą§ą¦²ą¦æą¦Ŗą¦ą¦æ ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą¦¤ą§ ą¦Ŗą¦¾ą¦°ą§ą¦Ø</a> ą¦¬ą¦¾ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¦ą¦ą¦ą¦æ ą¦Ŗą§ą¦²ą§ą¦Æą¦¼ą¦¾ą¦° ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦”</a> ą¦ą¦°ą¦¤ą§ ą¦Ŗą¦¾ą¦°ą§ą¦Øą„¤", + "timedmedia-more": "ą¦ą¦°ą¦...", + "timedmedia-dismiss": "ą¦¬ą¦Øą§ą¦§", + "timedmedia-download": "ą¦«ą¦¾ą¦ą¦² ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą§ą¦Ø", + "timedmedia-play-media": "ą¦®ą¦æą¦”ą¦æą¦Æą¦¼ą¦¾ ą¦ą¦¾ą¦²ą¦¾ą¦Ø", + "timedmedia-desc-link": "ą¦ą¦ ą¦«ą¦¾ą¦ą¦²ą§ą¦° ą¦¬ą§ą¦¤ą§ą¦¤ą¦¾ą¦Øą§ą¦¤", + "timedmedia-status-header": "ą¦ą§ą¦°ą¦¾ą¦Øą§ą¦øą¦ą§ą¦” ą¦
ą¦¬ą¦øą§ą¦„ą¦¾", + "timedmedia-update-status": "ą¦ą§ą¦°ą¦¾ą¦Øą§ą¦øą¦ą§ą¦” ą¦
ą¦¬ą¦øą§ą¦„ą¦¾ ą¦¹ą¦¾ą¦²ą¦Øą¦¾ą¦ą¦¾ą¦¦ ą¦ą¦°ą§ą¦Ø", + "timedmedia-status": "ą¦
ą¦¬ą¦øą§ą¦„ą¦¾", + "timedmedia-status-unknown": "ą¦
ą¦¬ą¦øą§ą¦„ą¦¾ ą¦
ą¦ą¦¾ą¦Øą¦¾", + "timedmedia-transcodeinfo": "ą¦¬ą§ą¦Æą§ą§ą¦Ŗą¦Øą§ą¦Ø ą¦¬ą¦°ą§ą¦£ą¦Øą¦¾ ą¦ą§ą¦°ą¦¾ą¦Øą§ą¦øą¦ą§ą¦”", + "timedmedia-actions": "ą¦ą¦¾ą¦°ą§ą¦Æ", + "timedmedia-direct-link": "ą¦¬ą§ą¦Æą§ą§ą¦Ŗą¦Øą§ą¦Ø ą¦”ą¦¾ą¦ą¦Øą¦²ą§ą¦” ą¦ą¦°ą§ą¦Ø", + "timedmedia-not-ready": "ą¦¤ą§ą¦°ą¦æ ą¦Øą¦Æą¦¼", + "timedmedia-percent-done": "ą¦Ŗą§ą¦°ą¦¾ą¦Æą¦¼ $1% ą¦ą¦°ą¦¾ ą¦¹ą¦Æą¦¼ą§ą¦ą§", + "timedmedia-days": "{{PLURAL:$1|ą§§ ą¦¦ą¦æą¦Ø|$1 ą¦¦ą¦æą¦Ø}}", + "timedmedia-hours": "{{PLURAL:$1|ą§§ ą¦ą¦£ą§ą¦ą¦¾|$1 ą¦ą¦£ą§ą¦ą¦¾}}", + "timedmedia-minutes": "{{PLURAL:$1|ą§§ ą¦®ą¦æą¦Øą¦æą¦|$1 ą¦®ą¦æą¦Øą¦æą¦}}", + "timedmedia-seconds": "{{PLURAL:$1|ą§§ ą¦øą§ą¦ą§ą¦Øą§ą¦”|$1 ą¦øą§ą¦ą§ą¦Øą§ą¦”}}", + "timedmedia-source-file": "$1 ą¦ą§ą¦ø", + "timedmedia-source-audio-file-desc": "ą¦®ą§ą¦² $1 ą¦«ą¦¾ą¦ą¦² ($2)", + "timedmedia-derivative-desc-240p.ogv": "ą¦ą¦Æą¦¼ą§ą¦¬ ą¦øą§ą¦ą§ą¦°ą¦æą¦®ą¦Æą§ą¦ą§ą¦Æ ą¦
ą¦ ą¦ą¦æą¦”ą¦æą¦ (ą§Øą§Ŗą§¦P)", + "timedmedia-subtitle-new-go": "ą¦Æą¦¾ą¦", + "timedmedia-subtitle-language": "$1 ($2) ą¦øą¦¾ą¦¬ą¦ą¦¾ą¦ą¦ą§ą¦²", + "timedmedia-videos": "{{PLURAL:$1|$1ą¦ą¦æ ą¦ą¦æą¦”ą¦æą¦}}", + "timedmedia-file": "ą¦«ą¦¾ą¦ą¦²", + "timedmedia-audios": "{{PLURAL:$1|$1ą¦ą¦æ ą¦
ą¦”ą¦æą¦ ą¦«ą¦¾ą¦ą¦²}}", + "action-transcode-status": "ą¦¬ą¦°ą§ą¦¤ą¦®ą¦¾ą¦Ø ą¦ą§ą¦°ą¦¾ą¦Øą§ą¦øą¦ą§ą¦”ą¦æą¦ą¦Æą¦¼ą§ą¦° ą¦
ą¦¬ą¦øą§ą¦„ą¦¾ ą¦¦ą§ą¦ą§ą¦Ø" +} diff --git a/extensions/TimedMediaHandler/i18n/br.json b/extensions/TimedMediaHandler/i18n/br.json new file mode 100644 index 00000000..dd74c0c5 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/br.json @@ -0,0 +1,51 @@ +{ + "@metadata": { + "authors": [ + "Fohanno", + "Fulup", + "Y-M D" + ] + }, + "timedmedia-desc": "Skor video, son ha testenn sinkronelaet gant ar furmadoĆ¹ WebM, Ogg Theora hag SRT skoret", + "timedmedia-ogg-short-audio": "Restr son Ogg $1, $2", + "timedmedia-ogg-short-video": "Restr video Ogg $1, $2", + "timedmedia-ogg-short-general": "Restr media Ogg $1, $2", + "timedmedia-ogg-long-audio": "Restr son Ogg $1, pad $2, $3", + "timedmedia-ogg-long-video": "Restr video Ogg $1, pad $2, $4Ć$5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "Restr Ogg klevet/video liesplezhet $1, pad $2, $4Ć$5 piksel, $3 hollad", + "timedmedia-ogg-long-general": "Restr media Ogg, pad $2, $3", + "timedmedia-ogg-long-error": "Restr ogg direizh : $1", + "timedmedia-webm-short-video": "Restr video WebM $1, $2", + "timedmedia-webm-long-video": "Restr video/son WebM, $1, pad $2, $4 Ć $5 piksel, $3 en holl", + "timedmedia-no-player-js": "Ho tigarez, pe eo diweredekaet JavaScript war ho merdeer pen n'eo ket skoret lenner ebet gantaƱ.<br />\n<a href=\"$1\">PellgargaƱ ar c'hlip</a> a c'hallit pe <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">pellgargaƱ ul lenner</a> da lenn ar c'hlip gant ho merdeer.", + "timedmedia-more": "Muioc'h...", + "timedmedia-dismiss": "SerriƱ", + "timedmedia-download": "PellgargaƱ ar restr", + "timedmedia-play-media": "Lenn ar media", + "timedmedia-desc-link": "Diwar-benn ar restr-maƱ", + "timedmedia-oggThumb-version": "Rekis eo stumm $1 oggThumb, pe nevesoc'h, evit implijout OggHandler.", + "timedmedia-oggThumb-failed": "N'eo ket deuet a-benn oggThumb da grouiƱ ar munud.", + "timedmedia-status": "Statud", + "timedmedia-status-unknown": "Statud dianav", + "timedmedia-actions": "OberoĆ¹", + "timedmedia-not-ready": "N'eo ket prest", + "timedmedia-percent-done": "War-dro $1 % zo bet graet", + "timedmedia-days": "{{PLURAL:$1|1 devezh|$1 devezh}}", + "timedmedia-hours": "{{PLURAL:$1|1 eurvezh|$1 eurvezh}}", + "timedmedia-minutes": "{{PLURAL:$1|1 vunutenn|$1 munutenn}}", + "timedmedia-seconds": "$1 {{PLURAL:$1|eilenn|eilenn}}", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Mammenn $1", + "timedmedia-source-file-desc": "Orin $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Restr orin $1 ($2)", + "timedmedia-derivative-desc-160p.ogv": "Video Ogg izelgas (160P)", + "timedmedia-derivative-desc-360p.ogv": "Video Ogg lennus war-eeun war ar Gwiad (360p)", + "timedmedia-derivative-desc-480p.ogv": "Video Ogg lennus war-eeun war ar Gwiad (480p)", + "timedmedia-derivative-desc-720p.ogv": "Video Ogg da bellgargaƱ gant ur c'halite a-feson (720p)", + "timedmedia-derivative-desc-360p.webm": "WebM lennus war-eeun eus ar Gwiad (360p)", + "timedmedia-derivative-desc-480p.webm": "WebM lennus war-eeun eus ar Gwiad (480p)", + "timedmedia-derivative-desc-720p.webm": "Video WebM da bellgargaƱ gant ur c'halite a-feson (720p)", + "timedmedia-subtitle-new-go": "Mont", + "timedmedia-subtitle-language": "istitloĆ¹ e $1 ($2)", + "timedmedia-file": "Restr" +} diff --git a/extensions/TimedMediaHandler/i18n/bs.json b/extensions/TimedMediaHandler/i18n/bs.json new file mode 100644 index 00000000..144f854e --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/bs.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "CERminator", + "Palapa", + "Semso98" + ] + }, + "timedmedia-desc": "UpravljaÄ za zvuk, video i vremenski tekst sa podrÅ”kom formata za WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 zvuÄna datoteka, $2", + "timedmedia-ogg-short-video": "Ogg $1 video datoteka, $2", + "timedmedia-ogg-short-general": "Ogg $1 medijalna datoteka, $2", + "timedmedia-ogg-long-audio": "Ogg $1 zvuÄna datoteka, dužina $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 video datoteka, dužina $2, $4Ć$5 piksela, $3", + "timedmedia-ogg-long-multiplexed": "Ogg multipleksna zvuÄna/video datoteka, $1, dužina $2, $4Ć$5 piksela, $3 sveukupno", + "timedmedia-ogg-long-general": "Ogg medijalna datoteka, dužina $2, $3", + "timedmedia-ogg-long-error": "Nevaljana ogg datoteka: $1", + "timedmedia-wav-long-audio": "WAV audio datoteka, dužina $1, $2 sveukupno", + "timedmedia-wav-pcm-required": "Možete postaviti samo PCM (Pulse Code Modulation) WAV.", + "timedmedia-no-player-js": "Žao nam je, vaÅ” preglednik ili je onemoguÄio JavaScript ili nema nijednog podržanog playera.<br />\nMožete <a href=\"$1\">uÄitati klip</a> ili <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">uÄitati player</a> za reproduciranje klipa u vaÅ”em pregledniku.", + "timedmedia-more": "ViÅ”e...", + "timedmedia-dismiss": "Zatvori", + "timedmedia-download": "UÄitaj datoteku", + "timedmedia-desc-link": "O ovoj datoteci", + "timedmedia-oggThumb-version": "OggHandler zahtijeva oggThumb verziju $1 ili kasniju.", + "timedmedia-oggThumb-failed": "oggThumb nije uspio napraviti smanjeni pregled.", + "timedmedia-source-file": "$1 izvor", + "timedmedia-source-file-desc": "Originalna $1 datoteka, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Originalna $1 datoteka ($2)", + "timedmedia-subtitle-language": "$1 ($2) podnaslovi" +} diff --git a/extensions/TimedMediaHandler/i18n/ca.json b/extensions/TimedMediaHandler/i18n/ca.json new file mode 100644 index 00000000..6a72f2d0 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ca.json @@ -0,0 +1,44 @@ +{ + "@metadata": { + "authors": [ + "Aleator", + "Alvaro Vidal-Abarca", + "Paucabot", + "Pitort", + "SMP", + "Toniher", + "Vriullop", + "Joan manel", + "Macofe" + ] + }, + "timedmedia-desc": "Gestor de fitxers de vĆdeo, Ć udio i text sincronitzat amb suport pels formats WebM, Ogg Theora, Vorbi i srt", + "timedmedia-ogg-short-audio": "Fitxer OGG d'Ć udio $1, $2", + "timedmedia-ogg-short-video": "Fitxer OGG de vĆdeo $1, $2", + "timedmedia-ogg-short-general": "Fitxer multimĆØdia OGG $1, $2", + "timedmedia-ogg-long-audio": "Ogg $1 fitxer de so, llargada $2, $3", + "timedmedia-ogg-long-video": "Fitxer OGG de vĆdeo $1, llargada $2, $4Ć$5 pĆxels, $3", + "timedmedia-ogg-long-multiplexed": "Arxiu Ć udio/vĆdeo multiplex, $1, llargada $2, $4Ć$5 pĆxels, $3 de mitjana", + "timedmedia-ogg-long-general": "Fitxer multimĆØdia OGG, llargada $2, $3", + "timedmedia-ogg-long-error": "Fitxer OGG invĆ lid: $1", + "timedmedia-no-player-js": "Ho sentim, el vostre navegador tĆ© el JavaScript desactivat o bĆ© no tĆ© cap reproductor compatible instalĀ·lat.<br />\nPodeu <a href=\"<span class=\" notranslate\"=\"\" translate=\"no\">$1</span>\">descarregar el clip</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">descarregar un reproductor</a> per a veure el vĆdeo al vostre navegador.", + "timedmedia-more": "MĆ©s...", + "timedmedia-dismiss": "Tanca", + "timedmedia-download": "Descarrega el fitxer", + "timedmedia-desc-link": "InformaciĆ³ del fitxer", + "timedmedia-transcodeinfo": "Format", + "timedmedia-direct-link": "Descarregar", + "timedmedia-days": "{{PLURAL:$1|1 dia|$1 dies}}", + "timedmedia-hours": "{{PLURAL:$1|1 hora|$1 hores}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minut|$1 minuts}}", + "timedmedia-seconds": "{{PLURAL:$1|1 segon|$1 segons}}", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Font $1", + "timedmedia-source-file-desc": "Arxiu original $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Fitxer original $1 ($2)", + "timedmedia-subtitle-language": "$1 ($2) subtĆtols", + "timedmedia-videos": "{{PLURAL:$1|$1 vĆdeo|$1 vĆdeos}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 vĆdeo Ogg|$1 vĆdeos Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 vĆdeo WebM|$1 vĆdeosWebM}}", + "timedmedia-file": "Fitxer" +} diff --git a/extensions/TimedMediaHandler/i18n/ce.json b/extensions/TimedMediaHandler/i18n/ce.json new file mode 100644 index 00000000..e6af995d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ce.json @@ -0,0 +1,85 @@ +{ + "@metadata": { + "authors": [ + "Sasan700", + "Š£Š¼Š°Ń" + ] + }, + "timedmedia-desc": "WebM, Ogg Theora, Vorbis, srt ŃŠ¾ŃŠ¼Š°ŃŠ°Ń Š»Š¾Š²Ń Š°ŃŠ“ŠøŠ¾, Š²ŠøŠ“ŠµŠ¾ Š°, ŃŃŠ±ŃŠøŃŃŠ°Ń Š° ŠŗŠµŃŠµŃŠ³", + "timedmedia-ogg-short-audio": "ŠŃŠ·Š½ŠøŠ¹Š½ ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-video": "ŠŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-general": "ŠŠµŠ“ŠøŠ°-ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-long-audio": "Š°ŃŠ·Š½ŠøŠ¹Š½ ŃŠ°Š¹Š» Ogg $1, Š“Š¾Ń
Š°Š»Š»Š° (Ń
Š°Š½) $2, $3", + "timedmedia-ogg-long-video": "Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg $1, Š¹Š¾Ń
Š°Š»Š»Š° $2, $4 Ć $5 {{PLURAL:$5|ŠæŠøŠŗŃŠµŠ»Ń}}, $3", + "timedmedia-ogg-long-multiplexed": "Š¼ŃŠ»ŃŃŠøŠæŠ»ŠµŠŗŠ°Š½ Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg, $1, Š¹Š¾Ń
Š°Š»Š»Š° $2, $4Ć$5 ŠæŠøŠŗŃŠµŠ»Ń, $3 ŠµŃŃŠøŠ³", + "timedmedia-ogg-long-general": "Š¼ŠµŠ“ŠøŠ°-ŃŠ°Š¹Š» Ogg, Š¹Š¾Ń
Š°Š»Š»Š° $2, $3", + "timedmedia-ogg-long-error": "Š½ŠøŠ¹ŃŠ° Š¹Š¾ŃŃ Ogg-ŃŠ°Š¹Š»: $1", + "timedmedia-ogg-long-no-streams": "ŠŃŠ»ŃŃŠøŠ¼ŠµŠ“ŠøŠ°-ŃŠ°Š¹Š» ogg. ŠÓŠ°Ń
ŃŠµŠ“Š°Ń: Š„ÓŠ¾ŠŗŃ
Ń ŃŠ°Š¹Š»Š°Ń Š»ŠµŠ»Š¾Ń Š¹Š¾Š»Ń ŃŃ
ŃŠ° ŠŗŠ¾Š“ŠµŠŗ Š±ŠøŠ»Š³Š°Š»Š¹ŠøŠ½Š° ŃŃ.", + "timedmedia-webm-short-video": "WebM $1 Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š», $2", + "timedmedia-webm-long-video": "WebM Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ ŃŠ°Š¹Š», $1, Š¹Š¾Ń
Š°Š»Š»Š° $2, $4 Ć $5 {{PLURAL:$5|ŠæŠøŠŗŃŠµŠ»Ń}}, ŠµŃŃŠøŠ³ $3", + "timedmedia-flac-short-audio": "ŠŃŠ“ŠøŠ¾ŃŠ°Š¹Š» FLAC, $1", + "timedmedia-flac-long-audio": "ŠŃŠ“ŠøŠ¾ŃŠ°Š¹Š» FLAC, Š¹Š¾Ń
Š°Š»Š»Š° ā $1, Š±ŠøŃŃŠµŠ¹Ń ā $2", + "timedmedia-wav-short-audio": "ŠŃŠ“ŠøŠ¾ŃŠ°Š¹Š» FLAC, $1", + "timedmedia-wav-long-audio": "ŠŃŠ“ŠøŠ¾ŃŠ°Š¹Š» WAV, Š¹Š¾Ń
Š°Š»Š»Š° ā $1, Š±ŠøŃŃŠµŠ¹Ń ā $2", + "timedmedia-wav-pcm-required": "ŠŃ
ŃŠ° ŃŃŃŠŗŠŗŃ
Š° Š¼ŠµŠ³Š° PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "WebM $1 Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š», $2", + "timedmedia-mp4-long-video": "ŠŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ŃŠ°Š¹Š» MP4 $1, Š¹Š¾Ń
Š°Š»Š»Š° ā $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ»Ń, Š±ŠøŃŃŠµŠ¹Ń ā $3", + "timedmedia-more": "ŠŃŠŗŃ
Š°ā¦", + "timedmedia-dismiss": "ŠŃŠ°Š¹Š»Š°ŃŠŗŠŗŃ
Š°", + "timedmedia-download": "Š¤Š°Š¹Š» ŃŃŃŠŗŠŗŃ
Š°Ń", + "timedmedia-play-media": "ŠŠ¾Š»Š°ŃŠ»ŠøŠ¹ŃŠ° Š¼ŠµŠ“ŠøŠ°-ŃŠ°Š¹Š»", + "timedmedia-desc-link": "Š„ÓŠ¾ŠŗŃ
Ń ŃŠ°Š¹Š»Š°Ń
Š»Š°ŃŃŠ½Š° Ń
Š°Š°Š¼", + "timedmedia-oggThumb-failed": "oggThumb ŃŠ°Ń ŃŠ°Š“ŠµŠ»ŠøŃŠ° Š¼ŠøŠ½ŠøŠ°ŃŃŃŠ° ŠŗŃ
Š¾Š»Š»Š°.", + "timedmedia-status-header": "Š®Ń
Ń ŠŗŠ¾Š“ŃŃŠ°Š½ Ń
ŃŠ°Š»", + "timedmedia-update-status": "Š®Ń
Ń ŠŗŠ¾Š“ŃŃŠ°Š½ ŃŃŠ°ŃŃŃ ŠŗŠ°ŃŠ»Š°ŃŠŗŠŗŃ
Š°", + "timedmedia-status": "Š„ŃŠ°Š»", + "timedmedia-status-unknown": "Š¦Š° Š“Š¾Š²Š·Š° Ń
ŃŠ°Š»", + "timedmedia-transcodeinfo": "Š®Ń
Ń ŠŗŠ¾Š“ŃŃŠ°Ń
Š»Š°ŃŃŠ½Š°", + "timedmedia-actions": "ŠŠøŠ¹ŃŠ°Ń", + "timedmedia-direct-link": "Š§ŃŃŠŗŠŗŃ
Š° Š¼Š¾Š“ŠøŃŠøŃŠøŃŠ¾Š²Š°Ń Š¹ŠøŠ½Š° Š²Š°ŃŠøŠ°Š½Ń", + "timedmedia-not-ready": "ŠŠøŠ¹ŃŠ° ŃŃ", + "timedmedia-completed-on": "$1 ŃŃ
Ń ŠŗŠ¾Š“ŃŃ ŃŠµŠŗŃ
Š“ŠµŠ»Šø", + "timedmedia-error-on": "$1 ŃŃ
Ń ŠŗŠ¾Š“ŃŠµŃ Š³ÓŠ°Š»Š°Ń", + "timedmedia-started-transcode": "Š®Ń
Ń ŠŗŠ¾Š“ŃŃ Š“Š¾Š»Š° Š“Š°Š»ŠøŠ¹ŃŠøŠ½Š° $1 Ń
ŃŠ°Š»Ń
Š°. $2", + "timedmedia-percent-done": "ŠŠµŃŠ³Š³Š°ŃŠ° Ń
ŃŠµŃŠ°ŠæŠµŃ
Ń $1% ŠŗŃ
Š¾ŃŃŃŠ“ŠøŠ½Š°", + "timedmedia-in-job-queue": "ŠŠ° Š“ŠµŠ·Š°ŃŠ³ $1 Ń
ŃŠ°Š»Ń
Š¾ ŃŠ¾Š³ÓŠµ Š“ŠøŠ»Š»ŠøŠ½Š°", + "timedmedia-days": "{{PLURAL:$1|$1 Š“Šµ}}", + "timedmedia-hours": "{{PLURAL:$1|1 ŃŠ°Ń
ŃŃ}}", + "timedmedia-minutes": "{{PLURAL:$1|$1 Š¼ŠøŠ½Š¾Ń}}", + "timedmedia-seconds": "{{PLURAL:$1|$1 ŃŠµŠŗŃŠ½Š“}}", + "timedmedia-reset": "Š®Ń
Ń ŠŗŠ¾Š“ŃŃ ŃÓŠµŃ
Š“Š°Š»ŠøŠ¹ŃŠ°Ń", + "timedmedia-reset-error": "Š®Ń
Ń ŠŗŠ¾Š“ŃŠµŃ Š³ÓŠ°Š»Š°Ń.", + "timedmedia-source-file": "Š„ŃŠ¾ŃŃ $1", + "timedmedia-source-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š» $1 ŃŠ°Š¹Š»Š°Š½, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š»Š°Š½ $1-ŃŠ°Š¹Š» ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg-Š²ŠøŠ“ŠµŠ¾ Š“ŠøŠŗŠ° Š¹Š¾ŃŃ (160p)", + "timedmedia-derivative-desc-360p.ogv": "ŠŠ¾Š³ÓŠ°Š¼Š°Š½ Ogg-Š²ŠøŠ“ŠµŠ¾ (360p)", + "timedmedia-derivative-desc-480p.ogv": "ŠŠ¾Š³ÓŠ°Š¼Š°Š½ Ogg-Š²ŠøŠ“ŠµŠ¾ (480p)", + "timedmedia-derivative-desc-720p.ogv": "Ogg-Š²ŠøŠ“ŠµŠ¾ Š“ŠøŠŗŠ° (720p)", + "timedmedia-derivative-desc-160p.webm": "ŠŠ¾Š³ÓŠ°Š¼Š°Š½ WebM-Š²ŠøŠ“ŠµŠ¾ (160p)", + "timedmedia-derivative-desc-360p.webm": "ŠŠ¾Š³ÓŠ°Š¼Š°Š½ WebM-Š²ŠøŠ“ŠµŠ¾ (360p)", + "timedmedia-derivative-desc-480p.webm": "ŠŠ¾Š³ÓŠ°Š¼Š°Š½ WebM-Š²ŠøŠ“ŠµŠ¾ (480p)", + "timedmedia-derivative-desc-720p.webm": "WebM-Š²ŠøŠ“ŠµŠ¾ Š“ŠøŠŗŠ° (720p)", + "timedmedia-derivative-desc-320p.mp4": "MP4 (320P) ŠŗŠµŃŃŃ", + "timedmedia-derivative-desc-480p.mp4": "ŠŠ¾Š³ÓŠ°Š¼Š°Š½ MP4-Š²ŠøŠ“ŠµŠ¾ (480p)", + "timedmedia-derivative-desc-720p.mp4": "MP4 HD-Š“ŠøŠŗŠ°Š»Š»ŠøŃŠ° (720P)", + "timedmedia-subtitle-new-go": "ŠŃ
Š¾ŃŃŃŠ“Ć©", + "timedmedia-subtitle-language": "$1 ($2) ŃŃŠ±ŃŠøŃŃŠ°Ń", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š»|$1 Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š»Š°Ń}}", + "timedmedia-ogg-videos": "$1 Ogg Š²ŠøŠ“ŠµŠ¾{{PLURAL:$1|ŃŠ°Š¹Š»}}", + "timedmedia-webm-videos": "$1 WebM Š²ŠøŠ“ŠµŠ¾{{PLURAL:$1|ŃŠ°Š¹Š»}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 ŃŃ
Ń ŠŗŠ¾Š“ŃŃ}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 ŃŃ
Ń ŠŗŠ¾Š“ŃŃ Š“Š¾Š»Š°Š“Š°Š»ŠøŠ¹ŃŠ°Ń}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 ŃŃ
Ń ŠŗŠ¾Š“ŃŃŠ°Š½ ŃŠ¾Š³ÓŠµŃ
Ń Ń}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 ŠŗŃ
Š¾ŃŃŃ ŃŠ° Ń
ŠøŠ»Š»Š° ŃŃ
Ń ŠŗŠ¾Š“ŃŃ}}", + "timedmedia-file": "Š¤Š°Š¹Š»", + "timedmedia-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š»|$1 Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š»Š°Ń}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š» Ogg|$1 Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š»Š°Ń Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š» FLAC|$1 Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š»Š°Ń FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š» WAV|$1 Š°ŃŠ“ŠøŠ¾-ŃŠ°Š¹Š»Š°Ń WAV}}", + "right-transcode-reset": "ŠŃ
Š¾ŃŃŠ° Š“ŠøŠŗŠ° Š¹Š¾ŃŃ Š²ŠøŠ“ŠµŠ¾Ń ŃŃŃ ŃŠ¾Š³ÓŠµŃ
Ń Ń
ŠøŠ»ŠøŠ¹ŃŠ°.", + "right-transcode-status": "Š„ŃŠ°Š¶Š° [[Special:TimedMediaHandler|ŃŃ
Ń ŠŗŠ¾Š“ Ń
ŠøŠ¹ŃŠ°ŃŠ°Š½ Ń
Š°Š°Š¼Šµ]]", + "orphanedtimedtext": "ŠÆŠ¹Š½Š° Š°Š³ÓŠ¾Š½Š°Ń TimedText", + "orphanedtimedtext-notimedtext": "TimedText Ń
ÓŠ¾ŠŗŃ
Ń Š²ŠøŠŗŠø ŃŠ¾Ń
Ń Š»Š°ŃŠøŠ½Š° Š“Š°Ń." +} diff --git a/extensions/TimedMediaHandler/i18n/ckb.json b/extensions/TimedMediaHandler/i18n/ckb.json new file mode 100644 index 00000000..4a345dc0 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ckb.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Calak", + "Asoxor", + "Muhammed taha" + ] + }, + "timedmedia-no-player-js": "ŲØŲØŁŁŲ±ŪŲ ŁŪŲØŚÆŪŲ±ŪŚ©ŪŲŖ ŪŲ§Ł JavaScript ŁŪ Ś©Ų§Ų± Ų®Ų³ŲŖŁŁŪ ŪŲ§Ł playerŪ Ł¾ŪŁŪŲ³ŲŖŪ ŁŪŪŪ.<br />\nŲÆŪŲŖŁŲ§ŁŪŲŖ <a href=\"$1\">Ś©ŁŪŁ¾ŪŚ©Ū ŲÆŲ§ŚÆŲ±ŪŲŖ</a> ŪŲ§Ł <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">playerŪŚ© ŲÆŲ§ŚÆŲ±ŪŲŖ</a> ŲØŪ Ų¦ŪŁŪŪ ŁŪ ŁŪŲØŚÆŪŚŪŚ©ŪŲŖŲÆŲ§ ŲØŪŲ®ŪŪŲŖŪ Ų³ŪŲ±.", + "timedmedia-source-file": "$1 Ų³ŪŲ±ŚŲ§ŁŪ", + "timedmedia-source-audio-file-desc": "Ł¾ŪŚŚÆŪŪ $1 ŲØŁŪŚŪŲŖŪ ($2)", + "right-transcode-reset": "ŚŪŚ©Ų®Ų³ŲŖŁŪŁŪŪ Ś¤ŪŲÆŪŪ Ų³ŪŲ±ŁŪŚ©ŁŲŖŁŁŪŚ©Ų§Ł ŪŲ§Ł ŲŖŲ±Ų§ŁŲ³Ś©ŪŲÆŚ©Ų±Ų§ŁŪŚ©Ų§Ł Ś¾ŪŲŖŲ§ ŲÆŪŲ³Ų§Ł ŲØŚŁŪŁŪ ŁŲ§Ł ŚŪŲ²Ū Ś©Ų§Ų±ŪŁŪ.", + "right-transcode-status": "ŲÆŪŲŖŁŪ [[ŲŖŲ§ŪŲØŪŲŖ:TimedMediaHandler|Ų²Ų§ŁŪŲ§Ų±Ū ŁŪŁ
ŪŚ ŚŲ§ŁŲ§Ś©ŪŪ ŲŖŲ±Ų§ŁŲ³Ś©ŪŲÆŪ Ś¾ŪŁŁŁŚ©ŪŪŪ]]" +} diff --git a/extensions/TimedMediaHandler/i18n/cs.json b/extensions/TimedMediaHandler/i18n/cs.json new file mode 100644 index 00000000..69a2c0ca --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/cs.json @@ -0,0 +1,75 @@ +{ + "@metadata": { + "authors": [ + "Chmee2", + "Li-sung", + "MatÄj GrabovskĆ½", + "Mormegil", + "Paxt", + "MatÄj SuchĆ”nek" + ] + }, + "timedmedia-desc": "Obsluha zvukÅÆ, videa a ÄasovanĆ©ho textu s podporou formĆ”tÅÆ WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "ZvukovĆ½ soubor ogg $1, $2", + "timedmedia-ogg-short-video": "Videosoubor ogg $1, $2", + "timedmedia-ogg-short-general": "MultimediĆ”lnĆ soubor ogg $1, $2", + "timedmedia-ogg-long-audio": "ZvukovĆ½ soubor ogg $1, dĆ©lka $2, $3", + "timedmedia-ogg-long-video": "Videosoubor $1, dĆ©lka $2, $4Ć$5 pixelÅÆ, $3", + "timedmedia-ogg-long-multiplexed": "multiplexovanĆ½ audio/video soubor Ogg, $1, dĆ©lka $2, $4Ć$5 pixelÅÆ, celkem $3", + "timedmedia-ogg-long-general": "Soubor mĆ©dia ogg, dĆ©lka $2, $3", + "timedmedia-ogg-long-error": "ChybnĆ½ soubor ogg: $1", + "timedmedia-webm-short-video": "Videosoubor WebM $1, $2", + "timedmedia-webm-long-video": "audio/video soubor WebM, $1, dĆ©lka $2, $4Ć$5 pixelÅÆ, celkem $3", + "timedmedia-wav-pcm-required": "MÅÆžete naÄĆtat jen WAV soubory ve formĆ”tu PCM (pulse code modulation).", + "timedmedia-mp4-short-video": "Videosoubor MP4 $1, $2", + "timedmedia-mp4-long-video": "audio/video soubor MP4, $1, dĆ©lka $2, $4Ć$5 pixelÅÆ, celkem $3", + "timedmedia-no-player-js": "Je mi lĆto, ale vĆ”Å” prohlĆžeÄ mĆ” buÄ vypnutĆ½ JavaScript, nebo nemĆ”te Å¾Ć”dnĆ½ podporovanĆ½ pÅehrĆ”vaÄ.<br />\nMÅÆžete si <a href=\"$1\">stĆ”hnout klip</a> nebo si <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">stĆ”hnout pÅehrĆ”vaÄ</a>, kterĆ½m si klip pÅehrajete v prohlĆžeÄi.", + "timedmedia-more": "VĆce...", + "timedmedia-dismiss": "ZavÅĆt", + "timedmedia-download": "StĆ”hnout soubor", + "timedmedia-play-media": "PÅehrĆ”t mĆ©dia", + "timedmedia-desc-link": "O tomto souboru", + "timedmedia-oggThumb-version": "OggHandler vyžaduje oggThumb verze $1 nebo novÄjÅ”Ć.", + "timedmedia-oggThumb-failed": "oggThumb nedokĆ”zal vytvoÅit nĆ”hled.", + "timedmedia-status-header": "Stav transkĆ³dovĆ”nĆ", + "timedmedia-update-status": "Aktualizovat stav transkĆ³dovĆ”nĆ", + "timedmedia-status": "Stav", + "timedmedia-status-unknown": "NeznĆ”mĆ½ stav", + "timedmedia-actions": "Akce", + "timedmedia-not-ready": "NepÅipraveno", + "timedmedia-completed-on": "TranskĆ³dovĆ”nĆ dokonÄeno v $1", + "timedmedia-error-on": "Chyba transkĆ³dovĆ”nĆ v $1", + "timedmedia-started-transcode": "TranskĆ³dovĆ”nĆ zaÄalo pÅed $1. $2", + "timedmedia-percent-done": "Hotovo asi $1 %", + "timedmedia-in-job-queue": "PÅed $1 pÅidĆ”no do fronty", + "timedmedia-unknown-target-size": "NeznĆ”mĆ” vĆ½slednĆ” velikost, zakĆ³dovĆ”no $1", + "timedmedia-days": "$1 {{PLURAL:$1|den|dny|dnĆ}}", + "timedmedia-hours": "$1 {{PLURAL:$1|hodina|hodiny|hodin}}", + "timedmedia-minutes": "$1 {{PLURAL:$1|minuta|minuty|minut}}", + "timedmedia-seconds": "$1 {{PLURAL:$1|sekunda|sekundy|sekund}}", + "timedmedia-reset": "Obnovit transkĆ³dovĆ”nĆ", + "timedmedia-source-file": "ZdrojovĆ½ soubor $1", + "timedmedia-source-audio-file-desc": "PÅÆvodnĆ soubor $1 ($2)", + "timedmedia-subtitle-new": "VytvoÅenĆ novĆ©ho pÅekladu nebo editace stĆ”vajĆcĆho", + "timedmedia-subtitle-new-desc": "Zvolte jazyk a stisknÄte tlaÄĆtko '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "PÅejĆt", + "timedmedia-subtitle-language": "titulky v jazyce $1 ($2)", + "timedmedia-subtitle-no-video": "K aktuĆ”lnĆ strĆ”nce titulkÅÆ nepatÅĆ Å¾Ć”dnĆ© video.", + "timedmedia-subtitle-no-subtitles": "K tomuto videu momentĆ”lnÄ neexistujĆ titulky v jazyce $1, pÅidat je mÅÆžete [{{fullurl:{{FULLPAGENAME}}|action=edit}} editacĆ tĆ©to strĆ”nky]", + "timedmedia-subtitle-remote": "SynchronizovanĆ½ text k tomuto souboru je uložen na $1", + "timedmedia-subtitle-remote-link": "[$1 StrĆ”nku s popisem tohoto souboru] si mÅÆžete prohlĆ©dnout na $2", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 videa|$1 videĆ}}", + "timedmedia-ogg-videos": "$1 {{PLURAL:$1|video|videa|videĆ}} Ogg", + "timedmedia-webm-videos": "$1 {{PLURAL:$1|video|videa|videĆ}} WebM", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transkĆ³dovĆ”nĆ}}", + "timedmedia-derivative-state-active": "$1 {{PLURAL:$1|probĆhajĆcĆ|probĆhajĆcĆ|probĆhajĆcĆch}} transkĆ³dovĆ”nĆ", + "timedmedia-derivative-state-queued": "$1 {{PLURAL:$1|naplĆ”novanĆ©|naplĆ”novanĆ”|naplĆ”novanĆ½ch}} transkĆ³dovĆ”nĆ", + "timedmedia-derivative-state-failed": "$1 {{PLURAL:$1|neĆŗspÄÅ”nĆ©|neĆŗspÄÅ”nĆ”|neĆŗspÄÅ”nĆ½ch}} transkĆ³dovĆ”nĆ", + "timedmedia-file": "Soubor", + "timedmedia-audios": "{{PLURAL:$1|$1 zvukovĆ½ soubor|$1 zvukovĆ© soubory|$1 zvukovĆ½ch souborÅÆ}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 zvukovĆ½ soubor|$1 zvukovĆ© soubory|$1 zvukovĆ½ch souborÅÆ}} Ogg", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 zvukovĆ½ soubor|$1 zvukovĆ© soubory|$1 zvukovĆ½ch souborÅÆ}} FLAC", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 zvukovĆ½ soubor|$1 zvukovĆ© soubory|$1 zvukovĆ½ch souborÅÆ}} WAV", + "right-transcode-status": "ZobrazenĆ [[Special:TimedMediaHandler|informacĆ o probĆhajĆcĆm transkĆ³dovĆ”nĆ]]", + "action-transcode-status": "vidÄt aktuĆ”lnĆ stav transkĆ³dovĆ”nĆ" +} diff --git a/extensions/TimedMediaHandler/i18n/cu.json b/extensions/TimedMediaHandler/i18n/cu.json new file mode 100644 index 00000000..5221b9ed --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/cu.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "ŠŠ¹Š" + ] + }, + "timedmedia-dismiss": "źŠ°ŠŗŃźŠø", + "timedmedia-source-file": "$1 ŠŗŠ»Š°Š“ѧźŃ", + "timedmedia-file": "Š“Ń£Š»Š¾" +} diff --git a/extensions/TimedMediaHandler/i18n/cv.json b/extensions/TimedMediaHandler/i18n/cv.json new file mode 100644 index 00000000..93c188e0 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/cv.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Chuvash2014" + ] + }, + "timedmedia-more": "ŠŃŠ¼Š°Š¹ŃŠ°Ń
ā¦" +} diff --git a/extensions/TimedMediaHandler/i18n/cy.json b/extensions/TimedMediaHandler/i18n/cy.json new file mode 100644 index 00000000..5ffa296c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/cy.json @@ -0,0 +1,50 @@ +{ + "@metadata": { + "authors": [ + "Lloffiwr", + "Ham II", + "Xxglennxx" + ] + }, + "timedmedia-ogg-short-audio": "Ffeil sain Ogg $1, $2", + "timedmedia-ogg-short-video": "Ffeil fideo Ogg $1, $2", + "timedmedia-ogg-short-general": "Ffeil gyfrwng Ogg $1, $2", + "timedmedia-ogg-long-audio": "Ffeil sain Ogg $1, yn para $2, $3", + "timedmedia-ogg-long-video": "Ffeil fideo Ogg $1, yn para $2, $4 Ć $5 picsel, $3", + "timedmedia-ogg-long-error": "Ffeil Ogg annilys: $1", + "timedmedia-more": "Mwyā¦", + "timedmedia-dismiss": "Caeer", + "timedmedia-download": "Lawrlwytho ffeil", + "timedmedia-play-media": "Chwarae'r ffeil gyfrwng", + "timedmedia-desc-link": "YnglÅ·n Ć¢'r ffeil hon", + "timedmedia-status-header": "Statws trawsgodio", + "timedmedia-update-status": "Diweddaru'r statws trawsgodio", + "timedmedia-status": "Statws", + "timedmedia-status-unknown": "Statws anhysbys", + "timedmedia-actions": "Gweithredoedd", + "timedmedia-not-ready": "Ddim yn barod", + "timedmedia-started-transcode": "Dechreuodd y trawsgodio $1 yn Ć“l. $2", + "timedmedia-percent-done": "Tua $1% wedi ei wneud", + "timedmedia-in-job-queue": "Ychwanegwyd i'r ciw tasgiau $1 yn Ć“l", + "timedmedia-unknown-target-size": "Maint anhysbys i'r gwrthrych, $1 wedi ei amgodio", + "timedmedia-days": "{{PLURAL:$1|$1 diwrnod|diwrnod|deuddydd|tridiau|$1 diwrnod}}", + "timedmedia-hours": "{{PLURAL:$1|$1 awr}}", + "timedmedia-minutes": "{{PLURAL:$1|$1 munud|$1 munud|$1 funud|$1 munud}}", + "timedmedia-seconds": "{{PLURAL:$1|$1 eiliad}}", + "timedmedia-reset": "Ailosod y trawsgodio", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "ffynhonnell $1", + "timedmedia-source-file-desc": "Y ffeil $1 gwreiddiol, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Y ffeil $1 gwreiddiol ($2)", + "timedmedia-derivative-desc-160p.ogv": "Fideo Ogg (160P) o led band isel", + "timedmedia-subtitle-new-desc": "Dewiswch iaith a gwasgu'r botwm '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Gwneler", + "timedmedia-subtitle-language": "Isdeitlau $1 ($2)", + "timedmedia-subtitle-remote-link": "Gallwch [$1 weld tudalen ddisgrifio'r] ffeil hon ar $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 fideo}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 fideo Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 fideo WebM}}", + "timedmedia-file": "Ffeil", + "action-transcode-status": "gweld statws presennol y trawsgodio" +} diff --git a/extensions/TimedMediaHandler/i18n/da.json b/extensions/TimedMediaHandler/i18n/da.json new file mode 100644 index 00000000..c9864945 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/da.json @@ -0,0 +1,100 @@ +{ + "@metadata": { + "authors": [ + "Byrial", + "Christian List", + "Fnielsen", + "HenrikKbh", + "Jon Harald SĆøby", + "Peter Alberti", + "Simeondahl", + "Steenth" + ] + }, + "timedmedia-desc": "UnderstĆøttelse for lyd, video og tidsbestemt txt med formaterne WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 lydfil, $2", + "timedmedia-ogg-short-video": "Ogg $1 videofil, $2", + "timedmedia-ogg-short-general": "Ogg $1 mediafil, $2", + "timedmedia-ogg-long-audio": "Ogg $1 lydfil, lƦngde $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videofil, lƦngde $2, $4Ć$5 pixel, $3", + "timedmedia-ogg-long-multiplexed": "Sammensat Ogg-lyd- og -videofil, $1, lƦngde $2, $4Ć$5 pixel, $3 samlet", + "timedmedia-ogg-long-general": "Ogg mediafil, lƦngde $2, $3", + "timedmedia-ogg-long-error": "Ugyldig Ogg-fil: $1", + "timedmedia-webm-short-video": "WebM $1 videofil, $2", + "timedmedia-webm-long-video": "WebM audio/video fil, $1, lƦngde $2, $4 Ć $5 pixel, $3 samlet", + "timedmedia-flac-short-audio": "FLAC lydfil, $1", + "timedmedia-flac-long-audio": "FLAC lydfil, varighed $1, $2 samlet", + "timedmedia-wav-short-audio": "WAV lydfil, $1", + "timedmedia-wav-long-audio": "WAV lydfil, varighed $1, $2 samlet", + "timedmedia-wav-pcm-required": "Du kan kun uploade PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "Mp4 $1 videofil, $2", + "timedmedia-mp4-long-video": "Mp4-fil for audio/video, $1, lƦngde $2, $4 Ć $5 pixel, $3 samlet", + "timedmedia-no-player-js": "Beklager, men din browser har enten deaktiveret JavaScript eller har ikke en afspiller, som vi understĆøtter.<br />\nDu kan enten <a href=\"$1\">hente klippet</a> eller <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">hente en afspiller</a> til at afspille klippet i din browser.", + "timedmedia-more": "Mere...", + "timedmedia-dismiss": "Luk", + "timedmedia-download": "Download fil", + "timedmedia-play-media": "Afspil medier", + "timedmedia-desc-link": "Om denne fil", + "timedmedia-oggThumb-version": "OggHandler krƦver oggThumb version $1 eller nyere.", + "timedmedia-oggThumb-failed": "oggThumb kunne ikke oprette et miniaturebillede.", + "timedmedia-status-header": "Transcode status", + "timedmedia-update-status": "Opdater transcode status", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Ukendt status", + "timedmedia-transcodeinfo": "Afledt transcode beskrivelse", + "timedmedia-actions": "Handlinger", + "timedmedia-direct-link": "Hent derivat", + "timedmedia-not-ready": "Ikke klar", + "timedmedia-completed-on": "GennemfĆørt transcode $1", + "timedmedia-error-on": "Fejl i omkodning ved $1", + "timedmedia-started-transcode": "Kode startet $1 siden. $2", + "timedmedia-percent-done": "Cirka $1 % udfĆørt", + "timedmedia-in-job-queue": "FĆøjet til jobkĆøen $1 siden", + "timedmedia-unknown-target-size": "Ukendt mĆ„l stĆørrelse, $1 kodet", + "timedmedia-days": "{{PLURAL:$1|$1 dag|$1 dage}}", + "timedmedia-hours": "{{PLURAL:$1|1 time|$1 timer}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minut|$1 minutter}}", + "timedmedia-seconds": "{{PLURAL:$1|$1 sekund|$1 sekunder}}", + "timedmedia-reset": "Nulstil transkode", + "timedmedia-reset-confirm": "Nulstilling af denne omkodning vil fjerne alle eksisterende filer (hvis der er nogen), og vil genindsƦtte omkodningen i jobkĆøen. Det vil tage nogen tid at omkode forfra.<br /><br />\nEr du sikker pĆ„, du vil fortsƦtte?", + "timedmedia-reset-error": "Fejl ved nulstilling af kode job.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 kilde", + "timedmedia-source-file-desc": "Original $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Original $1 file ($2)", + "timedmedia-derivative-desc-160p.ogv": "Lav bĆ„ndbredde Ogg video (160 P)", + "timedmedia-derivative-desc-360p.ogv": "Web streambar Ogg video (360 P)", + "timedmedia-derivative-desc-480p.ogv": "Web streambar Ogg video (480 P)", + "timedmedia-derivative-desc-720p.ogv": "HĆøjkvalitets hentbar Ogg video (720P)", + "timedmedia-derivative-desc-160p.webm": "Web streambar WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "Web streambar WebM (360 P)", + "timedmedia-derivative-desc-480p.webm": "Web streambar WebM (480 P)", + "timedmedia-derivative-desc-720p.webm": "HĆøjkvalitets hentbar WebM (720 P)", + "timedmedia-derivative-desc-320p.mp4": "enhedsvenlig MP4 (320 P)", + "timedmedia-derivative-desc-480p.mp4": "Web streambar MP4 (480 P)", + "timedmedia-derivative-desc-720p.mp4": "HD-kvalitet MP4 (720 P)", + "timedmedia-subtitle-new": "Opret nye oversƦttelse eller rediger eksisterende", + "timedmedia-subtitle-new-desc": "VƦlg sprog og tryk pĆ„ '''{{int:Timedmedia-undertitlen-ny-gĆ„}}'' ' knappen", + "timedmedia-subtitle-new-go": "KĆør", + "timedmedia-subtitle-language": "$1( $2 ) undertekster", + "timedmedia-subtitle-no-video": "Der er ingen video tilknyttet den aktuelle undertitel side", + "timedmedia-subtitle-no-subtitles": "Der er i Ćøjeblikket ingen undertekster i $1 denne video du kan [{{fullurl: {{FULLPAGENAME}} |action = Rediger}} redigere denne side] for at tilfĆøje dem", + "timedmedia-subtitle-remote": "Tidsbestemte tekst for denne fil er placeret pĆ„ $1", + "timedmedia-subtitle-remote-link": "Du kan [$1 se beskrivelses siden] til denne fil pĆ„ $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 videoer}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg video|$1 Ogg videoer}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM video|$1 WebM videoer}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transkode|$1 transkoder}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 kĆørende transcode|$1 kĆørende transcodes}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transkode i kĆø|$1 transkoder i kĆø}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transkode mislykket|$1 transkoder mislykkedes}}", + "timedmedia-file": "Fil", + "timedmedia-audios": "{{PLURAL:$1|$1 lydfil|$1 lydfiler}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg-lydfil|$1 Ogg-lydfiler}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC-lydfil|$1 FLAC-lydfiler}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV-lydfil|$1 WAV-lydfiler}}", + "right-transcode-reset": "Nulstil mislykkedes eller transkodede videoer sĆ„ de er sat ind i jobkĆøen igen.", + "right-transcode-status": "Vis [[Special:TimedMediaHandler|information om den aktuelle omkodningsaktivitet]]", + "action-transcode-status": "fĆ„ vist den aktuelle transkode status" +} diff --git a/extensions/TimedMediaHandler/i18n/de-formal.json b/extensions/TimedMediaHandler/i18n/de-formal.json new file mode 100644 index 00000000..be6d0c9d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/de-formal.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Kghbln" + ] + }, + "timedmedia-no-player-js": "Entschuldige, aber fĆ¼r Ihren Browser ist entweder die Nutzung von JavaScript deaktiviert oder er verfĆ¼gt Ć¼ber keine unterstĆ¼tzte Abspielsoftware.<br />\nSie kƶnnen <a href=\"$1\">den Clip herunterladen</a> oder <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">eine Abspielsoftware herunterladen</a>, um den Clip im Browser abspielen zu kƶnnen." +} diff --git a/extensions/TimedMediaHandler/i18n/de.json b/extensions/TimedMediaHandler/i18n/de.json new file mode 100644 index 00000000..cffaf6e2 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/de.json @@ -0,0 +1,130 @@ +{ + "@metadata": { + "authors": [ + "Filzstift", + "G.Hagedorn", + "Geitost", + "Kghbln", + "Leithian", + "Les Meloures", + "Metalhead64", + "MichaelFrey", + "Raimond Spekking", + "The Evil IP address", + "Umherirrender" + ] + }, + "extensionname-timedmedia": "TimedMediaHandler", + "timedmedia-desc": "Stellt ein Steuerungsprogramm fĆ¼r zeitgesteuerte Medien (Video, Audio, timedText) bereit, welches die Formate WebM, Ogg Theora, Ogg Vorbis und SubRip unterstĆ¼tzt", + "timedmedia-ogg-short-audio": "Ogg-$1-Audiodatei, $2", + "timedmedia-ogg-short-video": "Ogg-$1-Videodatei, $2", + "timedmedia-ogg-short-general": "Ogg-$1-Mediadatei, $2", + "timedmedia-ogg-long-audio": "Ogg-$1-Audiodatei, LƤnge: $2, $3", + "timedmedia-ogg-long-video": "Ogg-$1-Videodatei, LƤnge: $2, $4Ć$5 Pixel, $3 insgesamt", + "timedmedia-ogg-long-multiplexed": "Ogg-Audio-/Video-Datei, $1, LƤnge: $2, $4Ć$5 Pixel, $3 insgesamt", + "timedmedia-ogg-long-general": "Ogg-Mediadatei, LƤnge: $2, $3", + "timedmedia-ogg-long-error": "UngĆ¼ltige Ogg-Datei: $1", + "timedmedia-ogg-long-no-streams": "OGG-Mediendatei. Warnung: Keine der in dieser Datei verwendeten Codecs wurden erkannt.", + "timedmedia-webm-short-video": "WebM-$1-Videodatei, $2", + "timedmedia-webm-long-video": "WebM-Audio-/Video-Datei, $1, LƤnge: $2, $4Ć$5 Pixel, $3 insgesamt", + "timedmedia-flac-short-audio": "FLAC-Audiodatei, $1", + "timedmedia-flac-long-audio": "FLAC-Audiodatei, LƤnge: $1, $2 insgesamt", + "timedmedia-wav-short-audio": "WAV-Audiodatei, $1", + "timedmedia-wav-long-audio": "WAV-Audiodatei, LƤnge: $1, $2 insgesamt", + "timedmedia-wav-pcm-required": "Du kannst nur PCM-WAV-Dateien hochladen (Pulse Code Modulation).", + "timedmedia-mp4-short-video": "MP4-$1-Videodatei, $2", + "timedmedia-mp4-long-video": "MP4-Audio-/Video-Datei, $1, LƤnge $2, $4 Ć $5 Pixel, $3 insgesamt", + "timedmedia-no-player-js": "Entschuldige, aber fĆ¼r deinen Browser ist entweder die Nutzung von JavaScript deaktiviert oder er verfĆ¼gt Ć¼ber keine unterstĆ¼tzte Abspielsoftware.<br />\nDu kannst <a href=\"$1\">den Clip herunterladen</a> oder <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">eine Abspielsoftware herunterladen</a>, um den Clip im Browser abspielen zu kƶnnen.", + "timedmedia-more": "Optionen ā¦", + "timedmedia-dismiss": "SchlieĆen", + "timedmedia-download": "Datei herunterladen", + "timedmedia-play-media": "Mediendatei abspielen", + "timedmedia-desc-link": "Ćber diese Datei", + "timedmedia-oggThumb-version": "OggHandler erfordert oggThumb in der Version $1 oder hƶher.", + "timedmedia-oggThumb-failed": "oggThumb konnte kein Miniaturbild erstellen.", + "timedmedia-status-header": "Transkodierungstatus", + "timedmedia-update-status": "Transkodierungstatus aktualisieren", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Unbekannter Status", + "timedmedia-transcodebitrate": "Bitrate", + "timedmedia-transcodeduration": "Kodierungszeit", + "timedmedia-transcodeinfo": "Format", + "timedmedia-actions": "Aktionen", + "timedmedia-direct-link": "Herunterladen", + "timedmedia-not-ready": "Nicht bereit", + "timedmedia-completed-on": "Abgeschlossen um $1", + "timedmedia-error-on": "Fehler um $1", + "timedmedia-started-transcode": "Gestartet vor $1. $2", + "timedmedia-percent-done": "UngefƤhr $1 % sind erledigt", + "timedmedia-in-job-queue": "Vor $1 der Auftragswarteschlange hinzugefĆ¼gt", + "timedmedia-unknown-target-size": "Unbekannte ZielgrƶĆe, $1 codiert", + "timedmedia-days": "{{PLURAL:$1|1 Tag|$1 Tagen}}", + "timedmedia-hours": "{{PLURAL:$1|1 Stunde|$1 Stunden}}", + "timedmedia-minutes": "{{PLURAL:$1|1 Minute|$1 Minuten}}", + "timedmedia-seconds": "{{PLURAL:$1|1 Sekunde|$1 Sekunden}}", + "timedmedia-reset": "UmschlĆ¼sselung zurĆ¼cksetzen", + "timedmedia-reset-confirm": "Das ZurĆ¼cksetzen dieser UmschlĆ¼sselung wird, sofern vorhanden, die bestehende Datei entfernen und die UmschlĆ¼sselung erneut der Auftragswarteschlange hinzufĆ¼gen. Die erneute UmschlĆ¼sselung wird einige Zeit dauern.<br /><br />Soll dies tatsƤchlich gemacht werden?", + "timedmedia-reset-error": "Fehler beim ZurĆ¼cksetzen der UmschlĆ¼sselung", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Quelle ($1)", + "timedmedia-source-file-desc": "Original $1-Datei, $2 x $3 ($4)", + "timedmedia-source-audio-file-desc": "UrsprĆ¼ngliche $1-Datei ($2)", + "timedmedia-derivative-160p.ogv": "Ogg (160p)", + "timedmedia-derivative-desc-160p.ogv": "Ogg-Videodatei mit niedriger DatenĆ¼bertragungsrate (160p)", + "timedmedia-derivative-desc-240p.ogv": "WebstreamfƤhiges OGG-Video (240p)", + "timedmedia-derivative-desc-360p.ogv": "WebstreamingfƤhige Ogg-Videodatei (360p)", + "timedmedia-derivative-desc-480p.ogv": "WebstreamingfƤhige Ogg-Videodatei (480p)", + "timedmedia-derivative-desc-720p.ogv": "Qualitativ hochwertige Ogg-Videodatei (720p)", + "timedmedia-derivative-desc-1080p.ogv": "Herunterladbares Full-HD-OGG-Video (1080p)", + "timedmedia-derivative-desc-160p.webm": "WebstreamingfƤhige WebM-Videodatei (160p)", + "timedmedia-derivative-desc-360p.webm": "WebstreamingfƤhige WebM-Videodatei (360p)", + "timedmedia-derivative-desc-480p.webm": "WebstreamingfƤhige WebM-Videodatei (480p)", + "timedmedia-derivative-desc-720p.webm": "Qualitativ hochwertige WebM-Videodatei (720p)", + "timedmedia-derivative-desc-1080p.webm": "Herunterladbares Full-HD-WebM-Video (1080p)", + "timedmedia-derivative-desc-2160p.webm": "Herunterladbares Full-4K-WebM-Video (2160P)", + "timedmedia-derivative-360p.vp9.webm": "VP9 360P", + "timedmedia-derivative-desc-360p.vp9.webm": "WebstreamfƤhiges WebM-VP9-Video (360P)", + "timedmedia-derivative-480p.vp9.webm": "VP9 480P", + "timedmedia-derivative-desc-480p.vp9.webm": "WebstreamfƤhiges WebM-VP9-Video (480P)", + "timedmedia-derivative-720p.vp9.webm": "VP9 720P", + "timedmedia-derivative-desc-720p.vp9.webm": "HD-streamfƤhiges WebM-VP9-Video (720P)", + "timedmedia-derivative-1080p.vp9.webm": "VP9 1080P", + "timedmedia-derivative-desc-1080p.vp9.webm": "Full-HD-streamfƤhiges WebM-VP9-Video (1080P)", + "timedmedia-derivative-desc-2160p.vp9.webm": "StreamfƤhiges Full-4K-WebM-VP9-Video (2160P)", + "timedmedia-derivative-desc-320p.mp4": "GerƤtefreundliche MP4-Datei (320P)", + "timedmedia-derivative-desc-480p.mp4": "WebstreamingfƤhige MP4-Datei (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4-Datei in HD-QualitƤt (720P)", + "timedmedia-derivative-desc-1080p.mp4": "Full-HD-QualitƤt-MP4-Video (1080p)", + "timedmedia-derivative-desc-2160p.mp4": "Full-4K-QualitƤts-MP4-Video (2160P)", + "timedmedia-subtitle-new": "Neue Ćbersetzung erstellen oder vorhandene bearbeiten", + "timedmedia-subtitle-new-desc": "WƤhle eine Sprache aus und klicke auf '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Los", + "timedmedia-subtitle-language": "$1 ($2) Untertitel", + "timedmedia-subtitle-no-video": "Der aktuellen Seite mit Untertiteln ist kein Video zugeordnet.", + "timedmedia-subtitle-no-subtitles": "Derzeit gibt es keine Untertitel auf $1 fĆ¼r dieses Video. Zum HinzufĆ¼gen von Untertiteln kann [{{fullurl:{{FULLPAGENAME}}|action=edit}} diese Seite] bearbeitet werden.", + "timedmedia-subtitle-remote": "timedText fĆ¼r diese Datei befindet sich auf $1", + "timedmedia-subtitle-remote-link": "Du kannst [$1 die Beschreibungsseite] fĆ¼r diese Datei auf $2 ansehen", + "timedmediahandler": "Steuerungsprogramm fĆ¼r zeitgesteuerte Medien", + "timedmedia-videos": "{{PLURAL:$1|Ein Video|$1 Videos}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|Ein Ogg-Video|$1 Ogg-Videos}}", + "timedmedia-webm-videos": "{{PLURAL:$1|Ein WebM-Video|$1 WebM-Videos}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|Eine UmschlĆ¼sselung|$1 UmschlĆ¼sselungen}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|Eine laufende UmschlĆ¼sselung|$1 laufende UmschlĆ¼sselungen}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|Eine UmschlĆ¼sselung|$1 UmschlĆ¼sselungen}} in der Warteschlange", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|Eine fehlgeschlagene UmschlĆ¼sselung|$1 fehlgeschlagene UmschlĆ¼sselungen}}", + "timedmedia-file": "Datei", + "timedmedia-audios": "{{PLURAL:$1|Eine Audiodatei|$1 Audiodateien}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|Eine OGG-Audiodatei|$1 OGG-Audiodateien}}", + "timedmedia-flac-audios": "{{PLURAL:$1|Eine FLAC-Audiodatei|$1 FLAC-Audiodateien}}", + "timedmedia-wav-audios": "{{PLURAL:$1|Eine WAV-Audiodatei|$1 WAV-Audiodateien}}", + "right-transcode-reset": "Fehlgeschlagene oder erfolgreiche UmschlĆ¼sselungen von Video-Dateien zurĆ¼cksetzen, um sie erneut in die Auftragswarteschlange einzureihen", + "right-transcode-status": "[[Special:TimedMediaHandler|Informationen Ć¼ber aktuelle UmschlĆ¼sselungen]] betrachten", + "action-transcode-status": "den aktuellen Transkodierungstatus anzusehen", + "orphanedtimedtext": "Verwaiste TimedText-Seiten", + "orphanedtimedtext-summary": "Liste der [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]]-Seiten, die keine entsprechende Datei haben.", + "orphanedtimedtext-unsupported": "Diese Spezialseite wird nur auf MySQL-Datenbanken unterstĆ¼tzt.", + "orphanedtimedtext-notimedtext": "TimedText ist auf diesem Wiki nicht aktiviert.", + "apihelp-query+transcodestatus-example-1": "Ruft den Transkodierungsstatus fĆ¼r [[:File:Clip.webm]] ab", + "apihelp-transcodereset-param-title": "Der Titel der Mediendatei.", + "apihelp-transcodereset-example-1": "Setzt alle UmschlĆ¼sselungen fĆ¼r [[:File:Clip.webm]] zurĆ¼ck" +} diff --git a/extensions/TimedMediaHandler/i18n/din.json b/extensions/TimedMediaHandler/i18n/din.json new file mode 100644 index 00000000..194e1a5e --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/din.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Dinkawiki" + ] + }, + "timedmedia-source-file": "$1 tĆ«nĆ«yƶk" +} diff --git a/extensions/TimedMediaHandler/i18n/diq.json b/extensions/TimedMediaHandler/i18n/diq.json new file mode 100644 index 00000000..1b1ba84c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/diq.json @@ -0,0 +1,41 @@ +{ + "@metadata": { + "authors": [ + "Aspar", + "Erdemaslancan", + "Gorizon", + "Marmase", + "Mirzali", + "Xoser" + ] + }, + "timedmedia-desc": "Qen dĆŖ dosyayan dĆŖ WebM, Ogg Theora, Vorbis, srt rĆŖxo desti veng dekerdıŠu nuÅte ronayıÅ", + "timedmedia-ogg-short-audio": "Ogg $1 dosyaya vengi, $2", + "timedmedia-ogg-short-video": "Ogg $1 dosyaya filmi, $2", + "timedmedia-ogg-short-general": "Ogg $1 dosyaya medyayi, $2", + "timedmedia-ogg-long-audio": "Ogg $1 dosyaya medyayi, mudde $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 dosyaya filmi, mudde $2, $4Ć$5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg dosyaya filmi/vengi yo multiexed, $1, mudde $2, $4Ć$5 piksel, $3 bıumumi", + "timedmedia-ogg-long-general": "Ogg dosyaya medyayi, mudde $2, $3", + "timedmedia-ogg-long-error": "dosyaya oggi yo nemeqbul: $1", + "timedmedia-more": "hema....", + "timedmedia-dismiss": "RacnĆŖ", + "timedmedia-download": "dosya biyar war", + "timedmedia-play-media": "Medya bıcıne", + "timedmedia-desc-link": "Heqa na dosya de", + "timedmedia-status": "Weziyet", + "timedmedia-status-unknown": "Weziyeto nĆŖzanaye", + "timedmedia-transcodeinfo": "Åınasiya babetĆŖ transkodi", + "timedmedia-actions": "KerdıÅi", + "timedmedia-not-ready": "Hazır niyo", + "timedmedia-days": "{{PLURAL:$1|1 roce|$1 roci}}", + "timedmedia-hours": "{{PLURAL:$1|1 seate|$1 seati}}", + "timedmedia-minutes": "{{PLURAL:$1|1 deqa|$1 deqey}}", + "timedmedia-seconds": "{{PLURAL:$1|1 saniya|$1 saniyey}}", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 Ƨıme", + "timedmedia-source-audio-file-desc": "Dosyaya $1 oricinale ($2)", + "timedmedia-subtitle-new-go": "Åo", + "timedmediahandler": "ProgramĆŖ kontroliĆŖ zemanĆŖ kontrolbiyayey", + "timedmedia-file": "Dosya" +} diff --git a/extensions/TimedMediaHandler/i18n/dsb.json b/extensions/TimedMediaHandler/i18n/dsb.json new file mode 100644 index 00000000..6b65986b --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/dsb.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Michawiki" + ] + }, + "timedmedia-desc": "WĆ³ÅŗeÅski program za awdio, wideo a timedText, z formatoweju pĆ³dpÄru za WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 awdiodataja, $2", + "timedmedia-ogg-short-video": "Ogg $1 wideodataja, $2", + "timedmedia-ogg-short-general": "Ogg $1 medijowa dataja, $2", + "timedmedia-ogg-long-audio": "Ogg $1 awdiodataja, dÅujkosÄ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 wideodataja, dÅujkosÄ $2, $4Ć$5 pikselow, $3", + "timedmedia-ogg-long-multiplexed": "ogg multipleksowa awdio-/wideodataja, $1, dÅujkosÄ $2, $4Ć$5 pikselow, $3 dogromady", + "timedmedia-ogg-long-general": "Ogg medijowa dataja, dÅujkosÄ $2, $3", + "timedmedia-ogg-long-error": "NjepÅaÅiwa Ogg-dataja: $1", + "timedmedia-webm-short-video": "WebM $1 wideodataja, $2", + "timedmedia-webm-long-video": "WebM dataja awdio/wideo, $1, dÅujkosÄ $2, $4 x $5, $3 dogromady", + "timedmedia-no-player-js": "TwĆ³j wobglÄdowak jo bĆ³Å¾ko pak JavaScript znjemĆ³Å¾niÅ abo njama njepĆ³dpÄrany wĆ³tegrawak.<br />\nMĆ³Å¾oÅ” <a href=\"$1\">klip zeÅÄgnuÅ</a> abo <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">wĆ³tgrawak zeÅÄgnuÅ</a>, aby klip w swĆ³jom wobglÄdowaku wĆ³tegraÅ.", + "timedmedia-more": "WÄcej...", + "timedmedia-dismiss": "ZacyniÅ", + "timedmedia-download": "Dataju zeÅÄgnuÅ", + "timedmedia-play-media": "Medijowu dataju wĆ³tegraÅ", + "timedmedia-desc-link": "WĆ³ toÅ tej dataji", + "timedmedia-oggThumb-version": "OggHandler trjeba wersiju $1 oggThumb abo nowÅ”u.", + "timedmedia-oggThumb-failed": "oggThumb njejo mĆ³gÅ wobrazk napĆ³raÅ.", + "timedmedia-source-file": "ŽrÄdÅo ($1)", + "timedmedia-source-file-desc": "Originalna $1-dataja, $2 Ć $3 ($4)", + "timedmedia-derivative-desc-160p.ogv": "Niska Å”yrokosÄ pasma Ogg-widea (200p)", + "timedmedia-subtitle-language": "$1 ($2) pĆ³dtitele" +} diff --git a/extensions/TimedMediaHandler/i18n/dty.json b/extensions/TimedMediaHandler/i18n/dty.json new file mode 100644 index 00000000..905f6b6d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/dty.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "ą¤ą¤Øą¤ ą¤°ą¤¾ą¤ ą¤ą¤ą„ą¤", + "ą¤°ą¤®ą„ą¤¶ ą¤øą¤æą¤ą¤¹ ą¤¬ą„ą¤¹ą¤°ą¤¾", + "ą¤°ą¤¾ą¤® ą¤Ŗą„ą¤°ą¤øą¤¾ą¤¦ ą¤ą„ą¤¶ą„" + ] + }, + "timedmedia-no-player-js": "ą¤®ą¤¾ą¤« ą¤ą¤°ą„ą¤Æą¤¾, ą¤¤ą¤®ą¤°ą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤°ą¤®ą„ ą¤Æą¤¾ ą¤¤ ą¤ą¤¾ą¤µą¤¾ą¤øą„ą¤ą„ą¤°ą¤æą¤Ŗą„ą¤ ą¤
ą¤ą„ą¤·ą¤® ą¤ ą¤Æą¤¾ ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤ą„ą¤Ø ą„¤<br />\ną¤¤ą¤®ą„ <a href=\"$1\">ą¤ą„ą¤²ą¤æą¤Ŗą¤²ą¤¾ą¤ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤¦ą„ą¤¦ ą¤øą¤ą„ą¤¦ą„ą¤Æą¤¾ą¤¹ą„ ą¤
ą¤„ą¤µą¤¾ ą¤ą„ą¤²ą¤æą¤Ŗą¤²ą¤¾ą¤ ą¤ą¤«ą„ą¤Øą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤°ą¤®ą„ ą¤ą¤²ą¤¾ą¤ą¤Øą¤ą„ ą¤²ą¤¾ą¤ą¤æ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¤ą¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤¦ą„ą¤¦ ą¤øą¤ą„ą¤¦ą„ą¤Æą¤¾ ą¤¹ą„ ą„¤", + "timedmedia-source-file": "$1 ą¤¶ą„ą¤°ą„ą¤¤", + "timedmedia-source-audio-file-desc": "ą¤ą¤¾ą¤ø $1 ą¤ą¤æą¤¤ą„ą¤° ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/ee.json b/extensions/TimedMediaHandler/i18n/ee.json new file mode 100644 index 00000000..993eb5df --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ee.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Aguve" + ] + }, + "timedmedia-no-player-js": "TafltsÉ, YavaSkript mele sisi internet-dÉwÉnua dzi alo Ęonu aÉeke meli si ate Åu aĘoe o.<br />\nĆte Åu <a href=\"$1\">awÉ video kpui sia Ęe kÉpi le</a> alo <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">wÉ Ęonu aÉe Ęe kÉpi</a> nĆ tsÉ aĘo video kpui sia le wĆ² internet-dÉwÉnua me.", + "timedmedia-source-file": "TsoĘe $1" +} diff --git a/extensions/TimedMediaHandler/i18n/el.json b/extensions/TimedMediaHandler/i18n/el.json new file mode 100644 index 00000000..f1791421 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/el.json @@ -0,0 +1,28 @@ +{ + "@metadata": { + "authors": [ + "Consta", + "Dead3y3", + "Omnipaedista", + "ZaDiak", + "Evropi", + "Geraki" + ] + }, + "timedmedia-desc": "Ī§ĪµĪ¹ĻĪ¹ĻĻĪ®Ļ Ī³Ī¹Ī± Ī±ĻĻĪµĪÆĪ± Ogg Theora ĪŗĪ±Ī¹ Vorbis, Ī¼Īµ Ī±Ī½Ī±ĻĪ±ĻĪ±Ī³ĻĪ³ĪĪ± JavaScript", + "timedmedia-ogg-short-audio": "ĪĻĻĪµĪÆĪæ Ī®ĻĪæĻ
Ogg $1, $2", + "timedmedia-ogg-short-video": "ĪĻĻĪµĪÆĪæ Ī²ĪÆĪ½ĻĪµĪæ Ogg $1, $2", + "timedmedia-ogg-short-general": "ĪĻĻĪµĪÆĪæ Ī¼ĪĻĻĪ½ Ogg $1, $2", + "timedmedia-ogg-long-audio": "ĪĻĻĪµĪÆĪæ Ī®ĻĪæĻ
Ogg $1, Ī“Ī¹Ī¬ĻĪŗĪµĪ¹Ī± $2, $3", + "timedmedia-ogg-long-video": "ĪĻĻĪµĪÆĪæ Ī²ĪÆĪ½ĻĪµĪæ Ogg $1, Ī“Ī¹Ī¬ĻĪŗĪµĪ¹Ī± $2, $4Ć$5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "ĪĻĻĪµĪÆĪæ ĻĪæĪ»Ļ
ĻĪ»ĪµĪŗĻĪ¹ĪŗĪæĻ Ī®ĻĪæĻ
/Ī²ĪÆĪ½ĻĪµĪæ Ogg, $1, Ī“Ī¹Ī¬ĻĪŗĪµĪ¹Ī± $2, $4Ć$5 pixels, $3 ĪæĪ»Ī¹ĪŗĪ¬", + "timedmedia-ogg-long-general": "ĪĻĻĪµĪÆĪæ Ī¼ĪĻĻĪ½ Ogg, Ī“Ī¹Ī¬ĻĪŗĪµĪ¹Ī± $2, $3", + "timedmedia-ogg-long-error": "ĪĪŗĻ
ĻĪæ Ī±ĻĻĪµĪÆĪæ ogg: $1", + "timedmedia-no-player-js": "Ī£Ļ
Ī³Ī½ĻĪ¼Ī·, ĻĪæ ĻĻĻĪ³ĻĪ±Ī¼Ī¼Ī± ĻĪµĻĪ¹Ī®Ī³Ī·ĻĪ®Ļ ĻĪ±Ļ ĪµĪÆĻĪµ ĪĻĪµĪ¹ ĻĪ·Ī½ JavaScript Ī±ĻĪµĪ½ĪµĻĪ³ĪæĻĪæĪ¹Ī·Ī¼ĪĪ½Ī· Ī® Ī“ĪµĪ½ ĪĻĪµĪ¹ ĪæĻĪæĪ¹ĪæĪ“Ī®ĻĪæĻĪµ Ļ
ĻĪæĻĻĪ·ĻĪ¹Ī¶ĻĪ¼ĪµĪ½Īæ player.<br />\nĪĻĪæĻĪµĪÆĻĪµ Ī½Ī± <a href=\"$1\">ĪŗĪ±ĻĪµĪ²Ī¬ĻĻĪµ ĻĪæ ĪŗĪ»Ī¹Ļ</a> Ī® Ī½Ī± <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ĪŗĪ¬Ī½ĪµĻĪµ Ī»Ī®ĻĪ· ĪµĪ½ĻĻ player</a> Ī³Ī¹Ī± Ī½Ī± Ī±Ī½Ī±ĻĪ±ĻĪ¬Ī³ĪµĻĪµ ĻĪæ ĪŗĪ»Ī¹Ļ ĻĻĪæĪ½ browser ĻĪ±Ļ.", + "timedmedia-more": "Ī ĪµĻĪ¹ĻĻĻĻĪµĻĪ±...", + "timedmedia-dismiss": "ĪĪ»ĪµĪÆĻĪ¹Ī¼Īæ", + "timedmedia-download": "ĪĪ±ĻĪµĪ²Ī¬ĻĻĪµ ĻĪæ Ī±ĻĻĪµĪÆĪæ", + "timedmedia-desc-link": "Ī£ĻĪµĻĪ¹ĪŗĪ¬ Ī¼Īµ Ī±Ļ
ĻĻ ĻĪæ Ī±ĻĻĪµĪÆĪæ", + "timedmedia-source-file": "Ī Ī·Ī³Ī® $1", + "timedmedia-source-audio-file-desc": "Ī ĻĻĻĻĻĻ
ĻĪæ Ī±ĻĻĪµĪÆĪæ $1 ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/en-gb.json b/extensions/TimedMediaHandler/i18n/en-gb.json new file mode 100644 index 00000000..001bb5cc --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/en-gb.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Shirayuki", + "Captaindogfish" + ] + }, + "timedmedia-ogg-long-no-streams": "Ogg media file. Warning: None of the codecs used in this file are recognised.", + "timedmedia-derivative-desc-1080p.ogv": "Full HD downloadable Ogg video (1080P)", + "timedmedia-derivative-desc-1080p.webm": "Full HD downloadable WebM (1080P)", + "timedmedia-derivative-desc-1080p.mp4": "Full HD quality MP4 (1080P)" +} diff --git a/extensions/TimedMediaHandler/i18n/en.json b/extensions/TimedMediaHandler/i18n/en.json new file mode 100644 index 00000000..b17d0665 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/en.json @@ -0,0 +1,154 @@ +{ + "@metadata": { + "authors": [] + }, + "extensionname-timedmedia": "TimedMediaHandler", + "timedmedia-desc": "Handler for audio, video and timed text, with format support for WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 sound file, $2", + "timedmedia-ogg-short-video": "Ogg $1 video file, $2", + "timedmedia-ogg-short-general": "Ogg $1 media file, $2", + "timedmedia-ogg-long-audio": "Ogg $1 sound file, length $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 video file, length $2, $4 Ć $5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "Ogg multiplexed audio/video file, $1, length $2, $4 Ć $5 pixels, $3 overall", + "timedmedia-ogg-long-general": "Ogg media file, length $2, $3", + "timedmedia-ogg-long-error": "Invalid Ogg file: $1", + "timedmedia-ogg-long-no-streams": "Ogg media file. Warning: None of the codecs used in this file are recognized.", + "timedmedia-webm-short-video": "WebM $1 video file, $2", + "timedmedia-webm-long-video": "WebM audio/video file, $1, length $2, $4 Ć $5 pixels, $3 overall", + "timedmedia-flac-short-audio": "FLAC audio file, $1", + "timedmedia-flac-long-audio": "FLAC audio file, length $1, $2 overall", + "timedmedia-wav-short-audio": "WAV audio file, $1", + "timedmedia-wav-long-audio": "WAV audio file, length $1, $2 overall", + "timedmedia-wav-pcm-required": "You can only upload PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "MP4 $1 video file, $2", + "timedmedia-mp4-long-video": "MP4 audio/video file, $1, length $2, $4 Ć $5 pixels, $3 overall", + "timedmedia-no-player-js": "Sorry, your browser either has JavaScript disabled or does not have any supported player.<br />\nYou can <a href=\"$1\">download the clip</a> or <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">download a player</a> to play the clip in your browser.", + "timedmedia-more": "Moreā¦", + "timedmedia-dismiss": "Close", + "timedmedia-download": "Download file", + "timedmedia-play-media": "Play media", + "timedmedia-desc-link": "About this file", + "timedmedia-oggThumb-version": "OggHandler requires oggThumb version $1 or later.", + "timedmedia-oggThumb-failed": "oggThumb failed to create the thumbnail.", + "timedmedia-status-header": "Transcode status", + "timedmedia-update-status": "Update transcode status", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Unknown status", + "timedmedia-transcodebitrate": "Bitrate", + "timedmedia-transcodeduration": "Encode time", + "timedmedia-transcodeinfo": "Format", + "timedmedia-actions": "Actions", + "timedmedia-direct-link": "Download", + "timedmedia-not-ready": "Not ready", + "timedmedia-completed-on": "Completed $1", + "timedmedia-error-on": "Error on $1", + "timedmedia-started-transcode": "Started $1 ago. $2", + "timedmedia-percent-done": "About $1% done", + "timedmedia-in-job-queue": "Added to Job queue $1 ago", + "timedmedia-unknown-target-size": "Unknown target size, $1 encoded", + "timedmedia-days": "{{PLURAL:$1|1 day|$1 days}}", + "timedmedia-hours": "{{PLURAL:$1|1 hour|$1 hours}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minute|$1 minutes}}", + "timedmedia-seconds": "{{PLURAL:$1|1 second|$1 seconds}}", + "timedmedia-reset": "Reset transcode", + "timedmedia-reset-confirm": "Resetting this transcode will remove any existing file (if present), and it will re-add the transcode to the job queue. It will take some time to re-transcode.<br /><br />\nAre you sure you want to proceed?", + "timedmedia-reset-error": "Error in resetting transcode job.", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-mp4": "MP4", + "timedmedia-wav": "WAV", + "timedmedia-flac": "FLAC", + "timedmedia-source-file": "$1 source", + "timedmedia-source-file-desc": "Original $1 file, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Original $1 file ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160P", + "timedmedia-derivative-desc-160p.ogv": "Low bandwidth Ogg video (160P)", + "timedmedia-derivative-240p.ogv": "Ogg 240P", + "timedmedia-derivative-desc-240p.ogv": "Web streamable Ogg video (240P)", + "timedmedia-derivative-360p.ogv": "Ogg 360P", + "timedmedia-derivative-desc-360p.ogv": "Web streamable Ogg video (360P)", + "timedmedia-derivative-480p.ogv": "Ogg 480P", + "timedmedia-derivative-desc-480p.ogv": "Web streamable Ogg video (480P)", + "timedmedia-derivative-720p.ogv": "Ogg 720P", + "timedmedia-derivative-desc-720p.ogv": "High quality downloadable Ogg video (720P)", + "timedmedia-derivative-1080p.ogv": "Ogg 1080P", + "timedmedia-derivative-desc-1080p.ogv": "Full HD downloadable Ogg video (1080P)", + "timedmedia-derivative-160p.webm": "WebM 160P", + "timedmedia-derivative-desc-160p.webm": "Web streamable WebM (160P)", + "timedmedia-derivative-360p.webm": "WebM 360P", + "timedmedia-derivative-desc-360p.webm": "Web streamable WebM (360P)", + "timedmedia-derivative-480p.webm": "WebM 480P", + "timedmedia-derivative-desc-480p.webm": "Web streamable WebM (480P)", + "timedmedia-derivative-720p.webm": "WebM 720P", + "timedmedia-derivative-desc-720p.webm": "High quality downloadable WebM (720P)", + "timedmedia-derivative-1080p.webm": "WebM 1080P", + "timedmedia-derivative-desc-1080p.webm": "Full HD downloadable WebM (1080P)", + "timedmedia-derivative-2160p.webm": "WebM 2160P", + "timedmedia-derivative-desc-2160p.webm": "Full 4K downloadable WebM (2160P)", + "timedmedia-derivative-360p.vp9.webm": "VP9 360P", + "timedmedia-derivative-desc-360p.vp9.webm": "Web streamable WebM VP9 (360P)", + "timedmedia-derivative-480p.vp9.webm": "VP9 480P", + "timedmedia-derivative-desc-480p.vp9.webm": "Web streamable WebM VP9 (480P)", + "timedmedia-derivative-720p.vp9.webm": "VP9 720P", + "timedmedia-derivative-desc-720p.vp9.webm": "HD streamable WebM VP9 (720P)", + "timedmedia-derivative-1080p.vp9.webm": "VP9 1080P", + "timedmedia-derivative-desc-1080p.vp9.webm": "Full HD streamable WebM VP9 (1080P)", + "timedmedia-derivative-2160p.vp9.webm": "VP9 2160P", + "timedmedia-derivative-desc-2160p.vp9.webm": "Full 4K streamable WebM VP9 (2160P)", + "timedmedia-derivative-320p.mp4": "H264 320P", + "timedmedia-derivative-desc-320p.mp4": "Device-friendly MP4 (320P)", + "timedmedia-derivative-480p.mp4": "H264 480P", + "timedmedia-derivative-desc-480p.mp4": "Web streamable MP4 (480P)", + "timedmedia-derivative-720p.mp4": "H264 720P", + "timedmedia-derivative-desc-720p.mp4": "HD quality MP4 (720P)", + "timedmedia-derivative-1080p.mp4": "H264 1080P", + "timedmedia-derivative-desc-1080p.mp4": "Full HD quality MP4 (1080P)", + "timedmedia-derivative-2160p.mp4": "H264 2160P", + "timedmedia-derivative-desc-2160p.mp4": "Full 4K quality MP4 (2160P)", + "timedmedia-derivative-ogg": "Ogg Vorbis", + "timedmedia-derivative-desc-ogg": "Ogg Vorbis", + "timedmedia-derivative-opus": "Opus", + "timedmedia-derivative-desc-opus": "Opus", + "timedmedia-derivative-mp3": "MP3", + "timedmedia-derivative-desc-mp3": "MP3", + "timedmedia-derivative-m4a": "AAC", + "timedmedia-derivative-desc-m4a": "AAC", + "timedmedia-subtitle-new": "Create new translation or edit existing", + "timedmedia-subtitle-new-desc": "Select language and press the '''{{int:Timedmedia-subtitle-new-go}}''' button", + "timedmedia-subtitle-new-go": "Go", + "timedmedia-subtitle-language": "$1 ($2) subtitles", + "timedmedia-subtitle-no-video": "There is no video associated with the current subtitle page.", + "timedmedia-subtitle-no-subtitles": "There are currently no subtitles in $1 for this video, you can [{{fullurl:{{FULLPAGENAME}}|action=edit}} edit this page] to add them.", + "timedmedia-subtitle-remote": "Timed text for this file is hosted on $1", + "timedmedia-subtitle-remote-link": "You can [$1 view the description page] for this file on $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 videos}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg video|$1 Ogg videos}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM video|$1 WebM videos}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcode|$1 transcodes}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 running transcode|$1 running transcodes}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 queued transcode|$1 queued transcodes}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 failed transcode|$1 failed transcodes}}", + "timedmedia-file": "File", + "timedmedia-audios": "{{PLURAL:$1|$1 audio file|$1 audio files}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg audio file|$1 Ogg audio files}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC audio file|$1 FLAC audio files}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV audio file|$1 WAV audio files}}", + "right-transcode-reset": "Reset failed or transcoded videos so they are inserted into the job queue again", + "right-transcode-status": "View [[Special:TimedMediaHandler|information about the current transcode activity]]", + "action-transcode-status": "view the current transcoding status", + "orphanedtimedtext": "Orphaned TimedText pages", + "orphanedtimedtext-summary": "List of [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] pages which do not have a corresponding file.", + "orphanedtimedtext-unsupported": "This special page is only supported on MySQL databases.", + "orphanedtimedtext-notimedtext": "TimedText is not enabled on this wiki.", + "apihelp-query+transcodestatus-description": "Get transcode status for a given file page.", + "apihelp-query+transcodestatus-example-1": "Get transcode status for [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "Extends imageinfo to include video source (derivatives) information", + "apihelp-query+videoinfo-param-prop": "What video information to get:\n;timestamp:Adds timestamp for the uploaded version.\n;user:Adds the user who uploaded the video version.\n;userid:Add the user ID that uploaded the video version.\n;comment:Comment on the version.\n;parsedcomment:Parse the comment on the version.\n;canonicaltitle:Adds the canonical title of the video file.\n;url:Gives URL to the video and the description page.\n;size:Adds the size of the video in bytes, its height and its width. Page count and duration are added if applicable.\n;dimensions:Alias for size.\n;sha1:Adds SHA-1 hash for the video.\n;mime:Adds MIME type of the video.\n;thumbmime:Adds MIME type of the video thumbnail (requires url and param $1urlwidth).\n;mediatype:Adds the media type of the video.\n;metadata:Lists Exif metadata for the version of the video.\n;commonmetadata:Lists file format generic metadata for the version of the video.\n;extmetadata:Lists formatted metadata combined from multiple sources. Results are HTML formatted.\n;archivename:Adds the filename of the archive version for non-latest versions.\n;bitdepth:Adds the bit depth of the version.\n;uploadwarning:Used by the [[Special:Upload]] page to get information about an existing file. Not intended for use outside MediaWiki core.\n;derivatives:Adds an array of the different format and quality versions of an audio or video file that are available.", + "apihelp-query+videoinfo-example-1": "Fetch information about [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "Users with the 'transcode-reset' right can reset and re-run a transcode job.", + "apihelp-transcodereset-param-title": "The media file title.", + "apihelp-transcodereset-param-transcodekey": "The transcode key you wish to reset. Fetch from [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "Reset all transcodes for [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "Reset the '360_560kbs.webm' transcode key for [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/eo.json b/extensions/TimedMediaHandler/i18n/eo.json new file mode 100644 index 00000000..436317ea --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/eo.json @@ -0,0 +1,26 @@ +{ + "@metadata": { + "authors": [ + "Amikeco", + "ArnoLagrange", + "Yekrats", + "KuboF" + ] + }, + "timedmedia-desc": "Traktilo por sondosieroj, videoj, kaj horloÄigita teksto, kun formatsubteno por WebM kaj Ogg Theora kaj Vobis kaj srt.", + "timedmedia-ogg-short-audio": "Ogg $1 sondosiero, $2", + "timedmedia-ogg-short-video": "Ogg $1 videodosiero, $2", + "timedmedia-ogg-short-general": "Media Ogg-dosiero $1, $2", + "timedmedia-ogg-long-audio": "AÅda Ogg-dosiero $1, longeco $2, $3 entute", + "timedmedia-ogg-long-video": "Video Ogg-dosiero $1, longeco $2, $4Ć$5 pikseloj, $3 entute", + "timedmedia-ogg-long-multiplexed": "Kunigita aÅdio/video Ogg-dosiero, $1, longeco $2, $4Ć$5 pikseloj, $3 entute", + "timedmedia-ogg-long-general": "Ogg-mediodosiero, longeco $2, $3", + "timedmedia-ogg-long-error": "Malvalida Ogg-dosiero: $1", + "timedmedia-no-player-js": "Pardonu, estas malÅaltita Äavoskripto en via foliumilo aÅ Äi enhavas neniun subtenatan ludilon<br />\nVi povas <a href=\"$1\">elÅuti la videaĵon</a> aÅ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">elÅuti ludilon</a> por povi ludi la videaĵon en via foliumilo.", + "timedmedia-more": "Pli...", + "timedmedia-dismiss": "Fermi", + "timedmedia-download": "AlÅuti dosieron", + "timedmedia-desc-link": "Pri Äi tiu dosiero", + "timedmedia-source-file": "Fonta $1-dosiero", + "timedmedia-source-audio-file-desc": "Origina $1-dosiero ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/es.json b/extensions/TimedMediaHandler/i18n/es.json new file mode 100644 index 00000000..962436fb --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/es.json @@ -0,0 +1,117 @@ +{ + "@metadata": { + "authors": [ + "Aleator", + "Armando-Martin", + "Ciencia Al Poder", + "Crazymadlover", + "Jewbask", + "Maor X", + "Muro de Aguas", + "Remember the dot", + "Rodrigo Molinero", + "Rzuwig", + "Sanbec", + "Spacebirdy", + "Translationista", + "Fitoschido", + "Macofe" + ] + }, + "timedmedia-desc": "Manipulador de sonido, vĆdeo y texto sincronizado, con soporte para los formatos WebM, Ogg Theora, Vorbis y srt", + "timedmedia-ogg-short-audio": "Archivo de sonido Ogg $1, $2", + "timedmedia-ogg-short-video": "Archivo de video Ogg $1, $2", + "timedmedia-ogg-short-general": "Archivo Ogg $1, $2", + "timedmedia-ogg-long-audio": "Archivo de sonido Ogg $1, tamaƱo $2, $3", + "timedmedia-ogg-long-video": "Archivo de video Ogg $1, tamaƱo $2, $4Ć$5 pĆxeles, $3", + "timedmedia-ogg-long-multiplexed": "Archivo Ogg de audio/video multiplexado, $1, tamaƱo $2, $4Ć$5 pĆxeles, $3 en todo", + "timedmedia-ogg-long-general": "Archivo Ogg. tamaƱo $2, $3", + "timedmedia-ogg-long-error": "Archivo Ogg no vĆ”lido: $1", + "timedmedia-webm-short-video": "Archivo de vĆdeo WebM $1, $2", + "timedmedia-webm-long-video": "Archivo de audio/vĆdeo WebM, $1 , longitud $2 , $4 Ć $5 pĆxeles, $3 total", + "timedmedia-flac-short-audio": "Archivo de audio FLAC, $1", + "timedmedia-flac-long-audio": "Archivo de audio FLAC, duraciĆ³n: $1, $2 en general", + "timedmedia-wav-short-audio": "Archivo de audio WAV, $1", + "timedmedia-wav-long-audio": "Archivo de audio WAV, duraciĆ³n: $1, $2 en general", + "timedmedia-wav-pcm-required": "Solo puedes cargar WAV del tipo PCM (''Pulse Code Modulation'', por sus siglas en inglĆ©s).", + "timedmedia-mp4-short-video": "Archivo de vĆdeo MP4 $1, $2", + "timedmedia-mp4-long-video": "Archivo de audio/vĆdeo MP4, $1 , longitud $2 , $4 Ć $5 pĆxeles, $3 total", + "timedmedia-no-player-js": "Tu navegador tiene JavaScript desactivado o no tiene un reproductor compatible.<br />\nPuedes <a href=\"$1\">descargar el vĆdeo</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">descargar un reproductor</a> para ver el vĆdeo en tu navegador.", + "timedmedia-more": "Opciones...", + "timedmedia-dismiss": "Cerrar", + "timedmedia-download": "Descargar archivo", + "timedmedia-play-media": "Reproducir contenido multimedia", + "timedmedia-desc-link": "Sobre este archivo", + "timedmedia-oggThumb-version": "OggHandler requiere una versiĆ³n oggThumb $1 o posterior.", + "timedmedia-oggThumb-failed": "oggThumb no pudo crear la imagen miniatura.", + "timedmedia-status-header": "Estado de transcodificaciĆ³n", + "timedmedia-update-status": "Actualizar el estado de transcodificaciĆ³n", + "timedmedia-status": "Estado", + "timedmedia-status-unknown": "Estado desconocido", + "timedmedia-transcodeduration": "Tiempo de codificaciĆ³n", + "timedmedia-transcodeinfo": "Formato", + "timedmedia-actions": "Acciones", + "timedmedia-direct-link": "Descarga", + "timedmedia-not-ready": "No estĆ” listo", + "timedmedia-completed-on": "Completada $1", + "timedmedia-error-on": "Error a las $1", + "timedmedia-started-transcode": "Comenzada hace $1. $2", + "timedmedia-percent-done": "Aproximadamente $1 % completado", + "timedmedia-in-job-queue": "AƱadido a la cola de trabajos hace $1", + "timedmedia-unknown-target-size": "TamaƱo de archivo de destino desconocido, $1 codificado", + "timedmedia-days": "{{PLURAL:$1|1 dĆa|$1 dĆas}}", + "timedmedia-hours": "{{PLURAL:$1|1 hora|$1 horas}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuto|$1 minutos}}", + "timedmedia-seconds": "{{PLURAL:$1|1 segundo|$1 segundos}}", + "timedmedia-reset": "Reiniciar la transcodificaciĆ³n", + "timedmedia-reset-confirm": "Restablecer esta transcodificaciĆ³n eliminarĆ” cualquier archivo existente (si existe), y volverĆ” a aƱadir la transcodificaciĆ³n a la cola de trabajos. LlevarĆ” algĆŗn tiempo repetir la transcodificaciĆ³n.<br /><br />\nĀæEstĆ”s seguro de que quieres continuar?", + "timedmedia-reset-error": "Error al restablecer el trabajo de transcodificaciĆ³n.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Fuente $1", + "timedmedia-source-file-desc": "Archivo $1 original, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Archivo $1 original ($2)", + "timedmedia-derivative-desc-160p.ogv": "Video en formato Ogg de bajo ancho de banda (160 P)", + "timedmedia-derivative-desc-360p.ogv": "VĆdeo Ogg para la web (360P)", + "timedmedia-derivative-desc-480p.ogv": "VĆdeo Ogg para la web (480P)", + "timedmedia-derivative-desc-720p.ogv": "VĆdeo Ogg de alta calidad que se puede descargar (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Video ogg descargable Full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "WebM para la web (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM para la web (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM para la web (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM de alta calidad que se puede descargar (720P)", + "timedmedia-derivative-desc-1080p.webm": "WebM descargable Full HD (1080P)", + "timedmedia-derivative-desc-320p.mp4": "MP4 para dispositivos mĆ³viles (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 para la web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 de calidad HD (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4 calidad Full HD (1080P)", + "timedmedia-subtitle-new": "Crear una nueva traducciĆ³n o editar una existente", + "timedmedia-subtitle-new-desc": "Selecciona el idioma y pulsa el botĆ³n '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Ir", + "timedmedia-subtitle-language": "SubtĆtulos en $1 ($2)", + "timedmedia-subtitle-no-video": "No hay ningĆŗn video asociado con la pĆ”gina actual de subtĆtulos", + "timedmedia-subtitle-no-subtitles": "Actualmente no hay subtĆtulos en $1 para este video, puede [{{fullurl: {{FULLPAGENAME}} |action = edit}} editar esta pĆ”gina] para agregarlos", + "timedmedia-subtitle-remote": "El texto programado para este archivo estĆ” alojado en $1", + "timedmedia-subtitle-remote-link": "Puedes [$1 ver la pĆ”gina de descripciĆ³n] de este archivo en $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 vĆdeo|$1 vĆdeos}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 vĆdeo Ogg|$1 vĆdeos Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 vĆdeo WebM|$1 vĆdeos WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodificaciĆ³n|$1 transcodificaciones}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodificaciĆ³n activa|$1 transcodificaciones activas}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodificaciĆ³n|$1 transcodificaciones}} en la cola", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transcodificaciĆ³n fallida|$1 transcodificaciones fallidas}}", + "timedmedia-file": "Archivo", + "timedmedia-audios": "{{PLURAL:$1|$1 archivo|$1 archivos}} de audio", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 archivo|$1 archivos}} de audio Ogg", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 archivo|$1 archivos}} de audio FLAC", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 archivo|$1 archivos}} de audio WAV", + "right-transcode-reset": "Reiniciar los vĆdeos errĆ³neos o transcodificados por lo que se vuelven a colocar en la cola de trabajo", + "right-transcode-status": "Ver [[Special:TimedMediaHandler|informaciĆ³n sobre la actividad de transcodificaciĆ³n actual]]", + "action-transcode-status": "ver el estado de transcodificaciĆ³n actual", + "orphanedtimedtext": "PĆ”ginas TimedText huĆ©rfanas", + "orphanedtimedtext-summary": "Lista de pĆ”ginas [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] que no tienen un archivo correspondiente.", + "orphanedtimedtext-unsupported": "Esta pĆ”gina especial sĆ³lo estĆ” soportada en base de datos MySQL.", + "orphanedtimedtext-notimedtext": "TimedText no se activĆ³ en este wiki.", + "apihelp-query+videoinfo-example-1": "Obtener informaciĆ³n sobre [[:File:Folgers.ogv]]", + "apihelp-transcodereset-param-title": "El tĆtulo del archivo multimedia." +} diff --git a/extensions/TimedMediaHandler/i18n/et.json b/extensions/TimedMediaHandler/i18n/et.json new file mode 100644 index 00000000..ce910777 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/et.json @@ -0,0 +1,122 @@ +{ + "@metadata": { + "authors": [ + "Avjoska", + "Pikne", + "Silvar" + ] + }, + "timedmedia-desc": "WebM-, srt- ning Theora- ja Vorbis-tĆ¼Ć¼pi Ogg-vormingu toega heli-, video- ja ajastatud teksti kƤsitseja", + "timedmedia-ogg-short-audio": "$1-tĆ¼Ć¼pi Ogg-helifail, $2", + "timedmedia-ogg-short-video": "$1-tĆ¼Ć¼pi Ogg-videofail, $2", + "timedmedia-ogg-short-general": "$1-tĆ¼Ć¼pi Ogg-fail, $2", + "timedmedia-ogg-long-audio": "$1-tĆ¼Ć¼pi Ogg-helifail, kestus: $2, $3", + "timedmedia-ogg-long-video": "$1-tĆ¼Ć¼pi Ogg-videofail, kestus: $2, $4Ć$5 pikslit, $3", + "timedmedia-ogg-long-multiplexed": "Ogg-liitfail (heli ja video), $1, kestus: $2, $4Ć$5 pikslit, Ć¼ldbitikiirus: $3", + "timedmedia-ogg-long-general": "Ogg-fail, kestus: $2, $3", + "timedmedia-ogg-long-error": "Vigane Ogg-fail: $1", + "timedmedia-ogg-long-no-streams": "Ogg-meediafail. Hoiatus: Selles failis ei kasutata Ć¼htegi tuvastatud kodekit.", + "timedmedia-webm-short-video": "$1-tĆ¼Ć¼pi WebM-videofail, $2", + "timedmedia-webm-long-video": "WebM-fail (heli ja video), $1, kestus: $2, $4Ć$5 pikslit, Ć¼ldbitikiirus: $3", + "timedmedia-flac-short-audio": "FLAC-helifail, $1", + "timedmedia-flac-long-audio": "FLAC-helifail, kestus: $1, Ć¼ldbitikiirus: $2", + "timedmedia-wav-short-audio": "WAV-helifail, $1", + "timedmedia-wav-long-audio": "WAV-helifail, kestus: $1, Ć¼ldbitikiirus: $2", + "timedmedia-wav-pcm-required": "Saad Ć¼les laadida ainult impulssmodulatsiooniga (PCM) WAV-faile.", + "timedmedia-mp4-short-video": "$1-tĆ¼Ć¼pi MP4-videofail, $2", + "timedmedia-mp4-long-video": "MP4-fail (heli ja video), $1, kestus: $2, $4Ć$5 pikslit, Ć¼ldbitikiirus: $3", + "timedmedia-no-player-js": "Kahjuks on sinu veebilehitsejas JavaScript keelatud vƵi puudub sul sobiv esitustarkvara.<br />\nSaad <a href=\"$1\">lƵigu alla laadida</a> vƵi <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">laadida alla tarkvara</a>, millega lƵik veebilehitsejas esitada.", + "timedmedia-more": "Lisa...", + "timedmedia-dismiss": "Sule", + "timedmedia-download": "Laadi fail alla", + "timedmedia-play-media": "Esita meediafail", + "timedmedia-desc-link": "Info faili kohta", + "timedmedia-oggThumb-version": "OggHandleri jaoks on vaja oggThumbi versiooni $1 vƵi hilisemat.", + "timedmedia-oggThumb-failed": "oggThumb ei saanud pisipildi loomisega hakkama.", + "timedmedia-status-header": "Ćmberkodeeringu olek", + "timedmedia-update-status": "VƤrskenda Ć¼mberkodeeringu olekut", + "timedmedia-status": "Olek", + "timedmedia-status-unknown": "Tundmatu olek", + "timedmedia-transcodebitrate": "Bitikiirus", + "timedmedia-transcodeduration": "Kodeerimisaeg", + "timedmedia-transcodeinfo": "Vorming", + "timedmedia-actions": "Toimingud", + "timedmedia-direct-link": "Allalaadimine", + "timedmedia-not-ready": "Ei ole valmis", + "timedmedia-completed-on": "Valmimisaeg: $1", + "timedmedia-error-on": "TƵrkeaeg: $1", + "timedmedia-started-transcode": "Alustatud $1 tagasi. $2", + "timedmedia-percent-done": "Umbes $1% valmis", + "timedmedia-in-job-queue": "Lisatud tƶƶjƤrge $1 tagasi", + "timedmedia-unknown-target-size": "Sihtsuurus teadmata, $1 kodeeritud", + "timedmedia-days": "{{PLURAL:$1|1 pƤev|$1 pƤeva}}", + "timedmedia-hours": "{{PLURAL:$1|1 tund|$1 tundi}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minut|$1 minutit}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekund|$1 sekundit}}", + "timedmedia-reset": "LƤhtesta Ć¼mberkodeering", + "timedmedia-reset-confirm": "Ćmberkodeeringu lƤhtestamisel eemaldatakse kƵik olemasolevad failid (kui neid on) ja see lisatakse uuesti tƶƶjƤrge. Uus Ć¼mberkodeering kestab mƵnda aega.<br /><br />\nKas oled kindel, et tahad jƤtkata?", + "timedmedia-reset-error": "Ćmberkodeeringu lƤhtestamisel ilmnes tƵrge.", + "timedmedia-source-file": "Allikas ($1)", + "timedmedia-source-file-desc": "Algne $1-fail, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Algne $1-fail ($2)", + "timedmedia-derivative-desc-160p.ogv": "VƤikse ribalaiusega Ogg-video (160P)", + "timedmedia-derivative-desc-240p.ogv": "VƵrgus voogedastatav Ogg-video (240P)", + "timedmedia-derivative-desc-360p.ogv": "VƵrgus voogedastatav Ogg-video (360P)", + "timedmedia-derivative-desc-480p.ogv": "VƵrgus voogedastatav Ogg-video (480P)", + "timedmedia-derivative-desc-720p.ogv": "KƵrge kvaliteediga allalaaditav Ogg-video (720P)", + "timedmedia-derivative-desc-1080p.ogv": "TƤiskƵrglahutusega allalaaditav Ogg-video (1080P)", + "timedmedia-derivative-desc-160p.webm": "VƵrgus voogedastatav WebM-video (160P)", + "timedmedia-derivative-desc-360p.webm": "VƵrgus voogedastatav WebM-video (360P)", + "timedmedia-derivative-desc-480p.webm": "VƵrgus voogedastatav WebM-video (480P)", + "timedmedia-derivative-desc-720p.webm": "KƵrge kvaliteediga allalaaditav WebM-video (720P)", + "timedmedia-derivative-desc-1080p.webm": "TƤiskƵrglahutusega allalaaditav WebM-video (1080P)", + "timedmedia-derivative-desc-2160p.webm": "Allalaaditav 4K-tƤislahutusega WebM-video (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "VƵrgus voogedastatav VP9-tĆ¼Ć¼pi WebM-video (360P)", + "timedmedia-derivative-desc-480p.vp9.webm": "VƵrgus voogedastatav VP9-tĆ¼Ć¼pi WebM-video (480P)", + "timedmedia-derivative-desc-720p.vp9.webm": "KƵrglahutusega voogedastatav VP9-tĆ¼Ć¼pi WebM-video (720P)", + "timedmedia-derivative-desc-1080p.vp9.webm": "TƤiskƵrglahutusega voogedastatav VP9-tĆ¼Ć¼pi WebM-video (1080P)", + "timedmedia-derivative-desc-2160p.vp9.webm": "Voogedastatav 4K-tƤislahutusega VP9-tĆ¼Ć¼pi WebM-video (2160P)", + "timedmedia-derivative-desc-320p.mp4": "Seadmetele sobiv MP4-video (320P)", + "timedmedia-derivative-desc-480p.mp4": "VƵrgus voogedastatav MP4-video (480P)", + "timedmedia-derivative-desc-720p.mp4": "KƵrglahutusega MP4-video (720P)", + "timedmedia-derivative-desc-1080p.mp4": "TƤiskƵrglahutusega MP4-kvaliteetvideo (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "4K-tƤislahutusega MP4-kvaliteetvideo (2160P)", + "timedmedia-subtitle-new": "Uue tƵlkega alustamine vƵi olemasoleva muutmine", + "timedmedia-subtitle-new-desc": "Vali keel ja klƵpsa nuppu '''{{int:Timedmedia-subtitle-new-go}}'''.", + "timedmedia-subtitle-new-go": "Mine", + "timedmedia-subtitle-language": "$1 ($2) alltiitrid", + "timedmedia-subtitle-no-video": "Puudub selle alltiitrite lehekĆ¼ljega seotud video.", + "timedmedia-subtitle-no-subtitles": "Selle video alltiitrid puuduvad praegu selles keeles ($1). Saad seda lehekĆ¼lge [{{fullurl:{{FULLPAGENAME}}|action=edit}} redigeerida], et need lisada.", + "timedmedia-subtitle-remote": "Selle faili ajastatud tekst on hoidlas $1", + "timedmedia-subtitle-remote-link": "Selle faili [$1 kirjelduslehekĆ¼lge] saad vaadata hoidlas $2.", + "timedmediahandler": "Ajastatud meediafailide tƶƶtleja", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 videot}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg-video|$1 Ogg-videot}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM-video|$1 WebM-videot}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|Ćks Ć¼mberkodeering|$1 Ć¼mberkodeeringut}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|Ćks|$1}} tƤitmisel {{PLURAL:$1|Ć¼mberkodeering|Ć¼mberkodeeringut}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|Ćks|$1}} ootel {{PLURAL:$1|Ć¼mberkodeering|Ć¼mberkodeeringut}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|Ćks|$1}} ebaƵnnestunud {{PLURAL:$1|Ć¼mberkodeering|Ć¼mberkodeeringut}}", + "timedmedia-file": "Fail", + "timedmedia-audios": "{{PLURAL:$1|$1 helifail|$1 helifaili}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg-helifail|$1 Ogg-helifaili}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC-helifail|$1 FLAC-helifaili}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV-helifail|$1 WAV-helifaili}}", + "right-transcode-reset": "LƤhtestada ebaƵnnestunud vƵi Ć¼mberkodeeritud videoid, nii et need lisatakse uuesti tƶƶjƤrge", + "right-transcode-status": "Vaadata [[Special:TimedMediaHandler|teavet praegu aktiivsete Ć¼mberkodeeringute kohta]]", + "action-transcode-status": "vaadata praegust Ć¼mberkodeeringute olekut", + "orphanedtimedtext": "Ajastatud teksti orblehekĆ¼ljed", + "orphanedtimedtext-summary": "Loend nimeruumi [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] lehekĆ¼lgedest, millele vastav fail puudub.", + "orphanedtimedtext-unsupported": "Seda erilehekĆ¼lge toetatakse ainult MySQL-andmebaasides.", + "orphanedtimedtext-notimedtext": "Ajastatud tekst pole selles vikis lubatud.", + "apihelp-query+transcodestatus-description": "Antud faili Ć¼mberkodeerimise oleku hankimine.", + "apihelp-query+transcodestatus-example-1": "Hangi faili [[:File:Clip.webm|Clip.webm]] Ć¼mberkodeerimise olek", + "apihelp-query+videoinfo-description": "Laiendab moodulit \"imageinfo\", kaasa arvatakse teave video allika (tuletiste) kohta.", + "apihelp-query+videoinfo-param-prop": "Millist teavet video kohta hankida:\n;timestamp: Lisab Ć¼les laaditud versiooni ajatempli.\n;user: Lisab kasutaja, kes videoversiooni Ć¼les laadis.\n;userid: Lisab videoversiooni Ć¼les laadinud kasutaja identifikaatori.\n;comment: Lisab versioonikommentaari.\n;parsedcomment: Parsib versioonikommentaari.\n;canonicaltitle: Lisab videofaili kanoonilise pealkirja.\n;url: Tagastab videofaili ja kirjelduslehekĆ¼lje internetiaadressi.\n;size: Lisab video suuruse baitides ning selle kƵrguse ja laiuse. LehekĆ¼lgede arv ja kestus lisatakse, kui see on kohane.\n;dimensions: Elemendi \"size\" rƶƶpnimi.\n;sha1: Lisab video SHA-1 rƤsivƤƤrtuse.\n;mime: Lisab video MIME tĆ¼Ć¼bi.\n;thumbmime: Lisab video pisipildi MIME tĆ¼Ć¼bi (vaja elementi \"url\" ja parameetrit \"$1urlwidth\").\n;mediatype: Lisab video meediatĆ¼Ć¼bi.\n;metadata: Loetleb videoversiooni Exif-metaandmed.\n;commonmetadata: Loetleb videoversiooni failivormingu Ć¼ldised metaandmed.\n;extmetadata: Loetleb mitme allika vormindatud Ć¼hendmetaandmed. Tulemused on HTML-vormingus.\n;archivename: Lisab praegusest versioonist vanemate arhiiviversioonide failinimed.\n;bitdepth: Lisab versiooni bitisĆ¼gavuse.\n;uploadwarning: Kasutab lehekĆ¼lg [[Special:Upload]], et saada teavet olemasoleva faili kohta. Pole mƵeldud kasutamiseks vƤljaspool MediaWiki keskosa.\n;derivatives: Lisab heli- vƵi videofaili erinevaid saadaolevaid vorminguid ja kvaliteediversioone sisaldava massiivi.", + "apihelp-query+videoinfo-example-1": "Faili [[:File:Folgers.ogv|Folgers.ogv]] teabe vƤljavƵtt", + "apihelp-transcodereset-description": "Kasutajad, kellel on Ƶigus \"transcode-reset\", saavad Ć¼mberkodeerimistƶƶd lƤhtestada ja uuesti kƤitada.", + "apihelp-transcodereset-param-title": "Meediafaili pealkiri.", + "apihelp-transcodereset-param-transcodekey": "LƤhtestatava Ć¼mberkodeerimise vƵti. Leitav pƤringuga [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "LƤhtesta kƵik faili [[:File:Clip.webm|Clip.webm]] Ć¼mberkodeeringud", + "apihelp-transcodereset-example-2": "LƤhtesta faili [[:File:Clip.webm|Clip.webm]] Ć¼mberkodeerimisvƵti '360_560kbs.webm'" +} diff --git a/extensions/TimedMediaHandler/i18n/eu.json b/extensions/TimedMediaHandler/i18n/eu.json new file mode 100644 index 00000000..fb5ff526 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/eu.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "An13sa", + "Joxemai", + "Theklan", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ", + "Subi", + "Sator" + ] + }, + "timedmedia-desc": "Ogg Theora eta Vorbis fitxategientzako edukiontzia, JavaScript playerrarekin", + "timedmedia-ogg-short-audio": "Ogg $1 soinu fitxategia, $2", + "timedmedia-ogg-short-video": "Ogg $1 bideo fitxategia, $2", + "timedmedia-ogg-short-general": "Ogg $1 media fitxategia, $2", + "timedmedia-ogg-long-audio": "Ogg $1 soinu fitxategia, $2 iraupea, $3", + "timedmedia-ogg-long-error": "ogg fitxategi okerra: $1", + "timedmedia-more": "Gehiago...", + "timedmedia-dismiss": "Itxi", + "timedmedia-download": "Fitxategia jaitsi", + "timedmedia-desc-link": "Fitxategi honen inguruan", + "timedmedia-status": "Egoera", + "timedmedia-transcodeinfo": "Formatua", + "timedmedia-direct-link": "Jaitsi", + "timedmedia-source-file": "$1 iturri", + "timedmedia-source-audio-file-desc": "Jatorrizko $1 fitxategia ($2)", + "timedmedia-subtitle-new-go": "Joan", + "timedmedia-file": "Fitxategia" +} diff --git a/extensions/TimedMediaHandler/i18n/fa.json b/extensions/TimedMediaHandler/i18n/fa.json new file mode 100644 index 00000000..2a3a549c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/fa.json @@ -0,0 +1,123 @@ +{ + "@metadata": { + "authors": [ + "Alireza", + "Armin1392", + "Calak", + "Ebraminio", + "Huji", + "Mahdiz", + "Mjbmr", + "Reza1615", + "Ų¬ŁŲ§ŲÆ", + "Ł¾Ų§ŁŲ§Ų±ŁŁ
Ų§", + "Mehran" + ] + }, + "extensionname-timedmedia": "ŁŲÆŲ§ŪŲŖāŚ©ŁŁŲÆŁ Ų±Ų³Ų§ŁŁŁ Ų²Ł
Ų§ŁāŲÆŲ§Ų±", + "timedmedia-desc": "ŲØŁ ŲÆŲ³ŲŖ ŚÆŪŲ±ŁŲÆŁŁ Ł¾Ų±ŁŁŲÆŁāŁŲ§Ū ŲµŁŲŖŪŲ ŲŖŲµŁŪŲ±Ū Ł Ł
ŲŖŁāŁŲ§Ū Ų²Ł
Ų§ŁāŲØŁŲÆŪ Ų“ŲÆŁ ŲØŲ§ Ł¾Ų“ŲŖŪŲØŲ§ŁŪ Ų§Ų² Ogg Theora ŲVorbis Ł srt", + "timedmedia-ogg-short-audio": "Ł¾Ų±ŁŁŲÆŁ ŲµŁŲŖŪ Ogg $1Ų $2", + "timedmedia-ogg-short-video": "Ł¾Ų±ŁŁŲÆŁ ŲŖŲµŁŪŲ±Ū Ogg $1Ų $2", + "timedmedia-ogg-short-general": "Ł¾Ų±ŁŁŲÆŁ Ogg $1Ų $2", + "timedmedia-ogg-long-audio": "Ł¾Ų±ŁŁŲÆŁ ŲµŁŲŖŪ Ogg $1Ų Ł
ŲÆŲŖ $2Ų $3", + "timedmedia-ogg-long-video": "Ł¾Ų±ŁŁŲÆŁ ŲŖŲµŁŪŲ±Ū Ogg $1Ų Ł
ŲÆŲŖ $2 Ų $4Ć$5 Ł¾ŪŚ©Ų³ŁŲ $3", + "timedmedia-ogg-long-multiplexed": "Ł¾Ų±ŁŁŲÆŁ ŲµŁŲŖŪ/ŲŖŲµŁŪŲ±Ū Ł¾ŪŚŪŲÆŁ OggŲ $1Ų Ł
ŲÆŲŖ $2Ų $4Ć$5 Ł¾ŪŚ©Ų³ŁŲ $3 ŲÆŲ± Ł
Ų¬Ł
ŁŲ¹", + "timedmedia-ogg-long-general": "Ł¾Ų±ŁŁŲÆŁ OggŲ Ł
ŲÆŲŖ $2Ų $3", + "timedmedia-ogg-long-error": "Ł¾Ų±ŁŁŲÆŁŁ Ogg ŁŲ§Ł
Ų¬Ų§Ų²: $1", + "timedmedia-ogg-long-no-streams": "Ł¾Ų±ŁŁŲÆŁŁ Ų±Ų³Ų§ŁŁāŲ§Ū Ogg. ŁŲ“ŲÆŲ§Ų±: ŁŪŚāŪŚ© Ų§Ų² Ų§ŪŁ Ś©ŲÆŚ©āŁŲ§Ū Ų§Ų³ŲŖŁŲ§ŲÆŁāŲ“ŲÆŁ ŲÆŲ± Ų§ŪŁ Ł¾Ų±ŁŁŲÆŁāŁŲ§ Ų“ŁŲ§Ų®ŲŖŁāŲ“ŲÆŁ ŁŪŲ³ŲŖŁŲÆ.", + "timedmedia-webm-short-video": "Ų±Ų³Ų§ŁŁŁ ŁŲØ $1 Ł¾Ų±ŁŁŲÆŁŁ ŁŪŲÆŲ¦ŁŪŪŲ $2", + "timedmedia-webm-long-video": "Ų±Ų³Ų§ŁŁŁ ŁŲØ Ł¾Ų±ŁŁŲÆŁŁ ŲµŁŲŖŪ/ŲŖŲµŁŪŲ±ŪŲ $1Ų Ł
ŲÆŲŖ $2Ų $4 Ć $5 Ł¾ŪŚ©Ų³ŁŲ $3 Ś©ŁŪ", + "timedmedia-flac-short-audio": "Ł¾Ų±ŁŁŲÆŁŁ ŲµŁŲŖŪ Ų§ŁāŲ§ŁāŲ§ŪāŲ³ŪŲ $1", + "timedmedia-flac-long-audio": "Ł¾Ų±ŁŁŲÆŁŁ ŲµŁŲŖŪ Ų§ŁāŲ§ŁāŲ§ŪāŲ³ŪŲ Ł
ŲÆŲŖ $1Ų $2 Ś©ŁŪ", + "timedmedia-wav-short-audio": "Ł¾Ų±ŁŁŲÆŁŁ ŲµŁŲŖŪ WAVŲ $1", + "timedmedia-wav-long-audio": "Ł¾Ų±ŁŁŲÆŁŁ ŲµŁŲŖŪ WAVŲ Ł
ŲÆŲŖ $1Ų $2 Ś©ŁŪ", + "timedmedia-wav-pcm-required": "Ų“Ł
Ų§ ŁŁŲ· Ł
Ū ŲŖŁŲ§ŁŪŲÆ PCM Ł WAV Ų±Ų§ ŲØŲ§Ų± Ś©ŁŪŲÆ.", + "timedmedia-mp4-short-video": "MP4 $1 Ł¾Ų±ŁŁŲÆŁŁ ŁŪŲÆŲ¦ŁŪŪŲ $2", + "timedmedia-mp4-long-video": "Ł¾Ų±ŁŁŲÆŁāŁŲ§Ū ŲµŁŲŖŪ ŪŲ§ ŲŖŲµŁŪŲ±Ū ŲØŲ§ ŁŲ§ŁŲØ $1Ų Ų²Ł
Ų§Ł $2Ų $4 Ć $5 Ł¾ŪŚ©Ų³Ł Ł $3 ŲØŁ Ų·ŁŲ±Ś©ŁŪ", + "timedmedia-no-player-js": "ŲØŲ§ Ų¹Ų±Ų¶ Ł¾ŁŲ²Ų“Ų ŁŲ±Ł
Ų§ŁŲ²Ų§Ų± Ų¬Ų§ŁŲ§ Ų§Ų³Ś©Ų±ŪŁ¾ŲŖ ŲØŲ±Ų±ŁŪ Ł
Ų±ŁŲ±ŚÆŲ± Ų“Ł
Ų§ ŁŲ¹Ų§Ł ŁŪŲ³ŲŖŲ Ł ŪŲ§ Ł
Ų±ŁŲ±ŚÆŲ± Ų“Ł
Ų§ Ų§Ų² Ų§ŪŁ ŁŲ±Ł
Ų§ŁŲ²Ų§Ų± Ł¾Ų“ŲŖŪŲØŲ§ŁŪ ŁŁ
Ū Ś©ŁŲÆ.<br />\nŲ“Ł
Ų§ Ł
ŪŲŖŁŲ§ŁŪŲÆ <a href=\"$1\">Ų§ŪŁ ŁŪŲÆŪŁ Ų±Ų§ ŲÆŲ§ŁŁŁŲÆ</a> Ł ŪŲ§ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŪŚ© Ł¾Ų®Ų“ Ś©ŁŁŲÆŁ</a> ŲØŲ±Ų§Ū Ų§Ų¬Ų±Ų§Ū Ų§ŪŁ ŁŪŲÆŪŁ ŲÆŲ§ŁŁŁŲÆ ŁŁ
Ų§ŪŪŲÆ.", + "timedmedia-more": "ŲØŪŲ“ŲŖŲ±...", + "timedmedia-dismiss": "ŲØŲ³ŲŖŁ", + "timedmedia-download": "ŲÆŲ±ŪŲ§ŁŲŖ Ł¾Ų±ŁŁŲÆŁ", + "timedmedia-play-media": "Ł¾Ų®Ų“ Ų±Ų³Ų§ŁŁ", + "timedmedia-desc-link": "ŲÆŲ±ŲØŲ§Ų±ŁŁ Ų§ŪŁ Ł¾Ų±ŁŁŲÆŁ", + "timedmedia-oggThumb-version": "ŁŚÆŁŲÆŲ§Ų±ŁŲÆŁŁ Ogg ŲØŁ ŲØŁŲÆāŲ§ŁŚÆŲ“ŲŖŪ Ogg ŁŲ³Ų®ŁŁ $1 ŪŲ§ ŲØŲ§ŁŲ§ŲŖŲ± ŁŪŲ§Ų² ŲÆŲ§Ų±ŲÆ.", + "timedmedia-oggThumb-failed": "ŲØŁŲÆŲ§ŁŚÆŲ“ŲŖŪ Ogg ŲÆŲ± Ų³Ų§Ų®ŲŖ ŲØŁŲÆŲ§ŁŚÆŲ“ŲŖŪ ŲØŲ§ Ų®Ų·Ų§ Ł
ŁŲ§Ų¬Ł Ų“ŲÆ.", + "timedmedia-status-header": "ŁŲ¶Ų¹ŪŲŖ ŁŲ±Ų§Ś©ŲÆ", + "timedmedia-update-status": "ŁŲ¶Ų¹ŪŲŖ ŲØŁāŲ±ŁŲ²Ų±Ų³Ų§ŁŪ ŁŲ±Ų§Ś©ŲÆ", + "timedmedia-status": "ŁŲ¶Ų¹ŪŲŖ", + "timedmedia-status-unknown": "ŁŲ¶Ų¹ŪŲŖ ŁŲ§Ų“ŁŲ§Ų®ŲŖŁ", + "timedmedia-transcodeinfo": "ŲŖŁŲ¶ŪŲŲ§ŲŖ Ų§Ų“ŲŖŁŲ§ŁŪ ŁŲ±Ų§Ś©ŲÆ", + "timedmedia-actions": "ŁŲ¹Ų§ŁŪŲŖāŁŲ§", + "timedmedia-direct-link": "ŲÆŲ±ŪŲ§ŁŲŖ Ų§Ų“ŲŖŁŲ§ŁŪ", + "timedmedia-not-ready": "Ų¢Ł
Ų§ŲÆŁ ŁŪŲ³ŲŖ", + "timedmedia-completed-on": "ŲŖŚ©Ł
ŪŁ ŁŲ±Ų§Ś©ŲÆ $1", + "timedmedia-error-on": "Ų®Ų·Ų§ ŲÆŲ± ŁŲ±Ų§Ś©ŲÆ ŲÆŲ± $1", + "timedmedia-started-transcode": "ŁŲ±Ų§Ś©ŲÆ $1 Ł¾ŪŲ“ Ų¢ŲŗŲ§Ų² Ų“ŲÆ. $2", + "timedmedia-percent-done": "ŲŲÆŁŲÆ $1% Ų§ŁŲ¬Ų§Ł
Ų“ŲÆŁ", + "timedmedia-in-job-queue": "Ų§Ų¶Ų§ŁŁāŲ“ŲÆ ŲØŁ ŲµŁ Ś©Ų§Ų± $1 Ł¾ŪŲ“", + "timedmedia-unknown-target-size": "Ų§ŁŲÆŲ§Ų²ŁŁ ŁŲÆŁ ŁŲ§Ų“ŁŲ§Ų®ŲŖŁŲ $1 Ų±Ł
Ų²Ū", + "timedmedia-days": "{{PLURAL:$1|1 Ų±ŁŲ²|$1 Ų±ŁŲ²}}", + "timedmedia-hours": "{{PLURAL:$1|1 Ų³Ų§Ų¹ŲŖ|$1 Ų³Ų§Ų¹ŲŖ}}", + "timedmedia-minutes": "{{PLURAL:$1|1 ŲÆŁŪŁŁ|$1 ŲÆŁŪŁŁ}}", + "timedmedia-seconds": "{{PLURAL:$1|1 Ų«Ų§ŁŪŁ|$1 Ų«Ų§ŁŪŁ}}", + "timedmedia-reset": "ŲŖŁŲøŪŁ
Ł
Ų¬ŲÆŲÆ ŁŲ±Ų§Ś©ŲÆ", + "timedmedia-reset-confirm": "ŲŖŁŲøŪŁ
Ł
Ų¬ŲÆŲÆ ŁŲ±Ų§Ś©ŲÆ Ł¾Ų±ŁŁŲÆŁāŁŲ§Ū Ł
ŁŲ¬ŁŲÆ Ų±Ų§ ŲŲ°Ł Ų®ŁŲ§ŁŲÆ Ś©Ų±ŲÆ Ł ŁŲ±Ų§Ś©ŲÆ Ų±Ų§ ŲÆŲ± ŲµŁ Ś©Ų§Ų± Ų®ŁŲ§ŁŲÆ Ų§ŁŲ²ŁŲÆ. Ų§ŪŁ Ś©Ų§Ų± Ł
ŁŲÆŲ§Ų±Ū Ų²Ł
Ų§Ł ŁŲ§Ų²Ł
ŲÆŲ§Ų±ŲÆ.<br /><br />\nŲ¢ŪŲ§ Ł
ŪāŲ®ŁŲ§ŁŪŲÆ Ų§ŲÆŲ§Ł
Ł ŲÆŁŪŲÆŲ", + "timedmedia-reset-error": "Ų®Ų·Ų§ ŲÆŲ± ŲØŲ§Ų²ŁŲ“Ų§ŁŪ Ś©Ų§Ų± ŁŲ±Ų§Ś©ŲÆ.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 Ł
ŲØŲÆŲ£", + "timedmedia-source-file-desc": "Ų§ŲµŁŪ $1 Ł¾Ų±ŁŁŲÆŁŲ $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Ų§ŲµŁŪ $1 Ł¾Ų±ŁŁŲÆŁ ( $2 )", + "timedmedia-derivative-desc-160p.ogv": "ŁŪŲÆŲ¦Ł Ogg ŲØŲ§ Ł¾ŁŁŲ§Ū ŲØŲ§ŁŲÆ Ś©Ł
(160P)", + "timedmedia-derivative-desc-240p.ogv": "ŁŪŲÆŪŁŪ Ų¢ŚÆ ŁŲ§ŲØŁ ŲØŲ®Ų“ ŲÆŲ± ŁŲØ (Ū²Ū“Ū° ŁŁŲ·Ł)", + "timedmedia-derivative-desc-360p.ogv": "ŁŪŲÆŲ¦Ł Ogg ŲØŲ§ Ł¾ŁŁŲ§Ū ŁŲØ (360P)", + "timedmedia-derivative-desc-480p.ogv": "ŁŪŲÆŲ¦Ł Ogg ŲØŲ§ Ł¾ŁŁŲ§Ū ŁŲØ (480P)", + "timedmedia-derivative-desc-720p.ogv": "ŁŪŲÆŲ¦Ł Ogg ŁŲ§ŲØŁ ŲØŲ§Ų±ŚÆŪŲ±Ū ŲØŲ§ Ś©ŪŁŪŲŖ ŲØŲ§ŁŲ§ (720P)", + "timedmedia-derivative-desc-1080p.ogv": "ŁŪŲÆŪŁŪ Ų¢ŚÆ Ś©Ų§Ł
ŁŲ§Ł Ų§ŚāŲÆŪ (Ū±Ū°ŪøŪ° Ł¾ŪŚ©Ų³Ł)", + "timedmedia-derivative-desc-160p.webm": "Ų±Ų³Ų§ŁŁ ŁŲØ ŲØŲ§ Ł¾ŁŁŲ§Ū ŁŲØ (160P)", + "timedmedia-derivative-desc-360p.webm": "Ų±Ų³Ų§ŁŁ ŁŲØ ŲØŲ§ Ł¾ŁŁŲ§Ū ŁŲØ (360P)", + "timedmedia-derivative-desc-480p.webm": "Ų±Ų³Ų§ŁŁ ŁŲØ ŲØŲ§ Ł¾ŁŁŲ§Ū ŁŲØ (480P)", + "timedmedia-derivative-desc-720p.webm": "Ų±Ų³Ų§ŁŁ ŁŲØ ŁŲ§ŲØŁ ŲØŲ§Ų±ŚÆŪŲ±Ū ŲØŲ§ Ś©ŪŁŪŲŖ ŲØŲ§ŁŲ§ (720P)", + "timedmedia-derivative-desc-1080p.webm": "ŁŪŲÆŪŁŪ ŁŲØāŲ§Ł
Ś©Ų§Ł
ŁŲ§Ł Ų§ŚāŲÆŪ (Ū±Ū°ŪøŪ° Ł¾ŪŚ©Ų³Ł)", + "timedmedia-derivative-desc-320p.mp4": "Ų§ŲØŲ²Ų§Ų± Ų³Ų§Ų²ŚÆŲ§Ų± ŲØŲ§ MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Ł¾ŁŁŲ§Ū ŁŲØ MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "Ś©ŪŁŪŲŖ ŲØŲ§ŁŲ§ MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "ŁŪŲÆŪŁŪ Ų§Ł
āŁ¾ŪŪ“ Ś©Ų§Ł
ŁŲ§Ł Ų§ŚāŲÆŪ (Ū±Ū°ŪøŪ° Ł¾ŪŚ©Ų³Ł)", + "timedmedia-subtitle-new": "ŲŖŲ±Ų¬Ł
Ł Ų¬ŲÆŪŲÆŪ Ų±Ų§ Ų§ŪŲ¬Ų§ŲÆ Ś©ŁŪŲÆ ŪŲ§ ŲÆŲ± ŲµŁŲ±ŲŖ ŁŲ¬ŁŲÆ Ų¢Ł Ų±Ų§ ŁŪŲ±Ų§ŪŲ“ Ś©ŁŪŲÆ.", + "timedmedia-subtitle-new-desc": " Ų²ŲØŲ§Ł Ų±Ų§ Ų§ŁŲŖŲ®Ų§ŲØ Ś©ŁŪŲÆ Ł ŲÆŚ©Ł
ŁŁ '''{{int:Timedmedia-subtitle-new-go}}''' Ų±Ų§ ŲØŁŲ“Ų§Ų±ŪŲÆ", + "timedmedia-subtitle-new-go": "ŲØŲ±Ł", + "timedmedia-subtitle-language": "$1 ($2) Ų²ŪŲ±ŁŁŪŲ³āŁŲ§", + "timedmedia-subtitle-no-video": "ŁŪŚ ŁŪŲÆŲ¦ŁŪŪ Ł
Ų±ŲŖŲØŲ· ŲØŲ§ Ų²ŪŲ±Ų¹ŁŁŲ§Ł Ų§ŪŁ ŲµŁŲŁ Ł
ŁŲ¬ŁŲÆ ŁŪŲ³ŲŖ", + "timedmedia-subtitle-no-subtitles": "ŲÆŲ± ŲŲ§Ł ŲŲ§Ų¶Ų± Ų²ŪŲ±ŁŁŪŲ³Ū ŲØŲ±Ų§Ū $1 ŲÆŲ± Ų§ŪŁ ŁŪŲÆŪŁ ŁŲ¬ŁŲÆ ŁŲÆŲ§Ų±ŲÆŲ Ł
ŪāŲŖŁŲ§ŁŪŲÆ Ų§ŪŁ ŲµŁŲŁ Ų±Ų§ ŲØŲ±Ų§Ū Ų§ŁŲ²ŁŲÆŁ Ų¢ŁāŁŲ§ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ŁŪŲ±Ų§ŪŲ“ Ś©ŁŪŲÆ].", + "timedmedia-subtitle-remote": "Ł
ŲŖŁ Ų²Ł
Ų§ŁāŲÆŲ§Ų± ŲØŲ±Ų§Ū Ł¾Ų±ŁŁŲÆŁ Ų°Ų®ŪŲ±Ł Ų“ŲÆŁ ŲÆŲ± $1", + "timedmedia-subtitle-remote-link": "Ų“Ł
Ų§ Ł
Ū ŲŖŁŲ§ŁŪŲÆ [$1 ŲŖŁŲ¶ŪŲŲ§ŲŖ ŲµŁŲŁ Ł
Ų“Ų§ŁŲÆŁ Ś©ŁŪŲÆ] ŲØŲ±Ų§Ū Ų§ŪŁ Ł¾Ų±ŁŁŲÆŁ ŲÆŲ± $2", + "timedmediahandler": "ŁŲÆŲ§ŪŲŖāŚ©ŁŁŲÆŁ Ų±Ų³Ų§ŁŁŁ Ų²Ł
Ų§ŁāŲÆŲ§Ų±", + "timedmedia-videos": "{{PLURAL:$1|$1 ŁŪŲÆŲ¦Ł|$1 ŁŪŲÆŲ¦Ł}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 ŁŪŲÆŲ¦Ł Ogg|$1 ŁŪŲÆŲ¦Ł Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 ŁŪŲÆŲ¦Ł WebM|$1 ŁŪŲÆŲ¦Ł WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 ŁŲ±Ų§Ś©ŲÆŁŲ§|$1 ŁŲ±Ų§Ś©ŲÆŁŲ§}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 ŲÆŲ±ŲŲ§Ł Ų§Ų¬Ų±Ų§Ū ŁŲ±Ų§Ś©ŲÆŁŲ§|$1 ŲÆŲ± ŲŲ§Ł Ų§Ų¬Ų±Ų§Ū ŁŲ±Ų§Ś©ŲÆŁŲ§}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 ŲµŁ ŁŲ±Ų§Ś©ŲÆŁŲ§|$1 ŲµŁ ŁŲ±Ų§Ś©ŲÆŁŲ§}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 ŁŲ±Ų§Ś©ŲÆŁŲ§Ū Ų§Ų“ŲŖŲØŲ§Ł|$1 ŁŲ±Ų§Ś©ŲÆŁŲ§Ū Ų§Ų“ŲŖŲØŲ§Ł}}", + "timedmedia-file": "Ł¾Ų±ŁŁŲÆŁ", + "timedmedia-audios": "{{PLURAL:$1|$1 Ł¾ŁŲ“ŁŁ ŲµŁŲŖŪ|$1 Ł¾ŁŲ“ŁāŁŲ§Ū ŲµŁŲŖŪ}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ł¾ŁŲ“ŁŁ ŲµŁŲŖŪ Ų¢ŚÆ|$1 Ł¾ŁŲ“ŁāŁŲ§Ū ŲµŁŲŖŪ Ų¢ŚÆ}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1Ł¾ŁŲ“ŁāŁ ŲµŁŲŖŪ Ų§ŁāŲ§ŁāŲ§ŪāŲ³Ū|$1Ł¾ŁŲ“ŁāŁŲ§Ū ŲµŁŲŖŪ Ų§ŁāŲ§ŁāŲ§ŪāŲ³Ū}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 Ł¾ŁŲ“ŁāŁ ŲµŁŲŖŪ ŲÆŲØŁŪŁāŲ§ŪāŁŪ|$1 Ł¾ŁŲ“ŁāŁŲ§Ū ŲµŁŲŖŪ ŲÆŲØŁŪŁāŲ§ŪāŁŪ}}", + "right-transcode-reset": "ŲŖŁŲøŪŁ
Ł
Ų¬ŲÆŲÆ Ų§ŁŲ¬Ų§Ł
āŁŲ“ŲÆŁāŁŲ§ ŪŲ§ ŁŪŲÆŲ¦ŁŁŲ§Ū ŁŲ±Ų§Ś©ŲÆŲ“ŲÆŁ Ų§Ų¹Ł
Ų§Ł Ų“ŲÆ. ŲÆŲ± ŁŲŖŪŲ¬Ł Ł
Ų¬ŲÆŲÆŲ§Ł Ų¢ŁŁŲ§ ŲÆŲ± ŲµŁ Ś©Ų§Ų± ŁŲ±Ų§Ų± ŚÆŲ±ŁŲŖŁŲÆ.", + "right-transcode-status": "Ł
Ų“Ų§ŁŲÆŁŁ [[Special:TimedMediaHandler|Ų§Ų·ŁŲ§Ų¹Ų§ŲŖ ŲÆŲ± Ł
ŁŲ±ŲÆ ŁŲ¹Ų§ŁŪŲŖ ŁŲ±Ų§Ś©ŲÆ]]", + "action-transcode-status": "ŁŁ
Ų§ŪŲ“ ŁŲ¶Ų¹ŪŲŖ ŁŲ±Ų§Ś©ŲÆŚÆŲ°Ų§Ų±Ū Ś©ŁŁŁŪ", + "orphanedtimedtext": "ŲµŁŲŁāŁŲ§Ū TimedText ŪŲŖŪŁ
", + "orphanedtimedtext-summary": "ŁŁŲ±Ų³ŲŖ ŲµŁŲŁāŁŲ§Ū [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] Ś©Ł ŲÆŲ§Ų±Ų§Ū Ł¾Ų±ŁŁŲÆŁŁ Ł
ŲŖŁŲ§ŲøŲ± ŁŪŲ³ŲŖŁŲÆ.", + "orphanedtimedtext-unsupported": "Ų§ŪŁ ŲµŁŲŁŁ Ų®Ų§Ųµ ŁŁŲ· ŲÆŲ± Ł¾Ų§ŪŚÆŲ§Ł ŲÆŲ§ŲÆŁāŁŲ§Ū Ł
Ų§ŪāŲ§Ų³āŚ©ŪŁŲ§Ł ŲŁ
Ų§ŪŲŖ Ų“ŲÆŁāŲ§Ų³ŲŖ.", + "orphanedtimedtext-notimedtext": "TimedText ŲÆŲ± Ų§ŪŁ ŁŪŚ©Ū ŁŲ¹Ų§Ł ŁŲ“ŲÆŁ Ų§Ų³ŲŖ.", + "apihelp-query+transcodestatus-description": "ŚÆŲ±ŁŲŖŁ ŁŲ¶Ų¹ŪŲŖ Ś©Ų°ŚÆŲ°Ų§Ų±Ū ŲØŲ±Ų§Ū ŪŚ© ŲµŁŲŁ Ł
Ų“Ų®Ųµ Ų“ŲÆŁ.", + "apihelp-query+transcodestatus-example-1": "ŚÆŲ±ŁŲŖŁ ŁŲ¶Ų¹ŪŲŖ Ś©ŲÆŚÆŲ°Ų§Ų±Ū [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "ŚÆŲ³ŲŖŲ±Ų“ Ų§Ų·ŁŲ§Ų¹Ų§ŲŖ ŲŖŲµŁŪŲ±Ū ŲØŁ Ų“Ų§Ł
Ł Ų“ŲÆŁ Ų§Ų·ŁŲ§Ų¹Ų§ŲŖ Ł
ŁŲØŲ¹ ŲŖŲµŁŪŲ± (Ų§Ų“ŲŖŁŲ§ŁāŲ“ŲÆŁāŁŲ§)", + "apihelp-query+videoinfo-param-prop": "ŚŁ Ų§Ų·ŁŲ§Ų¹Ų§ŲŖŪ ŲÆŲ±ŪŲ§ŁŲŖ Ł
ŪāŲ“ŁŲÆ:\n;timestamp:Ł
ŁŲ±Ų²Ł
Ų§ŁŪ ŲØŁ ŁŲ³Ų®ŁŁ ŲØŲ§Ų±ŚÆŲ°Ų§Ų±Ū Ų“ŲÆŁ Ł
ŪāŲ§ŁŲ²Ų§ŪŲÆ.\n;user:Ś©Ų§Ų±ŲØŲ±Ū Ś©Ł ŲŖŲµŁŪŲ± Ų±Ų§ ŲØŲ§Ų±ŚÆŲ°Ų§Ų±Ū Ś©Ų±ŲÆŁ Ų±Ų§ Ł
ŪāŲ§ŁŲ²Ų§ŪŲÆ.\n;userid:Ų“ŁŲ§Ų³ŁŁ Ś©Ų§Ų±ŲØŲ±Ū Ś©Ł ŁŪŲÆŪŁ Ų±Ų§ ŲØŲ§Ų±ŚÆŲ°Ų§Ų±Ū Ś©Ų±ŲÆŁ Ų§Ų³ŲŖ Ś©Ł ŁŲ³Ų®ŁŁ ŁŪŲÆŪŁŪŪ Ų±Ų§ ŲØŲ§Ų±ŚÆŲ°Ų§Ų±Ū Ś©Ų±ŲÆŁ Ų§Ų³ŲŖ Ł
ŪāŲ§ŁŲ²Ų§ŪŲÆ.\n;comment:ŲŖŁŲ¶ŪŲŲ§ŲŖ ŁŲ³Ų®Ł.\n;parsedcomment:ŲŖŲ¬Ų²ŪŁ ŲŖŁŲ¶ŪŲŲ§ŲŖ ŁŲ³Ų®Ł.\n;canonicaltitle:Ų¹ŁŁŲ§Ł Ł
ŲŖŁ
Ų±Ś©Ų² Ł¾Ų±ŁŁŲÆŁ ŁŪŲÆŪŁŪŪ.\n;url:ŁŲ“Ų§ŁŪ Ų§ŪŁŲŖŲ±ŁŲŖŪ Ų§Ų² ŁŪŲÆŪŁŪ Ł ŲµŁŲŁŁ ŲŖŁŲ¶ŪŲŲ§ŲŖ.\n;size:ŲŲ¬Ł
ŁŪŲÆŪŁ ŲØŁ ŲØŲ§ŪŲŖŲ Ų·ŁŁ Ł Ų¹Ų±Ų¶ Ų¢Ł Ų±Ų§ Ł
ŪāŲ§ŁŲ²Ų§ŪŲÆ. ŲŖŲ¹ŲÆŲ§ŲÆ ŲµŁŲŁ Ł Ų·ŁŁ Ų§ŚÆŲ± ŁŲ§ŲØŁ Ų§Ų·ŁŲ§Ł ŲØŲ§Ų“ŲÆ.\n;dimensions:ŁŲ§Ł
Ł
Ų³ŲŖŲ¹Ų§Ų± ŲØŲ±Ų§Ū Ų§ŁŲÆŲ§Ų²Ł.\n;sha1:Ų§ŁŲ²ŁŲÆ SHA-1 hash ŲØŲ±Ų§Ū ŁŪŲÆŲ¦Ł.\n;mime:Ų§ŁŲ²ŁŲÆ ŁŁŲ¹ MIME ŲØŲ±Ų§Ū ŁŪŲÆŲ¦Ł.\n;thumbmime:Ų§ŁŲ²ŁŲÆ ŁŁŲ¹ MIME ŲØŲ±Ų§Ū ŲØŁŲÆŲ§ŁŚÆŲ“ŲŖŪ ŁŪŲÆŲ¦Ł (ŁŪŲ§Ų²Ł
ŁŲÆ ŁŲ“Ų§ŁŪ Ł Ł
ŲŖŲŗŪŪŲ± $1urlwidth).\n;mediatype:ŁŁŲ¹ Ų±Ų³Ų§ŁŁŁ ŁŪŲÆŲ¦Ł Ų±Ų§ Ų§ŁŲ²ŁŲÆ.\n;metadata:ŁŲ±Ų§ŲÆŲ§ŲÆŁāŁŲ§Ū Exif ŲØŲ±Ų§Ū ŁŲ³Ų®ŁŁ ŁŪŲÆŪŁ ŁŁŲ±Ų³ŲŖ Ł
ŪāŚ©ŁŲÆ.\n;commonmetadata:ŁŲ±Ų§ŲÆŲ§ŲÆŁāŁŲ§Ū Ų¹Ł
ŁŁ
Ū ŲØŲ±Ų§Ū ŁŲ³Ų®ŁŁ ŁŲ§ŁŲØ Ł¾Ų±ŁŁŲÆŁ ŁŪŲÆŪŁ ŁŁŲ±Ų³ŲŖ Ł
ŪāŚ©ŁŲÆ.\n;extmetadata:ŁŲ±Ų§ŲÆŲ§ŲÆŁāŁŲ§Ū ŲŖŲ±Ś©ŪŲØŪ ŁŲ§ŁŲØāŲÆŁŪ Ų“ŲÆŁ Ų§Ų² ŚŁŲÆŪŁ Ł
ŁŲØŲ¹ Ų±Ų§ ŁŁŲ±Ų³ŲŖ Ł
ŪāŚ©ŁŲÆ. ŁŲŖŪŲ¬Ł Ų§Ų¬āŲŖŪāŲ§Ł
āŲ§Ł ŁŲ§ŁŲØāŲÆŁŪ Ų“ŲÆŁ Ų§Ų³ŲŖ.\n;archivename:ŁŲ§Ł
Ł¾Ų±ŁŁŲÆŁ ŁŲ³Ų®ŁŁ ŲØŲ§ŪŚÆŲ§ŁŪāŲ“ŲÆŁ Ų±Ų§ ŲØŲ±Ų§Ū ŁŲ³Ų®ŁāŁŲ§Ū ŲŗŪŲ± Ų¢Ų®Ų±ŪŁ Ł
ŪāŲ§ŁŲ²Ų§ŪŲÆ.\n;bitdepth:Ų¹Ł
Ł ŲØŪŲŖŪ ŁŲ³Ų®Ł Ų±Ų§ Ł
ŪāŲ§ŁŲ²Ų§ŪŲÆ.\n;uploadwarning:Ų§Ų³ŲŖŁŲ§ŲÆŁ Ų“ŲÆŁ ŲŖŁŲ³Ų· ŲµŁŲŁ [[Special:Upload]] ŲØŲ±Ų§Ū ŲÆŲ±ŪŲ§ŁŲŖ Ų§Ų·ŁŲ§Ų¹Ų§ŲŖŪ Ų§Ų² ŪŚ© Ł¾Ų±ŁŁŲÆŁ Ł
ŁŲ¬ŁŲÆ. ŲØŲ±Ų§Ū Ų§Ų³ŲŖŁŲ§ŲÆŁ ŲØŪŲ±ŁŁ Ų§Ų² ŁŲ³ŲŖŁŁā Ł
ŲÆŪŲ§ŁŪŚ©Ū ŁŪŲ³ŲŖ.\n;derivatives:Ų¢Ų±Ų§ŪŁāŲ§Ū Ų§Ų² ŁŲ§ŁŲØāŁŲ§ Ł Ś©ŪŁŪŲŖ ŁŲ³Ų®ŁāŁŲ§Ū ŪŚ© Ł¾Ų±ŁŁŲÆŁ ŲµŲÆŲ§ ŪŲ§ ŲŖŲµŁŪŲ±Ū Ś©Ł Ł¾Ų±ŁŁŲÆŁāŲ§Ū Ś©Ł Ł
ŁŲ¬ŁŲÆ Ų§Ų³ŲŖ Ł
ŪāŲ§ŁŲ²Ų§ŪŲÆ.", + "apihelp-query+videoinfo-example-1": "ŁŲ§Ś©Ų“Ū Ų§Ų·ŁŲ§Ų¹Ų§ŲŖŪ ŲÆŲ±ŲØŲ§Ų±Ł [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "Ś©Ų§Ų±ŲØŲ±ŁŪŪ Ś©Ł ŲÆŲ³ŲŖŲ±Ų³Ū 'transcode-reset' Ł
ŪāŲŖŁŲ§ŁŁŲÆ ŪŚ© Ś©Ų§Ų± Ś©ŲÆŚÆŲ°Ų§Ų±Ū Ų±Ų§ Ų§Ų² ŁŁ Ś©ŁŁŲÆ.", + "apihelp-transcodereset-param-title": "Ų¹ŁŁŲ§Ł Ł¾Ų±ŁŁŲÆŁ.", + "apihelp-transcodereset-param-transcodekey": "Ś©ŁŪŲÆ Ś©ŲÆŚÆŲ°Ų§Ų±Ū Ś©Ł Ł
ŪāŲ®ŁŲ§ŁŪŲÆ Ų§Ų² ŁŁ Ų“ŁŲÆ. ŚÆŲ±ŁŲŖŁ Ų§Ų² [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "Ų§Ų² ŁŁ Ś©Ų±ŲÆŁ Ś©ŲÆŚÆŲ°Ų§Ų±ŪāŁŲ§ ŲØŲ±Ų§Ū [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "Ų§Ų² ŁŁ Ś©Ų±ŲÆŁ Ś©ŁŪŲÆ Ś©ŲÆŚÆŲ°Ų§Ų±Ū '360_560kbs.webm' ŲØŲ±Ų§Ū [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/fi.json b/extensions/TimedMediaHandler/i18n/fi.json new file mode 100644 index 00000000..ef19cca9 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/fi.json @@ -0,0 +1,78 @@ +{ + "@metadata": { + "authors": [ + "Agony", + "Beluga", + "Crt", + "Nike", + "Pxos", + "Str4nd", + "VezonThunder", + "Pitke" + ] + }, + "timedmedia-desc": "KƤsittelijƤ ƤƤnelle, videolle ja tekstitykselle. Tukee muotoja WebM, Ogg Theora, Vorbis ja srt.", + "timedmedia-ogg-short-audio": "Ogg $1 -ƤƤnitiedosto, $2", + "timedmedia-ogg-short-video": "Ogg $1 -videotiedosto, $2", + "timedmedia-ogg-short-general": "Ogg $1 -mediatiedosto, $2", + "timedmedia-ogg-long-audio": "Ogg $1 -ƤƤnitiedosto, $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 -videotiedosto, $2, $4Ć$5, $3", + "timedmedia-ogg-long-multiplexed": "Ogg-tiedosto limitetty kuva ja ƤƤni, $1, $2, $4Ć$5, $3", + "timedmedia-ogg-long-general": "Ogg-tiedosto, $2, $3", + "timedmedia-ogg-long-error": "Kelvoton Ogg-tiedosto: $1", + "timedmedia-webm-short-video": "WebM $1 -videotiedosto, $2", + "timedmedia-webm-long-video": "WebM-ƤƤni-/videotiedosto, $1, pituus $2, $4Ć$5 pikseliƤ, yhteensƤ $3", + "timedmedia-mp4-short-video": "MP4 $1 -videotiedosto, $2", + "timedmedia-mp4-long-video": "MP4-ƤƤni-/videotiedosto, $1, pituus $2, $4Ć$5 pikseliƤ, yhteensƤ $3", + "timedmedia-no-player-js": "Valitettavasti selaimessasi on joko JavaScript pois pƤƤltƤ tai sille ei ole tuettua soitinta.<br />\nVoit <a href=\"$1\">ladata leikkeen</a> tai <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ladata soittimen</a> toistaaksesi sen selaimessasi.", + "timedmedia-more": "LisƤƤā¦", + "timedmedia-dismiss": "Sulje", + "timedmedia-download": "Lataa", + "timedmedia-play-media": "Toista mediaa", + "timedmedia-desc-link": "Tiedoston tiedot", + "timedmedia-oggThumb-version": "OggHandler vaatii oggThumbin version $1 tai uudemman.", + "timedmedia-oggThumb-failed": "oggThumb epƤonnistui pikkukuvan luomisessa.", + "timedmedia-status": "Tila", + "timedmedia-status-unknown": "Tuntematon tila", + "timedmedia-transcodeinfo": "Muoto", + "timedmedia-actions": "Toiminnot", + "timedmedia-direct-link": "Lataa", + "timedmedia-not-ready": "Ei valmis", + "timedmedia-completed-on": "Valmistui $1", + "timedmedia-started-transcode": "Alkoi $1 sitten. $2", + "timedmedia-percent-done": "Noin $1% valmiina", + "timedmedia-in-job-queue": "LisƤttiin tyƶjonoon $1 sitten", + "timedmedia-days": "{{PLURAL:$1|1 pƤivƤ|$1 pƤivƤƤ}}", + "timedmedia-hours": "{{PLURAL:$1|1 tunti|$1 tuntia}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuutti|$1 minuuttia}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekunti|$1 sekuntia}}", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "LƤhde $1", + "timedmedia-source-file-desc": "AlkuperƤinen $1-tiedosto, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "AlkuperƤinen $1-tiedosto ($2)", + "timedmedia-derivative-desc-160p.ogv": "Pienen kaistanleveyden Ogg-video (160p)", + "timedmedia-derivative-desc-240p.ogv": "Streamautuva Ogg-video (240p)", + "timedmedia-derivative-desc-360p.ogv": "verkossa suoratoistettavaa Ogg-videota (360p)", + "timedmedia-derivative-desc-480p.ogv": "Verkossa suoratoistettava Ogg-video (480p)", + "timedmedia-derivative-desc-720p.ogv": "Korkealaatuinen ladattava Ogg-video (720p)", + "timedmedia-derivative-desc-160p.webm": "Verkossa suoratoistettava WebM-video (160p)", + "timedmedia-derivative-desc-360p.webm": "Verkossa suoratoistettava WebM-video (360p)", + "timedmedia-derivative-desc-480p.webm": "Verkossa suoratoistettava WebM-video (480p)", + "timedmedia-derivative-desc-720p.webm": "Korkealaatuinen ladattava WebM-video (720p)", + "timedmedia-derivative-360p.vp9.webm": "VP9 360P", + "timedmedia-derivative-480p.vp9.webm": "VP9 480P", + "timedmedia-derivative-desc-320p.mp4": "LaiteystƤvƤllinen MP4 (320p)", + "timedmedia-derivative-desc-480p.mp4": "Verkossa suoratoistettava MP4 (480p)", + "timedmedia-derivative-desc-720p.mp4": "HD-laatuinen MP4 (720p)", + "timedmedia-subtitle-new": "Luo uusi kƤƤnnƶs tai muokkaa aiempaa", + "timedmedia-subtitle-new-desc": "Valitse kieli ja napsauta '''{{int:Timedmedia-subtitle-new-go}}'''.", + "timedmedia-subtitle-new-go": "Siirry", + "timedmedia-subtitle-language": "$1 ($2) kuvatekstit", + "timedmedia-subtitle-no-video": "TƤhƤn tekstityssivuun ei liity videota", + "timedmedia-subtitle-no-subtitles": "TƤlle videolle ei tƤllƤ hetkellƤ ole tekstityksiƤ kielellƤ $1. Voit [{{fullurl:{{FULLPAGENAME}}|action=edit}} muokata tƤtƤ sivua] lisƤtƤksesi ne.", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 videota}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg-video|$1 Ogg-videota}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM-video|$1 WebM-videota}}", + "timedmedia-file": "Tiedosto" +} diff --git a/extensions/TimedMediaHandler/i18n/fo.json b/extensions/TimedMediaHandler/i18n/fo.json new file mode 100644 index 00000000..a96f3de3 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/fo.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Spacebirdy", + "EileenSanda" + ] + }, + "timedmedia-no-player-js": "Halt okkum til gĆ³Ć°ar, tĆn brovsari hevur antin gjĆørt JavaScript Ć³virkiĆ° ella hevur ongan avspƦlara iĆ° virkar her.<br />\nTĆŗ kanst <a href=\"$1\">taka klippiĆ° niĆ°ur</a> ella <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">taka niĆ°ur ein avspƦlara</a> sum kann spƦla klippiĆ° Ć tĆnum internetkaga.", + "timedmedia-more": "Meira...", + "timedmedia-source-file": "$1 kelda", + "timedmedia-source-audio-file-desc": "Uppruna $1 fĆla ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/fr.json b/extensions/TimedMediaHandler/i18n/fr.json new file mode 100644 index 00000000..e252d5c4 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/fr.json @@ -0,0 +1,150 @@ +{ + "@metadata": { + "authors": [ + "Boniface", + "Brunoperel", + "Crochet.david", + "Erkethan", + "Gomoko", + "Grondin", + "Hashar", + "Hello71", + "IAlex", + "Jean-FrĆ©dĆ©ric", + "McDutchie", + "Od1n", + "Peter17", + "Rzuwig", + "Seb35", + "Sherbrooke", + "Shirayuki", + "Urhixidur", + "Verdy p", + "Framafan", + "Wladek92" + ] + }, + "timedmedia-desc": "Gestionnaire pour les vidĆ©os, enregistrements sonores et textes synchronisĆ©s, avec le support des formats WebM, Ogg Theora, Vorbis et srt", + "timedmedia-ogg-short-audio": "Fichier son Ogg $1, $2", + "timedmedia-ogg-short-video": "Fichier vidĆ©o Ogg $1, $2", + "timedmedia-ogg-short-general": "Fichier mĆ©dia Ogg $1, $2", + "timedmedia-ogg-long-audio": "Fichier son Ogg $1, durĆ©e $2, $3", + "timedmedia-ogg-long-video": "Fichier vidĆ©o Ogg $1, durĆ©e $2, $4 Ć $5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "Fichier multiplexĆ© audio/vidĆ©o Ogg, $1, durĆ©e $2, $4 Ć $5 pixels, $3 au total", + "timedmedia-ogg-long-general": "Fichier mĆ©dia Ogg, durĆ©e $2, $3", + "timedmedia-ogg-long-error": "Fichier Ogg invalide : $1", + "timedmedia-ogg-long-no-streams": "Fichier de mĆ©dia ogg. Attention : Aucun des codecs utilisĆ©s dans ce fichier nāest reconnu.", + "timedmedia-webm-short-video": "Fichier vidĆ©o WebM $1, $2", + "timedmedia-webm-long-video": "Fichier audio/vidĆ©o WebM, $1, longueur $2, $4 x $5 pixels, $3 l'ensemble", + "timedmedia-flac-short-audio": "Fichier audio FLAC, $1", + "timedmedia-flac-long-audio": "Fichier audio FLAC, durĆ©e $1, dĆ©bit $2 sur lāensemble", + "timedmedia-wav-short-audio": "Fichier audio WAV, $1", + "timedmedia-wav-long-audio": "Fichier audio WAV, durĆ©e $1, $2 sur lāensemble", + "timedmedia-wav-pcm-required": "Vous ne pouvez tĆ©lĆ©charger que des WAV PCM (Modulation dāimpulsion codĆ©e).", + "timedmedia-mp4-short-video": "Fichier vidĆ©o MP4 $1, $2", + "timedmedia-mp4-long-video": "Fichier audio/vidĆ©o MP4, $1, taille $2, $4 x $5 pixels, $3 au total", + "timedmedia-no-player-js": "DĆ©solĆ©, soit votre navigateur a JavaScript dĆ©sactivĆ©, soit il ne dispose dāaucun lecteur pris en charge.<br />\nVous pouvez <a href=\"$1\">tĆ©lĆ©charger le clip</a> ou <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">tĆ©lĆ©charger un lecteur</a> pour lire le clip dans votre navigateur.", + "timedmedia-more": "Plusā¦", + "timedmedia-dismiss": "Fermer", + "timedmedia-download": "TĆ©lĆ©charger le fichier", + "timedmedia-play-media": "Lire le mĆ©dia", + "timedmedia-desc-link": "Ć propos de ce fichier", + "timedmedia-oggThumb-version": "OggHandler nĆ©cessite oggThumb, version $1 ou supĆ©rieure.", + "timedmedia-oggThumb-failed": "oggThumb nāa pas rĆ©ussi Ć crĆ©er la miniature.", + "timedmedia-status-header": "Statut de transcodage", + "timedmedia-update-status": "Mettre Ć jour le statut de transcodage", + "timedmedia-status": "Statut", + "timedmedia-status-unknown": "Ćtat inconnu", + "timedmedia-transcodebitrate": "DĆ©bit en bits", + "timedmedia-transcodeduration": "DurĆ©e de l'encodage", + "timedmedia-transcodeinfo": "Transcode la description dĆ©rivĆ©e", + "timedmedia-actions": "Actions", + "timedmedia-direct-link": "TĆ©lĆ©charger", + "timedmedia-not-ready": "Pas prĆŖt", + "timedmedia-completed-on": "$1 terminĆ©", + "timedmedia-error-on": "Erreur sur $1", + "timedmedia-started-transcode": "DĆ©marrĆ© depuis $1. $2", + "timedmedia-percent-done": "Environ $1 % complĆ©tĆ©", + "timedmedia-in-job-queue": "AjoutĆ© Ć la file dāattente des travaux il y a $1", + "timedmedia-unknown-target-size": "Taille de la cible inconnue, $1 encodĆ©", + "timedmedia-days": "{{PLURAL:$1|1 jour|$1 jours}}", + "timedmedia-hours": "{{PLURAL:$1|1 heure|$1 heures}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minute|$1 minutes}}", + "timedmedia-seconds": "{{PLURAL:$1|1 seconde|$1 secondes}}", + "timedmedia-reset": "RĆ©initialiser le transcodage", + "timedmedia-reset-confirm": "Remettre Ć zĆ©ro ce transcodage supprimera tout fichier existant (sāil y en a) et ajoutera de nouveau le transcodage Ć la file de travaux. Cela prendra un certain temps pour ĆŖtre transcodĆ© de nouveau. <br /><br />\nĆtes-vous sĆ»r de vouloir continuer ?", + "timedmedia-reset-error": "Erreur en rĆ©initialisant le travail de transcodage.", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Source $1", + "timedmedia-source-file-desc": "Original fichier $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Fichier original $1 ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160p", + "timedmedia-derivative-desc-160p.ogv": "VidĆ©o Ogg bas dĆ©bit (160P)", + "timedmedia-derivative-desc-240p.ogv": "VidĆ©o Ogg en flux continu sur le web (240P)", + "timedmedia-derivative-360p.ogv": "Ogg 360p", + "timedmedia-derivative-desc-360p.ogv": "VidĆ©o Ogg lisible en continu sur le Web (360p)", + "timedmedia-derivative-480p.ogv": "Ogg 480p", + "timedmedia-derivative-desc-480p.ogv": "VidĆ©o Ogg lisible en continu sur le web (480p)", + "timedmedia-derivative-720p.ogv": "Ogg 720p", + "timedmedia-derivative-desc-720p.ogv": "VidĆ©o Ogg tĆ©lĆ©chargeable de grande qualitĆ© (720p)", + "timedmedia-derivative-desc-1080p.ogv": "VidĆ©o Ogg tĆ©lĆ©chargeable en HD total (1080P)", + "timedmedia-derivative-desc-160p.webm": "WebM lisible en continu depuis le web (160p)", + "timedmedia-derivative-360p.webm": "WebM 360p", + "timedmedia-derivative-desc-360p.webm": "WebM lisible en continu depuis le web (360p)", + "timedmedia-derivative-480p.webm": "WebM 480p", + "timedmedia-derivative-desc-480p.webm": "WebM lisible en continu depuis le web (480p)", + "timedmedia-derivative-720p.webm": "WebM 720p", + "timedmedia-derivative-desc-720p.webm": "VidĆ©o WebM tĆ©lĆ©chargeable de grande qualitĆ© (720p)", + "timedmedia-derivative-desc-1080p.webm": "WebM tĆ©lĆ©chargeable en HD total (1080P)", + "timedmedia-derivative-desc-2160p.webm": "WebM tĆ©lĆ©charheable en 4K total (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "WebM VP9 (360P) lisible en continu sur le web", + "timedmedia-derivative-desc-480p.vp9.webm": "WebM VP9 (480P) lisible en continu sur le web", + "timedmedia-derivative-desc-720p.vp9.webm": "WebM VP9 haute dĆ©finition (720P) lisible en continu sur le web", + "timedmedia-derivative-desc-1080p.vp9.webm": "WebM VP9 en haute dĆ©finition totale (1080P) lisible en continu sur le web", + "timedmedia-derivative-desc-2160p.vp9.webm": "WebM VP9 4K complet (2160P) lisible en continu sur le web", + "timedmedia-derivative-desc-320p.mp4": "MP4 compatible matĆ©riel (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 pour flux web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 qualitĆ© HD (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4 de qualitĆ© HD total (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "MP4 de qualitĆ© haute dĆ©finition 4K", + "timedmedia-subtitle-new": "CrĆ©er une nouvelle traduction ou modifier une traduction existante", + "timedmedia-subtitle-new-desc": "SĆ©lectionnez la langue et appuyez sur le bouton '''{{int:Timedmedia-subtitle-new-go}}'''.", + "timedmedia-subtitle-new-go": "Aller", + "timedmedia-subtitle-language": "sous-titres en $1 ($2)", + "timedmedia-subtitle-no-video": "Il nāy a aucune vidĆ©o associĆ©e Ć la page actuelle de sous-titre", + "timedmedia-subtitle-no-subtitles": "Il nāy a actuellement aucun sous-titres en $1 pour cette vidĆ©o, vous pouvez [{{fullurl: {{FULLPAGENAME}} | action=edit}} modifier cette page] pour les ajouter", + "timedmedia-subtitle-remote": "Le texte prĆ©vu pour ce fichier est hĆ©bergĆ© sur $1", + "timedmedia-subtitle-remote-link": "Vous pouvez [$1 voir la page de description] de ce fichier sur $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 vidĆ©o|$1 vidĆ©os}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 vidĆ©o Ogg|$1 vidĆ©os Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 vidĆ©o WebM|$1 vidĆ©os WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodage|$1 transcodages}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodage en cours|$1 transcodages en cours}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodage en file d'attente|$1 transcodages en file d'attente}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transcodage Ć©chouĆ©|$1 transcodages Ć©chouĆ©s}}", + "timedmedia-file": "Fichier", + "timedmedia-audios": "{{PLURAL:$1|$1 fichier audio|$1 fichiers audio}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 fichier audio Ogg|$1 fichiers audio Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 fichier audio FLAC|$1 fichiers audio FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 fichier audio WAV|$1 fichiers audio WAV}}", + "right-transcode-reset": "RĆ©initialiser les vidĆ©os en Ć©chec ou transcodĆ©es pour quāelles soient de nouveau insĆ©rĆ©es dans la file des travaux", + "right-transcode-status": "Afficher [[Special:TimedMediaHandler|l'information sur l'activitĆ© de transcodage actuelle]]", + "action-transcode-status": "afficher lāĆ©tat de transcodage actuel", + "orphanedtimedtext": "Pages orphelines de TimedText", + "orphanedtimedtext-summary": "Liste des pages [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] qui nāont pas de fichier correspondant.", + "orphanedtimedtext-unsupported": "Cette page spĆ©ciale nāest supportĆ©e que sur les bases de donnĆ©es MySQL.", + "orphanedtimedtext-notimedtext": "TimedText nāest pas activĆ© sur ce wiki.", + "apihelp-query+transcodestatus-description": "Obtenir lāĆ©tat de transcodage pour une page de fichier donnĆ©.", + "apihelp-query+transcodestatus-example-1": "Obtenir lāĆ©tat de transcodage pour [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "Ćtends imageinfo pour inclure les informations sur la source (et dĆ©rivĆ©es) vidĆ©o", + "apihelp-query+videoinfo-param-prop": "Quelles informations obtenir sur la vidĆ©o :\n;timestamp:Ajoute lāhorodatage pour la version tĆ©lĆ©chargĆ©e.\n;user:Ajoute lāutilisateur qui a tĆ©lĆ©chargĆ© la version de la vidĆ©o.\n;userid:Ajouter lāID de lāutilisateur qui a tĆ©lĆ©chargĆ© la version de la vidĆ©o.\n;comment:Commentaire sur la version.\n;parsedcomment:Analyser le commentaire sur la version.\n;canonicaltitle:Ajoute le titre canonique du fichier vidĆ©o.\n;url:Fournit lāURL de la vidĆ©o et la page de description.\n;size:Ajoute la taille de la vidĆ©o en octets, sa hauteur et sa largeur. Le compteur de page et la durĆ©e sont ajoutĆ©s le cas Ć©chĆ©ant.\n;dimensions:Alias pour la taille.\n;sha1:Ajoute le hachage SHA-1 pour la vidĆ©o.\n;mime:Ajoute le type MIME de la vidĆ©o.\n;thumbmime:Ajoute le type MIME de la vignette de la vidĆ©o (nĆ©cessite lāURL et le paramĆØtre $1urlwidth).\n;mediatype:Ajoute le type de mĆ©dia de la vidĆ©o.\n;metadata:Liste les mĆ©tadonnĆ©es Exif pour la version de la vidĆ©o.\n;commonmetadata:Liste les mĆ©tadonnĆ©es gĆ©nĆ©riques du format de fichier pour la version de la vidĆ©o.\n;extmetadata:Liste les mĆ©tadonnĆ©es mises en forme combinĆ©es depuis plusieurs sources. Les rĆ©sultats sont au format HTML.\n;archivename:Ajoute le nom de fichier de la version dāarchive pour les versions hors la derniĆØre.\n;bitdepth:Ajoute la profondeur en bits de la version.\n;uploadwarning:UtilisĆ© par la page [[Special:Upload]] pour obtenir des informations sur un fichier existant. Non prĆ©vu pour ĆŖtre utilisĆ© hors du cÅur de MĆ©diaWiki.\n;derivatives:Ajoute un tableau des diffĆ©rentes versions de format et de qualitĆ© dāun fichier audio ou vidĆ©o disponibles.", + "apihelp-query+videoinfo-example-1": "RĆ©cupĆ©rer des informations sur [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "Les utilisateurs avec le droit 'transcode-reset' peuvent rĆ©initialiser et relancer une tĆ¢che de transcodage.", + "apihelp-transcodereset-param-title": "Le titre du fichier mĆ©dia.", + "apihelp-transcodereset-param-transcodekey": "La clĆ© du transcodage que vous voulez rĆ©initialiser. RĆ©cupĆ©rĆ© depuis [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "RĆ©initialiser tous les codes de transcodage de [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "RĆ©initialiser la clĆ© de transcodage '360_560kbs.webm' pour [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/frp.json b/extensions/TimedMediaHandler/i18n/frp.json new file mode 100644 index 00000000..ecf9cbc8 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/frp.json @@ -0,0 +1,38 @@ +{ + "@metadata": { + "authors": [ + "ChrisPtDe" + ] + }, + "timedmedia-desc": "Assistance por los fichiĆ©rs mĆØdia que dĆØfilont (Ć“diĆ“, vidĆØĆ“ et tĆØxto sincronisĆ¢) avouĆ©c transcodĆ¢jo en WebM, Ogg Theora, Vorbis et srt.", + "timedmedia-ogg-short-audio": "FichiĆ©r son Ogg $1, $2", + "timedmedia-ogg-short-video": "FichiĆ©r vidĆØĆ“ Ogg $1, $2", + "timedmedia-ogg-short-general": "FichiĆ©r mĆØdia Ogg $1, $2", + "timedmedia-ogg-long-audio": "FichiĆ©r son Ogg $1, temps $2, $3", + "timedmedia-ogg-long-video": "FichiĆ©r vidĆØĆ“ Ogg $1, temps $2, $4Ć$5 pixĆØls, $3", + "timedmedia-ogg-long-multiplexed": "FichiĆ©r multiplĆØxo Ć“diĆ“ / vidĆØĆ“ Ogg, $1, temps $2, $4Ć$5 pixĆØls, $3", + "timedmedia-ogg-long-general": "FichiĆ©r mĆØdia Ogg, temps $2, $3", + "timedmedia-ogg-long-error": "FichiĆ©r Ogg envalido : $1", + "timedmedia-webm-short-video": "FichiĆ©r vidĆØĆ“ WebM $1, $2", + "timedmedia-webm-long-video": "FichiĆ©r Ć“diĆ“ / vidĆØĆ“ WebM, $1, longior $2, $4 x $5 pixĆØls, en tot $3", + "timedmedia-more": "De ples...", + "timedmedia-dismiss": "CllĆ“re", + "timedmedia-download": "TĆØlĆØchargiĆ©r lo fichiĆ©r", + "timedmedia-play-media": "LiĆ©re lo mĆØdia", + "timedmedia-desc-link": "Sur ceti fichiĆ©r", + "timedmedia-oggThumb-version": "OggHandler at fĆ“ta dāoggThumb, vĆØrsion $1 ou ben ples novĆØla.", + "timedmedia-oggThumb-failed": "oggThumb at pas reussi a fĆ¢re la figura.", + "timedmedia-status": "statut", + "timedmedia-status-unknown": "statut encognu", + "timedmedia-actions": "Accions", + "timedmedia-not-ready": "Pas prĆØst", + "timedmedia-percent-done": "A pou prĆ©s $1 % complĆØtĆ¢", + "timedmedia-days": "$1 jorn{{PLURAL:$1||s}}", + "timedmedia-hours": "$1 hor{{PLURAL:$1|a|es}}", + "timedmedia-minutes": "$1 menut{{PLURAL:$1|a|es}}", + "timedmedia-seconds": "$1 second{{PLURAL:$1|a|es}}", + "timedmedia-source-file": "SĆ“rsa $1", + "timedmedia-source-file-desc": "OriginĆ¢l $1, $2 Ć $3 ($4)", + "timedmedia-subtitle-language": "sot-titros en $1 ($2)", + "timedmedia-file": "FichiĆ©r" +} diff --git a/extensions/TimedMediaHandler/i18n/frr.json b/extensions/TimedMediaHandler/i18n/frr.json new file mode 100644 index 00000000..8a1f77a8 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/frr.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Murma174" + ] + }, + "timedmedia-no-player-js": "Bi dan browser as det brĆ¼ken faan JavaScript deaktiwiaret wurden of hi koon det ianfach ei ufspele.<br />\nDĆ¼ kƶnst <a href=\"$1\">det video deelloose</a> of <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">en software deelloose</a>, am det video uun dan browser uftuspelin.", + "timedmedia-source-file": "$1-kwel", + "timedmedia-source-audio-file-desc": "Originaal $1-datei ($2)", + "timedmediahandler": "Timed Media Handler" +} diff --git a/extensions/TimedMediaHandler/i18n/fur.json b/extensions/TimedMediaHandler/i18n/fur.json new file mode 100644 index 00000000..b80405f4 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/fur.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "Klenje" + ] + }, + "timedmedia-desc": "GjestĆ“r pai files audio, video e di test cul timp, cun supuart pai formĆ¢ts WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "File audio Ogg $1, $2", + "timedmedia-ogg-short-video": "File video Ogg $1, $2", + "timedmedia-ogg-short-general": "File multimediĆ¢l Ogg $1, $2", + "timedmedia-ogg-long-audio": "File audio Ogg $1, durade $2, $3", + "timedmedia-ogg-long-video": "File video Ogg $1, durade $2, dimensions $4Ć$5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "File audio/video multiplexed Ogg $1, lungjece $2, dimensions $4Ć$5 pixels, in dut $3", + "timedmedia-ogg-long-general": "File multimediĆ¢l Ogg, durade $2, $3", + "timedmedia-ogg-long-error": "File ogg no valit: $1", + "timedmedia-webm-short-video": "File video WebM $1, $2", + "timedmedia-more": "Altri...", + "timedmedia-dismiss": "Siere", + "timedmedia-download": "Discjame il file", + "timedmedia-desc-link": "Informazions su chest file", + "timedmedia-status": "StĆ¢t", + "timedmedia-actions": "Azions" +} diff --git a/extensions/TimedMediaHandler/i18n/fy.json b/extensions/TimedMediaHandler/i18n/fy.json new file mode 100644 index 00000000..747f3b0b --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/fy.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "Robin0van0der0vliet" + ] + }, + "timedmedia-more": "Mearā¦", + "timedmedia-dismiss": "Slute", + "timedmedia-days": "{{PLURAL:$1|1 dei|$1 dagen}}", + "timedmedia-hours": "{{PLURAL:$1|1 oere|$1 oere}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minĆŗt|$1 minuten}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekonde|$1 sekonden}}", + "timedmedia-source-file": "$1 boarne", + "timedmedia-source-audio-file-desc": "Orizjineel $1-triem ($2)", + "timedmedia-file": "Triem" +} diff --git a/extensions/TimedMediaHandler/i18n/ga.json b/extensions/TimedMediaHandler/i18n/ga.json new file mode 100644 index 00000000..d59b6164 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ga.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Spacebirdy", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "timedmedia-more": "NĆos mĆ³...", + "timedmedia-dismiss": "DĆŗn", + "timedmedia-actions": "GnĆomhartha", + "timedmedia-subtitle-new-go": "Gabh", + "timedmedia-file": "Comhad" +} diff --git a/extensions/TimedMediaHandler/i18n/gl.json b/extensions/TimedMediaHandler/i18n/gl.json new file mode 100644 index 00000000..8c40d72d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/gl.json @@ -0,0 +1,125 @@ +{ + "@metadata": { + "authors": [ + "ToliƱo", + "XosĆ©", + "Banjo", + "Elisardojm" + ] + }, + "timedmedia-desc": "Manipulador de son, vĆdeo e texto sincronizado, con soporte para os formatos WebM, Ogg Theora, Vorbis e srt", + "timedmedia-ogg-short-audio": "Ficheiro de son Ogg $1, $2", + "timedmedia-ogg-short-video": "Ficheiro de vĆdeo Ogg $1, $2", + "timedmedia-ogg-short-general": "Ficheiro multimedia Ogg $1, $2", + "timedmedia-ogg-long-audio": "Ficheiro de son Ogg $1, duraciĆ³n $2, $3", + "timedmedia-ogg-long-video": "Ficheiro de vĆdeo Ogg $1, duraciĆ³n $2, $4Ć$5 pĆxeles, $3", + "timedmedia-ogg-long-multiplexed": "Ficheiro de son/vĆdeo Ogg multiplex, $1, duraciĆ³n $2, $4Ć$5 pĆxeles, $3 total", + "timedmedia-ogg-long-general": "Ficheiro multimedia Ogg, duraciĆ³n $2, $3", + "timedmedia-ogg-long-error": "Ficheiro Ogg non vĆ”lido: $1", + "timedmedia-ogg-long-no-streams": "Ficheiro multimedia Ogg. AtenciĆ³n: Non se recoƱece ningĆŗn dos codecs usados neste ficheiro.", + "timedmedia-webm-short-video": "Ficheiro de vĆdeo WebM $1, $2", + "timedmedia-webm-long-video": "Ficheiro WebM de son/vĆdeo, $1, duraciĆ³n $2, $4Ć$5 pĆxeles, $3 total", + "timedmedia-flac-short-audio": "Ficheiro de son FLAC, $1", + "timedmedia-flac-long-audio": "Ficheiro de son FLAC, duraciĆ³n $1, $2 total", + "timedmedia-wav-short-audio": "Ficheiro de son WAV, $1", + "timedmedia-wav-long-audio": "Ficheiro de son WAV, duraciĆ³n $1, $2 total", + "timedmedia-wav-pcm-required": "Unicamente pode cargar WAV PCM (modulaciĆ³n por cĆ³digo de pulsos).", + "timedmedia-mp4-short-video": "Ficheiro de vĆdeo MP4 $1, $2", + "timedmedia-mp4-long-video": "Ficheiro MP4 de son/vĆdeo, $1, duraciĆ³n $2, $4Ć$5 pĆxeles, $3 total", + "timedmedia-no-player-js": "SentĆmolo, o seu navegador ten o JavaScript desactivado ou non conta con ningĆŗn reprodutor dos soportados.<br />\nPode <a href=\"$1\">descargar o vĆdeo</a> ou <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">descargar un reprodutor</a> para reproducir o vĆdeo no seu navegador.", + "timedmedia-more": "MĆ”is...", + "timedmedia-dismiss": "Pechar", + "timedmedia-download": "Descargar o ficheiro", + "timedmedia-play-media": "Reproducir o contido", + "timedmedia-desc-link": "Acerca deste ficheiro", + "timedmedia-oggThumb-version": "O OggHandler necesita a versiĆ³n $1 ou unha posterior do oggThumb.", + "timedmedia-oggThumb-failed": "Houbo un erro por parte do oggThumb ao crear a miniatura.", + "timedmedia-status-header": "Estado da transcodificaciĆ³n", + "timedmedia-update-status": "Actualizar o estado de transcodificaciĆ³n", + "timedmedia-status": "Estado", + "timedmedia-status-unknown": "Estado descoƱecido", + "timedmedia-transcodebitrate": "Taxa de transferencia", + "timedmedia-transcodeduration": "Tempo de codificaciĆ³n", + "timedmedia-transcodeinfo": "Formato", + "timedmedia-actions": "AcciĆ³ns", + "timedmedia-direct-link": "Descargar", + "timedmedia-not-ready": "AĆnda non estĆ” preparado", + "timedmedia-completed-on": "Completado o $1", + "timedmedia-error-on": "Erro en $1", + "timedmedia-started-transcode": "Comezou hai $1. $2", + "timedmedia-percent-done": "Preto do $1% feito", + "timedmedia-in-job-queue": "Engadido Ć” cola de traballos hai $1", + "timedmedia-unknown-target-size": "TamaƱo de destino descoƱecido; $1 codificados", + "timedmedia-days": "{{PLURAL:$1|1 dĆa|$1 dĆas}}", + "timedmedia-hours": "{{PLURAL:$1|1 hora|$1 horas}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuto|$1 minutos}}", + "timedmedia-seconds": "{{PLURAL:$1|1 segundo|$1 segundos}}", + "timedmedia-reset": "Restablecer a transcodificaciĆ³n", + "timedmedia-reset-confirm": "Ao restablecer a transcodificaciĆ³n eliminarase calquera ficheiro existente e volverĆ” engadir a transcodificaciĆ³n Ć” cola de traballos. A nova transcodificaciĆ³n levarĆ” bastante tempo.<br /><br />\nEstĆ” seguro de querer continuar?", + "timedmedia-reset-error": "Erro no restablecemento do traballo de transcodificaciĆ³n.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Fonte $1", + "timedmedia-source-file-desc": "Ficheiro $1 orixinal, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Ficheiro $1 orixinal ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160P", + "timedmedia-derivative-desc-160p.ogv": "VĆdeo Ogg de baixo ancho de banda (160P)", + "timedmedia-derivative-desc-240p.ogv": "VĆdeo Ogg para a web (240P)", + "timedmedia-derivative-desc-360p.ogv": "VĆdeo Ogg para a web (360P)", + "timedmedia-derivative-desc-480p.ogv": "VĆdeo Ogg para a web (480P)", + "timedmedia-derivative-desc-720p.ogv": "VĆdeo Ogg de alta calidade que se pode descargar (720P)", + "timedmedia-derivative-desc-1080p.ogv": "VĆdeo Ogg descargable en Full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "WebM para a web (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM para a web (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM para a web (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM de alta calidade que se pode descargar (720P)", + "timedmedia-derivative-desc-1080p.webm": "WebM descargable en Full HD (1080P)", + "timedmedia-derivative-desc-2160p.webm": "WebM descargable en 4K (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "WebM VP9 (360P) visualizable na rede", + "timedmedia-derivative-desc-480p.vp9.webm": "WebM VP9 (480P) visualizable na rede", + "timedmedia-derivative-desc-720p.vp9.webm": "WebM VP9 de alta definiciĆ³n (720P) visualizable na rede", + "timedmedia-derivative-desc-1080p.vp9.webm": "WebM VP9 de alta definiciĆ³n total (1080P) visualizable na rede", + "timedmedia-derivative-desc-2160p.vp9.webm": "WebM VP9 4K completa (2160P) visualizable na rede", + "timedmedia-derivative-desc-320p.mp4": "MP4 compatible con dispositivos mĆ³biles (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 para a web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 de calidade HD (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4 de calidade Full HD (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "MP4 de calidade de alta definiciĆ³n 4K", + "timedmedia-subtitle-new": "Crear unha nova traduciĆ³n ou editar a actual", + "timedmedia-subtitle-new-desc": "Seleccione a lingua e prema no botĆ³n \"'''{{int:Timedmedia-subtitle-new-go}}'''\"", + "timedmedia-subtitle-new-go": "Continuar", + "timedmedia-subtitle-language": "SubtĆtulos en $1 ($2)", + "timedmedia-subtitle-no-video": "Non hai ningĆŗn vĆdeo asociado coa pĆ”xina de subtĆtulos actual", + "timedmedia-subtitle-no-subtitles": "Actualmente non hai subtĆtulos en $1 para este vĆdeo; pode [{{fullurl:{{FULLPAGENAME}}|action=edit}} editar esta pĆ”xina] para engadilos", + "timedmedia-subtitle-remote": "Os subtĆtulos deste ficheiro estĆ”n aloxados en $1", + "timedmedia-subtitle-remote-link": "Pode [$1 ollar a pĆ”xina de descriciĆ³n] deste ficheiro en $2", + "timedmediahandler": "ExtensiĆ³n TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 vĆdeo|$1 vĆdeos}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 vĆdeo Ogg|$1 vĆdeos Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 vĆdeo WebM|$1 vĆdeos WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodificaciĆ³n|$1 transcodificaciĆ³ns}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodificaciĆ³n activa|$1 transcodificaciĆ³ns activas}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodificaciĆ³n|$1 transcodificaciĆ³ns}} na cola", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transcodificaciĆ³n fallida|$1 transcodificaciĆ³ns fallidas}}", + "timedmedia-file": "Ficheiro", + "timedmedia-audios": "{{PLURAL:$1|$1 ficheiro|$1 ficheiros}} de son", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 ficheiro|$1 ficheiros}} de son Ogg", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 ficheiro|$1 ficheiros}} de son FLAC", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 ficheiro|$1 ficheiros}} de son WAV", + "right-transcode-reset": "Restablecer os vĆdeos transcodificados erroneamente para incluĆlos de novo na cola de traballo.", + "right-transcode-status": "Ollar a [[Special:TimedMediaHandler|informaciĆ³n sobre a actividade de transcodificaciĆ³n actual]]", + "action-transcode-status": "ollar o estado da transcodificaciĆ³n actual", + "orphanedtimedtext": "PĆ”xinas orfas de TimedText", + "orphanedtimedtext-summary": "Lista de pĆ”xinas [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] que non teƱen un ficheiro correspondente.", + "orphanedtimedtext-unsupported": "Esta pĆ”xina especial sĆ³ estĆ” soportada en bases de datos MySQL.", + "orphanedtimedtext-notimedtext": "TimedText non se activou nesta wiki.", + "apihelp-query+transcodestatus-description": "Obter o estado de transcode para unha pĆ”xina de ficheiro dado.", + "apihelp-query+transcodestatus-example-1": "Obter o estado transcode para [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "Estende a informaciĆ³n da imaxe para incluĆr a informaciĆ³n da fonte de vĆdeo (derivado)", + "apihelp-query+videoinfo-param-prop": "Que informaciĆ³n de vĆdeo obter:\n;timestamp:Engade o selo de tempo da versiĆ³n subida.\n;user:Engade o usuario que subiu a versiĆ³n de vĆdeo.\n;userid:Engade o identificador de usuario que subiu a versiĆ³n de vĆdeo.\n;comment:Comentario da versiĆ³n.\n;parsedcomment:Comentario analizado na versiĆ³n.\n;canonicaltitle:Engade o tĆtulo canĆ³nico do ficheiro de vĆdeo.\n;url:Devolve a URL Ć³ vĆdeo e a pĆ”xina de descriciĆ³n.\n;size:Engade o tamaƱo do vĆdeo en bytes, a sĆŗa altura e anchura. O contador de pĆ”xina e duraciĆ³n tamĆ©n se engaden se Ć© aplicable.\n;dimensions:Alias para \"size\".\n;sha1:Engade a funciĆ³n hash SHA-1 do vĆdeo.\n;mime:Engade o tipo MIME do vĆdeo.\n;thumbmime:Engade o tipo MIME da miniatura do vĆdeo (requie url e parĆ”metro $1urlwidth).\n;mediatype:Engade o tipo de medio multimedia do vĆdeo.\n;metadata:Lista os metadatos Exif da versiĆ³n do vĆdeo.\n;commonmetadata:Lista os metadatos formateados combinados desde varias fontes. Os resultados estĆ”n formateados en HTML.\n;archivename:Engade o nome de ficheiro da versiĆ³n para versiĆ³ns anteriores Ć” Ćŗltima.\n;bitdepth:Engade a profundidade de bit da versiĆ³n.\n;uploadwarning:Usado pola pĆ”xina [[Special:Upload]] para obter informaciĆ³n sobre un ficheiro xa existente. Non previsto para usar fĆ³ra do nĆŗcleo MediaWiki.\n;derivatives:Engade unha matriz dos diferentes formatos e calidades dispoƱibles dun audio ou vĆdeo.", + "apihelp-query+videoinfo-example-1": "Buscar informaciĆ³n sobre [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "Usuarios co permiso 'transcode-reset' poden reiniciar e reexecutar un traballo transcode.", + "apihelp-transcodereset-param-title": "TĆtulo do ficheiro multimedia.", + "apihelp-transcodereset-param-transcodekey": "A chave transcode que quere resetear. Collida de [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "Resetear todos os transcodes para [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "Resetear a clave transcode '360_560kbs.webm' de [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/gom-deva.json b/extensions/TimedMediaHandler/i18n/gom-deva.json new file mode 100644 index 00000000..f72dab88 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/gom-deva.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Darshan kandolkar", + "Supriya kankumbikar", + "Vaishali Parab" + ] + }, + "timedmedia-no-player-js": "ą¤®ą¤¾ą¤« ą¤ą¤°ą¤ą„ą¤, ą¤¤ą„ą¤®ą¤ą„ą¤Æą¤¾ ą¤¬ą„ą¤°ą¤¾ą¤µą¤ą¤°ą¤¾ą¤ą¤¤ ą¤ą¤ ą¤¤ą¤° ą¤ą¤¾ą¤µą¤¾ą¤øą„ą¤ą„ą¤°ą¤æą¤Ŗą„ą¤ ą¤¦ą„ą¤¬ą¤³ą„ą¤ ą¤ą¤øą¤¾ ą¤µą¤¾ ą¤øą¤®ą¤°ą„ą¤„ą„ą¤¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤Øą¤¾ą„¤<br />\ną¤¤ą„ą¤®ą„ <a href=\"$1\">ą¤ą„ą¤²ą„ą¤Ŗ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤°ą„ą¤ ą¤¶ą¤ą¤¤ą¤¾ą¤¤ ą¤µą¤¾ ą¤ą„ą¤²ą„ą¤Ŗ ą¤¤ą„ą¤®ą¤ą„ą¤Æą¤¾ ą¤¬ą„ą¤°ą¤¾ą¤µą¤ą¤°ą¤¾ą¤Ø ą¤ą¤²ą„ą¤µą¤Ŗą¤¾ą¤ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¤ą¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤°ą„ą¤ ą¤¶ą¤ą¤¤ą¤¾ą¤¤.", + "timedmedia-source-file": "$1 ą¤ą¤ą¤®", + "timedmedia-source-audio-file-desc": "ą¤®ą„ą¤³ $1 ą¤«ą¤¾ą¤Æą¤² ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/gom-latn.json b/extensions/TimedMediaHandler/i18n/gom-latn.json new file mode 100644 index 00000000..1bffb01a --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/gom-latn.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "The Discoverer" + ] + }, + "timedmedia-no-player-js": "Maf korchem, tujea browserant ek tor JavaScript dublem asa vo somorthit player nam.<br />\nTum <a href=\"$1\">clipik download</a> korunk shoktai vo clip tujea browseran cholovpak <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ek playerak download</a> korunk shoktai.", + "timedmedia-source-file": "$1 strot", + "timedmedia-source-file-desc": "Mul $1 fail, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Mul $1 fail ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/grc.json b/extensions/TimedMediaHandler/i18n/grc.json new file mode 100644 index 00000000..ce201686 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/grc.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Crazymadlover", + "Flyax", + "Omnipaedista" + ] + }, + "timedmedia-ogg-long-error": "į¼ĪŗĻ
ĻĪ± į¼ĻĻĪµįæĪ± ogg: $1", + "timedmedia-more": "ĻĪ»ĪĪæĪ½...", + "timedmedia-dismiss": "ĪĪ»įæĪµĪ¹Ī½", + "timedmedia-source-file": "$1 Ī Ī·Ī³Ī®" +} diff --git a/extensions/TimedMediaHandler/i18n/gsw.json b/extensions/TimedMediaHandler/i18n/gsw.json new file mode 100644 index 00000000..fb38ce89 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/gsw.json @@ -0,0 +1,62 @@ +{ + "@metadata": { + "authors": [ + "Als-ChlƤmens", + "Als-Holder", + "Melancholie" + ] + }, + "timedmedia-desc": "Stellt e Styyrigsprogramm fir zytgstyyrti Medie (Video, Audio, timedText) zur Verfiegig, wo d Format WebM, Ogg Theora, Ogg Vorbis un SubRip unterstĆ¼tzt", + "timedmedia-ogg-short-audio": "Ogg-$1-Audiodatei, $2", + "timedmedia-ogg-short-video": "Ogg-$1-Videodatei, $2", + "timedmedia-ogg-short-general": "Ogg-$1-Mediadatei, $2", + "timedmedia-ogg-long-audio": "Ogg-$1-Audiodatei, LƤngi: $2, $3", + "timedmedia-ogg-long-video": "Ogg-$1-Videodatei, LƤngi: $2, $4Ć$5 Pixel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg-Audio-/Video-Datei, $1, LƤngi: $2, $4Ć$5 Pixel, $3", + "timedmedia-ogg-long-general": "Ogg-Mediadatei, LƤngi: $2, $3", + "timedmedia-ogg-long-error": "Uugiltigi Ogg-Datei: $1", + "timedmedia-webm-short-video": "WebM-$1-Videodatei, $2", + "timedmedia-webm-long-video": "WebM-Audio-/Video-Datei, $1, LƤngei: $2, $4Ć$5 Pixel, $3 insgsamt", + "timedmedia-no-player-js": "Excusez, aber Dyy Browser het entwƤder JavaScript deaktiviert oder kei unterstitzti Abspilsoftware.<br />\nDu chasch <a href=\"$1\">dr Clip abelade</a> oder <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">e Abspielsoftware abelade</a> go dr Clip im Browser abspile.", + "timedmedia-more": "Meh ā¦", + "timedmedia-dismiss": "Zuemache", + "timedmedia-download": "Datei spychere", + "timedmedia-play-media": "Mediedatei abspiile", + "timedmedia-desc-link": "Iber die Datei", + "timedmedia-oggThumb-version": "OggHandler brucht oggThumb in dr Version $1 oder hecher.", + "timedmedia-oggThumb-failed": "oggThumb het kei Miniaturbild chenne aalege.", + "timedmedia-status-header": "UmschlĆ¼sseligsstatus", + "timedmedia-update-status": "UmschlĆ¼sseligsstatus aktualisiere", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Status nit bekannt", + "timedmedia-transcodeinfo": "Abgleiteti Beschryybig umschlĆ¼ssle", + "timedmedia-actions": "Aktione", + "timedmedia-direct-link": "Ableitig abelade", + "timedmedia-not-ready": "Nit parat", + "timedmedia-completed-on": "UmschlĆ¼sselig vo $1 abgschlosse", + "timedmedia-error-on": "FƤƤler bim UmschlĆ¼ssle in $1.", + "timedmedia-started-transcode": "UmschlĆ¼sselig het vor $1 aagfange. $2", + "timedmedia-percent-done": "Ćbe $1 % fertig", + "timedmedia-in-job-queue": "Vor $1 zur Ufftragswarteschlange dezuegfiegt worde", + "timedmedia-unknown-target-size": "Unbekannti ZiilgrƶĆi, $1 codiert", + "timedmedia-days": "{{PLURAL:$1|1 Tag|$1 TƤg}}", + "timedmedia-hours": "{{PLURAL:$1|1 Stund|$1 Stunde}}", + "timedmedia-minutes": "{{PLURAL:$1|1 Minut|$1 Minute}}", + "timedmedia-seconds": "{{PLURAL:$1|1 Sekund|$1 Sekunde}}", + "timedmedia-reset": "UmschlĆ¼sselig zruggsetze", + "timedmedia-reset-confirm": "S Zruggsetze vo dere UmschlĆ¼sselig wird (wƤnn's vorhande isch), die aktuelli Datei ussenee un d UmschlĆ¼sselig no emool uff d Ufftragswarteschlange dezuefiege. E nƶii UmschlĆ¼sselig wird e Wyyl goo.<br /><br /> Sƶll des wĆ¼rkli gmacht werde?", + "timedmedia-reset-error": "FƤƤler bim Zruggsetze vo de UmschlĆ¼sselig.", + "timedmedia-source-file": "Quell ($1)", + "timedmedia-source-file-desc": "Original $1, $2 x $3 ($4)", + "timedmedia-source-audio-file-desc": "Urspringligi $1-Datei ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg-Videodatei mit niidriger DateĆ¼bertragigsrate (160p)", + "timedmedia-derivative-desc-360p.ogv": "WebstreamingfƤhigi Ogg-Videodatei (360p)", + "timedmedia-derivative-desc-480p.ogv": "WebstreamingfƤhigi Ogg-Videodatei (480p)", + "timedmedia-derivative-desc-720p.ogv": "Qualitativ hochwertigi Ogg-Videodatei (720p)", + "timedmedia-derivative-desc-360p.webm": "WebstreamingfƤhigi WebM-Videodatei (360p)", + "timedmedia-derivative-desc-480p.webm": "WebstreamingfƤhigi WebM-Videodatei (480p)", + "timedmedia-derivative-desc-720p.webm": "Qualitativ hochwertigi WebM-Videodatei (720p)", + "timedmedia-subtitle-language": "$1 ($2) Untertitel", + "timedmedia-subtitle-no-video": "Dere Untertitel-Syte isch kei Video zuegordnet.", + "timedmedia-subtitle-no-subtitles": "Es git uff $1 zurzit kei Untertitel fĆ¼r des Video. Bim dezuefiege vo Untertitel cha [{{fullurl:{{FULLPAGENAME}}|action=edit}} die Syte] bearbeitet werde." +} diff --git a/extensions/TimedMediaHandler/i18n/gu.json b/extensions/TimedMediaHandler/i18n/gu.json new file mode 100644 index 00000000..7c73dd97 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/gu.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "KartikMistry", + "Arbhatt", + "Dsvyas", + "NehalDaveND", + "Ashok modhvadia" + ] + }, + "timedmedia-no-player-js": "ąŖ®ąŖ¾ąŖ« ąŖąŖ°ąŖ¶ą«, ąŖ¤ąŖ®ąŖ¾ąŖ°ąŖ¾ ąŖ¬ą«ąŖ°ąŖ¾ąŖąŖąŖ°ąŖ®ąŖ¾ąŖ ąŖąŖ¾ąŖµąŖ¾ąŖøą«ąŖą«ąŖ°ąŖæąŖŖą«ąŖ ąŖøąŖą«ąŖ°ąŖæąŖÆ ąŖØąŖ„ą« ąŖ
ąŖ„ąŖµąŖ¾ ąŖ¤ą« ąŖøąŖŖą«ąŖ°ą«ąŖą«ąŖ” ąŖŖą«ąŖ²ą«ąŖÆąŖ° ąŖØąŖ„ą«.<br />\nąŖ¤ąŖ®ą« <a href=\"$1\">ąŖą«ąŖ²ąŖæąŖŖ ąŖ”ąŖ¾ąŖąŖØąŖ²ą«ąŖ”</a> ąŖąŖ°ą« ąŖ¶ąŖą« ąŖą« ąŖ
ąŖ„ąŖµąŖ¾ ąŖ ąŖą«ąŖ²ąŖæąŖŖąŖØą« ąŖ¤ąŖ®ąŖ¾ąŖ°ąŖ¾ ąŖ¬ą«ąŖ°ąŖ¾ąŖąŖąŖ°ąŖ®ąŖ¾ąŖ ąŖąŖ²ąŖ¾ąŖµąŖµąŖ¾ ąŖ®ąŖ¾ąŖą« <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ąŖąŖ ąŖŖą«ąŖ²ą«ąŖÆąŖ° ąŖ”ąŖ¾ąŖąŖØąŖ²ą«ąŖ”</a> ąŖąŖ°ą« ąŖ¶ąŖą« ąŖą«.", + "timedmedia-more": "ąŖµąŖ§ą«...", + "timedmedia-dismiss": "ąŖ¬ąŖąŖ§ ąŖąŖ°ą«", + "timedmedia-download": "ąŖ«ąŖ¾ąŖąŖ² ąŖ”ąŖ¾ąŖąŖØąŖ²ą«ąŖ” ąŖąŖ°ą«", + "timedmedia-status": "ąŖøą«ąŖ„ąŖæąŖ¤ąŖæ", + "timedmedia-status-unknown": "ąŖ
ąŖą«ąŖąŖ¾ąŖ¤ ąŖøą«ąŖ„ąŖæąŖ¤ąŖæ", + "timedmedia-actions": "ąŖą«ąŖ°ąŖæąŖÆąŖ¾ąŖ", + "timedmedia-not-ready": "ąŖ¤ą«ąŖÆąŖ¾ąŖ° ąŖØąŖ„ą«", + "timedmedia-source-file": "$1 ąŖøą«ąŖ°ą«ąŖ¤", + "timedmedia-source-audio-file-desc": "ąŖ®ą«ąŖ³ ąŖąŖµą«ąŖ¤ą«ąŖ¤ąŖæ $1 ąŖ«ąŖ¾ąŖąŖ² ($2)", + "timedmedia-subtitle-new-go": "ąŖąŖ¾ąŖ", + "timedmedia-file": "ąŖ«ąŖ¾ąŖąŖ²" +} diff --git a/extensions/TimedMediaHandler/i18n/gv.json b/extensions/TimedMediaHandler/i18n/gv.json new file mode 100644 index 00000000..66353585 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/gv.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "MacTire02" + ] + }, + "timedmedia-desc-link": "Mychione y choadan shoh" +} diff --git a/extensions/TimedMediaHandler/i18n/he.json b/extensions/TimedMediaHandler/i18n/he.json new file mode 100644 index 00000000..29cddf15 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/he.json @@ -0,0 +1,125 @@ +{ + "@metadata": { + "authors": [ + "Amire80", + "Guycn2", + "Rotem Liss", + "Rotemliss", + "YaronSh" + ] + }, + "timedmedia-desc": "×××¤× ××××× ××Ŗ×××× ×Ŗ ā ×××××, ש××¢, ××§×”× ××Ŗ×××× ā ×¢× ×Ŗ×××× ××Ŗ×”×××Ø× WebM‏, Ogg Theora‏, Vorbis ×Ö¾srt", + "timedmedia-ogg-short-audio": "ק××ׄ ש××¢ $1 ×©× Ogg, $2", + "timedmedia-ogg-short-video": "ק××ׄ ××××× $1 ×©× Ogg, $2", + "timedmedia-ogg-short-general": "ק××ׄ ×××× $1 ×©× Ogg, $2", + "timedmedia-ogg-long-audio": "ק××ׄ ש××¢ $1 ×©× Ogg, ××××Ø× $2, $3", + "timedmedia-ogg-long-video": "ק××ׄ ××××× $1 ×©× Ogg, ××××Ø× $2, $4Ć$5 פ×קה×××, $3", + "timedmedia-ogg-long-multiplexed": "ק××ׄ Ogg ××Ø××× ×©× ×©××¢ ××××××, $1, ××××Ø× $2, $4Ć$5 פ×קה×××, $3 ××”× ××××", + "timedmedia-ogg-long-general": "ק××ׄ ×××× ×©× Ogg, ××××Ø× $2, $3", + "timedmedia-ogg-long-error": "ק××ׄ ogg ×××Ŗ× ×Ŗק××: $1", + "timedmedia-ogg-long-no-streams": "ק××ׄ ×××× Ogg. ××××Ø×: ××£ ××× ××ק××ק×× ×ק××ׄ ××× ××× × ××Ö¼×Ö¼×Ø.", + "timedmedia-webm-short-video": "ק××ׄ ××××× WebM $1‏, $2", + "timedmedia-webm-long-video": "ק××ׄ ש××¢ ×××××× WebM‏, $1, ××××Ø× $2‏, $4 Ć $5 פ×קה×××, $3 ×”× ××××", + "timedmedia-flac-short-audio": "ק××ׄ ש××¢ FLACā, $1", + "timedmedia-flac-long-audio": "ק××ׄ ש××¢ FLACā, ×××Ø× $1, ×”× ×××× $2", + "timedmedia-wav-short-audio": "ק××ׄ ש××¢ WAVā, $1", + "timedmedia-wav-long-audio": "ק××ׄ ש××¢ WAV, ×××Ø× $1, ×”× ×××× $2", + "timedmedia-wav-pcm-required": "×פש×Ø ×××¢×××Ŗ ×Øק ק×××¦× WAV ××Ŗ×”×××Ø PCMā (Pulse Code Modulation).", + "timedmedia-mp4-short-video": "ק××ׄ ××××× MP4 $1‏, $2", + "timedmedia-mp4-long-video": "ק××ׄ ש××¢ ×××××× ×©× MP4‏, $1, ××××Ø× $2, $4 Ć $5 פ×הק×××, $3 ××”× ××××", + "timedmedia-no-player-js": "×צ××¢×Ø××, ××פ××¤× ×©×× ×× ××פע××Ŗ ×Ŗ×××× ×Ö¾JavaScript ×× ×©××× ×× × ×× × ×Ŗ××.<br />\n××פש×Ø××Ŗ× <a href=\"$1\">××××Ø×× ××××©× ××Ŗ ××”×Ø×××</a> ×× <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">××××Ø×× × ××</a> ש×× ×× ××Ŗ ××”×Ø××× ××פ××¤× ×©××.", + "timedmedia-more": "×¢××ā¦", + "timedmedia-dismiss": "×”×××Ø×", + "timedmedia-download": "×××Ø××Ŗ ×ק××ׄ", + "timedmedia-play-media": "×× ×× ××Ŗ ×××××", + "timedmedia-desc-link": "×××××Ŗ ×ק××ׄ", + "timedmedia-oggThumb-version": "OggHandler ×××Øש oggThumb ×××Ø×”× $1 ×× ××Ø×”× ×××©× ×××Ŗ×Ø.", + "timedmedia-oggThumb-failed": "oggThumb ×× ×צ××× ××צ××Ø ×Ŗ××× × ××ק×× ×Ŗ.", + "timedmedia-status-header": "××¦× ×××Ø× ××©× ××Ŗ", + "timedmedia-update-status": "×¢×××× ××¦× ×××Ø× ××©× ××Ŗ", + "timedmedia-status": "×צ×", + "timedmedia-status-unknown": "××¦× ×× ××××¢", + "timedmedia-transcodebitrate": "×§×¦× ×××××", + "timedmedia-transcodeduration": "××× ×§××××", + "timedmedia-transcodeinfo": "×Ŗ×”×××Ø", + "timedmedia-actions": "פע××××Ŗ", + "timedmedia-direct-link": "×××Ø××", + "timedmedia-not-ready": "×× ××××", + "timedmedia-completed-on": "××ש×× ×Ö¾$1", + "timedmedia-error-on": "ש×××× ×Ö¾$1", + "timedmedia-started-transcode": "××Ŗ×××× ××¤× × $1ā. $2", + "timedmedia-percent-done": "××¢×Ø× $1% × ×¢×©×", + "timedmedia-in-job-queue": "× ××”×£ ××Ŗ××Ø ×ש××××Ŗ ××¤× × $1", + "timedmedia-unknown-target-size": "×××× ××¢× ××× × ××××¢, ק×××× $1", + "timedmedia-days": "{{PLURAL:$1|××× ×××|××××××|$1 ××××}}", + "timedmedia-hours": "{{PLURAL:$1|×©×¢× ×××Ŗ|שע×Ŗ×××|$1 שע××Ŗ}}", + "timedmedia-minutes": "{{PLURAL:$1|××§× ×××Ŗ|$1 ×ק××Ŗ}}", + "timedmedia-seconds": "{{PLURAL:$1|×©× ××× ×××Ŗ|$1 ×©× ×××Ŗ}}", + "timedmedia-reset": "××Ŗ××× ×××Ø× ××©× ××Ŗ", + "timedmedia-reset-confirm": "××Ŗ××× ××××Ø× ××××Ŗ ×××ק ×× ×§××ׄ ק××× (×× ×ש ×××) ××××”××£ ש×× ××Ŗ ××××Ø× ×××©× ××Ŗ ××Ŗ××Ø ××ש××××Ŗ. ×××§× ××× ××× ××צע ××Ŗ ××××Ø× ×××©× ××Ŗ ש××.<br /><br />×××ש××?", + "timedmedia-reset-error": "ש×××× ×××Ŗ××× ×ש×××Ŗ ×××Ø× ××©× ××Ŗ", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "××ק××Ø $1", + "timedmedia-source-file-desc": "ק××ׄ $1 ×ק××Ø×, $2 Ć $3‏ ($4)", + "timedmedia-source-audio-file-desc": "ק××ׄ $1 ×ק××Ø× ($2)", + "timedmedia-derivative-desc-160p.ogv": "××××× Ogg (160P)‎ ××Ø××× ×¤×” × ×××", + "timedmedia-derivative-desc-240p.ogv": "××××× Ogg (240P)‎ ×× ××× × ×©××פ×Ŗ ×××Øש×Ŗ", + "timedmedia-derivative-desc-360p.ogv": "××××× Ogg (360P)‎ ×× ××× × ×©××פ×Ŗ ×××Øש×Ŗ", + "timedmedia-derivative-desc-480p.ogv": "××××× Ogg (480P)‎ ×× ××× × ×©××פ×Ŗ ×××Øש×Ŗ", + "timedmedia-derivative-desc-720p.ogv": "××××× Ogg (720P)‎ ××××××Ŗ ××××× ×©× ××Ŗ× ××××Ø××", + "timedmedia-derivative-desc-1080p.ogv": "××××× Ogg ש×פש×Ø ××××Ø×× ××××××Ŗ HD ×××× (1080P)", + "timedmedia-derivative-desc-160p.webm": "WebM ××××Ø×× ××Øש×Ŗ (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM × ××Ŗ× ×ש××××Ø ×©××£ ××Øש×Ŗ (360P)", + "timedmedia-derivative-desc-480p.webm": "××××× WebM (480P)‎ ×× ××× × ×©××פ×Ŗ ×××Øש×Ŗ", + "timedmedia-derivative-desc-720p.webm": "××××× WebM (720P)‎ ××××××Ŗ ××××× ×©× ××Ŗ× ××××Ø××", + "timedmedia-derivative-desc-1080p.webm": "ק××ׄ WebM ש×פש×Ø ××××Ø×× ××××××Ŗ HD ×××× (1080P)", + "timedmedia-derivative-desc-2160p.webm": "ק××ׄ WebM ש×פש×Ø ××××Ø×× ××××××Ŗ 4K ×××× (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "WebM VP9 × ××Ŗ× ××××Ø×× ××Øש×Ŗ (360P)", + "timedmedia-derivative-desc-480p.vp9.webm": "WebM VP9 × ××Ŗ× ××××Ø×× ××Øש×Ŗ (480P)", + "timedmedia-derivative-desc-720p.vp9.webm": "WebM VP9 ××××××Ŗ HD × ××Ŗ× ××××Ø×× ××Øש×Ŗ (720P)", + "timedmedia-derivative-desc-1080p.vp9.webm": "WebM VP9 ××××××Ŗ HD ×××× × ××Ŗ× ××××Ø×× ××Øש×Ŗ (1080P)", + "timedmedia-derivative-desc-2160p.vp9.webm": "WebM VP9 ××××××Ŗ 4K ×××× × ××Ŗ× ××××Ø×× ××Øש×Ŗ (2160P)", + "timedmedia-derivative-desc-320p.mp4": "MP4 ××××××Ŗ× ×××ש××Ø (320P)", + "timedmedia-derivative-desc-480p.mp4": "××××× WebM (480P)‎ ×× ××× × ×©××פ×Ŗ ×××Øש×Ŗ", + "timedmedia-derivative-desc-720p.mp4": "MP4 ××××××Ŗ ××××× (720P)", + "timedmedia-derivative-desc-1080p.mp4": "ק××ׄ MP4 ש×פש×Ø ××××Ø×× ××××××Ŗ HD ×××× (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "MP4 ××××××Ŗ 4K ×××× (2160P)", + "timedmedia-subtitle-new": "×צ××Ø×Ŗ ×Ŗ×Ø××× ××ש ×× ×¢×Ø×××Ŗ ×Ŗ×Ø××× ×§×××", + "timedmedia-subtitle-new-desc": "× × ×××××Ø ×©×¤× ×××××ׄ ×¢× ×פ×Ŗ××Ø '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "××¢××Ø", + "timedmedia-subtitle-language": "××Ŗ×××××Ŗ ×{{GRAMMAR:×Ŗ×××××Ŗ|$1}} ($2)", + "timedmedia-subtitle-no-video": "××× ××××× ×©×ש××× ×××£ ×××Ŗ×××××Ŗ ×× ××××", + "timedmedia-subtitle-no-subtitles": "××× ××¢×Ŗ ××Ŗ×××××Ŗ ×¢×××Ø ××©×¤× ××××: $1. ×פש×Ø [{{fullurl:{{FULLPAGENAME}}|action=edit}} ××¢×Ø×× ××Ŗ ×××£ ×××] ×××××”××£ ×××Ŗ×", + "timedmedia-subtitle-remote": "××§×”× ××Ŗ×××× ×¢×××Ø ×§××ׄ ×× ×××××”× ×{{GRAMMAR:×Ŗ×××××Ŗ|$1}}", + "timedmedia-subtitle-remote-link": "×פש×Ø [$1 ××צ×× ××Ŗ ××£ ××Ŗ××××Ø] ×©× ×ק××ׄ ××× ×××£ $2", + "timedmediahandler": "×××× ××Ŗ×××× ×Ŗ", + "timedmedia-videos": "{{PLURAL:$1|×”×Ø× ×××|$1 ×”×Ø×××}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|×”×Ø× Ogg ×××|$1 ×”×Ø×× Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|×”×Ø× WebM ×××|$1 ×”×Ø×× WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|×××Ø× ××©× ××Ŗ ×××Ŗ|$1 ×××Ø××Ŗ ××©× ×××Ŗ}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|×××Ø× ××©× ××Ŗ ×××Ŗ ×Øצ×|$1 ×××Ø××Ŗ ××©× ×××Ŗ ×Øצ××Ŗ}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|×××Ø× ××©× ××Ŗ ×××Ŗ ××Ŗ××Ø|$1 ×××Ø××Ŗ ××©× ×××Ŗ ××Ŗ××Ø}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|×××Ø××Ŗ ××©× ××Ŗ ×××Ŗ × ×ש××|$1 ×××Ø××Ŗ ××©× ×××Ŗ × ×ש××}}", + "timedmedia-file": "ק××ׄ", + "timedmedia-audios": "{{PLURAL:$1|ק××ׄ ש××¢ ×××|$1 ק×××¦× ×©××¢}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|ק××ׄ ש××¢ Ogg ×××|$1 ק×××¦× ×©××¢ Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|ק××ׄ ש××¢ FLAC ×××|$1 ק×××¦× ×©××¢ FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|ק××ׄ ש××¢ WAV ×××|$1 ק×××¦× ×©××¢ WAV}}", + "right-transcode-reset": "××Ŗ××× ×”×Ø××× ×©×§×××× ×××©× × ×©××× ××ש×× ×× × ××©× ×× ×©×× ×××× ×”×× ×××ש ××Ŗ××Ø ××ש××××Ŗ.", + "right-transcode-status": "×צ××Ŗ [[Special:TimedMediaHandler|××××¢ ×¢× ×¤×¢××××Ŗ ×××Ø×ŖÖ¾×××©× × ×× ×××××Ŗ]]", + "action-transcode-status": "××צ×× ××Ŗ ××¦× ×××Ø×ŖÖ¾×××©× ×", + "orphanedtimedtext": "××¤× ××§×”× ××Ŗ×××× ××Ŗ××××", + "orphanedtimedtext-summary": "×Øש××× ×©× ×× ××¤× [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] ש×× ×ש××× ××× ×§××ׄ.", + "orphanedtimedtext-unsupported": "×××£ ×××××× ××× × ×Ŗ×× ×Øק ×××”×× × ×Ŗ×× ×× MySQL.", + "orphanedtimedtext-notimedtext": "×××Ø××× TimedText ××× × ××פע××Ŗ ×××××§× ×××.", + "apihelp-query+transcodestatus-description": "ק×××Ŗ ××¦× ××××Ø× ×××©× ××Ŗ ×¢×××Ø ××£ ×ק××ׄ ×× ×Ŗ××.", + "apihelp-query+transcodestatus-example-1": "ק×××Ŗ ××¦× ××××Ø× ×××©× ××Ŗ ×¢×××Ø [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "××Ø×××Ŗ imageinfo ××××××Ŗ ××××¢ ×¢× ×ק××Ø ××××××× (× ×××Ø××Ŗ)", + "apihelp-query+videoinfo-param-prop": "×××× ××××¢ ×ק×× ×¢× ×××××××:\n;timestamp:××הפ×Ŗ ×××Ŗ× ××× ×××Ø×”× ×©××××Ŗ×.\n;user:××הפ×Ŗ ××ש×Ŗ×ש ש××¢×× ××Ŗ ××Ø×”×Ŗ ×××××××.\n;userid:××הפ×Ŗ ×××× ××ש×Ŗ×ש ש××¢×× ××Ŗ ××Ø×”×Ŗ ×××××××.\n;comment:××¢×Ø× ×¢× ×××Ø×”×.\n;parsedcomment:×¤×¢× ×× ×××¢×Ø× ×¢× ×××Ø×”×.\n;canonicaltitle:××הפ×Ŗ ××××Ŗ×Ø×Ŗ ××§× ×× ××Ŗ ×©× ×©× ×§××ׄ ×××××××.\n;url:××הפ×Ŗ URL ××××××× ××××£ ××Ŗ××××Ø.\n;size:××הפ×Ŗ ××××× ×©× ××××××× ×××Ŗ××, ××××× ×©×× ×××Ø××× ×©××. הפ××Ø×Ŗ ×פ×× ×××©× ××הפ×× ×ש×× ××Ŗ×××.\n;dimensions:×××Ŗ× ×××Ø ××× size.\n;sha1:××הפ×Ŗ ××××× SHA-1 ×©× ×××××××.\n;mime:××הפ×Ŗ ×”×× MIME ×©× ×××××××.\n;thumbmime:××הפ×Ŗ ×”×× MIME ×©× ××Ŗ××× × ××××××¢×Ø×Ŗ ×©× ××××××× (× ××Øש url ××פ×Ø×××Ø $1urlwidth).\n;mediatype:××הפ×Ŗ ×”×× ××××× ×©× ×××××××.\n;metadata:×Øש×××Ŗ ×××Ö¾× ×Ŗ×× × EXIF ×××Ø×”× ×©× ×××××××.\n;commonmetadata:×Øש×××Ŗ ×××Ö¾× ×Ŗ×× ×× ××××× ×©× ×Ŗ×”×××Ø ×ק××ׄ ×¢×××Ø ××Ø×”×Ŗ ×××××××.\n;extmetadata:×Øש×××Ŗ ×××Ö¾× ×Ŗ×× ×× ××¢×צ××× ×ש××××× ××הפ×Ø ×ק××Ø××Ŗ ××Ŗ×צ×××Ŗ ××¢×צ×××Ŗ ×¢× HTML.\n;archivename:××הפ×Ŗ ×©× ×ק××ׄ ×©× ××Ø×”×Ŗ ×××Ø×××× ×¢×××Ø ×××Ø×”×××Ŗ ש××× × ×××Ø×”× ××××Ø×× ×.\n;bitdepth:×¢××ק ×××××× ×©× ×××Ø×”×.\n;uploadwarning:×ש×ש ××Ŗ ×××£ [[Special:Upload]] ××× ×ק×× ××××¢ ×¢× ×§××ׄ ק×××. ×× ××××¢× ×ש×××ש ×××ׄ ×××××Ŗ MediaWiki.\n;derivatives:××הפ×Ŗ ××¢×Ø× ×©× ××Ø×”×××Ŗ ×××× ××Ŗ ש×× ××Ŗ ××××× ×Ŗ ×Ŗ×”×××Ø ××××××Ŗ ×©× ×§××ׄ ש××¢ ×× ×××××.", + "apihelp-query+videoinfo-example-1": "×××××Ø ××××¢ ×¢× [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "×ש×Ŗ×ש×× ×¢× ×××Øש×× 'transcode-reset' ×××××× ××פה ××××Ø×ׄ ××××ש ×ש×××Ŗ ×××Ø×ŖÖ¾××©× ×.", + "apihelp-transcodereset-param-title": "×××Ŗ×Ø×Ŗ ק××ׄ ×××××.", + "apihelp-transcodereset-param-transcodekey": "×פ×Ŗ× ×××Ø×ŖÖ¾×××©× × ×©××Øצ×× × ××פה. ×ש ×××××Ø ×××Ŗ× ×Ö¾[[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "××פ××” ×× ×××Ø××ŖÖ¾×××©× × ×¢×××Ø [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "××פ××” ×פ×Ŗ× ×××Ø×Ŗ ×××©× × '<span dir=\"ltr\">360_560kbs.webm</span>' ×¢×××Ø [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/hi.json b/extensions/TimedMediaHandler/i18n/hi.json new file mode 100644 index 00000000..08ef0a1d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/hi.json @@ -0,0 +1,39 @@ +{ + "@metadata": { + "authors": [ + "Kaustubh", + "Shyam", + "Siddhartha Ghai", + "ą¤øą¤ą¤ą„ą¤µ ą¤ą„ą¤®ą¤¾ą¤°", + "NehalDaveND" + ] + }, + "timedmedia-desc": "ą¤ą¤ ą¤„ą¤æą¤Æą„ą¤°ą¤¾ ą¤ą¤° ą¤µą„ą¤°ą„ą¤¬ą¤æą¤ø ą¤«ą¤¼ą¤¾ą¤ą¤²ą„ą¤øą¤ą„ ą¤²ą¤æą¤Æą„ ą¤ą¤¾ą¤²ą¤, ą¤ą¤¾ą¤µą¤¾ą¤øą„ą¤ą„ą¤°ą„ą¤Ŗą„ą¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤ą„ ą¤øą¤¾ą¤„", + "timedmedia-ogg-short-audio": "ą¤ą¤ $1 ą¤§ą„ą¤µą¤Øą„ ą¤«ą¤¼ą¤¾ą¤ą¤², $2", + "timedmedia-ogg-short-video": "ą¤ą¤ $1 ą¤ą¤²ą¤¤ą¤ą¤æą¤¤ą„ą¤° ą¤«ą¤¼ą¤¾ą¤ą¤², $2", + "timedmedia-ogg-short-general": "ą¤ą¤ $1 ą¤®ą„ą¤”ą¤æą¤Æą¤¾ ą¤«ą¤¼ą¤¾ą¤ą¤², $2", + "timedmedia-ogg-long-audio": "ą¤ą¤ $1 ą¤§ą„ą¤µą¤Øą„ ą¤«ą¤¼ą¤¾ą¤ą¤², ą¤²ą¤ą¤¬ą¤¾ą¤ $2, $3", + "timedmedia-ogg-long-video": "ą¤ą¤ $1 ą¤ą¤²ą¤¤ą¤ą¤æą¤¤ą„ą¤° ą¤«ą¤¼ą¤¾ą¤ą¤², ą¤²ą¤ą¤¬ą¤¾ą¤ $2, $4Ć$5 ą¤Ŗą„ą¤ą„ą¤øą„ą¤²ą„ą¤ø, $3", + "timedmedia-ogg-long-multiplexed": "ą¤ą¤ ą¤§ą„ą¤µą¤Øą„/ą¤ą¤æą¤¤ą„ą¤° ą¤«ą¤¼ą¤¾ą¤ą¤², $1, ą¤²ą¤ą¤¬ą¤¾ą¤ $2, $4Ć$5 ą¤Ŗą¤æą¤ą„ą¤øą„ą¤²ą„ą¤ø, $3 ą¤ą„ą¤²", + "timedmedia-ogg-long-general": "ą¤ą¤ ą¤®ą„ą¤”ą¤æą¤Æą¤¾ ą¤«ą¤¼ą¤¾ą¤ą¤², ą¤²ą¤ą¤¬ą¤¾ą¤ $2, $3", + "timedmedia-ogg-long-error": "ą¤ą¤²ą¤¤ ą¤ą¤ ą¤«ą¤¼ą¤¾ą¤ą¤²: $1", + "timedmedia-no-player-js": "ą¤ą„ą¤·ą¤®ą¤¾ ą¤ą¤°ą„ą¤, ą¤ą¤Ŗą¤ą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤¼ą¤° ą¤®ą„ą¤ ą¤Æą¤¾ ą¤¤ą„ ą¤ą¤¾ą¤µą¤¾ą¤øą„ą¤ą„ą¤°ą¤æą¤Ŗą„ą¤ ą¤
ą¤ą„ą¤·ą¤® ą¤¹ą„ ą¤Æą¤¾ ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤Øą¤¹ą„ą¤ ą¤¹ą„ą„¤<br />\ną¤ą¤Ŗ <a href=\"$1\">ą¤ą„ą¤²ą¤æą¤Ŗ ą¤ą„ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤° ą¤øą¤ą¤¤ą„ ą¤¹ą„ą¤ ą¤
ą¤„ą¤µą¤¾ ą¤ą„ą¤²ą¤æą¤Ŗ ą¤ą„ ą¤
ą¤Ŗą¤Øą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤¼ą¤° ą¤®ą„ą¤ ą¤ą¤²ą¤¾ą¤Øą„ ą¤ą„ ą¤²ą¤æą¤ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¤ą¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤° ą¤øą¤ą¤¤ą„ ą¤¹ą„ą¤ą„¤", + "timedmedia-more": "ą¤ą¤°...", + "timedmedia-dismiss": "ą¤¬ą¤ą¤¦ ą¤ą¤°ą„ą¤", + "timedmedia-download": "ą¤«ą¤¼ą¤¾ą¤ą¤² ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤” ą¤ą¤°ą„ą¤", + "timedmedia-desc-link": "ą¤ą¤ø ą¤«ą¤¼ą¤¾ą¤ą¤²ą¤ą„ ą¤¬ą¤¾ą¤°ą„ ą¤®ą„ą¤", + "timedmedia-status": "ą¤øą„ą¤„ą¤æą¤¤ą¤æ", + "timedmedia-status-unknown": "ą¤
ą¤ą„ą¤ą¤¾ą¤¤ ą¤øą„ą¤„ą¤æą¤¤ą¤æ", + "timedmedia-actions": "ą¤ą„ą¤°ą¤æą¤Æą¤¾ą¤ą¤", + "timedmedia-source-file": "$1 ą¤øą„ą¤°ą„ą¤¤", + "timedmedia-source-audio-file-desc": "ą¤®ą„ą¤² $1 ą¤«ą¤¼ą¤¾ą¤ą¤² ($2)", + "timedmedia-derivative-desc-1080p.ogv": "ą¤Ŗą„ą¤°ą„ą¤£ ą¤ą¤ą„ą¤ ą¤Ŗą¤°ą¤æą¤ą¤¾ą¤·ą¤¾ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤” ą¤ą¤°ą¤Øą„ ą¤Æą„ą¤ą„ą¤Æ ą¤ą¤ą„ą¤ą„ ą¤µą„ą¤”ą¤æą¤Æą„ (ą„§ą„¦ą„®ą„¦ą¤Ŗą„)", + "timedmedia-derivative-desc-1080p.webm": "ą¤Ŗą„ą¤°ą„ą¤£ ą¤ą¤ą„ą¤ ą¤Ŗą¤°ą¤æą¤ą¤¾ą¤·ą¤¾ ą¤ą„ ą¤øą¤¾ą¤„ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤” ą¤ą¤°ą¤Øą„ ą¤Æą„ą¤ą„ą¤Æ ą¤µą„ą¤¬-ą¤ą¤® (ą„§ą„¦ą„®ą„¦ą¤Ŗą„)", + "timedmedia-derivative-desc-1080p.mp4": "ą¤Ŗą„ą¤°ą„ą¤£ ą¤ą¤ą„ą¤ ą¤Ŗą¤°ą¤æą¤ą¤¾ą¤·ą¤¾ ą¤ą„ą¤£ą¤µą¤¤ą¤¾ ą¤ą¤®ą¤Ŗą„ą„Ŗ (ą„§ą„¦ą„®ą„¦ą¤Ŗą„)", + "timedmedia-subtitle-new-go": "ą¤ą¤¾ą¤ą¤", + "timedmedia-file": "ą¤«ą¤¼ą¤¾ą¤ą¤²", + "timedmedia-audios": "{{PLURAL:$1|$1 ą¤ą¤”ą¤æą¤Æą„ ą¤«ą¤¼ą¤¾ą¤ą¤²|$1 ą¤ą¤”ą¤æą¤Æą„ ą¤«ą¤¼ą¤¾ą¤ą¤²ą„ą¤}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg ą¤ą¤”ą¤æą¤Æą„ ą¤«ą¤¼ą¤¾ą¤ą¤²|$1 Ogg ą¤ą¤”ą¤æą¤Æą„ ą¤«ą¤¼ą¤¾ą¤ą¤²ą„ą¤}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC ą¤ą¤”ą¤æą¤Æą„ ą¤«ą¤¼ą¤¾ą¤ą¤²|$1 FLAC ą¤ą¤”ą¤æą¤Æą„ ą¤«ą¤¼ą¤¾ą¤ą¤²ą„ą¤}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV ą¤ą¤”ą¤æą¤Æą„ ą¤«ą¤¼ą¤¾ą¤ą¤²|$1 WAV ą¤ą¤”ą¤æą¤Æą„ ą¤«ą¤¼ą¤¾ą¤ą¤²ą„ą¤}}" +} diff --git a/extensions/TimedMediaHandler/i18n/hr.json b/extensions/TimedMediaHandler/i18n/hr.json new file mode 100644 index 00000000..b8d63e0f --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/hr.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "CERminator", + "Dalibor Bosits", + "Ex13", + "SpeedyGonsales", + "Roberta F.", + "Fraxinus", + "Teoo3" + ] + }, + "timedmedia-desc": "Poslužitelj za Ogg Theora i Vorbis datoteke, s JavaScript preglednikom", + "timedmedia-ogg-short-audio": "Ogg $1 zvuÄna datoteka, $2", + "timedmedia-ogg-short-video": "Ogg $1 video datoteka, $2", + "timedmedia-ogg-short-general": "Ogg $1 medijska datoteka, $2", + "timedmedia-ogg-long-audio": "Ogg $1 zvuÄna datoteka, duljine $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 video datoteka, duljine $2, $4x$5 piksela, $3", + "timedmedia-ogg-long-multiplexed": "Ogg multipleksirana zvuÄna/video datoteka, $1, duljine $2, $4Ć$5 piksela, $3 ukupno", + "timedmedia-ogg-long-general": "Ogg medijska datoteka, duljine $2, $3", + "timedmedia-ogg-long-error": "nevaljana ogg datoteka: $1", + "timedmedia-no-player-js": "Nažalost, u VaÅ”em pregledniku iskljuÄen je JavaScript, ili nije dostupan na ovom projektu.<br />\nMožete <a href=\"<span class=\" notranslate\"=\"\" translate=\"no\">$1</span>\">preuzeti videozapis</a> ili <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">uÄitati player</a> za reproduciranje videozapisa u pregledniku.", + "timedmedia-more": "ViÅ”e...", + "timedmedia-dismiss": "Zatvori", + "timedmedia-download": "Snimi datoteku", + "timedmedia-desc-link": "O ovoj datoteci", + "timedmedia-source-file": "Izvor $1", + "timedmedia-source-audio-file-desc": "Originalna $1 datoteka ($2)", + "timedmedia-derivative-desc-2160p.vp9.webm": "Full 4K streamable WebM VP9 (2160P)", + "timedmedia-derivative-desc-2160p.mp4": "MP4 pune 4K kvalitete (2160P)" +} diff --git a/extensions/TimedMediaHandler/i18n/hrx.json b/extensions/TimedMediaHandler/i18n/hrx.json new file mode 100644 index 00000000..80513f50 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/hrx.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Midnight Gambler" + ] + }, + "timedmedia-source-file": "Quell ($1)" +} diff --git a/extensions/TimedMediaHandler/i18n/hsb.json b/extensions/TimedMediaHandler/i18n/hsb.json new file mode 100644 index 00000000..094def43 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/hsb.json @@ -0,0 +1,83 @@ +{ + "@metadata": { + "authors": [ + "Dundak", + "Michawiki", + "Reedy" + ] + }, + "timedmedia-desc": "WodÅŗenski program za awdio, widejo a timedText z podpÄru za formaty WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Awdiodataja Ogg $1, $2", + "timedmedia-ogg-short-video": "Widejodataja Ogg $1, $2", + "timedmedia-ogg-short-general": "Ogg medijowa dataja $1, $2", + "timedmedia-ogg-long-audio": "Ogg-awdiodataja $1, doÅhosÄ: $2, $3", + "timedmedia-ogg-long-video": "Ogg-widejodataja $1, doÅhosÄ: $2, $4Ć$5 pikselow, $3", + "timedmedia-ogg-long-multiplexed": "Ogg multipleksna awdio-/widejodataja, $1, doÅhosÄ: $2, $4Ć$5 pikselow, $3", + "timedmedia-ogg-long-general": "Ogg medijowa dataja, doÅhosÄ: $2, $3", + "timedmedia-ogg-long-error": "NjepÅaÄiwa Ogg-dataja: $1", + "timedmedia-webm-short-video": "Widejodataja WebM $1, $2", + "timedmedia-webm-long-video": "Awdio-/widejodataja WebM, $1, doÅhosÄ $2, $4 x $5 pikselow, $3 dohromady", + "timedmedia-mp4-short-video": "MP4 $1 widejodataja, $2", + "timedmedia-mp4-long-video": "MP4 awdio-/widejodataja, $1, doÅhosÄ $2, $4 Ć $5 pikselow, $3 dohromady", + "timedmedia-no-player-js": "TwĆ³j wobhladowak je pak JavaScript znjemĆ³Å¾niÅ pak nima podpÄrowany wothrawak.<br />\nMĆ³Å¾eÅ” <a href=\"$1\">klip sÄahnyÄ</a> abo <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">wothrawak sÄahnyÄ</a>, zo by klip w swojim wobhladowaku wothrawaÅ.", + "timedmedia-more": "Wjace ...", + "timedmedia-dismiss": "ZaÄiniÄ", + "timedmedia-download": "Dataju sÄahnyÄ", + "timedmedia-play-media": "Medijowu dataju wothraÄ", + "timedmedia-desc-link": "Wo tutej dataji", + "timedmedia-oggThumb-version": "OggHandler trjeba wersiju $1 oggThumb abo nowÅ”u.", + "timedmedia-oggThumb-failed": "oggThumb njemĆ³Å¾eÅ”e wobrazk wutworiÄ.", + "timedmedia-status-header": "PÅekodowanski status", + "timedmedia-update-status": "PÅekodowanski status aktualizowaÄ", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Njeznaty status", + "timedmedia-transcodeinfo": "WotwodÅŗene wopisanje pÅekodowaÄ", + "timedmedia-actions": "Akcije", + "timedmedia-direct-link": "WotwodÅŗenje sÄahnyÄ", + "timedmedia-not-ready": "Nic hotowy", + "timedmedia-completed-on": "PÅekodowanje $1 wotzamknjene", + "timedmedia-error-on": "Zmylk pÅi pÅekodowanju $1", + "timedmedia-started-transcode": "PÅekodowanje pÅed $1 startowane. $2", + "timedmedia-percent-done": "Na wÅ”Ä $1% sÄinjene", + "timedmedia-in-job-queue": "PÅed $1 Äakanskemu rynÄkej pÅidaty", + "timedmedia-unknown-target-size": "Njeznata cilowa wulkosÄ, $1 kodowane", + "timedmedia-days": "{{PLURAL:$1|1 dÅŗeÅ|$1 dnjej|$1 dny|$1 dnjow}}", + "timedmedia-hours": "{{PLURAL:$1|1 hodÅŗina|$1 hodÅŗinje|$1 hodÅŗiny|$1 hodÅŗin}}", + "timedmedia-minutes": "{{PLURAL:$1|1 mjeÅÅ”ina|$1 mjeÅÅ”inje|$1 mjeÅÅ”iny|$1 mjeÅÅ”in}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekunda|$1 sekundÅŗe|$1 sekundy|$1 sekundow}}", + "timedmedia-reset": "PÅekodowanje wrĆ³Äo stajiÄ", + "timedmedia-reset-confirm": "WrĆ³Äostajenje tutoho pÅekodowanja wotstroni eksistowacu dataju (jeli tajka eksistuje), a budÅŗe pÅekodowanje znowa Äakanskemu rynÄkej pÅidawaÄ. Nowe pÅekodowanje budÅŗe nÄkotry Äas traÄ.<br /><br />\nChceÅ” woprawdÅŗe pokroÄowaÄ?", + "timedmedia-reset-error": "Zmylk pÅi wrĆ³Äostajenju pÅekodowanja.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Å½Ć³rÅo ($1)", + "timedmedia-source-file-desc": "Originalna dataja $1, $2 x $3 ($4)", + "timedmedia-source-audio-file-desc": "Originalna $1-dataja ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg-widejo z niskej Å”ÄrokosÄu pasma (160p)", + "timedmedia-derivative-desc-360p.ogv": "Ogg-widejo (360p), kotrež da so pÅez Web pÅenjesÄ", + "timedmedia-derivative-desc-480p.ogv": "Ogg-widejo (480p), kotrež da so pÅez Web pÅenjesÄ", + "timedmedia-derivative-desc-720p.ogv": "SÄahujomne Ogg-widejo wysokeje kwality (720p)", + "timedmedia-derivative-desc-160p.webm": "WebM-widejo (160p), kotrež da so pÅez Web pÅenjesÄ", + "timedmedia-derivative-desc-360p.webm": "WebM-widejo (360p), kotrež da so pÅez Web pÅenjesÄ", + "timedmedia-derivative-desc-480p.webm": "WebM-widejo (480p), kotrež da so pÅez Web pÅenjesÄ", + "timedmedia-derivative-desc-720p.webm": "SÄahujomna WebM-dataja wysokeje kwality (720p)", + "timedmedia-derivative-desc-320p.mp4": "GratapÅeÄelny MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4-dataja, kotraž da so pÅez Web pÅenjesÄ", + "timedmedia-derivative-desc-720p.mp4": "MP4 w HD-kwaliÄe (720P)", + "timedmedia-subtitle-new": "Nowy pÅeÅožk wutworiÄ abo eksistowacy wobdÅŗÄÅaÄ", + "timedmedia-subtitle-new-desc": "Wubjer rÄÄ a klikÅ na tÅĆ³Äatko '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "W porjadku", + "timedmedia-subtitle-language": "$1 ($2) podtitule", + "timedmedia-subtitle-no-video": "Widejo zwjazane z aktuelnej stronu podtitulow njeje", + "timedmedia-subtitle-no-subtitles": "Tuchwilu podtitule w $1 zu tute widejo njejsu, mĆ³Å¾eÅ” [{{fullurl:{{FULLPAGENAME}}|action=edit}} tutu stronu wobdÅŗÄÅaÄ], zo by je pÅidaÅ", + "timedmedia-subtitle-remote": "timedText za tutu dataju je na $1", + "timedmedia-subtitle-remote-link": "MĆ³Å¾eÅ” sej [$1 wopisansku stronu] za tutu dataja na $2 wobhladaÄ", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 widejo|$1 wideji|$1 wideja|$1 widejow}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg-widejo|$1 Ogg-wideji|$1 Ogg-wideja|$1 Ogg-widejow}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM-widejo|$1 WebM-wideji|$1 WebM-wideja|$1 WebM-widejow}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 pÅekodowanje|$1 pÅekodowani|$1 pÅekodowanja|$1 pÅekodowanjow}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 bÄžne pÅekodowanje|$1 bÄžnej pÅekodowani|$1 bÄžne pÅekodowanja|$1 bÄžnych pÅekodowanjow}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 pÅekodowanje|$1 pÅekodowani|$1 pÅekodowanja|$1 pÅekodowanjow}} w Äakanskim rynku", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 zwrÄsÄene pÅekodowanje|$1 zwrÄsÄenej pÅekodowani|$1 zwrÄsÄene pÅekodowanja|$1 zwrÄsÄenych pÅekodowanjow}}", + "timedmedia-file": "Dataja" +} diff --git a/extensions/TimedMediaHandler/i18n/ht.json b/extensions/TimedMediaHandler/i18n/ht.json new file mode 100644 index 00000000..54b45469 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ht.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Tisave" + ] + }, + "timedmedia-no-player-js": "Eskize, men swa JavaScript navigatĆØ ou deyaktive oswa li pa gen okenn mwayen pou ouvri fichye sa a.<br />\nOu ka <a href=\"$1\">telechaje fichye a</a> oswa <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">chĆØche yon lojisyĆØl</a> pou ouvri fichye a nan navigatĆØ ou.", + "timedmedia-source-file": "Referans $1" +} diff --git a/extensions/TimedMediaHandler/i18n/hu.json b/extensions/TimedMediaHandler/i18n/hu.json new file mode 100644 index 00000000..dbe3df87 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/hu.json @@ -0,0 +1,37 @@ +{ + "@metadata": { + "authors": [ + "Dani", + "Glanthor Reviol", + "Tgr", + "Csega", + "Samat", + "Dj" + ] + }, + "timedmedia-desc": "JavaScript nyelven Ćrt lejĆ”tszĆ³ Ogg Theora Ć©s Vorbis fĆ”jlokhoz", + "timedmedia-ogg-short-audio": "Ogg $1 hangfĆ”jl, $2", + "timedmedia-ogg-short-video": "Ogg $1 videofĆ”jl, $2", + "timedmedia-ogg-short-general": "Ogg $1 mĆ©diafĆ”jl, $2", + "timedmedia-ogg-long-audio": "Ogg $1 hangfĆ”jl, hossza: $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videĆ³fĆ”jl, hossza $2, $4Ć$5 kĆ©ppont, $3", + "timedmedia-ogg-long-multiplexed": "Ogg egyesĆtett audiĆ³- Ć©s videĆ³fĆ”jl, $1, hossz: $2, $4Ć$5 kĆ©ppont, $3 ƶsszesen", + "timedmedia-ogg-long-general": "Ogg mĆ©diafĆ”jl, hossza: $2, $3", + "timedmedia-ogg-long-error": "ĆrvĆ©nytelen ogg fĆ”jl: $1", + "timedmedia-no-player-js": "SajnĆ”ljuk, a bƶngĆ©szÅdben vagy le van tiltva a JavaScript, vagy nincs egyetlen tĆ”mogatott lejĆ”tszĆ³ja sem.<br />\n<a href=\"$1\">Letƶltheted a klipet</a>, vagy <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">letƶlthetsz egy lejĆ”tszĆ³t</a> a bƶngĆ©szÅben valĆ³ megtekintĆ©shez.", + "timedmedia-more": "TovĆ”bb...", + "timedmedia-dismiss": "BezĆ”rĆ”s", + "timedmedia-download": "FĆ”jl letƶltĆ©se", + "timedmedia-play-media": "MĆ©dia lejĆ”tszĆ”sa", + "timedmedia-desc-link": "FĆ”jlinformĆ”ciĆ³k", + "timedmedia-oggThumb-version": "Az OggHandlerhez $1 vagy kĆ©sÅbbi verziĆ³jĆŗ oggThumb szĆ¼ksĆ©ges.", + "timedmedia-oggThumb-failed": "Az oggThumb nem tudta elkĆ©szĆteni a bĆ©lyegkĆ©pet.", + "timedmedia-source-file": "ForrĆ”s ($1)", + "timedmedia-source-file-desc": "Eredeti $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Eredeti $1 fĆ”jl ($2)", + "timedmedia-derivative-desc-160p.ogv": "Alacsony sĆ”vszĆ©lessĆ©gű Ogg videĆ³ (160P)", + "timedmedia-derivative-desc-720p.ogv": "Magas minÅsĆ©gű, letƶlthetÅ Ogg videĆ³ (720P)", + "timedmedia-derivative-desc-720p.webm": "Magas minÅsĆ©gű, letƶlthetÅ WebM (720P)", + "right-transcode-status": "[[Special:TimedMediaHandler|a legutĆ³bbi Ć”tkĆ³dolĆ”si esemĆ©nyek informĆ”ciĆ³inak]] megtekintĆ©se", + "orphanedtimedtext": "Ćrva TimedText lapok" +} diff --git a/extensions/TimedMediaHandler/i18n/hy.json b/extensions/TimedMediaHandler/i18n/hy.json new file mode 100644 index 00000000..41aa6004 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/hy.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Xelgen", + "Vahe Gharakhanyan" + ] + }, + "timedmedia-no-player-js": "ÕÕ”Õ¾ÕøÖ, Õ±Õ„Ö Õ¾Õ„Õ¢Õ¤Õ«ÕæÕ”ÖÕÆÕ«Õ¹ÕøÖÕ“ Õ”Õ¶Õ»Õ”ÕæÕ¾Õ”Õ® Õ§ JavaScript-ÕØ ÕÆÕ”Õ“ Õ¢Õ”ÖÕ”ÕÆÕ”ÕµÕøÖÕ“ Õ§ Õ”Õ»Õ”ÕÆÖÕ¾ÕøÕ² Õ¶Õ¾Õ”Õ£Õ”ÖÕÆÕ«Õ¹:<br />\nŌ“ÕøÖÖ ÕÆÕ”ÖÕøÕ² Õ„Ö <a href=\"<span class=\" notranslate\"=\"\" translate=\"no\">$1</span>\">Õ¶Õ„ÖÕ¢Õ„Õ¼Õ¶Õ„Õ¬ ÕæÕ„Õ½Õ”Õ°ÕøÕ¬ÕøÕ¾Õ”ÕÆÕØ</a> ÕÆÕ”Õ“ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Õ¶Õ¾Õ”Õ£Õ”ÖÕÆÕ«Õ¹</a>:", + "timedmedia-source-file": "$1 Õ”Õ²Õ¢ÕµÕøÖÖ", + "timedmedia-source-audio-file-desc": "ÕÕÆÕ¦Õ¢Õ¶Õ”ÕÆÕ”Õ¶ $1 Õ¶Õ«Õ·Ö ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/ia.json b/extensions/TimedMediaHandler/i18n/ia.json new file mode 100644 index 00000000..a24d1b20 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ia.json @@ -0,0 +1,92 @@ +{ + "@metadata": { + "authors": [ + "McDutchie" + ] + }, + "timedmedia-desc": "Gestor pro audio, video e texto synchronisate, con supporto del formatos WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "File audio Ogg $1, $2", + "timedmedia-ogg-short-video": "File video Ogg $1, $2", + "timedmedia-ogg-short-general": "File media Ogg $1, $2", + "timedmedia-ogg-long-audio": "File audio Ogg $1, duration $2, $3", + "timedmedia-ogg-long-video": "File video Ogg $1, duration $2, $4Ć$5 pixel, $3", + "timedmedia-ogg-long-multiplexed": "File multiplexate audio/video Ogg, $1, duration $2, $4Ć$5 pixel, $3 in total", + "timedmedia-ogg-long-general": "File media Ogg, duration $2, $3", + "timedmedia-ogg-long-error": "File Ogg invalide: $1", + "timedmedia-webm-short-video": "File video WebM $1, $2", + "timedmedia-webm-long-video": "File audio/video WebM, $1, longitude $2, $4 Ć $5 pixels, $3 in total", + "timedmedia-flac-short-audio": "File audio FLAC, $1", + "timedmedia-flac-long-audio": "File audio FLAC, durata $1, $2 in total", + "timedmedia-wav-short-audio": "File audio WAV, $1", + "timedmedia-wav-long-audio": "File audio WAV, durata $1, $2 in total", + "timedmedia-wav-pcm-required": "Tu pote solmente incargar PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "File video MP4 $1, $2", + "timedmedia-mp4-long-video": "File audio/video MP4 $1, durata $2, dimensiones $4Ā ĆĀ $5 pixels, $3 in total", + "timedmedia-no-player-js": "Pardono, tu systema o ha JavaScript disactivate o non ha un reproductor supportate.<br />\nTu pote <a href=\"$1\">discargar le clip</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">discargar un reproductor</a> pro reproducer le clip in tu navigator.", + "timedmedia-more": "Plusā¦", + "timedmedia-dismiss": "Clauder", + "timedmedia-download": "Discargar file", + "timedmedia-play-media": "Reproducer multimedia", + "timedmedia-desc-link": "A proposito de iste file", + "timedmedia-oggThumb-version": "OggHandler require oggThumb version $1 o plus recente.", + "timedmedia-oggThumb-failed": "oggThumb ha fallite de crear le miniatura.", + "timedmedia-status-header": "Stato de transcodification", + "timedmedia-update-status": "Actualisar stato de transcodification", + "timedmedia-status": "stato", + "timedmedia-status-unknown": "stato incognite", + "timedmedia-transcodeinfo": "Description del file transcodificate", + "timedmedia-actions": "actiones", + "timedmedia-direct-link": "Discargar file transcodificate", + "timedmedia-not-ready": "Non preste", + "timedmedia-completed-on": "Transcodification de $1 complete", + "timedmedia-error-on": "Error in transcodification a $1", + "timedmedia-started-transcode": "Le transcodification comenciava $1 retro. $2", + "timedmedia-percent-done": "Circa $1% complete", + "timedmedia-in-job-queue": "Addite al cauda de actiones $1 retro", + "timedmedia-unknown-target-size": "Dimension del destination incognite, $1 codificate", + "timedmedia-days": "{{PLURAL:$1|1 die|$1 dies}}", + "timedmedia-hours": "{{PLURAL:$1|1 hora|$1 horas}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuta|$1 minutas}}", + "timedmedia-seconds": "{{PLURAL:$1|1 secunda|$1 secundas}}", + "timedmedia-reset": "Reinitialisar transcodification", + "timedmedia-reset-confirm": "Reinitialisar iste transcodification removera tote le files existente (si presente), e illo re-addera le transcodification al cauda de actiones. Le transcodification prendera un tempore. <br /><br />Es tu secur de voler continuar?", + "timedmedia-reset-error": "Error durante le reinitialisation del action de transcodification", + "timedmedia-source-file": "original $1", + "timedmedia-source-file-desc": "File $1 original, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "File $1 original ($2)", + "timedmedia-derivative-desc-160p.ogv": "Video Ogg a basse largor de banda (160P)", + "timedmedia-derivative-desc-360p.ogv": "Video Ogg transmissibile per fluxo web (360P)", + "timedmedia-derivative-desc-480p.ogv": "Video Ogg transmissibile per fluxo web (480P)", + "timedmedia-derivative-desc-720p.ogv": "Video Ogg discargabile de alte qualitate (720P)", + "timedmedia-derivative-desc-160p.webm": "WebM transmissibile per fluxo web (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM transmissibile per fluxo web (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM transmissibile per fluxo web (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM discargabile de alte qualitate (720P)", + "timedmedia-derivative-desc-320p.mp4": "MP4 pro dispositivos mobile (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 transmissibile per fluxo web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 in qualitate HD (720P)", + "timedmedia-subtitle-new": "Crear un nove traduction o modificar le existente", + "timedmedia-subtitle-new-desc": "Selige un lingua e preme le button '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Va", + "timedmedia-subtitle-language": "$1 ($2) subtitulos", + "timedmedia-subtitle-no-video": "Il non ha video associate con le actual pagina de subtitulos", + "timedmedia-subtitle-no-subtitles": "Il ha actualmente nulle subtitulos in $1 pro iste video. Tu pote [{{fullurl:{{FULLPAGENAME}}|action=edit}} modificar iste pagina] pro adder los.", + "timedmedia-subtitle-remote": "Le subtitulos pro iste file es albergate sur $1", + "timedmedia-subtitle-remote-link": "Tu pote [$1 vider le pagina de description] pro iste file sur $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 videos}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 video Ogg|$1 videos Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 video WebM|$1 videos WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodification|$1 transcodificationes}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodification|$1 transcodificationes}} active", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodification|$1 transcodificationes}} in cauda", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transcodification|$1 transcodificationes}} fallite", + "timedmedia-file": "File", + "timedmedia-audios": "{{PLURAL:$1|$1 file audio|$1 files audio}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 file audio Ogg|$1 files audio Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 file audio FLAC|$1 files audio FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 file audio WAV|$1 files audio WAV}}", + "right-transcode-reset": "Reinitialisar le videos fallite o transcodificate de sorta que illos es re-inserite in le cauda de actiones", + "right-transcode-status": "View [[Special:TimedMediaHandler|information sur le activitate currente de transcodification]]", + "action-transcode-status": "vider le stato actual de transcodification" +} diff --git a/extensions/TimedMediaHandler/i18n/id.json b/extensions/TimedMediaHandler/i18n/id.json new file mode 100644 index 00000000..48f6cc2a --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/id.json @@ -0,0 +1,97 @@ +{ + "@metadata": { + "authors": [ + "Bennylin", + "Farras", + "Irwangatot", + "IvanLanin", + "Iwan Novirion", + "Rex", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "timedmedia-desc": "Pemroses audio, video, dan teks berwaktu, dengan dukungan format WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Berkas suara $1 ogg, $2", + "timedmedia-ogg-short-video": "Berkas video $1 ogg, $2", + "timedmedia-ogg-short-general": "Berkas media $1 ogg, $2", + "timedmedia-ogg-long-audio": "Berkas suara $1 ogg, panjang $2, $3", + "timedmedia-ogg-long-video": "Berkas video $1 ogg, panjang $2, $4Ć$5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "Berkas audio/video multiplexed ogg, $1, panjang $2, $4Ć$5 piksel, $3 keseluruhan", + "timedmedia-ogg-long-general": "Berkas media ogg, panjang $2, $3", + "timedmedia-ogg-long-error": "Berkas ogg tak valid: $1", + "timedmedia-webm-short-video": "Berkas video $1 WebM, $2", + "timedmedia-webm-long-video": "Berkas audio/video WebM, $1, lama $2, $4 Ć $5 piksel, $3 keseluruhan", + "timedmedia-no-player-js": "Maaf, peramban Anda memiliki JavaScript yang dinonaktifkan atau tidak memiliki pemutar media apapun.<br />\nAnda dapat <a href=\"$1\">mengunduh klip</a> atau <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">mengunduh pemutar</a> untuk memutar klip di peramban Anda.", + "timedmedia-more": "Lainnya...", + "timedmedia-dismiss": "Tutup", + "timedmedia-download": "Unduh berkas", + "timedmedia-play-media": "Putar media", + "timedmedia-desc-link": "Mengenai berkas ini", + "timedmedia-oggThumb-version": "OggHandler membutuhkan oggThumb versi $1 atau terbaru.", + "timedmedia-oggThumb-failed": "oggThumb gagal membuat miniatur gambar.", + "timedmedia-status-header": "Status transkoder", + "timedmedia-update-status": "Memperbarui status transkoder", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Status tidak diketahui", + "timedmedia-transcodeinfo": "Deskripsi turunan transkoder", + "timedmedia-actions": "Tindakan", + "timedmedia-direct-link": "Unduh turunan", + "timedmedia-not-ready": "Belum siap", + "timedmedia-completed-on": "Transkoder komplit $1", + "timedmedia-error-on": "Kesalahan dalam transkoder pada $1 .", + "timedmedia-started-transcode": "Transkoder mulai $1 yang lalu. $2", + "timedmedia-percent-done": "Sekitar $1% selesai", + "timedmedia-days": "{{PLURAL:$1|$1 hari}}", + "timedmedia-hours": "{{PLURAL:$1|$1 jam}}", + "timedmedia-minutes": "{{PLURAL:$1|$1 menit}}", + "timedmedia-seconds": "{{PLURAL:$1|$1 detik}}", + "timedmedia-reset": "Reset transkoder", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Sumber $1", + "timedmedia-source-file-desc": "$1 asli, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Berkas ($2) asli $1", + "timedmedia-derivative-160p.ogv": "Ogg 160p", + "timedmedia-derivative-desc-160p.ogv": "Video Ogg lebar pita rendah (160P)", + "timedmedia-derivative-360p.ogv": "Ogg 360p", + "timedmedia-derivative-desc-360p.ogv": "Video Ogg aliran web (360P)", + "timedmedia-derivative-480p.ogv": "Ogg 480p", + "timedmedia-derivative-desc-480p.ogv": "Video Ogg aliran web (480P)", + "timedmedia-derivative-720p.ogv": "Ogg 720p", + "timedmedia-derivative-desc-720p.ogv": "Video Ogg unduhan berkualitas tinggi (720P)", + "timedmedia-derivative-160p.webm": "WebM 160p", + "timedmedia-derivative-360p.webm": "WebM 360p", + "timedmedia-derivative-desc-360p.webm": "WebM aliran web (360P)", + "timedmedia-derivative-480p.webm": "WebM 480p", + "timedmedia-derivative-desc-480p.webm": "WebM aliran web (480P)", + "timedmedia-derivative-720p.webm": "WebM 720p", + "timedmedia-derivative-desc-720p.webm": "WebM unduhan berkualitas tinggi (720P)", + "timedmedia-derivative-320p.mp4": "H264 320p", + "timedmedia-derivative-480p.mp4": "H264 480p", + "timedmedia-derivative-720p.mp4": "H264 720p", + "timedmedia-derivative-ogg": "Ogg Vorbis", + "timedmedia-derivative-desc-ogg": "Ogg Vorbis", + "timedmedia-derivative-opus": "Opus", + "timedmedia-derivative-desc-opus": "Opus", + "timedmedia-derivative-mp3": "MP3", + "timedmedia-derivative-desc-mp3": "MP3", + "timedmedia-derivative-m4a": "AAC", + "timedmedia-derivative-desc-m4a": "AAC", + "timedmedia-subtitle-new-go": "Lanjut", + "timedmedia-subtitle-language": "Teks film $1 ($2)", + "timedmedia-subtitle-no-video": "Tidak ada video yang terkait dengan halaman subjudul ini", + "timedmedia-subtitle-no-subtitles": "Saat ini tidak ada subjudul $1 untuk video ini. Anda dapat [{{fullurl: {{FULLPAGENAME}}|action=edit}} menyunting halaman ini] untuk menambahkannya", + "timedmediahandler": "Daftar berkas media", + "timedmedia-videos": "{{PLURAL:$1|$1 video}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Video ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 Video WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transkoder}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transkoder aktif}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 antrian transkoder}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transkoder rusak}}", + "timedmedia-file": "Berkas", + "right-transcode-reset": "Reset transkoder rusak ataupun yang tidak sehingga kembali dimasukkan dalam antrian.", + "right-transcode-status": "Lihat [[Special:TimedMediaHandler|informasi tentang aktifitas transkoder terkini]]", + "action-transcode-status": "lihat status transkoder terkini" +} diff --git a/extensions/TimedMediaHandler/i18n/ilo.json b/extensions/TimedMediaHandler/i18n/ilo.json new file mode 100644 index 00000000..11ce2be8 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ilo.json @@ -0,0 +1,89 @@ +{ + "@metadata": { + "authors": [ + "Lam-ang" + ] + }, + "timedmedia-desc": "Panagtengngel para iti audio, video ken naorasan a testo, nga adda ti porma a suporta para iti WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 a mangeg a papeles, $2", + "timedmedia-ogg-short-video": "Ogg $1 a video a papeles, $2", + "timedmedia-ogg-short-general": "Ogg $1 a midia a papeles, $2", + "timedmedia-ogg-long-audio": "Ogg $1 a mangeg a papeles, kaatiddog $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 a video a papeles, kaatiddog $2, $4 Ć $5 a piksel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg multiplexed nga audio/video a papeles, $1, kaatiddog $2, $4 Ć $5 a piksel, $3 amin-amin", + "timedmedia-ogg-long-general": "Ogg midia a papeles, kaatiddog $2, $3", + "timedmedia-ogg-long-error": "Imbalido nga Ogg a papeles: $1", + "timedmedia-webm-short-video": "WebM $1 a video a papeles, $2", + "timedmedia-webm-long-video": "WebM nga audio/video a papeles, $1, kaatiddog $2, $4 Ć $5 a piksel, $3 amin-amin", + "timedmedia-flac-short-audio": "Mangeg a papeles ti FLAC, $1", + "timedmedia-flac-long-audio": "Mangeg a papeles ti FLAC, kaatiddog $1, $2 ti amin a dagup", + "timedmedia-wav-short-audio": "Mangeg a papeles ti WAV, $1", + "timedmedia-wav-long-audio": "Mangeg a papeles ti WAV, kaatiddog $1, $2 ti amin a dagup", + "timedmedia-wav-pcm-required": "Mabalinmo laeng ti agikarga ti PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "MP4 $1 a video apapeles, $2", + "timedmedia-mp4-long-video": "MP4 nga audio/video a papeles, $1, kaatiddog $2, $4 Ć $5 a piksel, $3 amin-amin", + "timedmedia-no-player-js": "Pasensia, ti pagbasabasam ket mabalin a nabaldado ti JavaScript wenno awan ti nasuportaran a mangay-ayam.<br />\nMabalinmo ti <a href=\"$1\">agikarga ti sigpit</a> wenno <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">agikarga ti maysa a magay-ayam</a> tapno maay-ayam ti sigpit iti pagbasabasam.", + "timedmedia-more": "Adu pay...", + "timedmedia-dismiss": "Irikep", + "timedmedia-download": "Ikarga ti papeles", + "timedmedia-play-media": "Ay-ayamen ti midia", + "timedmedia-desc-link": "Maipanggep ti daytoy a papeles", + "timedmedia-oggThumb-version": "Ti OggHandler ket masapulna ti oggThumb a bersion ti $1 wenno ti naududi.", + "timedmedia-oggThumb-failed": "Napaay ti oggThumb nga agaramid ti imahen.", + "timedmedia-status-header": "Kasasaad ti transkodigo", + "timedmedia-update-status": "Pabaruen ti kasasaad ti transkodigo", + "timedmedia-status": "Kasasaad", + "timedmedia-status-unknown": "Di ammo a kasasaad", + "timedmedia-transcodeinfo": "Deribatibo a deskripsion ti transkodigo", + "timedmedia-actions": "Dagiti aramid", + "timedmedia-direct-link": "Ikarga ti deribatibo", + "timedmedia-not-ready": "Saan pay a sisasagana", + "timedmedia-completed-on": "Nakompleto ti transkodigo $1", + "timedmedia-error-on": "Biddut iti transkodigo iti $1", + "timedmedia-started-transcode": "Ti transkodigo ket nairugi di $1. $2", + "timedmedia-percent-done": "Agarup a $1% ti nalapasen", + "timedmedia-in-job-queue": "Nagnayon idiay Pagurayan ti maaramid idi $1", + "timedmedia-unknown-target-size": "Di ammo a kadakkel ti puntaan, $1 ti nakodigo", + "timedmedia-days": "{{PLURAL:$1|1 nga aldaw|$1 nga al-aldaw}}", + "timedmedia-hours": "{{PLURAL:$1|1 nga oras|$1 nga or-oras}}", + "timedmedia-minutes": "{{PLURAL:$1|1 a minuto|$1 a minutos}}", + "timedmedia-seconds": "{{PLURAL:$1|1 a segundo|$1 a seg-segundo}}", + "timedmedia-reset": "Iyasentar manen ti transkodigo", + "timedmedia-reset-confirm": "Ti papangyasentar ti daytoy a transkodigo ket mangikkat ti aniaman nga adda a papeles (no adda), ket manginayonto manen ti transkodigo iti pagurayan ti maaramid. <br /><br />\nSeguradoka kadi a kayatmo ti tumuloy?", + "timedmedia-reset-error": "Biddut ti panangiyasentar manen ti transkodigo a maaramid.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 taudan", + "timedmedia-source-file-desc": "Kasisigud a $1 a papeles, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Kasisigud a $1 a papeles ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ababa ti bandwidth a video ti Ogg (160P)", + "timedmedia-derivative-desc-360p.ogv": "Maiwaragawag ti web a video ti Ogg (360P)", + "timedmedia-derivative-desc-480p.ogv": "Maiwaragawag ti web a video ti Ogg (480P)", + "timedmedia-derivative-desc-720p.ogv": "Maikarga a nangato ti kalidadna a video ti Ogg (720P)", + "timedmedia-derivative-desc-160p.webm": "Maiwaragawag ti web a WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "Maiwaragawag ti web a WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "Maiwaragawag ti web a WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "Maikarga a nangato ti kalidadna a WebM (720)", + "timedmedia-derivative-desc-320p.mp4": "Mannakigayyem a ramit ti MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Maiwaragawag ti web a Mp4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD ti kalidadna a MP4 (720P)", + "timedmedia-subtitle-new": "Agpartuat ti baro a panagipatarus wenno urnosen ti adda", + "timedmedia-subtitle-new-desc": "Agpili ti pagsasao ken pinduten ti '''{{int:Timedmedia-subtitle-new-go}}''' a buton", + "timedmedia-subtitle-new-go": "Inkan", + "timedmedia-subtitle-language": "Dagiti $1 ($2) a subtitulo", + "timedmedia-subtitle-no-video": "Awan ti video a mainanig iti agdama a subtitulo ti panid", + "timedmedia-subtitle-no-subtitles": "Awan dagiti agdama asubtitulo iti $1 para iti daytoy a video, mabalinmo ti [{{fullurl:{{FULLPAGENAME}}|action=edit}} agurnods ti daytoy a panid] tapno makanayonka kaniada", + "timedmedia-subtitle-remote": "Ti naorasan a testo para iti daytoy a papeles ket nanisangaili idiay $1", + "timedmedia-subtitle-remote-link": "Mabalinmo a [$1 kitaen ti deskripsion ti panid] para iti daytoy a papeles idiay $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 a video|dagiti $1 a video}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 nga Ogg a video|dagiti $1 nga Ogg a video}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 a WebM a video|dagiti $1 a WebM a video}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 a transkodigo|dagiti $1 a transkodigo}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 nga agtartaray a transkodigo|dagiti $1 nga agtartaray a transkodigo}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 a naiyur-uray a transkodigo|dagiti $1 a naiyur-uray a transkodigo}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 a napaay a transkodigo|dagiti $1 a napaay a transkodigo}}", + "timedmedia-file": "Papeles", + "right-transcode-reset": "Iyasentar manen ti napaay wenno dagiti naitranskodigo a video tapno maisengngatda manen ti pagurayan ti maaramid", + "right-transcode-status": "Kitaen ti [[Special:TimedMediaHandler|pakaammo a maipanggep ti agdama a tignay ti transkodigo]]", + "action-transcode-status": "kitaen ti agdama a kasasaad ti transkodigo" +} diff --git a/extensions/TimedMediaHandler/i18n/io.json b/extensions/TimedMediaHandler/i18n/io.json new file mode 100644 index 00000000..8977382c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/io.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Malafaya" + ] + }, + "timedmedia-ogg-long-error": "Ne-valida Ogg-arkivo: $1", + "timedmedia-more": "Plusā¦", + "timedmedia-dismiss": "Klozar", + "timedmedia-desc-link": "Pri ca arkivo" +} diff --git a/extensions/TimedMediaHandler/i18n/is.json b/extensions/TimedMediaHandler/i18n/is.json new file mode 100644 index 00000000..3188925c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/is.json @@ -0,0 +1,60 @@ +{ + "@metadata": { + "authors": [ + "S.Ćrvarr.S", + "SnƦvar", + "Spacebirdy" + ] + }, + "timedmedia-desc": "Rekill fyrir hljĆ³Ć°, myndbƶnd og texta myndbanda meĆ° stuĆ°ningi viĆ° skrĆ”arsniĆ°in WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 hljĆ³Ć°skrĆ”, $2", + "timedmedia-ogg-short-video": "Ogg $1 myndbandskrĆ”, $2", + "timedmedia-ogg-short-general": "Ogg $1 margmiĆ°lunarskrĆ”, $2", + "timedmedia-ogg-long-audio": "Ogg $1 hljĆ³Ć°skrĆ”, lengd $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 myndbandskrĆ”, lengd $2, $4Ć$5 dĆlar, $3", + "timedmedia-ogg-long-multiplexed": "Ogg myndbandaskrĆ”, $1, lengd $2, $4 Ć $5 dĆlar, $3 samanlagt", + "timedmedia-ogg-long-general": "Ogg margmiĆ°lunarskrĆ”, lengd $2, $3", + "timedmedia-ogg-long-error": "Ćgild Ogg skrĆ”: $1", + "timedmedia-webm-short-video": "WebM $1 myndbandskrĆ”, $2", + "timedmedia-webm-long-video": "WebM myndbandaskrĆ”, $1, lengd $2, $4 Ć $5 dĆlar, $3 samanlagt", + "timedmedia-mp4-short-video": "MP4 $1 myndbandaskrĆ”, $2", + "timedmedia-mp4-long-video": "MP4 myndbandaskrĆ”, $1, lengd $2, $4 Ć $5 dĆlar, $3 samanlagt", + "timedmedia-no-player-js": "ĆvĆ miĆ°ur hefur vafrinn Ć¾inn annaĆ°hvort Ć³virkan JavaScript eĆ°a engan studdann spilara.<br />\nĆĆŗ getur <a href=\"$1\">hlaĆ°iĆ° niĆ°ur skrĆ”nni</a> eĆ°a <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">hlaĆ°iĆ° niĆ°ur spilara</a> til Ć¾ess aĆ° spila skrĆ”nna Ć vafranum.", + "timedmedia-more": "Meira...", + "timedmedia-dismiss": "Loka", + "timedmedia-download": "SƦkja skrĆ”", + "timedmedia-play-media": "Spila margmiĆ°lunarskrĆ”", + "timedmedia-desc-link": "Um Ć¾essa skrĆ”", + "timedmedia-oggThumb-version": "OggHandler Ć¾arfnast oggThumb ĆŗtgĆ”fu $1 eĆ°a nĆ½rri.", + "timedmedia-oggThumb-failed": "oggThumb mistĆ³kst aĆ° bĆŗa til smĆ”mynd.", + "timedmedia-status": "StaĆ°a", + "timedmedia-actions": "AĆ°gerĆ°ir", + "timedmedia-direct-link": "SƦkja eftirgerĆ°", + "timedmedia-not-ready": "Ekki tilbĆŗin", + "timedmedia-percent-done": "Um $1% lokiĆ°", + "timedmedia-unknown-target-size": "ĆĆ¾ekkt markstƦrĆ°, $1 kĆ³Ć°aĆ°", + "timedmedia-days": "$1 {{PLURAL:$1|dagur|dagar}}", + "timedmedia-hours": "$1 {{PLURAL:$1|klukkutĆmi|klukkutĆmar}}", + "timedmedia-minutes": "$1 {{PLURAL:$1|mĆnĆŗta|mĆnĆŗtur}}", + "timedmedia-seconds": "$1 {{PLURAL:$1|sekĆŗnda|sekĆŗndur}}", + "timedmedia-source-file": "$1 uppruni", + "timedmedia-source-file-desc": "Upphafleg $1 skrĆ”, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Upphafleg $1 skrĆ” ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg myndband fyrir litla bandbreidd (160P)", + "timedmedia-derivative-desc-360p.ogv": "Ogg myndbands streymi (360P)", + "timedmedia-derivative-desc-480p.ogv": "Ogg myndbands streymi (480P)", + "timedmedia-derivative-desc-720p.ogv": "HĆ”gƦưa niĆ°urhalanlegt Ogg myndband (720P)", + "timedmedia-derivative-desc-160p.webm": "WebM myndbands streymi (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM myndbands streymi (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM myndbands streymi (480P)", + "timedmedia-derivative-desc-720p.webm": "HĆ”gƦưa niĆ°urhalanlegt WebM myndband (720P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 myndbands streymi (480P)", + "timedmedia-derivative-desc-720p.mp4": "HĆ”skerpu MP4 (720P)", + "timedmedia-subtitle-new-desc": "Veldu tungumĆ”liĆ° og smelltu Ć” '''{{int:Timedmedia-subtitle-new-go}}''' takkann", + "timedmedia-subtitle-new-go": "Ćfram", + "timedmedia-subtitle-no-video": "Ekkert myndband tengist Ć¾essum myndbanda texta", + "timedmedia-videos": "{{PLURAL:$1|$1 myndband|$1 myndbƶnd}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg myndband|$1 Ogg myndbƶnd}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM myndband|$1 WebM myndbƶnd}}", + "timedmedia-file": "SkrĆ”" +} diff --git a/extensions/TimedMediaHandler/i18n/it.json b/extensions/TimedMediaHandler/i18n/it.json new file mode 100644 index 00000000..fe37c8b2 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/it.json @@ -0,0 +1,108 @@ +{ + "@metadata": { + "authors": [ + ".anaconda", + "Beta16", + "BrokenArrow", + "Darth Kule", + "F. Cosoleto", + "Gianfranco", + "Raoli", + "Peg60" + ] + }, + "timedmedia-desc": "Gestore per i file audio, video e con i sottotitoli; formati supportati: WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "File audio Ogg $1, $2", + "timedmedia-ogg-short-video": "File video Ogg $1, $2", + "timedmedia-ogg-short-general": "File multimediale Ogg $1, $2", + "timedmedia-ogg-long-audio": "File audio Ogg $1, durata $2, $3", + "timedmedia-ogg-long-video": "File video Ogg $1, durata $2, dimensioni $4Ć$5 pixel, $3", + "timedmedia-ogg-long-multiplexed": "File audio/video multiplexed Ogg $1, durata $2, dimensioni $4Ć$5 pixel, complessivamente $3", + "timedmedia-ogg-long-general": "File multimediale Ogg, durata $2, $3", + "timedmedia-ogg-long-error": "File ogg non valido: $1", + "timedmedia-ogg-long-no-streams": "File multimediale Ogg. Attenzione: non ĆØ stato riconosciuto alcuno dei codec usati in questo file.", + "timedmedia-webm-short-video": "File video WebM $1, $2", + "timedmedia-webm-long-video": "File audio/video WebM $1, durata $2, dimensioni $4Ć$5 pixel, complessivamente $3", + "timedmedia-flac-short-audio": "File audio FLAC, $1", + "timedmedia-flac-long-audio": "File audio FLAC, durata $1, complessivamente $2", + "timedmedia-wav-short-audio": "File audio WAV, $1", + "timedmedia-wav-long-audio": "File audio WAV, durata $1, complessivamente $2", + "timedmedia-wav-pcm-required": "Puoi caricare solo PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "File video MP4 $1, $2", + "timedmedia-mp4-long-video": "File audio/video MP4 $1, durata $2, dimensioni $4Ć$5 pixel, complessivamente $3", + "timedmedia-no-player-js": "Si sta utilizzando un browser che ha JavaScript disattivato oppure non ha alcun riproduttore supportato.<br />\nĆ possibile <a href=\"$1\">scaricare il clip multimediale</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">un riproduttore</a> per riprodurre il clip nel proprio browser.", + "timedmedia-more": "Altro...", + "timedmedia-dismiss": "Chiudi", + "timedmedia-download": "Scarica il file", + "timedmedia-play-media": "Riproduci file multimediale", + "timedmedia-desc-link": "Informazioni su questo file", + "timedmedia-oggThumb-version": "OggHandler richiede la versione $1 o superiore di oggThumb.", + "timedmedia-oggThumb-failed": "oggThumb non ĆØ riuscito a creare la miniatura.", + "timedmedia-status-header": "Stato transcodifica", + "timedmedia-update-status": "Aggiorna stato transcodifica", + "timedmedia-status": "Stato", + "timedmedia-status-unknown": "Stato sconosciuto", + "timedmedia-transcodeinfo": "Formato", + "timedmedia-actions": "Azioni", + "timedmedia-direct-link": "Scarica", + "timedmedia-not-ready": "Non pronto", + "timedmedia-completed-on": "Completato $1", + "timedmedia-error-on": "Errore il $1", + "timedmedia-started-transcode": "Iniziato $1 fa. $2", + "timedmedia-percent-done": "$1% circa completato", + "timedmedia-in-job-queue": "Aggiunto alla coda di lavoro $1 fa", + "timedmedia-unknown-target-size": "Dimensioni di destinazione sconosciuta, $1 codificato", + "timedmedia-days": "{{PLURAL:$1|1 giorno|$1 giorni}}", + "timedmedia-hours": "{{PLURAL:$1|1 ora|$1 ore}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuto|$1 minuti}}", + "timedmedia-seconds": "{{PLURAL:$1|1 secondo|$1 secondi}}", + "timedmedia-reset": "Resetta transcodifica", + "timedmedia-reset-confirm": "Resettando questa transcodifica tutti i file esistenti (se presenti) saranno cancellati e la transcodifica sarĆ nuovamente aggiunta alla coda di lavoro. Ci vorrĆ qualche tempo per rieseguire la transcodifica. <br /><br />\nContinuare?", + "timedmedia-reset-error": "Errore nel resettaggio della transcodifica.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Fonte $1", + "timedmedia-source-file-desc": "File originale $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "File originale $1 ($2)", + "timedmedia-derivative-desc-160p.ogv": "Video Ogg a bassa larghezza di banda (160P)", + "timedmedia-derivative-desc-360p.ogv": "Video Ogg trasmettibile in streaming via Web (360P)", + "timedmedia-derivative-desc-480p.ogv": "Video Ogg trasmettibile in streaming via Web (480P)", + "timedmedia-derivative-desc-720p.ogv": "Video Ogg scaricabile in alta qualitĆ (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Video Ogg scaricabile in Full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "WebM trasmettibile in streaming via Web (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM trasmettibile in streaming via Web (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM trasmettibile in streaming via Web (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM scaricabile in alta qualitĆ (720P)", + "timedmedia-derivative-desc-1080p.webm": "WebM scaricabile in Full HD (1080P)", + "timedmedia-derivative-desc-320p.mp4": "MP4 per dispositivi compatibili (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 trasmettibile in streaming via Web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 in qualitĆ HD (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4 di qualitĆ Full HD (1080P)", + "timedmedia-subtitle-new": "Creare una nuova traduzione o modificare esistenti", + "timedmedia-subtitle-new-desc": "Seleziona la lingua e premi il pulsante '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Vai", + "timedmedia-subtitle-language": "$1 ($2) sottotitoli", + "timedmedia-subtitle-no-video": "Non non c'ĆØ nessun video associato all'attuale pagina dei sottotitoli", + "timedmedia-subtitle-no-subtitles": "Non ci sono al momento sottotitoli in $1 per questo video, ĆØ possibile [{{fullurl:{{FULLPAGENAME}}|action=edit}} modificare questa pagina] per aggiungerli", + "timedmedia-subtitle-remote": "I sottotitoli per questo file sono ospitati su $1", + "timedmedia-subtitle-remote-link": "Puoi vedere la [$1 pagina di descrizione] per questo file su $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 video}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 video Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 video WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodifica|$1 transcodifiche}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodifica|$1 transcodifiche}} in esecuzione", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodifica|$1 transcodifiche}} in coda", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transcodifica fallita|$1 transcodifiche fallite}}", + "timedmedia-file": "File", + "timedmedia-audios": "{{PLURAL:$1|$1 file audio}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 file audio Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 file audio FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 file audio WAV}}", + "right-transcode-reset": "Reimposta i video difettosi o transcodificati cosƬ che possano essere inclusi nuovamente in coda di lavoro.", + "right-transcode-status": "Visualizza [[Special:TimedMediaHandler|informazioni sull'attuale attivitĆ di transcodifica]]", + "action-transcode-status": "visualizzare l'attuale stato della transcodifica", + "orphanedtimedtext": "Pagine sottotitoli orfane", + "orphanedtimedtext-summary": "Elenco di pagine [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] che non hanno un file corrispondente.", + "orphanedtimedtext-unsupported": "Questa pagina speciale ĆØ supportata solo su database MySQL.", + "orphanedtimedtext-notimedtext": "TimedText non ĆØ abilitato su questo wiki." +} diff --git a/extensions/TimedMediaHandler/i18n/ja.json b/extensions/TimedMediaHandler/i18n/ja.json new file mode 100644 index 00000000..291a5224 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ja.json @@ -0,0 +1,91 @@ +{ + "@metadata": { + "authors": [ + "Aotake", + "Fryed-peach", + "JtFuruhata", + "Kahusi", + "Shirayuki", + "éåå®ę", + "Otokoume" + ] + }, + "timedmedia-desc": "WebMćOgg TheoraćVorbisćsrt å½¢å¼ć«åƾåæćććåē»ćé³å£°ćåå¹ć®ćć³ćć©ć¼", + "timedmedia-ogg-short-audio": "Ogg $1 é³å£°ćć”ć¤ć«ć$2", + "timedmedia-ogg-short-video": "Ogg $1 åē»ćć”ć¤ć«ć$2", + "timedmedia-ogg-short-general": "Ogg $1 ć”ćć£ć¢ćć”ć¤ć«ć$2", + "timedmedia-ogg-long-audio": "Ogg $1 é³å£°ćć”ć¤ć«ćé·ć $2ć$3", + "timedmedia-ogg-long-video": "Ogg $1 åē»ćć”ć¤ć«ćé·ć $2ć$4 Ć $5 ććÆć»ć«ć$3", + "timedmedia-ogg-long-multiplexed": "Ogg å¤éé³å£°/åē»ćć”ć¤ć«ć$1ćé·ć $2ć$4 Ć $5 ććÆć»ć«ćå
Øä½ć§ $3", + "timedmedia-ogg-long-general": "Ogg ć”ćć£ć¢ćć”ć¤ć«ćé·ć $2ć$3", + "timedmedia-ogg-long-error": "ē”å¹ćŖ Ogg ćć”ć¤ć«: $1", + "timedmedia-ogg-long-no-streams": "Ogg ć”ćć£ć¢ ćć”ć¤ć«ćč¦å: ćć®ćć”ć¤ć«ć§ä½æēØććć¦ććć©ć®ć³ć¼ćććÆćčŖčć§ćć¾ććć§ććć", + "timedmedia-webm-short-video": "WebM $1 åē»ćć”ć¤ć«ć$2", + "timedmedia-webm-long-video": "WebM é³å£°/åē»ćć”ć¤ć«ć$1ćé·ć $2ć$4 Ć $5 ććÆć»ć«ćå
Øä½ć§ $3", + "timedmedia-flac-short-audio": "FLAC é³å£°ćć”ć¤ć«ć$1", + "timedmedia-flac-long-audio": "FLAC é³å£°ćć”ć¤ć«ćé·ć $1ćå
Øä½ć§ $2", + "timedmedia-wav-short-audio": "WAV é³å£°ćć”ć¤ć«ć$1", + "timedmedia-wav-long-audio": "WAV é³å£°ćć”ć¤ć«ćé·ć $1ćå
Øä½ć§ $2", + "timedmedia-wav-pcm-required": "ć¢ćććć¼ćć§ććć®ćÆ PCM (ćć«ć¹ē¬¦å·å¤čŖæ) WAV ć®ćæć§ćć", + "timedmedia-mp4-short-video": "MP4 $1 åē»ćć”ć¤ć«ć$2", + "timedmedia-mp4-long-video": "MP4 é³å£°/åē»ćć”ć¤ć«ć$1ćé·ć $2ć$4 Ć $5 ććÆć»ć«ćå
Øä½ć§ $3", + "timedmedia-no-player-js": "ē³ćčسććć¾ććććććŖćć®ćć©ć¦ć¶ć¼ć§ćÆJavaScriptćē”å¹ć«ćŖć£ć¦ććććåƾåæćć¦ćććć¬ć¼ć¤ć¼ćććć¾ććć<br />\nåēććć«ćÆć<a href=\"$1\">ćÆćŖććććć¦ć³ćć¼ć</a>ćććć<a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ćć¬ć¼ć¤ć¼ććć¦ć³ćć¼ć</a>ććåæ
č¦ćććć¾ćć", + "timedmedia-more": "ćć®ä»ā¦", + "timedmedia-dismiss": "éćć", + "timedmedia-download": "ćć”ć¤ć«ććć¦ć³ćć¼ććć", + "timedmedia-play-media": "ć”ćć£ć¢ćåēćć", + "timedmedia-desc-link": "ćć”ć¤ć«ć®č©³ē“°", + "timedmedia-oggThumb-version": "OggHandler ć«ćÆ oggThumb ćć¼ćøć§ć³ $1 ć¾ććÆćć仄éćåæ
č¦ć§ćć", + "timedmedia-oggThumb-failed": "oggThumb ć«ćććµć ćć¤ć«ä½ęć«å¤±ęćć¾ććć", + "timedmedia-status": "ē¶ę
", + "timedmedia-status-unknown": "äøęćŖē¶ę
", + "timedmedia-transcodebitrate": "ćććć¬ć¼ć", + "timedmedia-transcodeduration": "ćØć³ć³ć¼ćęé", + "timedmedia-transcodeinfo": "å½¢å¼", + "timedmedia-actions": "ęä½", + "timedmedia-direct-link": "ćć¦ć³ćć¼ć", + "timedmedia-not-ready": "ęŗåćć§ćć¦ćć¾ćć", + "timedmedia-error-on": "$1 ć§ć®ćØć©ć¼", + "timedmedia-percent-done": "ē“ $1% å®äŗ", + "timedmedia-in-job-queue": "$1åć«ćøć§ć ćć„ć¼ć«čæ½å ććć¾ćć", + "timedmedia-days": "{{PLURAL:$1|$1 ę„}}", + "timedmedia-hours": "{{PLURAL:$1|$1 ęé}}", + "timedmedia-minutes": "{{PLURAL:$1|$1 å}}", + "timedmedia-seconds": "{{PLURAL:$1|$1 ē§}}", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 ć½ć¼ć¹", + "timedmedia-source-file-desc": "ćŖćŖćøćć« $1 ćć”ć¤ć«ć$2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ćŖćŖćøćć« $1 ćć”ć¤ć« ($2)", + "timedmedia-derivative-desc-160p.ogv": "ä½åøÆå Ogg åē» (160P)", + "timedmedia-derivative-desc-360p.ogv": "ć¦ć§ć ć¹ććŖć¼ćć³ć°åÆč½ Ogg åē» (360P)", + "timedmedia-derivative-desc-480p.ogv": "ć¦ć§ć ć¹ććŖć¼ćć³ć°åÆč½ Ogg åē» (480P)", + "timedmedia-derivative-desc-720p.ogv": "é«åč³Ŗćć¦ć³ćć¼ćåÆč½ Ogg åē» (720P)", + "timedmedia-derivative-desc-1080p.ogv": "ćć« HD ćć¦ć³ćć¼ćåÆč½ Ogg åē» (1080P)", + "timedmedia-derivative-desc-160p.webm": "ć¦ć§ć ć¹ććŖć¼ćć³ć°åÆč½ WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "ć¦ć§ć ć¹ććŖć¼ćć³ć°åÆč½ WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "ć¦ć§ć ć¹ććŖć¼ćć³ć°åÆč½ WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "é«åč³Ŗćć¦ć³ćć¼ćåÆč½ WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "ćć« HD ćć¦ć³ćć¼ćåÆč½ WebM (1080P)", + "timedmedia-derivative-desc-320p.mp4": "ććć¤ć¹ćć¬ć³ććŖć¼ MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "ć¦ć§ć ć¹ććŖć¼ćć³ć°åÆč½ MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD åč³Ŗ MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "ćć« HD åč³Ŗ MP4 (1080P)", + "timedmedia-subtitle-new": "ēæ»čسć®ę°č¦ä½ęćć¾ććÆę¢åć®ēæ»čسć®ē·Øé", + "timedmedia-subtitle-new-desc": "čØčŖćéøęćć¦ć'''{{int:Timedmedia-subtitle-new-go}}'''ććæć³ćę¼ćć¦ćć ććć", + "timedmedia-subtitle-new-go": "å®č”", + "timedmedia-subtitle-language": "$1 ($2) åå¹", + "timedmedia-subtitle-no-video": "ē¾åØć®åå¹ćć¼ćøć«é¢é£ä»ććććåē»ćÆććć¾ććć", + "timedmedia-subtitle-no-subtitles": "ē¾åØććć®åē»ć«ćÆ$1ć®åå¹ćÆććć¾ćććć[{{fullurl:{{FULLPAGENAME}}|action=edit}} ćć®ćć¼ćøćē·Øé]ćć¦čæ½å ć§ćć¾ćć", + "timedmedia-subtitle-remote": "ćć®ćć”ć¤ć«ć®åå¹ćÆ$1ć§ćć¹ćććć¦ćć¾ć", + "timedmedia-subtitle-remote-link": "$2 ć§ćć®ćć”ć¤ć«ć®[$1 č§£čŖ¬ćć¼ćøćé²č¦§]ć§ćć¾ć", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 件ć®åē»}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 ä»¶ć® Ogg åē»}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 ä»¶ć® WebM åē»}}", + "timedmedia-file": "ćć”ć¤ć«", + "timedmedia-audios": "{{PLURAL:$1|$1 件ć®é³å£°ćć”ć¤ć«}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 ä»¶ć® Ogg é³å£°ćć”ć¤ć«}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 ä»¶ć® FLAC é³å£°ćć”ć¤ć«}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 ä»¶ć® WAV é³å£°ćć”ć¤ć«}}", + "apihelp-transcodereset-param-title": "ć”ćć£ć¢ćć”ć¤ć«ć®ćæć¤ćć«ć" +} diff --git a/extensions/TimedMediaHandler/i18n/jut.json b/extensions/TimedMediaHandler/i18n/jut.json new file mode 100644 index 00000000..c8c30c29 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/jut.json @@ -0,0 +1,21 @@ +{ + "@metadata": { + "authors": [ + "HuslĆ„ke", + "Jyllanj" + ] + }, + "timedmedia-desc": "HĆ„ndlƦr fĆør Ogg Theora og Vorbis filer, ve JavaScript spƦler", + "timedmedia-ogg-short-audio": "Ogg $1 lydfile, $2", + "timedmedia-ogg-short-video": "Ogg $1 videofil, $2", + "timedmedia-ogg-short-general": "Ogg $1 mediafil, $2", + "timedmedia-ogg-long-audio": "Ogg $1 lydfil, lƦngd $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videofil, lƦngd $2, $4Ć$5 pixel, $3", + "timedmedia-ogg-long-multiplexed": "Sammelsatt Ogg-lyd- Ć„ -videofil, $1, lƦngd $2, $4Ć$5 pixel, $3 sammeltj", + "timedmedia-ogg-long-general": "Ogg mediafil, lƦngd $2, $3", + "timedmedia-ogg-long-error": "Udjylji Ogg-fil: $1", + "timedmedia-more": "Mier...", + "timedmedia-dismiss": "Lokk", + "timedmedia-download": "LƤgg fil nier", + "timedmedia-desc-link": "Om fili" +} diff --git a/extensions/TimedMediaHandler/i18n/jv.json b/extensions/TimedMediaHandler/i18n/jv.json new file mode 100644 index 00000000..0bb2c6ee --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/jv.json @@ -0,0 +1,65 @@ +{ + "@metadata": { + "authors": [ + "Meursault2004", + "NoiX180", + "Pras" + ] + }, + "timedmedia-desc": "Sing ngurusi berkas Ogg Theora lan Vorbis mawa pamain JavaScript", + "timedmedia-ogg-short-audio": "Berkas swara $1 ogg, $2", + "timedmedia-ogg-short-video": "Berkas vidĆ©o $1 ogg, $2", + "timedmedia-ogg-short-general": "Berkas mĆ©dia $1 ogg, $2", + "timedmedia-ogg-long-audio": "Berkas swara $1 ogg, dawanĆ© $2, $3", + "timedmedia-ogg-long-video": "Berkas vidĆ©o $1 ogg, dawanĆ© $2, $4Ć$5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "Berkas audio/vidĆ©o multiplexed ogg, $1, dawanĆ© $2, $4Ć$5 piksel, $3 gunggungĆ©", + "timedmedia-ogg-long-general": "Berkas mĆ©dia ogg, dawanĆ© $2, $3", + "timedmedia-ogg-long-error": "Berkas ogg ora absah: $1", + "timedmedia-more": "Luwih akĆØh...", + "timedmedia-dismiss": "Tutup", + "timedmedia-download": "Undhuh berkas", + "timedmedia-play-media": "Puter mĆ©dia", + "timedmedia-desc-link": "Prekara berkas iki", + "timedmedia-oggThumb-version": "OggHandler mbutuhakĆ© oggThumb vĆØrsi $1 utawa sakbanjurĆ©.", + "timedmedia-oggThumb-failed": "oggTumb gagal nggawĆ© gambar mini.", + "timedmedia-status-header": "Status transkodhĆ©", + "timedmedia-update-status": "Anyari status transkodhĆ©", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Status ora dingertĆØni", + "timedmedia-transcodeinfo": "Katrangan turunan transkodhĆ©", + "timedmedia-actions": "Laku", + "timedmedia-direct-link": "Undhuh turunan", + "timedmedia-not-ready": "Durung siap", + "timedmedia-completed-on": "Nglengkapi transkodhĆ© $1", + "timedmedia-error-on": "Kasalahan nĆØng transkodhĆ© $1.", + "timedmedia-started-transcode": "TranskodhĆ© lekas $1 kapungkur. $2", + "timedmedia-percent-done": "Kira-kira $1 rampung", + "timedmedia-in-job-queue": "NambahakĆ© nĆØng antrian Pakaryan $1 kapungkur", + "timedmedia-unknown-target-size": "GedhĆ© patujon oradingertĆØni, $1 kasandhĆØkakĆ©", + "timedmedia-days": "{{PLURAL:$1|dina|dina}}", + "timedmedia-hours": "{{PLURAL:$1|jam|jam}}", + "timedmedia-minutes": "{{PLURAL:$1|menit|menit}}", + "timedmedia-seconds": "{{PLURAL:$1|detik|detik}}", + "timedmedia-reset": "SetĆØl ulang transkodhĆ©", + "timedmedia-reset-error": "Kasalahan nalika nyetĆØl ulang tugas transkodhĆ©.", + "timedmedia-source-file": "Sumber $1", + "timedmedia-source-file-desc": "$1 asli, $2 Ć $3 ($4)", + "timedmedia-derivative-desc-160p.ogv": "Vidio Ogg bandwidth cilik (160P)", + "timedmedia-derivative-desc-720p.ogv": "Vidio Ogg sing bisa diundhuh mawa kualitas dhuwur (720P)", + "timedmedia-derivative-desc-720p.webm": "WebM sing bisa diundhuh mawa kualitas dhuwur (720P)", + "timedmedia-subtitle-new": "GawĆ© terjemahan anyar utawa sunting sing wis ana", + "timedmedia-subtitle-new-desc": "Ganti bagĆ©yan '''$1''' nganggo [[:en:ISO 639|kodhĆ© basa]] SampĆ©yan lan pencĆØt tombol '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Nuju", + "timedmedia-subtitle-language": "Subjudhul $1 ($2)", + "timedmedia-subtitle-no-video": "Ora ana vidio sing cocok karo kaca subjudhul saiki", + "timedmedia-subtitle-no-subtitles": "Sawetara durung ana subjudhul nĆØng $1 kanggo vidio iki, SampĆ©yan bisa [{{fullurl:{{FULLPAGENAME}}|action=edit}} nyunting kaca iki] kanggo nambahi", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 vidio|$1 vidio}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 vidio Ogg|$1 vidio Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 vidio WebM|$1 vidio WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transkodhĆ©|$1 transkodhĆ©}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transkodhĆ© lumangsung|$1 transkodhĆ© lumangsung}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transkodhĆ© ngantri|$1 transkodhĆ© ngantri}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transkodhĆ© gagal|$1 transkodhĆ© gagal}}", + "timedmedia-file": "Berkas" +} diff --git a/extensions/TimedMediaHandler/i18n/ka.json b/extensions/TimedMediaHandler/i18n/ka.json new file mode 100644 index 00000000..5c43ea7b --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ka.json @@ -0,0 +1,89 @@ +{ + "@metadata": { + "authors": [ + "BRUTE", + "David1010", + "Malafaya", + "Tokoko", + "įįįį įįįįįį" + ] + }, + "timedmedia-desc": "įį£įįįį”, įįįįįį” įį į”į£įį¢įį¢į įįįį” įįįįįį£įØįįįįįįį, įØįįįįįį į¤įį įįį¢įįįį” įį®įį įįįįį įį: WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 į®įįįįįį į¤įįįį, $2", + "timedmedia-ogg-short-video": "Ogg $1 įįįįį į¤įįįį, $2", + "timedmedia-ogg-short-general": "Ogg $1 įįįįį į¤įįįį, $2", + "timedmedia-ogg-long-audio": "Ogg $1 į®įįįįįį į¤įįįį, į”įįį į«į $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 įįįįį į¤įįįį, į”įįį į«į $2, $4 Ć $5 įįį„į”įįį, $3", + "timedmedia-ogg-long-multiplexed": "Ogg įį£įį¢įįįįį„į”į£į į įį£įįį/įįįįį į¤įįįį, $1, į”įįį į«į $2, $4 Ć $5 įįį„į”įįį, $3 į”į į£įį", + "timedmedia-ogg-long-general": "Ogg įįįįį į¤įįįį, į”įįį į«į $2, $3", + "timedmedia-ogg-long-error": "įį įį”į¬įį į Ogg-į¤įįįį: $1", + "timedmedia-webm-short-video": "WebM $1 įįįįį į¤įįįį, $2", + "timedmedia-webm-long-video": "WebM įį£įįį/įįįįį į¤įįįį, $1, į”įįį į«į $2, $4 Ć $5 įįį„į”įįį, $3 į”į į£įį", + "timedmedia-flac-short-audio": "FLAC įį£įįį į¤įįįį, $1", + "timedmedia-wav-short-audio": "WAV įį£įįį į¤įįįį, $1", + "timedmedia-mp4-short-video": "MP4 $1 įįįįį į¤įįįį, $2", + "timedmedia-mp4-long-video": "MP4 įį£įįį/įįįįį į¤įįįį, $1, į”įįį į«į $2, $4 Ć $5 įįį„į”įįį, $3 į”į į£įį", + "timedmedia-no-player-js": "į”įįį¬į£į®įį įį, įį„įįį įį įį£įįį įØį įįįįį įį£įįį JavaScript įį įį įį įį” į”įįįį į įįįįįį įįį.<br />\nįį„įįį įØįįįį«įįįį <a href=\"$1\">įįįįįį¬įį įį įįįįį</a> įį <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">įįįįįį¬įį įį įįįįįį įįį</a> įįįįįį” įį įį£įįį įØį įįį”įįį įįįį.", + "timedmedia-more": "įįį¢į...", + "timedmedia-dismiss": "įįį®į£į įį", + "timedmedia-download": "į¤įįįįį” į©įįįį¢įįį įįį", + "timedmedia-play-media": "įįįįį-į¤įįįįį” įįįįį į", + "timedmedia-desc-link": "įį į¤įįįįį” įØįį”įį®įį", + "timedmedia-oggThumb-version": "OggHandler-į” į”įįį įįįį oggThumb-įį” įįį į”įį $1 įį į£į¤į į įįįįįįįįį.", + "timedmedia-oggThumb-failed": "oggThumb-įį įįį įįįį®įį į®į įįįįįį¢įį£į įį” įØįį„įįį.", + "timedmedia-status-header": "įįįįįįį įįįį” į”į¢įį¢į£į”į", + "timedmedia-update-status": "įįįįįįį įįįį” į”į¢įį¢į£į”įį” įįįįį®įįįį", + "timedmedia-status": "į”į¢įį¢į£į”į", + "timedmedia-status-unknown": "į£įŖįįįį į”į¢įį¢į£į”į", + "timedmedia-transcodeinfo": "į¤įį įįį¢į", + "timedmedia-actions": "įįį„įįįįįį", + "timedmedia-direct-link": "įįįįįį¬įį į", + "timedmedia-not-ready": "įį įį įįįį", + "timedmedia-completed-on": "$1-įį” įįįįįįį įįį įįį”į į£įįįį£įįį", + "timedmedia-error-on": "įØįįŖįįįį įįįįįįį įįįį”įį” $1-įį.", + "timedmedia-started-transcode": "įįįįįįį įįį įįįØįįįį£įįį $1 į¬įį. $2", + "timedmedia-percent-done": "įįįį®įįįįįį $1% įØįį”į į£įįįį£įįį", + "timedmedia-in-job-queue": "įįįįį¢įįį£įįį įįįįįįįįįįį” į įįįØį $1 į¬įį", + "timedmedia-unknown-target-size": "į£įŖįįįį į”įįįįįį įįįį, $1 įįįįį įįįį”įį”", + "timedmedia-days": "{{PLURAL:$1|1 įį¦į|$1 įį¦į}}", + "timedmedia-hours": "{{PLURAL:$1|1 į”įįįį|$1 į”įįįį}}", + "timedmedia-minutes": "{{PLURAL:$1|1 į¬į£įį|$1 į¬į£įį}}", + "timedmedia-seconds": "{{PLURAL:$1|1 į¬įįį|$1 į¬įįį}}", + "timedmedia-reset": "įįįįįįį įįįį” įįįįįįį įįį§įįįįį", + "timedmedia-reset-confirm": "įįįįįįį įįįį” įįįįįįį įįį§įįįįį į¬įįØįįį” įį į”įįį£į į¤įįįį” (įį£įį įį” įį į”įįįįį”) įį įįįįįįį įįį įįįįį įįįįįį¢įįį įįįįįįįįįįį” į įįįØį. įįįįįįį įįįį įįįįįįį įįįį” įįįįį įįįį įįį įįįį£įį įį į. <br /><br />\nįįį į¬įį£įįįį£įį į®įį į, į įį įį”į£į į įįįįį į«įįįį?", + "timedmedia-reset-error": "įØįįŖįįįį įįįįįįį įįįį” įįįįįįį įįį§įįįįįį”įį”.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "į¬į§įį į $1", + "timedmedia-source-file-desc": "įį įįįįįįį $1 į¤įįįį, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "įį įįįįįįį $1 į¤įįįį ($2)", + "timedmedia-derivative-desc-160p.ogv": "įįįįįį į®įį įį”į®įį” Ogg-įįįįį (160P)", + "timedmedia-derivative-desc-360p.ogv": "įįį-įįįįįį£į į Ogg-įįįįį (360P)", + "timedmedia-derivative-desc-480p.ogv": "įįį-įįįįįį£į į Ogg-įįįįį (480P)", + "timedmedia-derivative-desc-720p.ogv": "įįį¦įįį į®įį įį”į®įį” įįįįįį¬įį įįį Ogg-įįįįį (720P)", + "timedmedia-derivative-desc-160p.webm": "įįį-įįįįįį£į į WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "įįį-įįįįįį£į į WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "įįį-įįįįįį£į į WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "įįį¦įįį į®įį įį”į®įį” įįįįįį¬įį įįį WebM (720P)", + "timedmedia-derivative-desc-320p.mp4": "įįįįįį į£įį-įįį¬į§įįįįįįį MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "įįį-įįįįįį£į į MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD į®įį įį”į®į MP4 (720P)", + "timedmedia-subtitle-new": "įØįį„įįįįį įį®įįį įįį įįįįį įį įįįį įįįį„į¢įį įį įį į”įįį£įį", + "timedmedia-subtitle-new-desc": "įįį į©įįį įįį įį įįįįįį įį į¦įįįįį” '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "įįįį", + "timedmedia-subtitle-language": "$1 ($2) į”į£įį¢įį¢į įįį", + "timedmedia-subtitle-no-video": "įį„ įį įį įį” įįįįį, į įįįįįįŖ įįįįįįØįį įįį£įįį į”į£įį¢įį¢į įįįį” įįįįįįįį į įįįį įįįį", + "timedmedia-subtitle-no-subtitles": "įįįįįįį $1 į”į£įį¢įį¢į įįį įį įįįįįį”įįįįį” įį įį įį”, įį„įįį įØįįįį«įįįį [{{fullurl:{{FULLPAGENAME}}|action=edit}} įØįįŖįįįįį įį” įįįį įį] įįį įįį”įįįį¢įįįįį", + "timedmedia-subtitle-remote": "įį į¤įįįįį” įį įįįįįį į¢įį„į”į¢į įįįįįįį”įįį£įįį $1-įį", + "timedmedia-subtitle-remote-link": "įį„įįį įØįįįį«įįįį [$1 įį®įįįį įį į¤įįįįį” įį¦į¬įį įį” įįįį įį] $2-įį", + "timedmediahandler": "įį įį£įį įįįįį įįį įįįį” įį įįį įįį", + "timedmedia-videos": "{{PLURAL:$1|$1 įįįįį|$1 įįįįį}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg įįįįį|$1 Ogg įįįįį}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM įįįįį|$1 WebM įįįįį}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 įįįįįįį įįį£įį|$1 įįįįįįį įįį£įį}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|įįįįįįįį įįįį” $1 įįįįįįį įįį|įįįįįįįį įįįį” $1 įįįįįįį įįį}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|į įįįØįį $1 įįįįįįį įįį|į įįįØįį $1 įįįįįįį įįį}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 įįįįįįį įįį į©įįįØįįį|$1 įįįįįįį įįį į©įįįØįįį}}", + "timedmedia-file": "į¤įįįį", + "right-transcode-status": "įį®įįįį [[Special:TimedMediaHandler|įįį¤įį įįįŖįį įįįįįįįį į įįįįįįį įįįį” įØįį”įį®įį]]", + "action-transcode-status": "įį®įįįį įįįįįįįį į įįįįįįį įįįį” į”į¢įį¢į£į”į" +} diff --git a/extensions/TimedMediaHandler/i18n/khw.json b/extensions/TimedMediaHandler/i18n/khw.json new file mode 100644 index 00000000..821b2a13 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/khw.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Rachitrali" + ] + }, + "timedmedia-no-player-js": "Ł
Ų¹Ų°Ų±ŲŖŲ ŲŖŪ ŲØŲ±Ų§Ų¤Ų²Ų±Ų§ Ų¬Ų§ŁŲ§Ų³Ś©Ų±Ł¾Ł¹ ŁŲ¹Ų§Ł ŁŪŚ©Ū ŪŲ§ Ś©ŪŪ Ł
Ų¹Ų§ŁŁ Ł¾ŁŪŲ¦Ų± Ų“Ų§Ł
Ł ŁŪŚ©ŪŪ<br />\nŚ¾ŪŪ Ś©ŁŁ¾Ł ŲŖŲ§Ł ŲØŲ±Ų§Ų¤Ų²Ų±Ų§ ŚŁŲ¦ŪŚ©Ł ŲØŚŪ ŲŖŁ Ś¾ŪŪ <a href=\"$1\">Ś©ŁŁ¾Ł ŚŲ§Ų¤ŁŁŁŚ</a> Ś©ŁŲ±Ū ŪŲ§ </a> or <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\">Ł¾ŁŪŲ¦Ų± ŚŲ§Ų¤ŁŁŁŚ</a> Ś©ŁŲ±ŪŪ", + "timedmedia-source-file": "$1 Ł
Ų³ŁŲÆŪ", + "timedmedia-source-audio-file-desc": "Ų§ŲµŁŪ $1 ŁŲ§Ų¦Ł($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/kk-arab.json b/extensions/TimedMediaHandler/i18n/kk-arab.json new file mode 100644 index 00000000..e348e4d2 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/kk-arab.json @@ -0,0 +1,15 @@ +{ + "@metadata": [], + "timedmedia-ogg-short-audio": "Ogg $1 ŲÆŁŲØŁŲ³ ŁŲ§ŁŁŁ, $2", + "timedmedia-ogg-short-video": "Ogg $1 ŲØŪŁŁŪ ŁŲ§ŁŁŁ, $2", + "timedmedia-ogg-short-general": "Ogg $1 ŲŖŲ§Ų³Ł¾Ų§ ŁŲ§ŁŁŁ, $2", + "timedmedia-ogg-long-audio": "Ogg $1 ŲÆŁŲØŁŲ³ ŁŲ§ŁŁŁ, ŪŲ²Ų§ŁŲŖŁŲ¹Ł $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 ŲØŪŁŁŪ ŁŲ§ŁŁŁ, ŪŲ²Ų§ŁŲŖŁŲ¹Ł $2, $4 Ć $5 Ł¾ŁŁŁŲ³ŪŁ, $3", + "timedmedia-ogg-long-multiplexed": "Ogg ŁŪŲ±Ų§Ł
ŲÆŁ ŲÆŁŲØŁŲ³/ŲØŪŁŁŪ ŁŲ§ŁŁŁ, $1, ŪŲ²Ų§ŁŲŖŁŲ¹Ł $2, $4 Ć $5 Ł¾ŁŁŁŲ³ŪŁ, $3 ŁŪ ŲØŲ§Ų±ŁŁŲ¹Ł", + "timedmedia-ogg-long-general": "Ogg ŲŖŲ§Ų³Ł¾Ų§ ŁŲ§ŁŁŁ, ŪŲ²Ų§ŁŲŖŁŲ¹Ł $2, $3", + "timedmedia-ogg-long-error": "Ų¬Ų§Ų±Ų§Ł
Ų³ŁŲ² ogg ŁŲ§ŁŁŁ: $1", + "timedmedia-more": "ŁŁŲØŁŲ±ŪŁ...", + "timedmedia-dismiss": "Ų¬Ų§ŲØŪ", + "timedmedia-download": "ŁŲ§ŁŁŲÆŁ Ų¬ŪŁŲŖŪŪ", + "timedmedia-desc-link": "ŲØŪŁ ŁŲ§ŁŁ ŲŖŪŲ±Ų§ŁŁ" +} diff --git a/extensions/TimedMediaHandler/i18n/kk-cyrl.json b/extensions/TimedMediaHandler/i18n/kk-cyrl.json new file mode 100644 index 00000000..c378cf48 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/kk-cyrl.json @@ -0,0 +1,56 @@ +{ + "@metadata": { + "authors": [ + "Arystanbek" + ] + }, + "timedmedia-ogg-short-audio": "Ogg $1 Š“ŃŠ±ŃŃ ŃŠ°Š¹Š»Ń, $2", + "timedmedia-ogg-short-video": "Ogg $1 Š±ŠµŠ¹Š½Šµ ŃŠ°Š¹Š»Ń, $2", + "timedmedia-ogg-short-general": "Ogg $1 ŃŠ°ŃŠæŠ° ŃŠ°Š¹Š»Ń, $2", + "timedmedia-ogg-long-audio": "Ogg $1 Š“ŃŠ±ŃŃ ŃŠ°Š¹Š»Ń, Ņ±Š·Š°ŅŃŃŅŃ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 Š±ŠµŠ¹Š½Šµ ŃŠ°Š¹Š»Ń, Ņ±Š·Š°ŅŃŃŅŃ $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ», $3", + "timedmedia-ogg-long-multiplexed": "Ogg ŅŅ±ŃŠ°Š¼Š“Ń Š“ŃŠ±ŃŃ/Š±ŠµŠ¹Š½Šµ ŃŠ°Š¹Š»Ń, $1, Ņ±Š·Š°ŅŃŃŅŃ $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ», $3 Š½Šµ Š±Š°ŃŠ»ŃŅŃ", + "timedmedia-ogg-long-general": "Ogg ŃŠ°ŃŠæŠ° ŃŠ°Š¹Š»Ń, Ņ±Š·Š°ŅŃŃŅŃ $2, $3", + "timedmedia-ogg-long-error": "ŠŠ°ŃŠ°Š¼ŃŃŠ· ogg ŃŠ°Š¹Š»Ń: $1", + "timedmedia-webm-short-video": "WebM $1 Š²ŠøŠ“ŠµŠ¾ ŃŠ°Š¹Š», $2", + "timedmedia-flac-short-audio": "FLAC Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š», $1", + "timedmedia-flac-long-audio": "FLAC Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š», Ņ±Š·ŃŠ½Š“ŃŅŃ $1, Š±ŠøŃŃŠµŠ¹Ń ā $2", + "timedmedia-wav-short-audio": "WAV Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š», $1", + "timedmedia-wav-long-audio": "WAV Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š», $1 Ņ±Š·ŃŠ½Š“ŃŅŃ $1, Š±ŠøŃŃŠµŠ¹Ń ā $2", + "timedmedia-mp4-short-video": "MP4 $1 Š²ŠøŠ“ŠµŠ¾ ŃŠ°Š¹Š», $2", + "timedmedia-more": "ŠÓ©Š±ŃŃŠµŠŗ...", + "timedmedia-dismiss": "ŠŠ°Š±Ń", + "timedmedia-download": "Š¤Š°Š¹Š»Š“Ń Š¶ŅÆŠŗŃŠµŃ", + "timedmedia-play-media": "ŠŠµŠ“ŠøŠ°Š½Ń ŠŗÓ©ŃŃŠµŃŃ", + "timedmedia-desc-link": "ŠŅ±Š» ŃŠ°Š¹Š» ŃŃŃŠ°Š»Ń", + "timedmedia-status": "Š”ŃŠ°ŃŃŃŃ", + "timedmedia-status-unknown": "ŠŠµŠ»Š³ŃŃŃŠ· ŃŃŠ°ŃŃŃ", + "timedmedia-actions": "ÓŃŠµŠŗŠµŃŃŠµŃ", + "timedmedia-not-ready": "ŠŠ°Š¹ŃŠ½ ŠµŠ¼ŠµŃ", + "timedmedia-days": "{{PLURAL:$1|1 ŠŗŅÆŠ½|$1 ŠŗŅÆŠ½}}", + "timedmedia-hours": "{{PLURAL:$1|Š±ŃŃ ŃŠ°ŅŠ°Ń|$1 ŃŠ°ŅŠ°Ń}}", + "timedmedia-minutes": "{{PLURAL:$1|1 Š¼ŠøŠ½ŃŃ|$1 Š¼ŠøŠ½ŃŃ}}", + "timedmedia-seconds": "{{PLURAL:$1|$ ŃŠµŠŗŃŠ½Ń|ŃŠµŠŗŃŠ½Ń}}", + "timedmedia-source-file": "$1 ŅŠ°Š¹Š½Š°Ń", + "timedmedia-derivative-desc-160p.ogv": "Š¢Ó©Š¼ŠµŠ½Š³Ń ŃŠ°ŠæŠ°Š»Ń Ogg Š²ŠøŠ“ŠµŠ¾ (160P)", + "timedmedia-derivative-desc-720p.ogv": "ŠŠ¾ŅŠ°ŃŃ ŃŠ°ŠæŠ°Š“Š°ŅŃ Š¶ŅÆŠŗŃŠµŠ»ŃŠ½ŠµŃŃŠ½ Ogg Š²ŠøŠ“ŠµŠ¾ (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Š¢Š¾Š»ŃŅ HD Š¶Ņ±ŠŗŃŠµŠ»ŃŠ½ŠµŃŃŠ½ Ogg Š²ŠøŠ“ŠµŠ¾ (1080P)", + "timedmedia-derivative-desc-720p.webm": "ŠŠ¾ŅŠ°ŃŃ ŃŠ°ŠæŠ°Š“Š°ŅŃ Š¶ŅÆŠŗŃŠµŠ»ŃŠ½ŠµŃŃŠ½ WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "Š¢Š¾Š»ŃŅ HD Š¶Ņ±ŠŗŃŠµŠ»ŃŠ½ŠµŃŃŠ½ WebM (1080P)", + "timedmedia-derivative-desc-720p.mp4": "HD ŃŠ°ŠæŠ° MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "Š¢Š¾Š»ŃŅ HD ŃŠ°ŠæŠ° MP4 (1080P)", + "timedmedia-subtitle-new": "ŠŠ°Ņ£Š° Š°ŃŠ“Š°ŃŠ¼Š° Š±Š°ŃŃŠ°Ń Š½ŠµŠ¼ŠµŃŠµ Š±Š°ŃŃŠ½ Ó©Ņ£Š“ŠµŃ", + "timedmedia-subtitle-new-desc": "Š¢ŃŠ»Š“Ń ŃŠ°Ņ£Š“Š°Ņ£ŃŠ· Š¶ÓŠ½Šµ '''{{int:Timedmedia-subtitle-new-go}}''' Š±Š°ŃŃŃŠ¼Š°ŃŃŠ½ Š±Š°ŃŃŅ£ŃŠ·", + "timedmedia-subtitle-new-go": "ÓØŃŃ", + "timedmedia-subtitle-language": "$1 ($2) ŃŃŠ±ŃŠøŃŃŠ»ŠµŃ", + "timedmedia-videos": "{{PLURAL:$1|$1 Š²ŠøŠ“ŠµŠ¾|$1 Š²ŠøŠ“ŠµŠ¾Š»Š°Ń}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg Š²ŠøŠ“ŠµŠ¾|$1 Ogg Š²ŠøŠ“ŠµŠ¾Š»Š°Ń}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM Š²ŠøŠ“ŠµŠ¾|$1 WebM Š²ŠøŠ“ŠµŠ¾Š»Š°Ń}}", + "timedmedia-file": "Š¤Š°Š¹Š»", + "timedmedia-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š»|$1 Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š»Š“Š°Ń}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š»|$1 Ogg Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š»Š“Š°Ń}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š»|$1 FLAC Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š»Š“Š°Ń}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š»|$1 WAV Š°ŃŠ“ŠøŠ¾ ŃŠ°Š¹Š»Š“Š°Ń}}", + "right-transcode-status": "[[Special:TimedMediaHandler|information about the current transcode activity]] ŠŗÓ©ŃŃ", + "apihelp-transcodereset-param-title": "ŠŠµŠ“ŠøŠ° ŃŠ°Š¹Š» ŃŠ°ŅŃŃŃŠ±Ń." +} diff --git a/extensions/TimedMediaHandler/i18n/kk-latn.json b/extensions/TimedMediaHandler/i18n/kk-latn.json new file mode 100644 index 00000000..ef140659 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/kk-latn.json @@ -0,0 +1,15 @@ +{ + "@metadata": [], + "timedmedia-ogg-short-audio": "Ogg $1 dıbıs faĆ½lı, $2", + "timedmedia-ogg-short-video": "Ogg $1 beĆ½ne faĆ½lı, $2", + "timedmedia-ogg-short-general": "Ogg $1 taspa faĆ½lı, $2", + "timedmedia-ogg-long-audio": "Ogg $1 dıbıs faĆ½lı, uzaqtıÄı $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 beĆ½ne faĆ½lı, uzaqtıÄı $2, $4 Ć $5 pĆÆksel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg quramdı dıbıs/beĆ½ne faĆ½lı, $1, uzaqtıÄı $2, $4 Ć $5 pĆÆksel, $3 ne barlıÄı", + "timedmedia-ogg-long-general": "Ogg taspa faĆ½lı, uzaqtıÄı $2, $3", + "timedmedia-ogg-long-error": "Jaramsız ogg faĆ½lı: $1", + "timedmedia-more": "Kƶbirek...", + "timedmedia-dismiss": "Jabw", + "timedmedia-download": "FaĆ½ldı jĆ¼ktew", + "timedmedia-desc-link": "Bul faĆ½l twralı" +} diff --git a/extensions/TimedMediaHandler/i18n/km.json b/extensions/TimedMediaHandler/i18n/km.json new file mode 100644 index 00000000..47cf1d5e --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/km.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Chhorran", + "Lovekhmer", + "T-Rithy", + "Thearith", + "įįøįįįįįį»į" + ] + }, + "timedmedia-desc": "įį¶įįįįį
įįįį Ogg Theora įį·į Vorbis files, įį¶įį½į į§įįįįįį¢į¶į JavaScript", + "timedmedia-ogg-short-audio": "įÆįįį¶į įįį”įį Ogg $1, $2", + "timedmedia-ogg-short-video": "įÆįįį¶įįįøįįį¢į¼ Ogg $1, $2", + "timedmedia-ogg-short-general": "įÆįįį¶įįįįį¶Ogg $1, $2", + "timedmedia-ogg-long-audio": "įÆįįį¶įįįį”įįįįįįįįOgg $1, įįįįįį$2 įį·įįįį į$3", + "timedmedia-ogg-long-video": "įÆįįį¶įįįøįįį¢į¼įįįįįįOgg $1, įįįįįį$2, $4Ć$5px, $3", + "timedmedia-ogg-long-multiplexed": "įÆįįį¶įį¢į¼įįøįįį¼/įįøįįį¢į¼į
įįįį»įįįįįįįOgg , $1, įįįįįį$2, $4Ć$5px, įįįį įį$3", + "timedmedia-ogg-long-general": "įÆįįį¶įįįįį¶įįįįįįOgg, įįįįįį$2, $3", + "timedmedia-ogg-long-error": "įÆįįį¶į ogg įį·įįį¶į įį»įįįį¶į į $1", + "timedmedia-more": "įįįįįį...", + "timedmedia-dismiss": "įį·į", + "timedmedia-download": "įį¶įįįįÆįįį¶į", + "timedmedia-desc-link": "į¢įįįøįÆįįį¶įįįį" +} diff --git a/extensions/TimedMediaHandler/i18n/kn.json b/extensions/TimedMediaHandler/i18n/kn.json new file mode 100644 index 00000000..4b39e37d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/kn.json @@ -0,0 +1,17 @@ +{ + "@metadata": { + "authors": [ + "VASANTH S.N.", + "Omshivaprakash" + ] + }, + "timedmedia-more": "ą²¹ą³ą²ą³ą²ą³...", + "timedmedia-dismiss": "ą²®ą³ą²ą³ą²ą²æ", + "timedmedia-desc-link": "ą² ą²ą²ą²¦ ą²¬ą²ą³ą²ą³", + "timedmedia-status": "ą²øą³ą²„ą²¾ą²Øą²®ą²¾ą²Ø", + "timedmedia-actions": "ą²ą³ą²°ą²æą²Æą³ą²ą²³ą³", + "timedmedia-source-file": "$1 ą²®ą³ą²²", + "timedmedia-source-audio-file-desc": "ą²
ą²øą²²ą³ $1 ą²ą²”ą²¤ ($2)", + "timedmedia-subtitle-new-go": "ą²¹ą³ą²ą³", + "timedmedia-file": "ą²ą²”ą²¤" +} diff --git a/extensions/TimedMediaHandler/i18n/ko.json b/extensions/TimedMediaHandler/i18n/ko.json new file mode 100644 index 00000000..b0d45e53 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ko.json @@ -0,0 +1,104 @@ +{ + "@metadata": { + "authors": [ + "ITurtle", + "Kwj2772", + "Priviet", + "ToePeu", + "ģė¼", + "Hym411", + "Revi", + "IRTC1015", + "Hwangjy9", + "Kurousagi" + ] + }, + "timedmedia-desc": "WebM, OGG Theora, Vorbis, srtė„¼ ģķ ķ¬ė§· ģ§ģź³¼ ģė¦¬, ėģģź³¼ ģė§ģ ģķ ķøė¤ė¬", + "timedmedia-ogg-short-audio": "Ogg $1 ģė¦¬ ķģ¼, $2", + "timedmedia-ogg-short-video": "Ogg $1 ėģģ ķģ¼, $2", + "timedmedia-ogg-short-general": "Ogg $1 ėÆøėģ“ ķģ¼, $2", + "timedmedia-ogg-long-audio": "Ogg $1 ģė¦¬ ķģ¼, źøøģ“ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 ėģģ ķģ¼, źøøģ“ $2, $4 Ć $5 ķ½ģ
, $3", + "timedmedia-ogg-long-multiplexed": "Ogg ė¤ģ¤ ģė¦¬/ėģģ ķģ¼, $1, źøøģ“ $2, $4 Ć $5 ķ½ģ
, ėėµ $3", + "timedmedia-ogg-long-general": "Ogg ėÆøėģ“ ķģ¼, źøøģ“ $2, $3", + "timedmedia-ogg-long-error": "ģėŖ»ė Ogg ķģ¼: $1", + "timedmedia-ogg-long-no-streams": "Ogg ėÆøėģ“ ķģ¼ģ
ėė¤. ź²½ź³ : ģ“ ķģ¼ģ ģ¬ģ©ė ģ½ė±ģ ģ ģ ģģµėė¤.", + "timedmedia-webm-short-video": "WebM $1 ėģģ ķģ¼, $2", + "timedmedia-webm-long-video": "WebM ģė¦¬/ėģģ ķģ¼, $1, źøøģ“ $2, $4 Ć $5ķ½ģ
, ėėµ $3", + "timedmedia-flac-short-audio": "FLAC ģė¦¬ ķģ¼, $1", + "timedmedia-flac-long-audio": "FLAC ģė¦¬ ķģ¼, źøøģ“ $1, ėėµ $2", + "timedmedia-wav-short-audio": "WAV ģė¦¬ ķģ¼, $1", + "timedmedia-wav-long-audio": "WAV ģė¦¬ ķģ¼, źøøģ“ $1, ėėµ $2", + "timedmedia-wav-pcm-required": "PCM(ķģ¤ ė¶ķø ė³ģ”°) WAVė§ ģ¬ė¦“ ģ ģģµėė¤.", + "timedmedia-mp4-short-video": "MP4 $1 ėģģ ķģ¼, $2", + "timedmedia-mp4-long-video": "MP4 ģė¦¬/ėģģ ķģ¼, $1, źøøģ“ $2, $4 Ć $5ķ½ģ
, ėėµ $3", + "timedmedia-no-player-js": "ģ£ģ”ķ©ėė¤, ģģ¤ķ
ģ ģė°ģ¤ķ¬ė¦½ķøė„¼ ģ§ģķģ§ ģź±°ė ģ§ģķė ėÆøėģ“ ķė ģ“ģ“ź° ģ¤ģ¹ėģ“ ģģ§ ģģµėė¤.<br />\n<a href=\"$1\">ėÆøėģ“ ķ“ė¦½ģ ė¤ģ“ė”ė</a>ķź±°ė, <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ėÆøėģ“ ķė ģ“ģ“ė„¼ ė¤ģ“ė”ė</a>ķ ģ ģģµėė¤.", + "timedmedia-more": "ė ė³“źø°ā¦", + "timedmedia-dismiss": "ė«źø°", + "timedmedia-download": "ķģ¼ ė¤ģ“ė”ė", + "timedmedia-play-media": "ėÆøėģ“ ģ¬ģ", + "timedmedia-desc-link": "ģ“ ķģ¼ģ ėķ ģ ė³“", + "timedmedia-oggThumb-version": "OggHandlerė oggThumb ė²ģ $1 ģ“ģģ“ ķģķ©ėė¤.", + "timedmedia-oggThumb-failed": "oggThumbź° ģ¬ė¤ģ¼ģ ė§ė¤ģ§ ėŖ»ķģµėė¤.", + "timedmedia-status-header": "ģ½ė ė³ķ ģķ", + "timedmedia-update-status": "ģ½ė ė³ķ ģķ ģ
ė°ģ“ķø", + "timedmedia-status": "ģķ", + "timedmedia-status-unknown": "ģ ģ ģė ģķ", + "timedmedia-transcodeinfo": "ķģ", + "timedmedia-actions": "ėģ", + "timedmedia-direct-link": "ė¤ģ“ė”ė", + "timedmedia-not-ready": "ģ¤ė¹ķģ§ ģģ", + "timedmedia-completed-on": "$1 ģė£", + "timedmedia-error-on": "$1ģ ģ¤ė„", + "timedmedia-started-transcode": "$1 ģ ģ ģģėģģµėė¤. $2", + "timedmedia-percent-done": "ģ½ $1% ģė£", + "timedmedia-in-job-queue": "$1 ģ ģ ģģ
ėźø°ģ“ģ ģ¶ź°ėØ", + "timedmedia-unknown-target-size": "ģ ģ ģė ėģ ķ¬źø°, $1 ģøģ½ėķØ", + "timedmedia-days": "{{PLURAL:$1|1ģ¼|$1ģ¼}}", + "timedmedia-hours": "{{PLURAL:$1|1ģź°|$1ģź°}}", + "timedmedia-minutes": "{{PLURAL:$1|1ė¶|$1ė¶}}", + "timedmedia-seconds": "{{PLURAL:$1|1ģ“|$1ģ“}}", + "timedmedia-reset": "ģ½ė ė³ķ ģ“źø°ķ", + "timedmedia-reset-confirm": "ģ½ė ė³ķģ ģ“źø°ķķė©“ źø°ģ”“ ķģ¼ģ“ (ģė ź²½ģ°) ģ ź±°ėė©°, ģģ
ėźø°ģ“ė” ģ½ė ė³ķģ ė¤ģ ģ¶ź°ķ©ėė¤. ė¤ģ ė³ķķė ė° ė¤ģ ģź°ģ“ ź±øė¦“ ź²ģ
ėė¤. <br /><br />\nź³ģķź² ģµėź¹?", + "timedmedia-reset-error": "ģ½ė ė³ķ ģģ
ģ ģ“źø°ķķė ė° ģ¤ė„ź° ė¬ģµėė¤.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 ģė³ø", + "timedmedia-source-file-desc": "ģė³ø $1 ķģ¼, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ģė³ø $1 ķģ¼ ($2)", + "timedmedia-derivative-desc-160p.ogv": "ė®ģ ėģķ Ogg ė¹ėģ¤ (160P)", + "timedmedia-derivative-desc-240p.ogv": "ģ¹ ģ¤ķøė¦¬ė° ź°ė„ Ogg ėģģ (240P)", + "timedmedia-derivative-desc-360p.ogv": "ģ¹ ģ¤ķøė¦¬ė° ź°ė„ Ogg ėģģ (360P)", + "timedmedia-derivative-desc-480p.ogv": "ģ¹ ģ¤ķøė¦¬ė° ź°ė„ Ogg ėģģ (480P)", + "timedmedia-derivative-desc-720p.ogv": "ź³ ķģ§ ė¤ģ“ė”ė ź°ė„ Ogg ėģģ (720P)", + "timedmedia-derivative-desc-160p.webm": "ģ¹ ģ¤ķøė¦¬ė° ź°ė„ WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "ģ¹ ģ¤ķøė¦¬ė° ź°ė„ WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "ģ¹ ģ¤ķøė¦¬ė° ź°ė„ WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "ź³ ķģ§ ė¤ģ“ė”ė ź°ė„ WebM (720P)", + "timedmedia-derivative-desc-320p.mp4": "ģ„ģ¹ ģ¹ķģ MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "ģ¹ ģ¤ķøė¦¬ė° ź°ė„ MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD ķģ§ MP4 (720P)", + "timedmedia-subtitle-new": "ģ ė²ģ ė§ė¤źø° ėė źø°ģ”“ ė²ģ ķøģ§", + "timedmedia-subtitle-new-desc": "ģøģ“ė„¼ ģ ķķź³ '''{{int:Timedmedia-subtitle-new-go}}''' ė²ķ¼ģ ėė„“ģøģ", + "timedmedia-subtitle-new-go": "ź°źø°", + "timedmedia-subtitle-language": "$1 ($2) ģė§", + "timedmedia-subtitle-no-video": "ķģ¬ ģė§ ķģ“ģ§ģ ź“ė Øė ėģģģ“ ģģµėė¤", + "timedmedia-subtitle-no-subtitles": "ķģ¬ ģ“ ėģģģ ėķ $1ģ ģė§ģ“ ģģµėė¤, ģ¶ź°ķė ¤ė©“ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ģ“ ė¬øģė„¼ ķøģ§ķ ] ģ ģģµėė¤.", + "timedmedia-subtitle-remote": "ģ“ ķģ¼ģ ėķ ģė§ģ $1ģ ķøģ¤ķøķģµėė¤", + "timedmedia-subtitle-remote-link": "$2ģ ģ“ ķģ¼ģ ėķ [$1 ģ¤ėŖ
ė¬øģė„¼ ė³¼] ģ ģģµėė¤", + "timedmediahandler": "ģė§ėÆøėģ“ķøė¤ė¬", + "timedmedia-videos": "{{PLURAL:$1|ėģģ $1ź°}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|Ogg ėģģ $1ź°}}", + "timedmedia-webm-videos": "{{PLURAL:$1|WebM ėģģ $1ź°}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|ģ½ė ė³ķ $1ź°}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|ģ¤ķ ģ¤ģø ģ½ė ė³ķ $1ź°}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|ėźø° ģ¤ģø ģ½ė ė³ķ $1ź°}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|ģ¤ķØķ ģ½ė ė³ķ $1ź°}}", + "timedmedia-file": "ķģ¼", + "timedmedia-audios": "{{PLURAL:$1|ģ¤ėģ¤ ķģ¼ $1ź°}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|Ogg ģ¤ėģ¤ ķģ¼ $1ź°}}", + "timedmedia-flac-audios": "{{PLURAL:$1|FLAC ģ¤ėģ¤ ķģ¼ $1ź°}}", + "timedmedia-wav-audios": "{{PLURAL:$1|WAV ģ¤ėģ¤ ķģ¼ $1ź°}}", + "right-transcode-reset": "ė³ķėź±°ė ģ¤ķØķ ė¹ėģ¤ė„¼ ģģ
ėźø°ģ“ģ ė¤ģ ģ¶ź°ėėė” ģ“źø°ķ", + "right-transcode-status": "[[Special:TimedMediaHandler|ķģ¬ ģ½ė ė³ķ ķėģ ėķ ģ ė³“]] ė³“źø°", + "action-transcode-status": "ķģ¬ ģ½ė ė³ķ ģķ ė³“źø°" +} diff --git a/extensions/TimedMediaHandler/i18n/krc.json b/extensions/TimedMediaHandler/i18n/krc.json new file mode 100644 index 00000000..e27d9595 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/krc.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Iltever" + ] + }, + "timedmedia-no-player-js": "ŠŠ¶Š°ŃŃŃŃŠ³ŃŠ°, ŃŠøŠ·Š½Šø Š±ŃŠ°ŃŠ·ŠµŃŠøŠ³ŠøŠ·Š“Šµ JavaScript Š“Š¶ŃŠŗŃŠ»Š°Š½ŃŠ±Š“Ń Š½ŠµŠ“Š° ŠŗŠµŃŠµŠŗŠ»Šø Š¾Š¹Š½Š°ŃŃŃŃŃ Š“Š¶Š¾ŠŗŃŠ“Ń.<br />\nŠ”ŠøŠ· <a href=\"$1\">ŠŗŠ»ŠøŠæŠ½Šø ŃŠ½Š“ŠøŃŠøŃŠ³Šµ</a> Š½ŠµŠ“Š° ŠŗŠ»ŠøŠæŠ½Šø Š±ŃŠ°ŃŠ·ŠµŃŠ“Šµ Š¾Š¹Š½Š°ŃŃŃ ŃŃŃŠ½ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š¾Š¹Š½Š°ŃŃŃŃŃ ŃŠ½Š“ŠøŃŠøŃŠ³Šµ</a> Š±Š¾Š»Š»ŃŠŗŃŃŃŠ·.", + "timedmedia-more": "ŠŠ½ŃŠ“Š°ā¦", + "timedmedia-source-file": "$1 ŠŗŃŠ°Š¹Š½Š°Š³ŃŃ", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š» $1-ŃŠ°Š¹Š» ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/krj.json b/extensions/TimedMediaHandler/i18n/krj.json new file mode 100644 index 00000000..32fffc84 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/krj.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Jose77" + ] + }, + "timedmedia-more": "Raku pa..." +} diff --git a/extensions/TimedMediaHandler/i18n/ksh.json b/extensions/TimedMediaHandler/i18n/ksh.json new file mode 100644 index 00000000..0dacd011 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ksh.json @@ -0,0 +1,81 @@ +{ + "@metadata": { + "authors": [ + "Purodha" + ] + }, + "timedmedia-desc": "E Projamm (<i lang=\"en\">handler</i>) fƶr Meedije met Zickaandeil\nā Viddejos, Tondatteieje, <i lang=\"en\">timedText</i> (Ongertittelle) ā\nmet Ongershtƶzung fƶr de Fommaate <i lang=\"en\">WebM</i>, <i lang=\"en\">Ogg Theora</i>, <i lang=\"en\">Vorbis</i> un <i lang=\"en\">srt</i>.", + "timedmedia-ogg-short-audio": "<i lang=\"en\">Ogg $1</i> Tondatei, $2", + "timedmedia-ogg-short-video": "<i lang=\"en\">Ogg $1</i> Viddejodatei, $2", + "timedmedia-ogg-short-general": "<i lang=\"en\">Ogg $1</i> Medijedatei, $2", + "timedmedia-ogg-long-audio": "<i lang=\"en\">Ogg $1</i> Tondatei fum Ćmfang $2, $3", + "timedmedia-ogg-long-video": "<i lang=\"en\">Ogg $1</i> Viddejodatei fum Ćmfang $2 un {{PLURAL:$4|ein Pixel|$4 Pixelle|kei Pixel}} Ć {{PLURAL:$5|ei Pixel|$4 Pixelle|kei Pixel}}, $3", + "timedmedia-ogg-long-multiplexed": "<i lang=\"en\">Ogg</i> jemultipex Ton- un Viddejodatei, $1, fum Ćmfang $2 un {{PLURAL:$4|ein Pixel|$4 Pixelle|kei Pixel}} Ć {{PLURAL:$5|ei Pixel|$4 Pixelle|kei Pixel}}, $3 ennsjesammp", + "timedmedia-ogg-long-general": "<i lang=\"en\">Ogg</i> Medijedatei fum Ćmfang $2, $3", + "timedmedia-ogg-long-error": "En kapodde <i lang=\"en\">Ogg</i>-Dattei: $1", + "timedmedia-webm-short-video": "En $1 Viddejo-Dattei em WebM-Fommaat vun $2", + "timedmedia-webm-long-video": "Ene Viddejo udder en Toondattei em WebM-Fommaat, $1, $2 jruuĆ, $4 Ć $5 Pixelle, $3 enĆjesammp", + "timedmedia-no-player-js": "Schad, Dinge Brauser hƤt entweder JavaSkrepp uĆjeschalldt udder kein zopaĆ Projramm zom Afschpelle.<br />Do kanns jƤz <a href=\"$1\">dat Stƶck eronger laade</a> udder <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">e Afspeller-Projramm eronger laade</a>, ƶm dat Schtƶk en Dingem Brauser afzeschpelle.", + "timedmedia-more": "Enshtelle ā¦", + "timedmedia-dismiss": "Zohmaache!", + "timedmedia-download": "Dattei eronger lahde", + "timedmedia-play-media": "Afshpelle", + "timedmedia-desc-link": "Ćvver di Dattei", + "timedmedia-oggThumb-version": "DƤ <code lang=\"en\">OggHandler</code> bruch <code lang=\"en\">oggThumb</code> in dƤ Version $1 udder hĆ¼Ć¼ter.", + "timedmedia-oggThumb-failed": "<code lang=\"en\">oggThumb</code> kunnt kei MiniBelldsche maache.", + "timedmedia-status": "Zohschtand", + "timedmedia-status-unknown": "Onbikannte Zohschtand", + "timedmedia-direct-link": "AfflƤhjer eronger lahde", + "timedmedia-not-ready": "Nit parraht", + "timedmedia-started-transcode": "De Ćmwandlong hƤt vƶr $1 bejonne. $2 sin jedonn.", + "timedmedia-percent-done": "ƶm de $1% jedonn", + "timedmedia-in-job-queue": "En de Waadeschlang met de Aufjahbe jedonn vƶr $1", + "timedmedia-days": "{{PLURAL:$1|einem Daach|$1 DƤƤsch|keinem Daach}}", + "timedmedia-hours": "{{PLURAL:$1|eine Schtond|$1 Schtonde|keinem Schtond}}", + "timedmedia-minutes": "{{PLURAL:$1|eine Menutt|$1 Menutte|keine Menutt}}", + "timedmedia-seconds": "{{PLURAL:$1|eine Sekund|$1 Sekunde|keine Sekund}}", + "timedmedia-ogg": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"\">Ogg</i>", + "timedmedia-webm": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"\">WebM</i>", + "timedmedia-mp4": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Moving Picture Experts Group - āExpƤƤtejropp fƶr bewƤƤschte Belderā - VƤsjohn 4\">MP4</i>", + "timedmedia-wav": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"RIFF WAVE - Resource Interchange File Format - fƶr de WƤlle vun Tƶhn\">WAV</i>", + "timedmedia-flac": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Free Lossless Audio Codec āFreije verloĆfreie Kodehrer un Dekodehrer vun Tƶhnā\">FLAC</i>", + "timedmedia-source-file": "Quell-Dattei em $1-Fommaat", + "timedmedia-source-file-desc": "Ojinahl $1-Dattei, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Ojinahl $1-Dattei ($2)", + "timedmedia-derivative-160p.ogv": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Ogg Vorbis\">Ogg</i> 160P", + "timedmedia-derivative-desc-160p.ogv": "En Viddejo-Dattei met winnesch Bandbreide (160P) em <i lang=\"en\">Ogg</i>-Fommaat", + "timedmedia-derivative-360p.ogv": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Ogg Vorbis\">Ogg</i> 360P", + "timedmedia-derivative-desc-360p.ogv": "En Viddejo-Dattei em <i lang=\"en\">Ogg</i>-Fommaat (360p) fƶr ene Dahteshtrohm ƶvver et Nez", + "timedmedia-derivative-480p.ogv": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Ogg Vorbis\">Ogg</i> 480P", + "timedmedia-derivative-desc-480p.ogv": "En Viddejo-Dattei (met 480p) em <i lang=\"en\">Ogg</i>-Fommaat fƶr ene Dahteshtrohm ƶvver et Nez", + "timedmedia-derivative-720p.ogv": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Ogg Vorbis\">Ogg</i> 720P", + "timedmedia-derivative-desc-720p.ogv": "En Viddejo-Dattei met huhe Qualiteit (met 720p) em <i lang=\"en\">Ogg</i>-Fommaat zom eronger laade", + "timedmedia-derivative-1080p.ogv": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Ogg Vorbis\">Ogg</i> 1080P", + "timedmedia-derivative-desc-1080p.ogv": "Full HD downloadable <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Ogg Vorbis\">Ogg</i> video (1080P)", + "timedmedia-derivative-160p.webm": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> 160P", + "timedmedia-derivative-desc-160p.webm": "Web streamable <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> (160P)", + "timedmedia-derivative-360p.webm": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> 360P", + "timedmedia-derivative-desc-360p.webm": "Ene WebM Viddejo (met 360p) fƶr ene Dahteshtrohm ƶvver et Nez", + "timedmedia-derivative-480p.webm": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> 480P", + "timedmedia-derivative-desc-480p.webm": "Ene WebM Viddejo (met 480p) fƶr ene Dahteshtrohm ƶvver et Nez", + "timedmedia-derivative-720p.webm": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> 720P", + "timedmedia-derivative-desc-720p.webm": "En <i lang=\"en\">WebM</i> Viddejo-Dattei met huhe Qualiteit (met 720p) zom eronger laade", + "timedmedia-derivative-1080p.webm": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> 1080P", + "timedmedia-derivative-desc-1080p.webm": "Full HD downloadable <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"WebM\">WebM</i> (1080P)", + "timedmedia-derivative-desc-320p.mp4": "Device-friendly <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Moving Picture Experts Group - āExpƤƤtejropp fƶr bewƤƤschte Belderā - VƤsjohn 4\">MP4</i> (320P)", + "timedmedia-derivative-desc-480p.mp4": "Web streamable <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Moving Picture Experts Group - āExpƤƤtejropp fƶr bewƤƤschte Belderā - VƤsjohn 4\">MP4</i> (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD quality <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Moving Picture Experts Group - āExpƤƤtejropp fƶr bewƤƤschte Belderā - VƤsjohn 4\">MP4</i> (720P)", + "timedmedia-derivative-desc-1080p.mp4": "Full HD quality <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Moving Picture Experts Group - āExpƤƤtejropp fƶr bewƤƤschte Belderā - VƤsjohn 4\">MP4</i> (1080P)", + "timedmedia-derivative-mp3": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Moving Picture Experts Group - āExpƤƤtejropp fƶr bewƤƤschte Belderā - VƤsjohn 3\">MP3</i>", + "timedmedia-derivative-desc-mp3": "<i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Moving Picture Experts Group - āExpƤƤtejropp fƶr bewƤƤschte Belderā - VƤsjohn 3\">MP3</i>", + "timedmedia-subtitle-new": "Maach en neue ĆvversƤzong udder Ƥnder ein, di et alld jitt", + "timedmedia-subtitle-new-desc": "Sƶhg en Schprohch uĆ un klegg op ā{{int:Timedmedia-subtitle-new-go}}ā", + "timedmedia-subtitle-new-go": "LohĆ Jonn!", + "timedmedia-subtitle-language": "Ongertittele en $1 ($2)", + "timedmedia-file": "Dattei", + "timedmedia-audios": "{{PLURAL:$1|Ein Tohndattei|$1 Tohndatteije|kein Tohndattei}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|Ein Tohndattei|$1 Tohndatteije|kein Tohndattei}} em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Ogg Vorbis\">Ogg</i>-Fommaht", + "timedmedia-flac-audios": "{{PLURAL:$1|Ein Tohndattei|$1 Tohndatteije|kein Tohndattei}} em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"Free Lossless Audio Codec āFreije verloĆfreie Kodehrer un Dekodehrer vun Tƶhnā\">FLAC</i>-Fommaht", + "timedmedia-wav-audios": "{{PLURAL:$1|Ein Tohndattei|$1 Tohndatteije|kein Tohndattei}} em <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"RIFF WAVE - Resource Interchange File Format - fƶr de WƤlle vun Tƶhn\">WAV</i>-Fommaht", + "apihelp-transcodereset-param-title": "De Ćvverschreff vun dƤ Mehdijedattei." +} diff --git a/extensions/TimedMediaHandler/i18n/ku-latn.json b/extensions/TimedMediaHandler/i18n/ku-latn.json new file mode 100644 index 00000000..48f4f644 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ku-latn.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "BikarhĆŖner", + "George Animal" + ] + }, + "timedmedia-more": "ZĆŖdetir...", + "timedmedia-dismiss": "Bigre", + "timedmedia-download": "DosyeyĆŖ daxe", + "timedmedia-desc-link": "Di derbarĆŖ vĆŖ dosyeyĆŖ de", + "timedmedia-source-file": "ƧavkanĆ® $1", + "timedmedia-source-audio-file-desc": "Dosyeye orijĆ®nal a $1 ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/ky.json b/extensions/TimedMediaHandler/i18n/ky.json new file mode 100644 index 00000000..79dce232 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ky.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Janatkg" + ] + }, + "timedmedia-source-file": "$1 Š±ŃŠ»Š°ŠŗŃŠ°Š½" +} diff --git a/extensions/TimedMediaHandler/i18n/la.json b/extensions/TimedMediaHandler/i18n/la.json new file mode 100644 index 00000000..ae42c49c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/la.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "SPQRobin", + "UV" + ] + }, + "timedmedia-more": "Plusā¦" +} diff --git a/extensions/TimedMediaHandler/i18n/lad.json b/extensions/TimedMediaHandler/i18n/lad.json new file mode 100644 index 00000000..082e7dcb --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/lad.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Menachem.Moreira", + "Universal Life" + ] + }, + "timedmedia-subtitle-new-go": "Ir", + "timedmedia-file": "Dosya" +} diff --git a/extensions/TimedMediaHandler/i18n/lb.json b/extensions/TimedMediaHandler/i18n/lb.json new file mode 100644 index 00000000..0a3c78c8 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/lb.json @@ -0,0 +1,73 @@ +{ + "@metadata": { + "authors": [ + "Les Meloures", + "Robby" + ] + }, + "timedmedia-desc": "Steierungsprogramm fir Audio, Video an 'timed text', mat ĆnnerstĆ«tzung vun de Formater WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg-$1-Tounfichier, $2", + "timedmedia-ogg-short-video": "Ogg-$1-Videofichier, $2", + "timedmedia-ogg-short-general": "Ogg-$1-Mediefichier, $2", + "timedmedia-ogg-long-audio": "tmh-$1-Tounfichier, Dauer: $2, $3", + "timedmedia-ogg-long-video": "Ogg-$1-Videofichier, Dauer: $2, $4Ć$5 Pixel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg-Toun-/Video-Fichier, $1, Dauer: $2, $4Ć$5 Pixel, $3", + "timedmedia-ogg-long-general": "Ogg Media-Fichier, Dauer $2, $3", + "timedmedia-ogg-long-error": "OngĆ«ltegen Ogg-Fichier: $1", + "timedmedia-webm-short-video": "WebM $1 Video Fichier, $2", + "timedmedia-webm-long-video": "WebM-Audio/Video-Fichier, $1, Dauer $2, $4Ć$5 Pixel, $3 am Ganzen", + "timedmedia-flac-short-audio": "FLAC-Audiofichier, $1", + "timedmedia-flac-long-audio": "FLAC-audiofichier, LƤngt $1, $2 am Ganzen", + "timedmedia-wav-short-audio": "WAV-Audiofichier, $1", + "timedmedia-mp4-short-video": "MP4 $1 Videofichier, $2", + "timedmedia-no-player-js": "Pardon, Ćre Browser huet entweder JavaScript ausgeschalt oder en huet kee Player-Programm deen Ć«nnerstĆ«tzt gĆ«tt.<br />\nDir kĆ«nnt <a href=\"$1\"> de Clip eroflueden</a> oder <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">e Player-Programm erofluede</a> fir de Clip an Ćrem Browser ze spillen.", + "timedmedia-more": "MĆ©i ...", + "timedmedia-dismiss": "Zoumaachen", + "timedmedia-download": "Fichier eroflueden", + "timedmedia-desc-link": "Iwwer dĆ«se Fichier", + "timedmedia-oggThumb-version": "Den OggHandler brauch d'Versioun $1 (oder mĆ©i eng nei Versioun) vun OggThumb.", + "timedmedia-oggThumb-failed": "oggThumb konnt d'Miniaturbild (thumbnail) net uleeĆ«n.", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Onbekannte Status", + "timedmedia-transcodeinfo": "Format", + "timedmedia-actions": "Aktiounen", + "timedmedia-direct-link": "Eroflueden", + "timedmedia-not-ready": "Net fƤerdeg", + "timedmedia-completed-on": "FƤerdeg den $1", + "timedmedia-error-on": "Feeler op $1", + "timedmedia-started-transcode": "Ugefaang viru(n) $1. $2", + "timedmedia-percent-done": "OngefĆ©ier $1% fƤerdeg", + "timedmedia-days": "{{PLURAL:$1|1 Dag|$1 Deeg}}", + "timedmedia-hours": "{{PLURAL:$1|1 Stonn|$1 Stonnen}}", + "timedmedia-minutes": "{{PLURAL:$1|1 Minutt|$1 Minutten}}", + "timedmedia-seconds": "{{PLURAL:$1|1 Sekonn|$1 Sekonnen}}", + "timedmedia-reset": "Transcode zrĆ©cksetzen", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Quell ($1)", + "timedmedia-source-file-desc": "Original $1 Fichier, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Original $1 Fichier ($2)", + "timedmedia-derivative-desc-240p.ogv": "Ogg-Video (240P) deen iwwer de Web gestreamt gi kann", + "timedmedia-derivative-360p.vp9.webm": "VP9 360P", + "timedmedia-derivative-480p.vp9.webm": "VP9 480P", + "timedmedia-derivative-desc-2160p.vp9.webm": "Komplette streamfƤege 4K-WebM-VP9-Video (2160P)", + "timedmedia-derivative-desc-720p.mp4": "HD-QualitĆ©it MP4 (720P)", + "timedmedia-derivative-desc-2160p.mp4": "Komplette 4K MP4-QualitĆ©itsvideo (2160P)", + "timedmedia-subtitle-new": "Nei Iwwersetzung maachen oder eng dĆ©i et gĆ«tt Ƥnneren", + "timedmedia-subtitle-new-desc": "Sicht d'Sprooch eraus an drĆ©ckt de KnƤppchen ''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Lass", + "timedmedia-subtitle-language": "$1 ($2) Ćnnertitelen", + "timedmedia-subtitle-no-video": "Et ass kee Video mat der aktueller SƤit vun Ćnnertitelen associĆ©iert.", + "timedmedia-subtitle-no-subtitles": "Et sinn elo keng Ćnnertitelen op $1 fir dĆ«se Video, Dir kĆ«nnt [{{fullurl:{{FULLPAGENAME}}|action=edit}} dĆ«s SƤit Ƥnneren] fir se derbƤizesetzen", + "timedmedia-subtitle-remote-link": "Dir kĆ«nnt [$1 d'BeschreiwungssƤit] fir dĆ«se Fichier op $2 gesinn", + "timedmedia-videos": "{{PLURAL:$1|$1 Video|$1 Videoen}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg Video|$1 Ogg Videoen}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM Video|$1 WebM Videoen}}", + "timedmedia-file": "Fichier", + "timedmedia-audios": "{{PLURAL:$1|$1 Audio-Fichier|$1 Audio-Fichieren}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg Audio-Fichier|$1 Ogg Audio-Fichieren}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC Audio-Fichier|$1 FLAC Audio-Fichieren}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV Audio-Fichier|$1 WAV Audio-Fichieren}}", + "orphanedtimedtext-unsupported": "DĆ«s SpezialsƤit funktionĆ©iert nĆ«mme mat MySQL Datebanken.", + "orphanedtimedtext-notimedtext": "TimedText ass op dĆ«ser Wiki net aktivĆ©iert.", + "apihelp-transcodereset-param-title": "Den Titel vum Mediefichier." +} diff --git a/extensions/TimedMediaHandler/i18n/lfn.json b/extensions/TimedMediaHandler/i18n/lfn.json new file mode 100644 index 00000000..23c9c268 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/lfn.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Malafaya" + ] + }, + "timedmedia-more": "Pluā¦" +} diff --git a/extensions/TimedMediaHandler/i18n/li.json b/extensions/TimedMediaHandler/i18n/li.json new file mode 100644 index 00000000..2f63a4cd --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/li.json @@ -0,0 +1,21 @@ +{ + "@metadata": { + "authors": [ + "Matthias", + "Ooswesthoesbes" + ] + }, + "timedmedia-desc": "Handelt Ogg Theora- en Vorbis-bestande aaf met 'n JavaScript-mediaspeler", + "timedmedia-ogg-short-audio": "Ogg $1 geluidsbestandj, $2", + "timedmedia-ogg-short-video": "Ogg $1 videobestandj, $2", + "timedmedia-ogg-short-general": "Ogg $1 mediabestandj, $2", + "timedmedia-ogg-long-audio": "Ogg $1 geluidsbestandj, lingdje $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videobestandj, lingdje $2, $4Ć$5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "Ogg gemultiplexeerd geluids-/videobestandj, $1, lingdje $2, $4Ć$5 pixels, $3 totaal", + "timedmedia-ogg-long-general": "Ogg mediabestandj, lingdje $2, $3", + "timedmedia-ogg-long-error": "Ćngeljig oggg-bestandj: $1", + "timedmedia-more": "MieĆ«...", + "timedmedia-dismiss": "Sloet", + "timedmedia-download": "Bestandj downloade", + "timedmedia-desc-link": "Euver dit bestandj" +} diff --git a/extensions/TimedMediaHandler/i18n/lrc.json b/extensions/TimedMediaHandler/i18n/lrc.json new file mode 100644 index 00000000..b897768a --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/lrc.json @@ -0,0 +1,44 @@ +{ + "@metadata": { + "authors": [ + "Bonevarluri", + "Mogoeilor" + ] + }, + "timedmedia-ogg-short-audio": "Ų¬Ų§ŁŪŲ§ ŲÆŁŚÆ Ų§ŁŚÆ $1Ų$2", + "timedmedia-ogg-short-video": "Ogg $1 Ų¬Ų§ŁŪŲ§ ŁŪŲÆŪŁ, $2", + "timedmedia-ogg-short-general": "Ogg $1 Ų¬Ų§ŁŪŲ§ ŁŲ§Ų±Ų³ŚÆŲ± , $2", + "timedmedia-ogg-long-audio": "Ogg $1 Ų¬Ų§ŁŪŲ§ ŲÆŁŚÆ , ŲÆŲ±Ų§Ų²Ų§ $2, $3", + "timedmedia-ogg-long-error": "Ų¬Ų§ŁŪŲ§ ŲÆŁŚÆ Ų§ŁŚÆ ŁŲ§Ł
Ų¹ŲŖŁŲ±:$1", + "timedmedia-webm-short-video": "WebM $1 Ų¬Ų§ŁŪŲ§ ŁŪŲÆŪŁ, $2", + "timedmedia-flac-short-audio": "FLAC Ų¬Ų§ŁŪŲ§ ŲÆŁŚÆŲÆŲ§Ų± , $1", + "timedmedia-wav-short-audio": "WAV Ų¬Ų§ŁŪŲ§ ŲÆŁŚÆŲÆŲ§Ų±, $1", + "timedmedia-wav-pcm-required": "Ų“Ł
Ų§ ŁŁŲ· ŲŖŁŁŪŲŖ Ł¾Ū Ų³Ū Ų§Ł
ŁŁ Ų³ŁŲ§Ų± ŲØŚ©ŪŲÆ", + "timedmedia-mp4-short-video": "MP4 $1 Ų¬Ų§ŁŪŲ§ ŁŪŲÆŪŁ, $2", + "timedmedia-no-player-js": "ŲÆ ŲØŲÆŲØŲ®ŲŖŪ ŲÆŁŲ§Ų±ŲŖŁ ŁŪŲ¦Ų± ŲÆ ŁŲŲ§Ųø Ų¬Ų§ŁŲ§ ŁŪŲ³Ų³Ł ŁŲ§Ś©Ų“ŲŖŚÆŲ± ŲØŪŁ ŪŲ§ Ų“Ų§ŪŲŖ ŲŲ§Ł
ŪŁŲÆŲ§Ų± ŁŪŚ ŲÆŁŚÆŪŲ§Ų±Ū ŁŲ¦.<br />\nŲ“Ł
Ų§ Ł
Ū ŲŖŁŁŪŲŖ<a href=\"$1\">Ś©ŁŪŁ¾ ŁŁ ŲØŚÆŲ±ŪŲŖ</a> ŪŲ§<a <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŪŁ ŚÆŁ ŲÆŁŚÆŪŲ§Ų± ŁŁ ŲØŚÆŲ±ŪŲŖ</a> Ų³Ū ŪŁ Ś©Ł Ś©ŁŪŁ¾ ŁŁ ŲÆ ŲÆŁŲ§Ų±ŲŖŁ ŁŪŲ¦Ų±ŲŖŁ ŲØŁ ŁŁŪŲŖ..", + "timedmedia-more": "ŲØŪŲ“ŲŖŲ±....", + "timedmedia-dismiss": "ŲØŲ³Ł", + "timedmedia-download": "ŚÆŲ±ŲŖŁ Ų¬Ų§ŁŪŲ§", + "timedmedia-play-media": "Ų±ŁŲ“Ł Ś©Ų±ŲÆŁ ŁŲ§Ų±Ų³ŚÆŲ±", + "timedmedia-desc-link": "ŲÆŲØŲ§Ų±Ł Ų§Ū Ų¬Ų§ŁŪŲ§", + "timedmedia-status": "ŲŲ§Ł ŁŲØŲ§Ł", + "timedmedia-status-unknown": "ŲŲ§Ł Ł ŲØŲ§Ł ŁŲ§ŲÆŪŲ§Ų±", + "timedmedia-actions": "Ś©ŁŲ“ŚÆŲ±ŪŲ§", + "timedmedia-not-ready": "Ų¢Ł
Ų§ŲÆŁ ŁŲ¦", + "timedmedia-percent-done": "ŲÆ ŲŲÆŁŲÆ $1% Ų§ŁŲ¬ŁŁ
ŲØŪ", + "timedmedia-days": "{{PLURAL:$1|1 Ų±ŁŲ²|$1 Ų±ŁŲ²}}", + "timedmedia-hours": "{{PLURAL:$1|$1 Ų³Ų§Ų¹ŲŖ|$1 Ų³Ų§Ų¹ŲŖ ŪŲ§}}", + "timedmedia-minutes": "{{PLURAL:$1|$1 ŲÆŪŁŁ|$1 ŲÆŪŁŁ ŪŲ§}}", + "timedmedia-seconds": "{{PLURAL:$1|$1 Ų«Ų§ŁŪŁ|$1 Ų«Ų§ŁŪŁ ŪŲ§}}", + "timedmedia-source-file": "Ų³Ų±ŚŲ“Ł
Ł $1", + "timedmedia-source-file-desc": "Ų§ŲµŁŪ $1 Ų¬Ų§ŁŪŲ§, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Ų¬Ų§ŁŪŲ§ Ų§ŲµŁŪ$1 ($2)", + "timedmedia-subtitle-new-go": "Ų±Ų¤", + "timedmedia-subtitle-language": "$1 ($2) Ų²ŪŲ±ŁŪŲ³", + "timedmedia-videos": "{{PLURAL:$1|$1 ŁŪŲÆŪŁ|$1 ŁŪŲÆŪŁŪŲ§}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg ŁŪŲÆŪŁ|$1 Ogg ŁŪŲÆŪŁŪŲ§}}", + "timedmedia-file": "Ų¬Ų§ŁŪŲ§", + "timedmedia-audios": "{{PLURAL:$1|$1 Ų¬Ų§ŁŪŲ§ ŲÆŁŚÆŲÆŲ§Ų±|$1 Ų¬Ų§ŁŪŲ§ŪŲ§ ŲÆŁŚÆŲÆŲ§Ų±}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ų¬Ų§ŁŪŲ§ ŲÆŁŚÆ ŁŚÆŲÆŲ§Ų± Ų§ŁŚÆ|$1 Ų¬Ų§ŁŪŲ§ŪŲ§ ŲÆŁŚÆŲÆŲ§Ų± Ų§ŁŚÆ}}", + "apihelp-transcodereset-param-title": "ŲÆŲ§Ų³ŁŁ Ų¬Ų§ŁŪŲ§ ŁŲ§Ų±Ų³ŚÆŲ±." +} diff --git a/extensions/TimedMediaHandler/i18n/lt.json b/extensions/TimedMediaHandler/i18n/lt.json new file mode 100644 index 00000000..bee1ed8d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/lt.json @@ -0,0 +1,123 @@ +{ + "@metadata": { + "authors": [ + "Homo", + "Matasg", + "Hugo.arg", + "Albertas" + ] + }, + "timedmedia-desc": "Audio, video ir teksto su laiku doroklÄ, kuri palaiko WebM, Ogg Theora, Vorbis, srt formatus", + "timedmedia-ogg-short-audio": "Ogg $1 garso byla, $2", + "timedmedia-ogg-short-video": "Ogg $1 video byla, $2", + "timedmedia-ogg-short-general": "Ogg $1 medija byla, $2", + "timedmedia-ogg-long-audio": "Ogg $1 garso byla, ilgis $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 video byla, ilgis $2, $4Ć$5 pikseliai, $3", + "timedmedia-ogg-long-multiplexed": "Ogg sutankinta audio/video byla, $1, ilgis $2, $4Ć$5 pikseliai, $3 viso", + "timedmedia-ogg-long-general": "Ogg media byla, ilgis $2, $3", + "timedmedia-ogg-long-error": "Bloga ogg byla: $1", + "timedmedia-ogg-long-no-streams": "Ogg medijos failas. Ä®spÄjimas: nei vienas faile naudojamas kodavimo standartas nebuvo atpažintas.", + "timedmedia-webm-short-video": "WebM $1 video failas, $2", + "timedmedia-webm-long-video": "WebM audio/video failas, $1, ilgio $2, $4 Ć $5 pikselių, $3 iÅ”viso", + "timedmedia-flac-short-audio": "FLAC audio failas, $1", + "timedmedia-flac-long-audio": "FLAC audio failas, ilgio $1, $2 iÅ” viso", + "timedmedia-wav-short-audio": "WAV audio failas, $1", + "timedmedia-wav-long-audio": "WAV audio failas, ilgio $1, $2 iÅ” viso", + "timedmedia-wav-pcm-required": "Galite ÄÆkelti tik PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "MP4 $1 video failas, $2", + "timedmedia-mp4-long-video": "MP4 audio/video failas, $1, ilgio $2, $4 Ć $5 pikselių, $3 iÅ” viso", + "timedmedia-no-player-js": "AtsipraÅ”ome, bet jÅ«sų narÅ”yklÄje arba iÅ”jungtas JavaScript, arba neturi jokio palaikomo grotuvo.<br />\nJÅ«s galite <a href=\"$1\">atsisiųsti ÄÆraÅ”Ä
</a> arba <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">grotuvÄ
</a>, kad galÄtumÄte leisti ÄÆraÅ”Ä
savo narÅ”yklÄje.", + "timedmedia-more": "Daugiau...", + "timedmedia-dismiss": "Uždaryti", + "timedmedia-download": "Atsisiųsti bylÄ
", + "timedmedia-play-media": "Groti medijÄ
", + "timedmedia-desc-link": "Apie Å”iÄ
bylÄ
", + "timedmedia-oggThumb-version": "OggHandler reikalauja oggThumb $1 versijos arba vÄlesnÄs.", + "timedmedia-oggThumb-failed": "oggThumb nepavyko sukurti miniatiÅ«ros.", + "timedmedia-status-header": "Perkodavimo statusas", + "timedmedia-update-status": "Atnaujinti perkodavimo statusÄ
", + "timedmedia-status": "BÅ«sena", + "timedmedia-status-unknown": "Nežinomas statusas", + "timedmedia-transcodebitrate": "KokybÄ", + "timedmedia-transcodeduration": "Kodavimo laikas", + "timedmedia-transcodeinfo": "Formatas", + "timedmedia-actions": "Veiksmai", + "timedmedia-direct-link": "Atsisiųsti", + "timedmedia-not-ready": "NeparuoÅ”ta", + "timedmedia-completed-on": "Baigta $1", + "timedmedia-error-on": "Klaida $1", + "timedmedia-started-transcode": "PradÄta prieÅ” $1. $2", + "timedmedia-percent-done": "Atlikta apie $1%", + "timedmedia-in-job-queue": "PridÄta prie darbų eilÄs prieÅ” $1", + "timedmedia-unknown-target-size": "Nežinomas rezultato dydis, $1 užkoduota", + "timedmedia-days": "{{PLURAL:$1|1 diena|$1 dienos}}", + "timedmedia-hours": "{{PLURAL:$1|1 valanda|$1 valandos}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minutÄ|$1 minutÄs}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekundÄ|$1 sekundÄs}}", + "timedmedia-reset": "Atstatyti perkodavimÄ
", + "timedmedia-reset-confirm": "Å io perkodavimo atstatymas paÅ”alins visus egzistuojanÄius failus (jeigu jų yra) ir vÄl pridÄs perkodavimÄ
ÄÆ darbų eilÄ. Perkodavimas užtruks kažkiek laiko.<br /><br />\nAr tikrai norite tÄsti?", + "timedmedia-reset-error": "Klaida perkodavimo atstatymo užduotyje.", + "timedmedia-source-file": "$1 Å”altinis", + "timedmedia-source-file-desc": "Originalus $1 failas, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "PirminÄ $1 rinkmena ($2)", + "timedmedia-derivative-desc-160p.ogv": "Žemo pralaidumo Ogg video (160P)", + "timedmedia-derivative-desc-240p.ogv": "Internetu transliuotinas Ogg video (240P)", + "timedmedia-derivative-desc-360p.ogv": "Internetu transliuotinas Ogg video (360P)", + "timedmedia-derivative-desc-480p.ogv": "Internetu transliuotinas Ogg video (480P)", + "timedmedia-derivative-desc-720p.ogv": "AukÅ”tos kokybÄs atsisiųstinas Ogg video (720P)", + "timedmedia-derivative-desc-1080p.ogv": "VisiÅ”kai aukÅ”tos kokybÄs atsisiųstinas Ogg video (1080P)", + "timedmedia-derivative-desc-160p.webm": "Internetu transliuotinas WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "Internetu transliuotinas WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "Internetu transliuotinas WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "AukÅ”tos kokybÄs atsisiųstinas WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "VisiÅ”kai aukÅ”tos kokybÄs atsisiųstinas WebM (1080P)", + "timedmedia-derivative-desc-2160p.webm": "Pilnai 4K atsisiųstinas WebM (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "Internetu transliuotinas WebM VP9 (360P)", + "timedmedia-derivative-desc-480p.vp9.webm": "Internetu transliuotinas WebM VP9 (480P)", + "timedmedia-derivative-desc-720p.vp9.webm": "AukÅ”tos kokybÄs transliuotinas WebM VP9 (720P)", + "timedmedia-derivative-desc-1080p.vp9.webm": "VisiÅ”kai aukÅ”tos kokybÄs transliuotinas WebM VP9 (1080P)", + "timedmedia-derivative-desc-2160p.vp9.webm": "Pilnai 4K transliuotinas WebM VP9 (2160P)", + "timedmedia-derivative-desc-320p.mp4": "Ä®renginiams draugiÅ”kas MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Internetu transliuotinas MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "AukÅ”tos kokybÄs MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "VisiÅ”kai aukÅ”tos kokybÄs MP4 (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "Pilnos 4K kokybÄs MP4 (2160P)", + "timedmedia-subtitle-new": "Sukurti naujÄ
vertimÄ
arba redaguoti egzistuojantÄÆ", + "timedmedia-subtitle-new-desc": "Pasirinkite kalbÄ
ir paspauskite '''{{int:Timedmedia-subtitle-new-go}}''' mygtukÄ
", + "timedmedia-subtitle-new-go": "Vykdyti", + "timedmedia-subtitle-language": "$1 ($2) subtitrai", + "timedmedia-subtitle-no-video": "NÄra video, susieto su dabartiniu subtitrų puslapiu.", + "timedmedia-subtitle-no-subtitles": "Kol kas Å”iam video nÄra subtitrų $1, bet JÅ«s galite [{{fullurl:{{FULLPAGENAME}}|action=edit}} redaguoti Å”ÄÆ puslapÄÆ], norÄdami juos pridÄti.", + "timedmedia-subtitle-remote": "Å io failo tekstas su laiku yra patalpintas $1", + "timedmedia-subtitle-remote-link": "Galite [$1 peržiÅ«rÄti Å”io failo apraÅ”ymo puslapÄÆ] $2", + "timedmediahandler": "MedijosSuLaikuDoroklis", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 video failai}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg video|$1 Ogg video failai}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM video|$1 WebM video failai}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 perkodavimas|$1 perkodavimai}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 vykdomas perkodavimas|$1 vykdomi perkodavimai}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 ieÅ”komas perkodavimas|$1 ieÅ”komi perkodavimai}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 nepavykÄs perkodavimas|$1 nepavykÄ perkodavimai}}", + "timedmedia-file": "Failas", + "timedmedia-audios": "{{PLURAL:$1|$1 audio failas|$1 audio failai}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg audio failas|$1 Ogg audio failai}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC audio failas|$1 FLAC audio failai}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV audio failas|$1 WAV audio failai}}", + "right-transcode-reset": "Atstatymas nepavyko arba video failai buvo perkoduoti, todÄl jie vÄl buvo pridÄti ÄÆ darbų eilÄ", + "right-transcode-status": "PeržiÅ«rÄti [[Special:TimedMediaHandler|informacijÄ
apie dabartines perkodavimo veiklas]]", + "action-transcode-status": "peržiÅ«rÄti dabartinÄ perkodavimo bÅ«senÄ
", + "orphanedtimedtext": "Pamesto teksto su laiku puslapiai", + "orphanedtimedtext-summary": "SÄ
raÅ”as [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] puslapių, kurie neturi atitinkamų failų.", + "orphanedtimedtext-unsupported": "Å is specialus puslapis palaiko tik MySQL duomenų bazes.", + "orphanedtimedtext-notimedtext": "Tekstas su laiku nÄra aktyvuotas Å”iame vikyje.", + "apihelp-query+transcodestatus-description": "Gauti perkodavimo statusÄ
pateiktajam failo puslapiui.", + "apihelp-query+transcodestatus-example-1": "Gauti perkodavimo bÅ«senÄ
[[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "Papildo paveikslÄlio informacijÄ
, kad bÅ«tų pridÄta video Å”altinio (iÅ”vestinio) informacija", + "apihelp-query+videoinfo-param-prop": "KuriÄ
video informacijÄ
norite gauti:\n;timestamp:Prideda ÄÆkeltosios versijos laiko žymÄ.\n;user:Prideda naudotojÄ
, kuris ÄÆkÄlÄ video versijÄ
.\n;userid:Prideda ID naudotojo, kuris ÄÆkÄlÄ video versijÄ
.\n;comment:Versijos komentaras.\n;parsedcomment:Apdorotas versijos komentaras.\n;canonicaltitle:Prideda kanoninÄÆ video failo pavadinimÄ
.\n;url:Pateikia URL, nukreipiantÄÆ ÄÆ video ir apraÅ”ymo puslapÄÆ.\n;size:Prideda video dydÄÆ baitais, jo aukÅ”tÄÆ ir plotÄÆ. Puslapio skaitliukas ir trukmÄ yra pridedami, jeigu prieinama.\n;dimensions:Dydžio alternatyva.\n;sha1:Prideda video SHA-1 maiÅ”os funkcijos reikÅ”mÄ.\n;mime:Prideda video MIME tipÄ
.\n;thumbmime:Prideda video MIME tipo miniatiÅ«rÄ
(reikalauja URL ir parametro $1urlwidth).\n;mediatype:Prideda video medijos tipÄ
.\n;metadata:Pateikia video versijos Exif metaduomenų sÄ
raÅ”Ä
.\n;commonmetadata:Pateikia video versijos failo formatų bendrų metaduomenų sÄ
raÅ”Ä
.\n;extmetadata:Pateikia formatuotų metaduomenų sÄ
raÅ”Ä
, sukombinuotÄ
iÅ” skirtingų Å”altinių. Rezultatas yra suformatuotas HTML.\n;archivename:Prideda ne paskutinių versijų archyvo failo vardÄ
.\n;bitdepth:Prideda versijos bitų gilumÄ
.\n;uploadwarning:Naudojamas [[Special:Upload]] puslapyje gauti informacijai apie egzistuojantÄÆ failÄ
. NÄra skirtas naudojimui MediaWiki branduolio iÅ”orÄje.\n;derivatives:Prideda skirtingų prieinamų audio ir video failų formatų ir kokybÄs versijų sÄ
raÅ”Ä
.", + "apihelp-query+videoinfo-example-1": "Gauti informacijÄ
apie [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "Naudotojai turintys 'perkodavimo-atsatymo' teises gali atstatyti ir pakartotinai paleisti perkodavimo užduotÄÆ.", + "apihelp-transcodereset-param-title": "Medijos failo pavadinimas.", + "apihelp-transcodereset-param-transcodekey": "Perkodavimo raktas, kurÄÆ norite atstatyti. Galite paimti iÅ” [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "Atstatyti visus [[:File:Clip.webm]] perkodavimus", + "apihelp-transcodereset-example-2": "Atstatyti '360_560kbs.webm' perkodavimo raktÄ
[[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/luz.json b/extensions/TimedMediaHandler/i18n/luz.json new file mode 100644 index 00000000..4ab30bc0 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/luz.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Ų¹ŁŪ Ų³Ų§Ś©Ū ŁŲ±Ų³ŲŖŲ§ŁŪ" + ] + }, + "timedmedia-no-player-js": "ŪŲ§Ų³Ū ŪŲØŲ®Ų“ŪŲŖŲŁ
Ų±ŪŲ±ŚÆŲ± Ų§ŪŲ“Ų§ ŪŚ¾ ŲµŪŲ±ŲŖ Ų¬Ų§ŪŲ§ Ų§Ų³Ś©Ų±ŪŁ¾ŲŖ ŲŗŪŲ±ŁŲ¹Ų§Ł ŪŲ§ŲØŪŲÆŚ¾ Ū ŁŪŚ Ł¾ŁŪŲ± Ł¾Ų“ŲŖŪŲØŲ§ŁŪ ŁŲ§Ų±Ś¾.<br /> Ų§ŪŲ“Ų§ ŪŲ§ Ś©ŁŪŚ Ų±Ū Ų§Ū Ų§ŪŲŖŲ±ŪŲÆ <a href=\"$1\">download the clip</a> or <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">download a player</a> Ś©ŁŪŁ¾ŁŁ Ł
Ų¦ŁŁ Ł
Ų±ŪŲ±ŚÆŲ± Ų®ŪŲŖŪŁ Ł¾Ų®Ų“ Ś©ŁŪŲŖ.", + "timedmedia-source-file": "$1 Ų³Ų±ŚŲ“Ł
Ł", + "timedmedia-source-audio-file-desc": "Ų§ŲµŁŪ $1 ŁŲ§ŪŁ ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/lv.json b/extensions/TimedMediaHandler/i18n/lv.json new file mode 100644 index 00000000..9554b20b --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/lv.json @@ -0,0 +1,22 @@ +{ + "@metadata": { + "authors": [ + "Papuass", + "Xil", + "Silraks" + ] + }, + "timedmedia-more": "VairÄk...", + "timedmedia-dismiss": "AizvÄrt", + "timedmedia-download": "LejupielÄdÄt failu", + "timedmedia-desc-link": "Par Å”o failu", + "timedmedia-status": "Statuss", + "timedmedia-status-unknown": "NezinÄms statuss", + "timedmedia-transcodeinfo": "FormÄts", + "timedmedia-actions": "DarbÄ«bas", + "timedmedia-direct-link": "LejupielÄdÄt", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 avots", + "timedmedia-subtitle-new-go": "Aiziet!", + "timedmedia-subtitle-language": "$1 ($2) subtitri" +} diff --git a/extensions/TimedMediaHandler/i18n/mai.json b/extensions/TimedMediaHandler/i18n/mai.json new file mode 100644 index 00000000..7d189ffd --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/mai.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "ą¤¬ą¤æą¤Ŗą„ą¤²ą¤¬ ą¤ą¤Øą¤Øą„ą¤¦" + ] + }, + "timedmedia-no-player-js": "ą¤ą„ą¤·ą¤®ą¤¾ ą¤ą¤°ą„, ą¤
ą¤¹ą¤¾ą¤ą¤ą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤° ą¤®ą„ą¤ ą¤Æą¤¾ ą¤¤ ą¤ą¤¾ą¤µą¤¾ą¤øą„ą¤ą„ą¤°ą¤æą¤Ŗą„ą¤ ą¤
ą¤ą„ą¤·ą¤® ą¤
ą¤ą¤æ ą¤Æą¤¾ ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤Øą„ ą¤
ą¤ą¤æą„¤<br />\ną¤
ą¤¹ą¤¾ą¤ <a href=\"$1\">ą¤ą„ą¤²ą¤æą¤Ŗą¤ą„ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą„ą¤° ą¤øą¤ą„ ą¤ą„ ą¤µą¤¾ ą¤ą„ą¤²ą¤æą¤Ŗą¤ą„ ą¤
ą¤Ŗą¤Ø ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤°ą¤®ą„ą¤ ą¤ą¤²ą¤¾ą¤µą¤¾ą¤ ą¤²ą„ą¤² <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¤ą¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą„ą¤° ą¤øą¤ą„ ą¤ą„ą„¤", + "timedmedia-source-file": "$1 ą¤øą„ą¤°ą„ą¤¤", + "timedmedia-source-audio-file-desc": "ą¤®ą„ą¤² $1 ą¤«ą¤¾ą¤ą¤² ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/mg.json b/extensions/TimedMediaHandler/i18n/mg.json new file mode 100644 index 00000000..ed53f4f9 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/mg.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Jagwar" + ] + }, + "timedmedia-no-player-js": "Miala tsiny indrindra, na tsy mampiasa JavaScript ny mpitety tranonkalanao, na tsy manana mpamaky zaka ilay izy.<br />\nAzonao atao ny <a href=\"$1\">mampidina ilay kilipy</a> na <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">mampidina mpamaky iray</a> hamakiana ilay kilipy eo amin'ny mpitetinao.", + "timedmedia-source-file": "Fango $1", + "timedmedia-source-audio-file-desc": "Rakitra niaviana $1 ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/min.json b/extensions/TimedMediaHandler/i18n/min.json new file mode 100644 index 00000000..5b8b13a5 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/min.json @@ -0,0 +1,30 @@ +{ + "@metadata": { + "authors": [ + "Iwan Novirion" + ] + }, + "timedmedia-transcodeinfo": "Deskripsi turunan transkoder", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-derivative-160p.ogv": "Ogg 160p", + "timedmedia-derivative-360p.ogv": "Ogg 360p", + "timedmedia-derivative-480p.ogv": "Ogg 480p", + "timedmedia-derivative-720p.ogv": "Ogg 720p", + "timedmedia-derivative-160p.webm": "WebM 160p", + "timedmedia-derivative-360p.webm": "WebM 360p", + "timedmedia-derivative-480p.webm": "WebM 480p", + "timedmedia-derivative-720p.webm": "WebM 720p", + "timedmedia-derivative-320p.mp4": "H264 320p", + "timedmedia-derivative-480p.mp4": "H264 480p", + "timedmedia-derivative-720p.mp4": "H264 720p", + "timedmedia-derivative-ogg": "Ogg Vorbis", + "timedmedia-derivative-desc-ogg": "Ogg Vorbis", + "timedmedia-derivative-opus": "Opus", + "timedmedia-derivative-desc-opus": "Opus", + "timedmedia-derivative-mp3": "MP3", + "timedmedia-derivative-desc-mp3": "MP3", + "timedmedia-derivative-m4a": "AAC", + "timedmedia-derivative-desc-m4a": "AAC", + "timedmediahandler": "Daftar berkas media" +} diff --git a/extensions/TimedMediaHandler/i18n/mk.json b/extensions/TimedMediaHandler/i18n/mk.json new file mode 100644 index 00000000..69ba9495 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/mk.json @@ -0,0 +1,144 @@ +{ + "@metadata": { + "authors": [ + "Bjankuloski06", + "Brest" + ] + }, + "extensionname-timedmedia": "Š¢ŠøŃŠ»Š¾Š²Šø", + "timedmedia-desc": "ŠŠ±ŃŠ°Š±Š¾ŃŃŠ²Š°Ń Š·Š° Š°ŃŠ“ŠøŠ¾, Š²ŠøŠ“ŠµŠ¾ Šø ŃŠøŃŠ»Š¾Š²Šø, ŃŠ¾ ŠæŠ¾Š“Š“ŃŃŠŗŠ° Š·Š° ŃŠ¾ŃŠ¼Š°ŃŠøŃŠµ WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 Š·Š²ŃŃŠ½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°, $2", + "timedmedia-ogg-short-video": "Ogg $1 Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ°, $2", + "timedmedia-ogg-short-general": "ŠŃŠ»ŃŠøŠ¼ŠµŠ“ŠøŃŠ°Š»Š½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ° Ogg $1, $2", + "timedmedia-ogg-long-audio": "Ogg $1 Š·Š²ŃŃŠ½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°, Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 Š²ŠøŠ“ŠµŠ¾ ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°, Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµ $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ»Šø, $3", + "timedmedia-ogg-long-multiplexed": "Ogg Š¼ŃŠ»ŃŠøŠæŠ»ŠµŠŗŃŠøŃŠ°Š½Š° Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ ŃŠ½ŠøŠ¼ŠŗŠ°, $1, Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµ $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ»Šø, Š²ŠŗŃŠæŠ½Š¾ $3", + "timedmedia-ogg-long-general": "ŠŃŠ»ŃŠøŠ¼ŠµŠ“ŠøŃŠ°Š»Š½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ° Ogg, Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµ $2, $3", + "timedmedia-ogg-long-error": "ŠŃŃŠµŃŠµŠ½Š° Ogg-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°: $1", + "timedmedia-ogg-long-no-streams": "Ogg-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°. ŠŃŠµŠ“ŃŠæŃŠµŠ“ŃŠ²Š°ŃŠµ: ŠŠµ ŠæŃŠµŠæŠ¾Š·Š½Š°Š² Š½ŠøŠµŠ“ŠµŠ½ Š¾Š“ ŠŗŠ¾ŃŠøŃŃŠµŠ½ŠøŃŠµ ŠŗŠ¾Š“ŠµŃŠø.", + "timedmedia-webm-short-video": "WebM $1 Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ°, $2", + "timedmedia-webm-long-video": "WebM Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ ŃŠ½ŠøŠ¼ŠŗŠ°, $1, Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµ: $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ»Šø, Š²ŠŗŃŠæŠ½Š¾ $3", + "timedmedia-flac-short-audio": "ŠŃŠ“ŠøŠ¾ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ° FLAC, $1", + "timedmedia-flac-long-audio": "ŠŃŠ“ŠøŠ¾ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ° FLAC, Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµ: $1, Š²ŠŗŃŠæŠ½Š¾ $2", + "timedmedia-wav-short-audio": "ŠŃŠ“ŠøŠ¾ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ° WAV, $1", + "timedmedia-wav-long-audio": "ŠŃŠ“ŠøŠ¾ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ° WAV, Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµ: $1, Š²ŠŗŃŠæŠ½Š¾ $2", + "timedmedia-wav-pcm-required": "ŠŠ¾Š¶ŠµŃŠµ Š“Š° ŠæŠ¾Š“ŠøŠ³Š°ŃŠµ ŃŠ°Š¼Š¾ WAV-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠø ŃŠ¾ PCM (ŠøŠ¼ŠæŃŠ»ŃŠ½Š° ŠŗŠ¾Š“Š½Š° Š¼Š¾Š“ŃŠ»Š°ŃŠøŃŠ°).", + "timedmedia-mp4-short-video": "MP4 $1 Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ°, $2", + "timedmedia-mp4-long-video": "MP4 Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ ŃŠ½ŠøŠ¼ŠŗŠ°, $1, Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµ $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ»Šø, Š²ŠŗŃŠæŠ½Š¾ $3", + "timedmedia-no-player-js": "ŠŠ° Š¶Š°Š», Š²Š°ŃŠøŠ¾Ń ŠæŃŠµŠ»ŠøŃŃŃŠ²Š°Ń ŠøŠ»Šø ŠøŠ¼Š° Š¾Š½ŠµŠ²Š¾Š·Š¼Š¾Š¶ŠµŠ½Š¾ JavaScript, ŠøŠ»Šø Š½ŠµŠ¼Š° Š½ŠøŃŃ ŠµŠ“ŠµŠ½ ŠæŠ¾Š“Š“ŃŠ¶Š°Š½ ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń.<br />\nŠŠ¾Š¶ŠµŃŠµ Š“Š° Š³Š¾ <a href=\"$1\">ŠæŃŠµŠ·ŠµŠ¼ŠµŃŠµ ŠŗŠ»ŠøŠæŠ¾Ń</a> ŠøŠ»Šø <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š“Š° ŠæŃŠµŠ·ŠµŠ¼ŠµŃŠµ ŠøŠ·Š²ŠµŠ“ŃŠ²Š°Ń</a> Š·Š° Š“Š° ŃŠ° ŠæŃŃŃŠøŃŠµ ŃŠ½ŠøŠ¼ŠŗŠ°ŃŠ° Š²Š¾ Š²Š°ŃŠøŠ¾Ń ŠæŃŠµŠ»ŠøŃŃŃŠ²Š°Ń.", + "timedmedia-more": "ŠŠ¾Š²ŠµŃŠµ...", + "timedmedia-dismiss": "ŠŠ°ŃŠ²Š¾ŃŠø", + "timedmedia-download": "ŠŃŠµŠ·ŠµŠ¼Šø ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°", + "timedmedia-play-media": "ŠŃŃŃŠø ŃŠ½ŠøŠ¼ŠŗŠ°", + "timedmedia-desc-link": "ŠŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŠø Š·Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°ŃŠ°", + "timedmedia-oggThumb-version": "OggHandler Š±Š°ŃŠ° oggThumb Š²ŠµŃŠ·ŠøŃŠ° $1 ŠøŠ»Šø ŠæŠ¾Š½Š¾Š²Š°.", + "timedmedia-oggThumb-failed": "oggThumb Š½Šµ ŃŃŠæŠµŠ° Š“Š° ŃŠ° ŃŠ¾Š·Š“Š°Š“Šµ Š¼ŠøŠ½ŠøŃŠ°ŃŃŃŠ°ŃŠ°.", + "timedmedia-status-header": "Š”ŃŠ°ŃŃŃ Š½Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾", + "timedmedia-update-status": "ŠŠ¾Š“Š½Š¾Š²Šø ŃŃŠ°ŃŃŃ Š½Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ", + "timedmedia-status": "ŃŃŠ°ŃŃŃ", + "timedmedia-status-unknown": "ŠŠµŠæŠ¾Š·Š½Š°Ń ŃŃŠ°ŃŃŃ", + "timedmedia-transcodebitrate": "ŠŃŠ¾ŠæŃŃŠ½Š¾ŃŃ", + "timedmedia-transcodeduration": "Š¢ŃŠ°ŠµŃŠµ Š½Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾", + "timedmedia-transcodeinfo": "Š¤Š¾ŃŠ¼Š°Ń", + "timedmedia-actions": "ŠŠµŃŃŃŠ²Š°", + "timedmedia-direct-link": "ŠŃŠµŠ·ŠµŠ¼Š°ŃŠµ", + "timedmedia-not-ready": "ŠŠµ Šµ Š³Š¾ŃŠ¾Š²Š¾", + "timedmedia-completed-on": "ŠŠ°Š²ŃŃŠµŠ½Š¾ Š½Š° $1", + "timedmedia-error-on": "ŠŃŠµŃŠŗŠ° Š½Š° $1", + "timedmedia-started-transcode": "ŠŠ°ŠæŠ¾ŃŠ½Š°ŃŠ¾ ŠæŃŠµŠ“ $1. $2", + "timedmedia-percent-done": "Š”ŃŠ°Š±Š¾ŃŠµŠ½Š¾: Š¾ŠŗŠ¾Š»Ń $1%", + "timedmedia-in-job-queue": "ŠŠ¾Š“Š°Š“ŠµŠ½Š¾ Š²Š¾ ŃŠµŠ“ŠøŃŠ°ŃŠ° Š½Š° Š·Š°Š“Š°ŃŠø ŠæŃŠµŠ“ $1", + "timedmedia-unknown-target-size": "ŠŠµŠæŠ¾Š·Š½Š°ŃŠ° ŃŠµŠ»Š½Š° Š³Š¾Š»ŠµŠ¼ŠøŠ½Š°. $1 Šµ ŃŠøŃŃŠøŃŠ°Š½Š¾", + "timedmedia-days": "{{PLURAL:$1|ŠµŠ“ŠµŠ½ Š“ŠµŠ½|$1 Š“ŠµŠ½Š°}}", + "timedmedia-hours": "{{PLURAL:$1|ŠµŠ“ŠµŠ½ ŃŠ°Ń|$1 ŃŠ°ŃŠ°}}", + "timedmedia-minutes": "{{PLURAL:$1|ŠµŠ“Š½Š° Š¼ŠøŠ½ŃŃŠ°|$1 Š¼ŠøŠ½ŃŃŠø}}", + "timedmedia-seconds": "{{PLURAL:$1|ŠµŠ“Š½Š° ŃŠµŠŗŃŠ½Š“Š°|$1 ŃŠµŠŗŃŠ½Š“Šø}}", + "timedmedia-reset": "ŠŠ“Š½Š¾Š²Š¾", + "timedmedia-reset-confirm": "ŠŃŠ°ŃŠ°ŃŃŠø Š³Š¾ Š¾Š²Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ Š¾Š“Š½Š¾Š²Š¾ ŃŠµ ŃŠ° Š¾ŃŃŃŃŠ°Š½ŠøŃŠµ ŠæŠ¾ŃŃŠ¾ŠµŃŠŗŠ°ŃŠ° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ° (Š°ŠŗŠ¾ ŃŠ° ŠøŠ¼Š°) Šø ŃŠµ Š³Š¾ Š²ŃŠ°ŃŠøŃŠµ ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾ Š²Š¾ ŃŠµŠ“ŠøŃŠ°ŃŠ° Š½Š° Š·Š°Š“Š°ŃŠø. ŠŠ¾Š²ŃŠ¾ŃŠ½Š¾ŃŠ¾ ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ ŃŠµ ŠæŠ¾ŃŃŠ°Šµ. <br /><br />ŠŠ°Š»Šø ŃŃŠµ ŃŠøŠ³ŃŃŠ½Šø Š“ŠµŠŗŠ° ŃŠ°ŠŗŠ°ŃŠµ Š“Š° ŠæŃŠ¾Š“Š¾Š»Š¶ŠøŃŠµ?", + "timedmedia-reset-error": "ŠŃŠµŃŠŗŠ° ŠæŃŠø ŠæŠ¾Š²ŃŠ¾ŃŠ½Š¾ŃŠ¾ ŠæŃŃŃŠ°ŃŠµ Š½Š° ŃŃŠ°Š½ŃŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾.", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "ŠŠ·Š²Š¾Ń Š½Š° $1", + "timedmedia-source-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š»Š½Š° $1-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š»Š½Š° $1-ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ° ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160Šæ", + "timedmedia-derivative-desc-160p.ogv": "ŠŠøŃŠŗŠ¾ŠæŃŠ¾ŠæŃŃŠ½Š¾ Ogg-Š²ŠøŠ“ŠµŠ¾ (160Šæ)", + "timedmedia-derivative-240p.ogv": "Ogg 240 Šæ", + "timedmedia-derivative-desc-240p.ogv": "Ogg-Š²ŠøŠ“ŠµŠ¾ Š·Š° ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (240 ŠæŠøŠŗŃŠµŠ»Šø)", + "timedmedia-derivative-360p.ogv": "Ogg 360Šæ", + "timedmedia-derivative-desc-360p.ogv": "Ogg-Š²ŠøŠ“ŠµŠ¾ Š·Š° ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (360 ŠæŠøŠŗŃŠµŠ»Šø)", + "timedmedia-derivative-480p.ogv": "Ogg 480Šæ", + "timedmedia-derivative-desc-480p.ogv": "Ogg-Š²ŠøŠ“ŠµŠ¾ Š·Š° ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (480 ŠæŠøŠŗŃŠµŠ»Šø)", + "timedmedia-derivative-720p.ogv": "Ogg 720Šæ", + "timedmedia-derivative-desc-720p.ogv": "ŠŠøŃŠ¾ŠŗŠ¾ŠŗŠ²Š°Š»ŠøŃŠµŃŠ½Š¾ Ogg-Š²ŠøŠ“ŠµŠ¾ Š·Š° ŠæŃŠµŠ·ŠµŠ¼Š°ŃŠµ (720Šæ)", + "timedmedia-derivative-1080p.ogv": "Ogg 1080Šæ", + "timedmedia-derivative-desc-1080p.ogv": "ŠŠøŃŠ¾ŠŗŠ¾ŃŠ°Š·Š“ŠµŠ»Š½Š° Ogg-Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ° Š·Š° ŠæŃŠµŠ·ŠµŠ¼Š°ŃŠµ (1080Šæ)", + "timedmedia-derivative-160p.webm": "WebM 160Šæ", + "timedmedia-derivative-desc-160p.webm": "WebM Š·Š° ŠŗŠ°Š½Š°Š»ŃŠŗŠ¾ ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (160Šæ)", + "timedmedia-derivative-360p.webm": "WebM 360Šæ", + "timedmedia-derivative-desc-360p.webm": "WebM Š·Š° ŠŗŠ°Š½Š°Š»ŃŠŗŠ¾ ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (360Šæ)", + "timedmedia-derivative-480p.webm": "WebM 480Šæ", + "timedmedia-derivative-desc-480p.webm": "WebM Š·Š° ŠŗŠ°Š½Š°Š»ŃŠŗŠ¾ ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (480Šæ)", + "timedmedia-derivative-720p.webm": "WebM 720Šæ", + "timedmedia-derivative-desc-720p.webm": "ŠŠøŃŠ¾ŠŗŠ¾ŠŗŠ²Š°Š»ŠøŃŠµŃŠµŠ½ WebM Š·Š° ŠæŃŠµŠ·ŠµŠ¼Š°ŃŠµ (720Šæ)", + "timedmedia-derivative-1080p.webm": "WebM 1080Šæ", + "timedmedia-derivative-desc-1080p.webm": "ŠŠ¾Š»Š½Š¾ŃŠ°Š·Š“ŠµŠ»Š½Š° WebM-Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ° Š·Š° ŠæŃŠµŠ·ŠµŠ¼Š°ŃŠµ (1080Šæ)", + "timedmedia-derivative-desc-2160p.webm": "ŠŠ¾Š»Š½Š¾ŃŠ°Š·Š“ŠµŠ»Š½Š° 4Š WebM-Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ° Š·Š° ŠæŃŠµŠ·ŠµŠ¼Š°ŃŠµ (2160Šæ)", + "timedmedia-derivative-360p.vp9.webm": "VP9 360Šæ", + "timedmedia-derivative-desc-360p.vp9.webm": "WebM Š·Š° ŠŗŠ°Š½Š°Š»ŃŠŗŠ¾ ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (360Šæ)", + "timedmedia-derivative-480p.vp9.webm": "VP9 480Šæ", + "timedmedia-derivative-desc-480p.vp9.webm": "WebM Š·Š° ŠŗŠ°Š½Š°Š»ŃŠŗŠ¾ ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (480Šæ)", + "timedmedia-derivative-720p.vp9.webm": "VP9 720Šæ", + "timedmedia-derivative-desc-720p.vp9.webm": "WebM Š·Š° Š²ŠøŃŠ¾ŠŗŠ¾ŃŠ°Š·Š“ŠµŠ»Š½Š¾ ŠŗŠ°Š½Š°Š»ŃŠŗŠ¾ ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (720Šæ)", + "timedmedia-derivative-1080p.vp9.webm": "VP9 1080Šæ", + "timedmedia-derivative-desc-1080p.vp9.webm": "WebM Š·Š° ŠæŠ¾Š»Š½Š¾ŃŠ°Š·Š“ŠµŠ»Š½Š¾ ŠŗŠ°Š½Š°Š»ŃŠŗŠ¾ ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (1080Šæ)", + "timedmedia-derivative-desc-2160p.vp9.webm": "ŠŠ¾Š»Š½Š¾ŃŠ°Š·Š“ŠµŠ»Š½Š° 4Š WebM VP9 Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ° Š·Š° ŠæŃŠµŠ·ŠµŠ¼Š°ŃŠµ (2160Šæ)", + "timedmedia-derivative-320p.mp4": "H264 320Šæ", + "timedmedia-derivative-desc-320p.mp4": "MP4 Š·Š° ŃŃŠµŠ“Šø (320Šæ)", + "timedmedia-derivative-480p.mp4": "H264 480Šæ", + "timedmedia-derivative-desc-480p.mp4": "MP4 Š·Š° ŠŗŠ°Š½Š°Š»ŃŠŗŠ¾ ŠµŠ¼ŠøŃŃŠ²Š°ŃŠµ (480Šæ)", + "timedmedia-derivative-720p.mp4": "H264 720Šæ", + "timedmedia-derivative-desc-720p.mp4": "MP4-ŃŠ½ŠøŠ¼ŠŗŠ° ŃŠ¾ HD-ŠŗŠ²Š°Š»ŠøŃŠµŃ (720Šæ)", + "timedmedia-derivative-1080p.mp4": "H264 1080Šæ", + "timedmedia-derivative-desc-1080p.mp4": "ŠŠøŃŠ¾ŠŗŠ¾ŃŠ°Š·Š“ŠµŠ»Š±Š° MP4-Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ° (1080Šæ) Š·Š° ŠæŃŠµŠ·ŠµŠ¼Š°ŃŠµ", + "timedmedia-derivative-desc-2160p.mp4": "ŠŠ¾Š»Š½Š¾ŃŠ°Š·Š“ŠµŠ»Š½Š° 4Š ŠŗŠ²Š°Š»ŠøŃŠµŃŠ½Š° MP4-Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ° (2160Šæ)", + "timedmedia-subtitle-new": "Š”Š¾Š·Š“Š°Ń Š½Š¾Š² ŠæŃŠµŠ²Š¾Š“ ŠøŠ»Šø ŠøŠ·Š¼ŠµŠ½Šø ŠæŠ¾ŃŃŠ¾ŠµŃŠŗŠø", + "timedmedia-subtitle-new-desc": "ŠŠ·Š±ŠµŃŠµŃŠµ ŃŠ°Š·ŠøŠŗ Šø ŃŃŠøŃŠ½ŠµŃŠµ Š½Š° ŠŗŠ¾ŠæŃŠµŃŠ¾ '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "ŠŠ°Ń", + "timedmedia-subtitle-language": "$1 ($2) ŃŠøŃŠ»Š¾Š²Šø", + "timedmedia-subtitle-no-video": "ŠŠµŠ¼Š° Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ° ŠæŠ¾Š²ŃŠ·Š°Š½Š° ŃŠ¾ ŃŠµŠŗŠ¾Š²Š½Š°ŃŠ° ŃŃŃŠ°Š½ŠøŃŠ° ŃŠ¾ ŃŠøŃŠ»Š¾Š²Šø", + "timedmedia-subtitle-no-subtitles": "ŠŠ¾Š¼ŠµŠ½ŃŠ°Š»Š½Š¾ Š½ŠµŠ¼Š° $1 ŃŠøŃŠ»Š¾Š²Šø Š·Š° Š¾Š²Š°Š° Š²ŠøŠ“ŠµŠ¾ŃŠ½ŠøŠ¼ŠŗŠ°. ŠŠ¾Š¶ŠµŃŠµ Š“Š° Š³Šø Š“Š¾Š“Š°Š“ŠµŃŠµ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ŃŃŠµŠ“ŃŠ²Š°ŃŃŠø ŃŠ° ŃŃŃŠ°Š½ŠøŃŠ°Š²Š°]", + "timedmedia-subtitle-remote": "Š¢ŠøŃŠ»Š¾Š²ŠøŃŠµ Š½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°Š²Š° ŃŠµ Š²Š“Š¾Š¼ŠµŠ½Šø Š²Š¾ $1", + "timedmedia-subtitle-remote-link": "ŠŠ¾Š¶ŠµŃŠµ Š“Š° ŃŠ° [$1 ŠæŠ¾Š³Š»ŠµŠ“Š°ŃŠµ Š¾ŠæŠøŃŠ½Š°ŃŠ° ŃŃŃŠ°Š½ŠøŃŠ°] Š½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°Š²Š° Š½Š° $2", + "timedmediahandler": "Š¢ŠøŃŠ»Š¾Š²Šø", + "timedmedia-videos": "{{PLURAL:$1|$1 Š²ŠøŠ“ŠµŠ¾|$1 Š²ŠøŠ“ŠµŠ°}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg-Š²ŠøŠ“ŠµŠ¾|$1 Ogg-Š²ŠøŠ“ŠµŠ°}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM-Š²ŠøŠ“ŠµŠ¾|$1 WebM-Š²ŠøŠ“ŠµŠ°}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ|$1 ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠ°}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ Š²Š¾ ŃŠµŠŗ|$1 ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠ° Š²Š¾ ŃŠµŠŗ}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ Š²Š¾ ŃŠµŠ“ŠøŃŠ° Š½Š° ŃŠµŠŗŠ°ŃŠµ|$1 ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠ° Š²Š¾ ŃŠµŠ“ŠøŃŠ° Š½Š° ŃŠµŠŗŠ°ŃŠµ}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 Š½ŠµŃŃŠæŠµŃŠ½Š¾ ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ|$1 Š½ŠµŃŃŠæŠµŃŠ½Šø ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠ°}}", + "timedmedia-file": "ŠŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°", + "timedmedia-audios": "{{PLURAL:$1|ŠŠ“Š½Š° Š°ŃŠ“ŠøŠ¾ŃŠ½ŠøŠ¼ŠŗŠ°|$1 Š°ŃŠ“ŠøŠ¾ŃŠ½ŠøŠ¼ŠŗŠø}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|ŠŠ“Š½Š° Ogg-Š°ŃŠ“ŠøŠ¾ŃŠ½ŠøŠ¼ŠŗŠ°|$1 Ogg-Š°ŃŠ“ŠøŠ¾ŃŠ½ŠøŠ¼ŠŗŠø}}", + "timedmedia-flac-audios": "{{PLURAL:$1|ŠŠ“Š½Š° FLAC-Š°ŃŠ“ŠøŠ¾ŃŠ½ŠøŠ¼ŠŗŠ°|$1 FLAC-Š°ŃŠ“ŠøŠ¾ŃŠ½ŠøŠ¼ŠŗŠø}}", + "timedmedia-wav-audios": "{{PLURAL:$1|ŠŠ“Š½Š° WAV-Š°ŃŠ“ŠøŠ¾ŃŠ½ŠøŠ¼ŠŗŠ°|$1 WAV-Š°ŃŠ“ŠøŠ¾ŃŠ½ŠøŠ¼ŠŗŠø}}", + "right-transcode-reset": "ŠŃŠµŠ·Š°Š“Š°Š²Š°ŃŠµŃŠ¾ Š½Šµ ŃŃŠæŠµŠ° ŠøŠ»Šø ŠøŠ¼Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°Š½Šø Š²ŠøŠ“ŠµŠ°, ŠæŠ° Š·Š°ŃŠ¾Š° ŠæŠ¾Š²ŃŠ¾ŃŠ½Š¾ ŃŠµ ŃŃŠ°Š²ŠµŠ½Šø Š²Š¾ ŃŠµŠ“ŠøŃŠ°ŃŠ° Š½Š° Š·Š°Š“Š°ŃŠø.", + "right-transcode-status": "ŠŃŠµŠ³Š»ŠµŠ“ Š½Š° [[Special:TimedMediaHandler|ŠøŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŠø Š·Š° ŃŠµŠŗŠ¾Š²Š½ŠøŃŠµ Š°ŠŗŃŠøŠ²Š½Š¾ŃŃŠø Š²Š¾ ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾]]", + "action-transcode-status": "ŠæŃŠµŠ³Š»ŠµŠ“ Š½Š° ŃŠµŠŗŠ¾Š²Š½ŠøŠ¾Ń ŃŃŠ°ŃŃŃ Š½Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾", + "orphanedtimedtext": "ŠŃŠ°Š¼ŠµŠ½Šø ŃŃŃŠ°Š½ŠøŃŠø ŃŠ¾ ŃŠøŃŠ»Š¾Š²Šø", + "orphanedtimedtext-summary": "Š”ŠæŠøŃŠ¾Šŗ Š½Š° ŃŃŃŠ°Š½ŠøŃŠø ŃŠ¾ [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] ŃŃŠ¾ Š½ŠµŠ¼Š°Š°Ń ŃŠ²Š¾ŃŠ° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°.", + "orphanedtimedtext-unsupported": "ŠŠ²Š°Š° ŃŠ»ŃŠ¶Š±ŠµŠ½Š° ŃŃŃŠ°Š½ŠøŃŠ° Šµ ŠæŠ¾Š“Š“ŃŠ¶Š°Š½Š° ŃŠ°Š¼Š¾ Š½Š° MySQL-Š±Š°Š·Šø.", + "orphanedtimedtext-notimedtext": "Š¢ŠøŃŠ»Š¾Š²ŠøŃŠµ Š½Šµ ŃŠµ Š¾Š²Š¾Š·Š¼Š¾Š¶ŠµŠ½Šø Š½Š° Š¾Š²Š° Š²ŠøŠŗŠø.", + "apihelp-query+transcodestatus-description": "ŠŠ°Ń ŃŃŠ°ŃŃŃ Š½Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾ Š½Š° Š“Š°Š“ŠµŠ½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠ½Š° ŃŃŃŠ°Š½ŠøŃŠ°.", + "apihelp-query+transcodestatus-example-1": "ŠŠ°Ń ŃŃŠ°ŃŃŃ Š½Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾ Š½Š° [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "ŠŠø Š“Š¾ŠæŠ¾Š»Š½ŃŠ²Š° ŠøŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŠøŃŠµ ŃŠ¾ ŠæŠ¾Š“Š°ŃŠ¾Šŗ Š·Š° ŠøŠ·Š²Š¾ŃŠ¾Ń Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾ (ŠøŠ·Š²ŠµŠ“ŠµŠ½Šø)", + "apihelp-query+videoinfo-param-prop": "ŠŠ¾Šø ŠøŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŠø Š·Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾ Š“Š° ŃŠµ Š“Š°Š“Š°Ń:\n;timestamp: ŠŠ¾Š“Š°Š²Š° Š“Š°ŃŃŠ¼ Šø Š²ŃŠµŠ¼Šµ Š·Š° ŠæŠ¾Š“ŠøŠ³Š½Š°ŃŠ°ŃŠ° Š²ŠµŃŠ·ŠøŃŠ°.\n;user: ŠŠ¾ Š“Š¾Š“Š°Š²Š° ŠŗŠ¾ŃŠøŃŠ½ŠøŠŗŠ¾Ń ŃŃŠ¾ ŃŠ° ŠæŠ¾Š“ŠøŠ³Š½Š°Š» Š²ŠµŃŠ·ŠøŃŠ°ŃŠ° Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾.\n;userid: ŠŠ° Š“Š¾Š“Š°Š²Š° Š½Š°Š·Š½Š°ŠŗŠ°ŃŠ° Š½Š° ŠŗŠ¾ŃŠøŃŠ½ŠøŠŗŠ¾Ń ŃŃŠ¾ Š³Š¾ ŠæŠ¾Š“ŠøŠ³Š½Š°Š» Š²ŠøŠ“ŠµŠ¾ŃŠ¾.\n;comment: ŠŠ¾Š¼ŠµŠ½ŃŠ°Ń Š½Š° Š²ŠµŃŠ·ŠøŃŠ°ŃŠ°.\n;parsedcomment: Š Š°ŃŃŠ»ŠµŠ½ŃŠ²Š°ŃŠµ Š½Š° ŠŗŠ¾Š¼ŠµŠ½ŃŠ°ŃŠ¾Ń Š½Š° Š²ŠµŃŠ·ŠøŃŠ°ŃŠ°.\n;canonicaltitle: ŠŠ¾ Š“Š¾Š“Š°Š²Š° ŠŗŠ°Š½Š¾Š½ŃŠŗŠøŠ¾Ń Š½Š°ŃŠ»Š¾Š² Š½Š° Š²ŠøŠ“ŠµŠ¾ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°ŃŠ°.\n;url: ŠŠ°Š²Š° URL-Š°Š“ŃŠµŃŠ° Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾ Šø Š¾ŠæŠøŃŠ½Š°ŃŠ° ŃŃŃŠ°Š½ŠøŃŠ°.\n;size: ŠŠ° Š“Š¾Š“Š°Š²Š° Š·Š°ŃŠ°ŃŠ½ŠøŠ½Š°ŃŠ° Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾ Š²Š¾ Š±Š°ŃŃŠø, Š½ŠµŠ³Š¾Š²Š°ŃŠ° Š²ŠøŃŠøŠ½Š° Šø ŃŠøŃŠøŠ½Š°. ŠŠµ ŃŠµ Š“Š¾Š“Š°Š“Šµ Šø Š±ŃŠ¾ŃŠ¾Ń Š½Š° ŃŃŃŠ°Š½ŠøŃŠø Šø Š²ŃŠµŠ¼ŠµŃŃŠ°ŠµŃŠµŃŠ¾, Š°ŠŗŠ¾ ŃŠµ ŠæŃŠøŠ¼ŠµŠ½Š»ŠøŠ²Šø.\n;dimensions: ŠŠ»ŠøŃŠ°Ń Š·Š° Š·Š°ŃŠ°ŃŠ½ŠøŠ½Š°.\n;sha1: ŠŠ¾Š“Š°Š²Š° ŃŠ°ŃŠ°Š±Š° SHA-1 Š·Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾.\n;mime: ŠŠ¾Š“Š°Š²Š° MIME-ŃŠøŠæ Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾.\n;thumbmime: ŠŠ¾Š“Š°Š²Š° MIME-ŃŠøŠæ Š°Š½ Š¼ŠøŠ½ŠøŃŠ°ŃŃŃŠ°ŃŠ° Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾ (Š±Š°ŃŠ° URL-Š°Š“ŃŠµŃŠ° Šø ŠæŠ°ŃŠ°Š¼ŠµŃŠ°ŃŠ¾Ń $1urlwidth).\n;mediatype: ŠŠ¾ Š“Š¾Š“Š°Š²Š° Š¼ŠµŠ“ŠøŃŠ¼ŃŠŗŠøŠ¾Ń ŃŠøŠæ Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾.\n;metadata: ŠŃŠæŠøŃŃŠ²Š° Exif-Š¼ŠµŃŠ°ŠæŠ¾Š“Š°ŃŠ¾ŃŠø Š·Š° Š²ŠµŃŠ·ŠøŃŠ°ŃŠ° Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾.\n;commonmetadata: ŠŃŠæŠøŃŃŠ²Š° Š¾ŠæŃŃŠø Š¼ŠµŃŠ°ŠæŠ¾Š“Š°ŃŠ¾ŃŠø Š½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠ½ŠøŠ¾Ń ŃŠ¾ŃŠ¼Š°Ń Š·Š° Š²ŠµŃŠ·ŠøŃŠ°ŃŠ° Š½Š° Š²ŠøŠ“ŠµŠ¾ŃŠ¾.\n;extmetadata: ŠŃŠæŠøŃŃŠ²Š° ŃŠ¾ŃŠ¼Š°ŃŠøŃŠ°Š½Šø Š¼ŠµŃŠ°ŠæŠ¾Š“Š°ŃŠ¾ŃŠø ŃŠ¾Š±ŃŠ°Š½Šø Š¾Š“ ŠæŠ¾Š²ŠµŃŠµ ŠøŠ·Š²Š¾ŃŠø. Š ŠµŠ·ŃŠ»ŃŠ°ŃŠøŃŠµ ŃŠµ ŃŠ¾ŃŠ¼Š°ŃŠøŃŠ°Š½Šø Š²Š¾ HTML.\n;archivename: ŠŠ¾ Š“Š¾Š“Š°Š²Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŃŠ½Š¾ŃŠ¾ ŠøŠ¼Šµ Š½Š° Š°ŃŃ
ŠøŠ²ŃŠŗŠ°ŃŠ° Š²ŠµŃŠ·ŠøŃŠ° Š·Š° ŃŠøŃŠµ Š²ŠµŃŠ·ŠøŠø Š¾ŃŠ²ŠµŠ½ Š½Š°ŃŠ½Š¾Š²Š°ŃŠ°.\n;bitdepth: ŠŠ° Š“Š¾Š“Š°Š²Š° Š±ŠøŃŠ¾Š²Š°ŃŠ° Š“Š»Š°Š±Š¾ŃŠøŠ½Š° Š½Š° Š²ŠµŃŠ·ŠøŃŠ°ŃŠ°.\n;uploadwarning: Š”Šµ ŠŗŠ¾ŃŠøŃŃŠø Š½Š° ŃŃŃŠ°Š½ŠøŃŠ°ŃŠ° [[Special:Upload]] Š·Š° Š“Š¾Š±ŠøŠ²Š°ŃŠµ Š½Š° ŠøŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŠø Š·Š° ŠæŠ¾ŃŃŠ¾ŠµŃŠŗŠ° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°. ŠŠµ Šµ ŠæŃŠµŠ“Š²ŠøŠ“ŠµŠ½Š¾ Š·Š° ŃŠæŠ¾ŃŃŠµŠ±Š° Š²Š¾Š½ ŃŠ°Š“ŃŠ¾ŃŠ¾ Š½Š° ŠŠµŠ“ŠøŃŠ°ŠŠøŠŗŠø.\n;derivatives: ŠŠ¾Š“Š°Š²Š° Š½ŠøŠ·Š° Š¾Š“ ŃŠ°Š·Š»ŠøŃŠ½ŠøŠ¾Ń ŃŠ¾ŃŠ¼Š°Ń Šø ŃŠ°ŃŠæŠ¾Š»Š¾Š¶ŠøŠ²ŠøŃŠµ ŠŗŠ²Š°Š»ŠøŃŠµŃŠø Š½Š° Š°ŃŠ“ŠøŠ¾- ŠøŠ»Šø Š²ŠøŠ“ŠµŠ¾ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°ŃŠ°.", + "apihelp-query+videoinfo-example-1": "ŠŠ°Ń ŠøŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŠø Š·Š° [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "ŠŠ¾ŃŠøŃŠ½ŠøŃŠøŃŠµ ŃŠ¾ ŠæŃŠ°Š²Š¾ŃŠ¾ ātranscode-resetā Š¼Š¾Š¶Š°Ń Š“Š° Š³Šø Š²ŃŠ°ŃŠ°Š°Ń ŠæŠ¾ Š¾ŃŠ½Š¾Š²Š½Š¾ ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠ°ŃŠ° Šø Š“Š° Š³Šø Š²ŃŃŠ°Ń Š¾Š“Š½Š¾Š²Š¾.", + "apihelp-transcodereset-param-title": "ŠŠ°ŃŠ»Š¾Š² Š½Š° ŠæŠ¾Š“Š°ŃŠ¾ŃŠµŠŗŠ°ŃŠ°.", + "apihelp-transcodereset-param-transcodekey": "ŠŠ»ŃŃŠ¾Ń Š½Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾ ŃŃŠ¾ ŃŠ°ŠŗŠ°ŃŠµ Š“Š° Š³Š¾ ŠæŃŠµŠ·Š°Š“Š°Š“ŠµŃŠµ. ŠŃŠµŠ·ŠµŠ¼Šø Š¾Š“ [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "ŠŃŠ°ŃŠø Š³Šø ŠæŠ¾ Š¾ŃŠ½Š¾Š²Š½Š¾ ŃŠøŃŠµ ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠ° Š½Š° [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "ŠŃŠ°ŃŠø Š³Š¾ ŠæŠ¾ Š¾ŃŠ½Š¾Š²Š½Š¾ ŠŗŠ»ŃŃŠ¾Ń ā360_560kbs.webmā Š·Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµŃŠ¾ Š½Š° [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/ml.json b/extensions/TimedMediaHandler/i18n/ml.json new file mode 100644 index 00000000..0b04df45 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ml.json @@ -0,0 +1,124 @@ +{ + "@metadata": { + "authors": [ + "Praveenp", + "Shijualex", + "Vssun", + "Santhosh.thottingal" + ] + }, + "timedmedia-desc": "ą“ą“ąµ ą“¤ą“æą“Æąµą“±, ą“µąµąµ¼ą“¬ą“æą“øąµ, ą“ą“øąµ.ą“ąµ¼.ą“ą“æ, ą“µąµą“¬ąµą“ą“ ą“¤ąµą“ą“ąµą“ą“æą“Æą“µą“Æąµą“ąµą“ąµą“³ąµą“³ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æą“ą“ąµą“ą“®ąµą“³ąµą“³ ą“¶ą“¬ąµą“¦, ą“ą“²ą“ąµą“ą“æą“¤ąµą“°, ą“øą“®ą“Æą“®ą“Øąµą“øą“°ą“æą“ąµą“ąµ ą“Ŗąµą“°ą“¦ąµ¼ą“¶ą“æą“Ŗąµą“Ŗą“æą“ąµą“ąµą“Øąµą“Ø ą“ą““ąµą“¤ąµą“¤ąµą“ąµ¾ ą“ą“Øąµą“Øą“æą“µą“Æąµą“ąµą“ąµą“³ąµą“³ ą“ąµą“ą“¾ą“°ąµą“Æąµą“Ŗą“ą“°ą“£ą“", + "timedmedia-ogg-short-audio": "ą“ą“ąµ $1 ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $2", + "timedmedia-ogg-short-video": "ą“ą“ąµ $1 ą“µąµą“”ą“æą“Æąµ ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $2", + "timedmedia-ogg-short-general": "ą“ą“ąµ $1 ą“®ąµą“”ą“æą“Æ ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $2", + "timedmedia-ogg-long-audio": "ą“ą“ąµ $1 ą“¶ą“¬ąµą“¦ ą“Ŗąµą“°ą“®ą“¾ą“£ą“, ą“¦ąµąµ¼ą“ąµą“Æą“ $2, $3", + "timedmedia-ogg-long-video": "ą“ą“ąµ $1 ą“µąµą“”ą“æą“Æąµ ą“Ŗąµą“°ą“®ą“¾ą“£ą“, ą“¦ąµąµ¼ą“ąµą“Æą“ $2, $4Ć$5 ą“¬ą“æą“Øąµą“¦ąµ, $3", + "timedmedia-ogg-long-multiplexed": "ą“ą“ąµ ą“®ąµ¾ą“ąµą“ą“æą“Ŗąµą“²ą“ąµą“øąµāāą“”ąµ ą“¶ą“¬ąµą“¦/ą“ą“²ą“ąµą“ą“æą“¤ąµą“° ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $1, ą“¦ąµąµ¼ą“ąµą“Æą“ $2, $4Ć$5 ą“¬ą“æą“Øąµą“¦ąµ, ą“ą“ąµą“ąµą“ąµą“ą“æ $3", + "timedmedia-ogg-long-general": "ą“ą“ąµ ą“®ąµą“”ą“æą“Æ ą“Ŗąµą“°ą“®ą“¾ą“£ą“, ą“¦ąµąµ¼ą“ąµą“Æą“ $2, $3", + "timedmedia-ogg-long-error": "ą“
ą“øą“¾ą“§ąµą“µą“¾ą“Æ ą“ą“ąµ ą“Ŗąµą“°ą“®ą“¾ą“£ą“: $1", + "timedmedia-ogg-long-no-streams": "ą“ą“ąµ ą“®ąµą“”ą“æą“Æ ą“Ŗąµą“°ą“®ą“¾ą“£ą“. ą“®ąµą“Øąµą“Øą“±ą“æą“Æą“æą“Ŗąµą“Ŗąµ: ą“ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æąµ½ ą“ą“Ŗą“Æąµą“ą“æą“ąµą“ą“æą“°ą“æą“ąµą“ąµą“Øąµą“Ø ą“ąµą“”ąµą“ąµą“ą“³ąµą“Øąµą“Øąµą“ ą“¤ą“æą“°ą“æą“ąµą“ą“±ą“æą“ąµą“ą“æą“ąµą“ą“æą“²ąµą“².", + "timedmedia-webm-short-video": "ą“µąµą“¬ąµą“ą“ $1 ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $2", + "timedmedia-webm-long-video": "ą“µąµą“¬ąµą“ą“ ą“¶ą“¬ąµą“¦/ą“ą“²ą“ąµą“ą“æą“¤ąµą“° ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $1, ą“¦ąµąµ¼ą“ąµą“Æą“ $2, $4 Ć $5 ą“¬ą“æą“Øąµą“¦ąµ, ą“ą“ąµą“ąµą“ąµą“ą“æ $3", + "timedmedia-flac-short-audio": "ą“«ąµą“²ą“¾ą“ąµ ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $1", + "timedmedia-flac-long-audio": "ą“«ąµą“²ą“¾ą“ąµ ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“, ą“¦ąµąµ¼ą“ąµą“Æą“ $1, ą“ą“ąµ $2", + "timedmedia-wav-short-audio": "ą“µąµą“µąµ ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $1", + "timedmedia-wav-long-audio": "ą“µąµą“µąµ ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“, ą“¦ąµąµ¼ą“ąµą“Æą“ $1, ą“ą“ąµ $2", + "timedmedia-wav-pcm-required": "ą“Ŗą“æ.ą“øą“æ.ą“ą“. (ą“Ŗąµ¾ą“øąµ ą“ą“”ą“æą“Æąµ ą“®ąµą“”ąµą“²ąµą“·ąµ») ą“µąµą“µąµ ą“®ą“¾ą“¤ąµą“°ą“®ąµ ą“
ą“Ŗąµāą“²ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“Øą“¾ą“µąµ.", + "timedmedia-mp4-short-video": "ą“ą“ą“Ŗą“æ4 $1 ą“µąµą“”ą“æą“Æąµ ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $2", + "timedmedia-mp4-long-video": "ą“ą“ą“Ŗą“æ4 ą“¶ą“¬ąµą“¦/ą“ą“²ą“ąµą“ą“æą“¤ąµą“° ą“Ŗąµą“°ą“®ą“¾ą“£ą“, $1, ą“¦ąµąµ¼ą“ąµą“Æą“ $2, $4 Ć $5 ą“¬ą“æą“Øąµą“¦ąµ, ą“ą“ąµą“ąµą“ąµą“ą“æ $3", + "timedmedia-no-player-js": "ą“ąµą“·ą“®ą“æą“ąµą“ąµą“, ą“¤ą“¾ą“ąµą“ą“³ąµą“ąµ ą“¬ąµą“°ąµą“øą“±ą“æąµ½ ą“ą“¾ą“µą“¾ą“øąµą“ąµą“°ą“æą“Ŗąµą“±ąµą“±ąµ ą“øą“ąµą“ą“®ą“¾ą“ąµą“ą“æą“Æą“æą“ąµą“ą“æą“²ąµą“² ą“
ą“²ąµą“²ąµą“ąµą“ą“æąµ½ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“³ąµą“³ ą“Ŗąµą“²ąµą“Æąµ¼ ą“²ą“ąµą“Æą“®ą“²ąµą“².<br />\ną“¤ą“¾ą“ąµą“ąµ¾ą“ąµą“ąµ <a href=\"$1\">ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ą“¾ą“ą“ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“µąµą“Øąµą“Øą“¤ą“¾ą“£ąµ</a> ą“
ą“²ąµą“²ąµą“ąµą“ą“æąµ½ ą“¬ąµą“°ąµą“øą“±ą“æąµ½ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“ąµą“ą“¾ą“Øą“¾ą“Æą“æ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą“ą“°ąµ ą“Ŗąµą“²ąµą“Æąµ¼ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“µąµą“Øąµą“Øą“¤ą“¾ą“£ąµ</a>.", + "timedmedia-more": "ą“ąµą“ąµą“¤ąµ½...", + "timedmedia-dismiss": "ą“
ą“ą“Æąµą“ąµą“ąµą“", + "timedmedia-download": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“", + "timedmedia-play-media": "ą“®ąµą“”ą“æą“Æ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“æą“Ŗąµą“Ŗą“æą“ąµą“ąµą“", + "timedmedia-desc-link": "ą“ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ąµą“ąµą“ąµą“±ą“æą“ąµą“ąµ", + "timedmedia-oggThumb-version": "ą“ą“ąµ-ą“¤ą“®ąµą“Ŗąµ ą“Ŗą“¤ą“æą“Ŗąµą“Ŗąµ $1 ą“
ą“²ąµą“²ąµą“ąµą“ą“æąµ½ ą“Ŗąµą“¤ą“æą“Æą“¤ąµ ą“ą“ąµ-ą“¹ą“¾ąµ»ą“”ąµą“²ą“±ą“æą“Øą“¾ą“µą“¶ąµą“Æą“®ą“¾ą“£ąµ.", + "timedmedia-oggThumb-failed": "ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ ą“øąµą“·ąµą“ą“æą“ąµą“ąµą“Øąµą“Øą“¤ą“æąµ½ ą“ą“ąµ-ą“¤ą“®ąµą“Ŗąµ ą“Ŗą“°ą“¾ą“ą“Æą“Ŗąµą“Ŗąµą“ąµą“ąµ.", + "timedmedia-status-header": "ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“øąµą“„ą“æą“¤ą“æ", + "timedmedia-update-status": "ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“øąµą“„ą“æą“¤ą“æ ą“Ŗąµą“¤ąµą“ąµą“ąµą“", + "timedmedia-status": "ą“øąµą“„ą“æą“¤ą“æ", + "timedmedia-status-unknown": "ą“
ą“Ŗą“°ą“æą“ą“æą“¤ą“®ą“¾ą“Æ ą“øąµą“„ą“æą“¤ą“æ", + "timedmedia-transcodeinfo": "ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“µąµą“Æąµąµ½ą“Ŗąµą“Ŗą“Øąµą“Øą“¤ąµą“¤ą“æą“Øąµą“±ąµ ą“µą“æą“µą“°ą“£ą“", + "timedmedia-actions": "ą“Ŗąµą“°ą“µąµą“¤ąµą“¤ą“æą“ąµ¾", + "timedmedia-direct-link": "ą“µąµą“Æąµąµ½ą“Ŗąµą“Ŗą“Øąµą“Øą“ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“", + "timedmedia-not-ready": "ą“¤ą“Æąµą“Æą“¾ą“±ą“¾ą“Æą“æą“ąµą“ą“æą“²ąµą“²", + "timedmedia-completed-on": "ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµ½ ą“Ŗąµąµ¼ą“¤ąµą“¤ą“æą“Æą“¾ą“Æą“æ $1", + "timedmedia-error-on": "ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“ąµą“Æąµą“Æą“²ą“æąµ½ $1 ą“ą“Øąµą“Ø ą“øą“®ą“Æą“¤ąµą“¤ąµ ą“Ŗą“æą““ą“µąµą“£ąµą“ą“¾ą“Æą“æ", + "timedmedia-started-transcode": "ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµ½ $1 ą“®ąµą“®ąµą“Ŗąµ ą“ą“°ą“ą“ą“æą“ąµą“ąµ. $2", + "timedmedia-percent-done": "ą“ą“ą“¦ąµą“¶ą“ $1% ą“Ŗąµąµ¼ą“¤ąµą“¤ą“æą“Æą“¾ą“Æą“æ", + "timedmedia-in-job-queue": "ą“ąµą“¬ąµ ą“ąµą“Æąµą“µą“æą“²ąµą“Æąµą“ąµą“ąµ $1 ą“®ąµą“®ąµą“Ŗąµ ą“ąµąµ¼ą“¤ąµą“¤ąµ", + "timedmedia-unknown-target-size": "ą“²ą“ąµą“·ąµą“Æą“®ą“æą“ąµą“Øąµą“Ø ą“µą“²ą“æą“Ŗąµą“Ŗą“ ą“
ą“±ą“æą“Æą“æą“²ąµą“², $1 ą“ąµ»ą“ąµą“”ąµ ą“ąµą“Æąµą“¤ąµ", + "timedmedia-days": "{{PLURAL:$1|ą“ą“°ąµ ą“¦ą“æą“µą“øą“|$1 ą“¦ą“æą“µą“øą“}}", + "timedmedia-hours": "{{PLURAL:$1|ą“ą“°ąµ ą“®ą“£ą“æą“ąµą“ąµąµ¼|$1 ą“®ą“£ą“æą“ąµą“ąµąµ¼}}", + "timedmedia-minutes": "{{PLURAL:$1|ą“ą“°ąµ ą“®ą“æą“Øą“æą“±ąµą“±ąµ|$1 ą“®ą“æą“Øą“æą“±ąµą“±ąµ}}", + "timedmedia-seconds": "{{PLURAL:$1|ą“ą“°ąµ ą“øąµą“ąµą“ą“Øąµą“±ąµ|$1 ą“øąµą“ąµą“ą“Øąµą“±ąµ}}", + "timedmedia-reset": "ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµ½ ą“Ŗąµą“Øą“ą“øą“ąµą“ąµą“ą“°ą“æą“ąµą“ąµą“", + "timedmedia-reset-confirm": "ą“ ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµ½ ą“Ŗąµą“Øą“ą“øą“ąµą“ąµą“ą“°ą“æą“ąµą“ąµą“®ąµą“Ŗąµąµ¾ ą“Øą“æą“²ą“µą“æą“²ąµą“³ąµą“³ ą“«ą“Æąµ½ (ą“
ą“ąµą“ą“Øąµą“Æąµą“Øąµą“Øąµą“£ąµą“ąµą“ąµą“ą“æąµ½) ą“Øąµą“ąµą“ą“ ą“ąµą“Æąµą“Æą“Ŗąµą“Ŗąµą“ąµą“, ą“ą“Ŗąµą“Ŗą“ ą“
ą“¤ąµ ą“ąµą“¬ąµ ą“ąµą“Æąµą“µą“æą“²ąµą“Æąµą“ąµą“ąµ ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ąµ» ą“µąµą“£ąµą“ąµą“ ą“ąµąµ¼ą“ąµą“ą“Ŗąµą“Ŗąµą“ąµą“ą“Æąµą“ ą“ąµą“Æąµą“Æąµą“. ą“µąµą“£ąµą“ąµą“-ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ąµ» ą“
ą“²ąµą“Ŗą“øą“®ą“Æą“®ąµą“ąµą“ąµą“ąµą“Øąµą“Øą“¤ą“¾ą“£ąµ. <br /><br />\ną“¤ąµą“ą“°ą“£ą“®ąµą“Øąµą“Øąµ ą“¤ą“¾ą“ąµą“ąµ¾ą“ąµą“ąµą“±ą“Ŗąµą“Ŗą“¾ą“£ąµ?", + "timedmedia-reset-error": "ą“ąµą“°ą“¾ąµ»ą“øąµāą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµ½ ą“Ŗąµą“Øą“ą“øą“ąµą“ąµą“ą“°ą“æą“ąµą“ąµą“Øąµą“Øą“¤ą“æąµ½ ą“Ŗą“æą““ą“µąµą“£ąµą“ą“¾ą“Æą“æ.", + "timedmedia-ogg": "ą“ą“ąµ", + "timedmedia-webm": "ą“µąµą“¬ąµą“ą“", + "timedmedia-mp4": "ą“ą“ą“Ŗą“æ4", + "timedmedia-source-file": "$1 ą“øąµą“°ąµą“¤ą“øąµą“øąµ", + "timedmedia-source-file-desc": "ą“Æą“„ą“¾ąµ¼ą“¤ąµą“„ ą“Ŗąµą“°ą“®ą“¾ą“£ą“ $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ą“Æą“„ą“¾ąµ¼ą“¤ąµą“„ ą“Ŗąµą“°ą“®ą“¾ą“£ą“ $1 ($2)", + "timedmedia-derivative-160p.ogv": "ą“ą“ąµ 160ą“Ŗą“æ", + "timedmedia-derivative-desc-160p.ogv": "ą“ąµą“±ą“ąµą“ ą“¬ą“¾ąµ»ą“”ąµāą“µą“æą“”ąµą“¤ąµ ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ (160ą“¬ą“æ)", + "timedmedia-derivative-desc-240p.ogv": "ą“µąµą“¬ą“æą“²ąµą“ąµ ą“ą“ąµą“ąµą“ą“¾ą“µąµą“Øąµą“Ø ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ (240P)", + "timedmedia-derivative-360p.ogv": "ą“ą“ąµ 360ą“Ŗą“æ", + "timedmedia-derivative-desc-360p.ogv": "ą“µąµą“¬ą“æą“²ąµą“ąµ ą“ą“ąµą“ąµą“ą“¾ą“µąµą“Øąµą“Ø ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ (360ą“¬ą“æ)", + "timedmedia-derivative-480p.ogv": "ą“ą“ąµ 480ą“Ŗą“æ", + "timedmedia-derivative-desc-480p.ogv": "ą“µąµą“¬ą“æą“²ąµą“ąµ ą“ą“ąµą“ąµą“ą“¾ą“µąµą“Øąµą“Ø ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ (480ą“¬ą“æ)", + "timedmedia-derivative-720p.ogv": "ą“ą“ąµ 720ą“Ŗą“æ", + "timedmedia-derivative-desc-720p.ogv": "ą“ą“Øąµą“Øą“¤ ą“ąµą“£ą“®ąµą“Øąµą“®ą“Æą“æąµ½ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“µąµą“Øąµą“Ø ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ (720ą“¬ą“æ)", + "timedmedia-derivative-desc-1080p.ogv": "ą“Ŗąµąµ¼ą“£ąµą“£ ą“ą“ąµą“ąµ.ą“”ą“æ. ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“µąµą“Øąµą“Ø ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ (1080 ą“Ŗą“æ)", + "timedmedia-derivative-160p.webm": "ą“µąµą“¬ąµą“ą“ 160ą“Ŗą“æ", + "timedmedia-derivative-desc-160p.webm": "ą“µąµą“¬ą“æą“²ąµą“ąµ ą“ą“ąµą“ąµą“ą“¾ą“µąµą“Øąµą“Ø ą“µąµą“¬ąµą“ą“ (160ą“¬ą“æ)", + "timedmedia-derivative-360p.webm": "ą“µąµą“¬ąµą“ą“ 360ą“Ŗą“æ", + "timedmedia-derivative-desc-360p.webm": "ą“µąµą“¬ą“æą“²ąµą“ąµ ą“ą“ąµą“ąµą“ą“¾ą“µąµą“Øąµą“Ø ą“µąµą“¬ąµą“ą“ (360ą“¬ą“æ)", + "timedmedia-derivative-480p.webm": "ą“µąµą“¬ąµą“ą“ 480ą“Ŗą“æ", + "timedmedia-derivative-desc-480p.webm": "ą“µąµą“¬ą“æą“²ąµą“ąµ ą“ą“ąµą“ąµą“ą“¾ą“µąµą“Øąµą“Ø ą“µąµą“¬ąµą“ą“ (360ą“¬ą“æ)", + "timedmedia-derivative-720p.webm": "ą“µąµą“¬ąµą“ą“ 720ą“Ŗą“æ", + "timedmedia-derivative-desc-720p.webm": "ą“ą“Øąµą“Øą“¤ ą“ąµą“£ą“®ąµą“Øąµą“®ą“Æą“æąµ½ ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“µąµą“Øąµą“Ø ą“µąµą“¬ąµą“ą“ (720ą“¬ą“æ)", + "timedmedia-derivative-desc-1080p.webm": "ą“Ŗąµąµ¼ą“£ąµą“£ ą“ą“ąµą“ąµ.ą“”ą“æ. ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“µąµą“Øąµą“Ø ą“µąµą“¬ąµą“ą“ (1080 ą“Ŗą“æ)", + "timedmedia-derivative-desc-320p.mp4": "ą“ą“Ŗą“ą“°ą“£-ą“øąµą“¹ąµą“¦ąµ ą“ą“ą“Ŗą“æ4 (320ą“¬ą“æ)", + "timedmedia-derivative-desc-480p.mp4": "ą“µąµą“¬ą“æą“²ąµą“ąµ ą“ą“ąµą“ąµą“ą“¾ą“µąµą“Øąµą“Ø ą“ą“ą“Ŗą“æ4 (480ą“¬ą“æ)", + "timedmedia-derivative-desc-720p.mp4": "ą“ą“ąµą“ąµ.ą“”ą“æ. ą“ąµą“£ą“®ąµą“Øąµą“®ą“Æąµą“³ąµą“³ ą“ą“ą“Ŗą“æ4 (720ą“¬ą“æ)", + "timedmedia-derivative-desc-1080p.mp4": "ą“Ŗąµąµ¼ą“£ąµą“£ ą“ą“ąµą“ąµ.ą“”ą“æ. ą“”ąµąµŗą“²ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“µąµą“Øąµą“Ø ą“ą“ą“Ŗą“æ4 (1080 ą“Ŗą“æ)", + "timedmedia-derivative-ogg": "ą“ą“ąµ ą“µąµąµ¼ą“¬ą“æą“øąµ", + "timedmedia-derivative-desc-ogg": "ą“ą“ąµ ą“µąµąµ¼ą“¬ą“æą“øąµ", + "timedmedia-derivative-opus": "ą“ą“Ŗą“øąµ", + "timedmedia-derivative-desc-opus": "ą“ą“Ŗą“øąµ", + "timedmedia-derivative-mp3": "ą“ą“.ą“Ŗą“æ.3", + "timedmedia-derivative-desc-mp3": "ą“ą“.ą“Ŗą“æ.3", + "timedmedia-derivative-m4a": "ą“.ą“.ą“øą“æ.", + "timedmedia-derivative-desc-m4a": "ą“.ą“.ą“øą“æ.", + "timedmedia-subtitle-new": "ą“Ŗąµą“¤ą“æą“Æ ą“Ŗą“°ą“æą“ą“¾ą“· ą“¤ąµą“ą“ąµą“ąµą“ ą“
ą“²ąµą“²ąµą“ąµą“ą“æąµ½ ą“Øą“æą“²ą“µą“æą“²ąµą“³ąµą“³ą“¤ąµ ą“¤ą“æą“°ąµą“¤ąµą“¤ąµą“", + "timedmedia-subtitle-new-desc": "ą“ą“¾ą“· ą“¤ą“æą“°ą“ąµą“ąµą“ąµą“¤ąµą“¤ąµ, '''{{int:Timedmedia-subtitle-new-go}}''' ą“¬ą“ąµą“ąµŗ ą“
ą“®ąµ¼ą“¤ąµą“¤ąµą“", + "timedmedia-subtitle-new-go": "ą“Ŗąµą“ąµ", + "timedmedia-subtitle-language": "$1 ($2) ą“øą“ą“ą“¾ą“·ą“£ą“°ąµą“ą“ąµ¾", + "timedmedia-subtitle-no-video": "ą“ą“Ŗąµą“Ŗąµą““ą“¤ąµą“¤ąµ ą“øą“ą“ą“¾ą“·ą“£ą“°ąµą“ą“¾ ą“¤ą“¾ą“³ąµą“®ą“¾ą“Æą“æ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ąµą“ą“³ąµą“Øąµą“Øąµą“ ą“ąµąµ¼ą“¤ąµą“¤ą“æą“ąµą“ą“æą“²ąµą“²", + "timedmedia-subtitle-no-subtitles": "ą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“¤ąµą“¤ą“æą“Øąµ $1 ą“ą“¾ą“·ą“Æą“æąµ½ ą“ą“Ŗąµą“Ŗąµąµ¾ ą“øą“ą“ą“¾ą“·ą“£ą“°ąµą“ą“Æąµą“Øąµą“Øąµą“ ą“ą“²ąµą“², ą“¤ą“¾ą“ąµą“ąµ¾ą“ąµą“ąµ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ą“ ą“¤ą“¾ąµ¾ ą“¤ą“æą“°ąµą“¤ąµą“¤ą“æ] ą“
ą“µ ą“ąµą“ąµą“ą“æą“ąµą“ąµąµ¼ą“ąµą“ą“¾ą“µąµą“Øąµą“Øą“¤ą“¾ą“£ąµ", + "timedmedia-subtitle-remote": "ą“ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“Øąµą“³ąµą“³ ą“øą“®ą“Æą“®ą“Øąµą“øą“°ą“æą“ąµą“ąµą“³ąµą“³ ą“ą““ąµą“¤ąµą“¤ąµ $1-ąµ½ ą“¹ąµą“øąµą“±ąµą“±ąµ ą“ąµą“Æąµą“¤ą“æą“ąµą“ąµą“£ąµą“ąµ.", + "timedmedia-subtitle-remote-link": "ą“ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“Øąµą“³ąµą“³ [$1 ą“µą“æą“µą“°ą“£ ą“¤ą“¾ąµ¾] $2-ąµ½ ą“¤ą“¾ą“ąµą“ąµ¾ą“ąµą“ąµ ą“ą“¾ą“£ą“¾ą“µąµą“Øąµą“Øą“¤ą“¾ą“£ąµ", + "timedmediahandler": "ą“®ąµą“”ą“æą“Æ ą“øą“®ą“Æą“®ą“Øąµą“øą“°ą“æą“ąµą“ąµ ą“ąµą“ą“¾ą“°ąµą“Æą“ ą“ąµą“Æąµą“Æą“¾ą“Øąµą“³ąµą“³ą“Æąµą“Ŗą“ą“°ą“£ą“", + "timedmedia-videos": "{{PLURAL:$1|ą“ą“°ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“|$1 ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ąµą“ąµ¾}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|ą“ą“°ąµ ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“|$1 ą“ą“ąµ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ąµą“ąµ¾}}", + "timedmedia-webm-videos": "{{PLURAL:$1|ą“ą“°ąµ ą“µąµą“¬ąµą“ą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“|$1 ą“µąµą“¬ąµą“ą“ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ąµą“ąµ¾}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|ą“ą“°ąµ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ|$1 ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµą“ąµ¾}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|ą“ą“°ąµą“£ąµą“£ą“ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“Øąµą“Øąµ|$1 ą“ą“£ąµą“£ą“ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“Øąµą“Øąµ}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|ą“ą“°ąµą“£ąµą“£ą“ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“Øą“¾ą“Æą“æ ą“ą“£ąµą“ąµ|$1 ą“ą“£ąµą“£ą“ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ ą“ąµą“Æąµą“Æą“¾ą“Øą“¾ą“Æą“æ ą“ą“£ąµą“ąµ}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|ą“ą“°ąµą“£ąµą“£ą“ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“Øąµą“Øą“¤ąµ ą“Ŗą“°ą“¾ą“ą“Æą“Ŗąµą“Ŗąµą“ąµą“ąµ|$1 ą“ą“£ąµą“£ą“ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ ą“ąµą“Æąµą“Æąµą“Øąµą“Øą“¤ąµ ą“Ŗą“°ą“¾ą“ą“Æą“Ŗąµą“Ŗąµą“ąµą“ąµ}}", + "timedmedia-file": "ą“Ŗąµą“°ą“®ą“¾ą“£ą“", + "timedmedia-audios": "{{PLURAL:$1|ą“ą“°ąµ ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“|$1 ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“ąµą“ąµ¾}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|ą“ą“°ąµ ą“ą“ąµ (Ogg) ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“|$1 ą“ą“ąµ (Ogg) ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“ąµą“ąµ¾}}", + "timedmedia-flac-audios": "{{PLURAL:$1|ą“ą“°ąµ ą“«ąµą“²ą“¾ą“ąµ (FLAC) ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“|$1 ą“«ąµą“²ą“¾ą“ąµ (FLAC) ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“ąµą“ąµ¾}}", + "timedmedia-wav-audios": "{{PLURAL:$1|ą“ą“°ąµ ą“µąµą“µąµ (WAV) ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“|$1 ą“µąµą“µąµ (WAV) ą“¶ą“¬ąµą“¦ą“Ŗąµą“°ą“®ą“¾ą“£ą“ąµą“ąµ¾}}", + "right-transcode-reset": "ą“Ŗąµą“Øą“ą“ąµą“°ą“®ąµą“ą“°ą“£ą“ ą“Ŗą“°ą“¾ą“ą“Æą“Ŗąµą“Ŗąµą“ąµą“ąµ ą“
ą“²ąµą“²ąµą“ąµą“ą“æąµ½ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ ą“ąµą“Æąµą“¤ ą“ą“²ą“ąµą“ą“æą“¤ąµą“°ą“ąµą“ąµ¾ ą“ąµą“¬ąµ ą“ąµą“Æąµą“µą“æą“²ąµą“Æąµą“ąµą“ąµ ą“µąµą“£ąµą“ąµą“ ą“ąµąµ¼ą“¤ąµą“¤ąµ", + "right-transcode-status": "[[Special:TimedMediaHandler|ą“ą“Ŗąµą“Ŗąµą““ą“¤ąµą“¤ąµ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ąµ ą“Ŗąµą“°ą“µąµ¼ą“¤ąµą“¤ą“Øą“¤ąµą“¤ą“æą“Øąµą“±ąµ ą“µą“æą“µą“°ą“ąµą“ąµ¾]] ą“ą“¾ą“£ąµą“", + "action-transcode-status": "ą“ą“Ŗąµą“Ŗąµą““ą“¤ąµą“¤ąµ ą“ąµą“°ą“¾ąµ»ą“øąµą“ąµą“”ą“æą“ąµ ą“øąµą“„ą“æą“¤ą“æ ą“ą“¾ą“£ąµą“", + "orphanedtimedtext": "ą“ą“Ŗą“Æąµą“ą“æą“ąµą“ą“Ŗąµą“Ŗąµą“ą“¾ą“¤ąµą“¤ ą“øą“®ą“Æą“¾ą“Øąµą“øąµą“¤ą“Æąµą““ąµą“¤ąµą“¤ąµ ą“¤ą“¾ą“³ąµą“ąµ¾", + "orphanedtimedtext-summary": "ą“¬ą“Øąµą“§ą“Ŗąµą“Ŗąµą“ąµą“ ą“Ŗąµą“°ą“®ą“¾ą“£ą“ąµą“ąµ¾ ą“ą“²ąµą“²ą“¾ą“¤ąµą“¤ [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] ą“¤ą“¾ą“³ąµą“ą“³ąµą“ąµ ą“Ŗą“ąµą“ą“æą“.", + "orphanedtimedtext-unsupported": "ą“®ąµą“ą“øąµą“ąµą“Æąµą“ąµ½ ą“”ąµą“±ąµą“±ą“¾ą“¬ąµą“øąµą“ą“³ąµ ą“®ą“¾ą“¤ąµą“°ą“®ąµ ą“ ą“Ŗąµą“°ą“¤ąµą“Æąµą“ą“¤ą“¾ąµ¾ ą“Ŗą“æą“Øąµą“¤ąµą“£ą“Æąµą“ąµą“ąµą“Øąµą“Øąµą“³ąµą“³ąµ.", + "orphanedtimedtext-notimedtext": "ą“øą“®ą“Æą“¾ą“Øąµą“øąµą“¤ą“Æąµą““ąµą“¤ąµą“¤ąµ ą“ ą“µą“æą“ąµą“ą“æą“Æą“æąµ½ ą“øą“ąµą“ą“®ą“¾ą“ąµą“ą“æą“Æą“æą“ąµą“ą“æą“²ąµą“².", + "apihelp-transcodereset-param-title": "ą“®ąµą“”ą“æą“Æ ą“Ŗąµą“°ą“®ą“¾ą“£ą“¤ąµą“¤ą“æą“Øąµą“±ąµ ą“¤ą“²ą“ąµą“ąµą“ąµą“ąµ." +} diff --git a/extensions/TimedMediaHandler/i18n/mr.json b/extensions/TimedMediaHandler/i18n/mr.json new file mode 100644 index 00000000..0be5fe88 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/mr.json @@ -0,0 +1,28 @@ +{ + "@metadata": { + "authors": [ + "Kaustubh", + "V.narsikar", + "Htt" + ] + }, + "timedmedia-desc": "ą¤ą¤ ą¤„ą¤æą¤Æą„ą¤°ą¤¾ ą¤µ ą¤µą„ą¤°ą„ą¤¬ą¤æą¤ø ą¤øą¤ą¤ą¤æą¤ą¤¾ą¤ą¤øą¤¾ą¤ ą„ą¤ą¤¾ ą¤ą¤¾ą¤²ą¤, ą¤ą¤¾ą¤µą¤¾ą¤øą„ą¤ą„ą¤°ą„ą¤Ŗą„ą¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤øą¤ą¤", + "timedmedia-ogg-short-audio": "ą¤ą¤ $1 ą¤§ą„ą¤µą¤Øą„ ą¤øą¤ą¤ą¤æą¤ą¤¾, $2", + "timedmedia-ogg-short-video": "ą¤ą¤ $1 ą¤ą¤²ą¤¤ą¤ą¤æą¤¤ą„ą¤° ą¤øą¤ą¤ą¤æą¤ą¤¾, $2", + "timedmedia-ogg-short-general": "ą¤ą¤ $1 ą¤®ą„ą¤”ą¤æą¤Æą¤¾ ą¤øą¤ą¤ą¤æą¤ą¤¾, $2", + "timedmedia-ogg-long-audio": "ą¤ą¤ $1 ą¤§ą„ą¤µą¤Øą„ ą¤øą¤ą¤ą¤æą¤ą¤¾, ą¤²ą¤¾ą¤ą¤¬ą„ $2, $3", + "timedmedia-ogg-long-video": "ą¤ą¤ $1 ą¤ą¤²ą¤¤ą¤ą¤æą¤¤ą„ą¤° ą¤øą¤ą¤ą¤æą¤ą¤¾, ą¤²ą¤¾ą¤ą¤¬ą„ $2, $4Ć$5 ą¤Ŗą„ą¤ą„ą¤øą„ą¤²ą„ą¤ø, $3", + "timedmedia-ogg-long-multiplexed": "ą¤ą¤ ą¤§ą„ą¤µą¤Øą„/ą¤ą¤æą¤¤ą„ą¤° ą¤øą¤ą¤ą¤æą¤ą¤¾, $1, ą¤²ą¤¾ą¤ą¤¬ą„ $2, $4Ć$5 ą¤Ŗą¤æą¤ą„ą¤øą„ą¤²ą„ą¤ø, $3 ą¤ą¤ą„ą¤£", + "timedmedia-ogg-long-general": "ą¤ą¤ ą¤®ą„ą¤”ą¤æą¤Æą¤¾ ą¤øą¤ą¤ą¤æą¤ą¤¾, ą¤²ą¤¾ą¤ą¤¬ą„ $2, $3", + "timedmedia-ogg-long-error": "ą¤ą„ą¤ą„ą¤ą„ ą¤ą¤ ą¤øą¤ą¤ą¤æą¤ą¤¾: $1", + "timedmedia-more": "ą¤ą¤£ą¤ą„...", + "timedmedia-dismiss": "ą¤¬ą¤ą¤¦ ą¤ą¤°ą¤¾", + "timedmedia-download": "ą¤øą¤ą¤ą¤æą¤ą¤¾ ą¤
ą¤§ą¤æą¤ą¤¾ą¤°ą¤£ ą¤ą¤°ą¤¾", + "timedmedia-desc-link": "ą¤Æą¤¾ ą¤øą¤ą¤ą¤æą¤ą„ą¤¬ą¤¦ą„ą¤¦ą¤²ą¤ą„ ą¤®ą¤¾ą¤¹ą¤æą¤¤ą„", + "timedmedia-source-file": "$1 ą¤øą„ą¤°ą„ą¤¤", + "timedmedia-source-audio-file-desc": "ą¤®ą„ą¤³ $1 ą¤øą¤ą¤ą¤æą¤ą¤¾ ($2)", + "timedmediahandler": "ą¤ą¤¾ą¤ą¤®ą„ą¤”ą¤®ą¤æą¤”ą¤æą¤Æą¤¾ą¤¹ą„
ą¤ą¤”ą¤²ą¤°", + "timedmedia-videos": "{{PLURAL:$1|$1 ą¤µą„ą¤¹ą„ą¤”ą¤æą¤}}", + "timedmedia-audios": "{{PLURAL:$1|$1 ą¤§ą„ą¤µą¤Øą„ ą¤øą¤ą¤ą¤æą¤ą¤¾}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg ą¤§ą„ą¤µą¤Øą„ ą¤øą¤ą¤ą¤æą¤ą¤¾}}" +} diff --git a/extensions/TimedMediaHandler/i18n/ms.json b/extensions/TimedMediaHandler/i18n/ms.json new file mode 100644 index 00000000..504aa6f0 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ms.json @@ -0,0 +1,97 @@ +{ + "@metadata": { + "authors": [ + "Anakmalaysia", + "Aviator" + ] + }, + "timedmedia-desc": "Pemproses audio, video dan teks bermasa, dengan sokongan format untuk WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "fail bunyi Ogg $1, $2", + "timedmedia-ogg-short-video": "fail video Ogg $1, $2", + "timedmedia-ogg-short-general": "fail media Ogg $1, $2", + "timedmedia-ogg-long-audio": "fail bunyi Ogg $1, tempoh $2, $3", + "timedmedia-ogg-long-video": "fail video Ogg $1, tempoh $2, $4Ć$5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "fail audio/video multipleks Ogg, $1, tempoh $2, $4Ć$5 piksel, keseluruhan $3", + "timedmedia-ogg-long-general": "fail media Ogg, tempoh $2, $3", + "timedmedia-ogg-long-error": "Fail Ogg tidak sah: $1", + "timedmedia-webm-short-video": "fail video WebM $1, $2", + "timedmedia-webm-long-video": "fail audio/video webM, $1, tempoh $2, $4Ć$5 piksel, $3 keseluruhannya", + "timedmedia-flac-short-audio": "Fail audio FLAC, $1", + "timedmedia-flac-long-audio": "Fail audio FLAC, tempoh $1, $2 keseluruhannya", + "timedmedia-wav-short-audio": "Fail audio WAV, $1", + "timedmedia-wav-long-audio": "Fail audio WAV, tempoh $1, $2 keseluruhannya", + "timedmedia-wav-pcm-required": "Anda boleh memuat naik WAV PCM (Pulse Code Modulation) sahaja.", + "timedmedia-mp4-short-video": "fail video MP4 $1, $2", + "timedmedia-mp4-long-video": "fail audio/video MP4, $1, tempoh $2, $4Ć$5 piksel, $3 keseluruhannya", + "timedmedia-no-player-js": "Maaf, pelayar anda sama ada telah dimatikan JavaScript-nya ataupun tidak mempunyai sebarang pemain yang disokong.<br />\nAnda boleh <a href=\"$1\">memuat turun sedutan</a> itu atau <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">memuat turun pemain</a> yang boleh memutarkan sedutan berkenaan dalam pelayar anda.", + "timedmedia-more": "Lagiā¦", + "timedmedia-dismiss": "Tutup", + "timedmedia-download": "Muat turun fail", + "timedmedia-play-media": "Mainkan media", + "timedmedia-desc-link": "Perihal fail ini", + "timedmedia-oggThumb-version": "OggHandler memerlukan oggThumb versi $1 ke atas.", + "timedmedia-oggThumb-failed": "oggThumb gagal mencipta gambar kenit.", + "timedmedia-status-header": "Status transkod", + "timedmedia-update-status": "Kemaskinikan status transkod", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Status tidak diketahui", + "timedmedia-transcodeinfo": "Keterangan hasil terbitan transkod", + "timedmedia-actions": "Tindakan", + "timedmedia-direct-link": "Muat turun terbitan", + "timedmedia-not-ready": "Belum sedia", + "timedmedia-completed-on": "Pentranskodan selesai pada $1", + "timedmedia-error-on": "Ralat dalam transkod pada $1", + "timedmedia-started-transcode": "Pentranskodan bermula $1 lalu. $2", + "timedmedia-percent-done": "Kira-kira $1% selesai", + "timedmedia-in-job-queue": "Ditambahkan ke dalam baris gilir kerja $1 lalu", + "timedmedia-unknown-target-size": "Saiz sasaran tidak diketahui, $1 dikodkan", + "timedmedia-days": "$1 hari", + "timedmedia-hours": "$1 jam", + "timedmedia-minutes": "$1 minit", + "timedmedia-seconds": "$1 saat", + "timedmedia-reset": "Set semula transkod", + "timedmedia-reset-confirm": "Mengeset semula transkod ini akan membuang sebarang fail yang sedia ada (jika ada), lalu menambahkan semula transkod ke dalam baris gilir tugas. Pentranskodan semula akan memakan masa.<br /><br />Adakah anda tetap ingin melakukannya?", + "timedmedia-reset-error": "Ralat ketika mengeset semula tugas pentranskodan.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Sumber $1", + "timedmedia-source-file-desc": "Fail $1 asli, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Fail $1 asli ($2)", + "timedmedia-derivative-desc-160p.ogv": "Video Ogg lebar jalur rendah (160P)", + "timedmedia-derivative-desc-360p.ogv": "Video Ogg boleh strim web (360P)", + "timedmedia-derivative-desc-480p.ogv": "Video Ogg boleh strim web (480P)", + "timedmedia-derivative-desc-720p.ogv": "Video Ogg boleh muat turun bermutu tinggi (720P)", + "timedmedia-derivative-desc-1080p.ogv": "video Ogg HD sepenuhnya yang boleh dimuat turun (1080P)", + "timedmedia-derivative-desc-160p.webm": "WebM boleh strim web (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM boleh strim web (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM boleh strim web (480P)", + "timedmedia-derivative-desc-720p.webm": "Video WebM boleh muat turun bermutu tinggi (720P)", + "timedmedia-derivative-desc-1080p.webm": "WebM HD sepenuhnya yang boleh dimuat turun (1080P)", + "timedmedia-derivative-desc-320p.mp4": "MP4 mesra peranti (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 boleh strim web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 bermutu HD (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4 bermutu HD sepenuhnya (1080P)", + "timedmedia-subtitle-new": "Buat terjemahan baru atau sunting terjemahan sedia ada", + "timedmedia-subtitle-new-desc": "Pilih bahasa dan tekan butang '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Pergi", + "timedmedia-subtitle-language": "Sari kata $1 ($2)", + "timedmedia-subtitle-no-video": "Tiada video yang berkaitan dengan halaman sari kata ini", + "timedmedia-subtitle-no-subtitles": "Sekarang, tiada sari kata dalam $1 bagi video ini; anda boleh [{{fullurl:{{FULLPAGENAME}}|action=edit}} menyunting halaman ini] untuk menambahkannya", + "timedmedia-subtitle-remote": "Teks termasa untuk fail ini dihoskan di $1", + "timedmedia-subtitle-remote-link": "Anda boleh [$1 membaca halaman keterangan] untuk fail ini di $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "$1 video", + "timedmedia-ogg-videos": "$1 video Ogg", + "timedmedia-webm-videos": "$1 video WebM", + "timedmedia-derivative-state-transcodes": "$1 transkod", + "timedmedia-derivative-state-active": "$1 transkod aktif", + "timedmedia-derivative-state-queued": "$1 transkod berbaris", + "timedmedia-derivative-state-failed": "$1 transkod gagal", + "timedmedia-file": "Fail", + "timedmedia-audios": "$1 fail audio", + "timedmedia-ogg-audios": "$1 fail audio Ogg", + "timedmedia-flac-audios": "$1 fail audio FLAC", + "timedmedia-wav-audios": "$1 fail audio WAV", + "right-transcode-reset": "Mengeset semula video-video yang gagal atau ditranskodkan supaya dimasukkan semula ke dalam barisan gilir.", + "right-transcode-status": "Melihat [[Special:TimedMediaHandler|maklumat tentang kegiatan transkod semasa]]", + "action-transcode-status": "melihat status pentranskodan semasa" +} diff --git a/extensions/TimedMediaHandler/i18n/mt.json b/extensions/TimedMediaHandler/i18n/mt.json new file mode 100644 index 00000000..a60fd776 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/mt.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Leli Forte" + ] + }, + "timedmedia-no-player-js": "JiddispjaÄina li l-browser tiegħek jew m'għandux JavaScript attivat jew m'għandu l-ebda player supportat.<br />\nTista' <a href=\"$1\"> tniżżel il-vidjow</a> jew <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">tniżżel player</a> biex tara l-vidjow fuq il-browser tiegħek.", + "timedmedia-more": "Aktar", + "timedmedia-source-file": "Sors $1", + "timedmedia-source-audio-file-desc": "Fajl oriÄ”inali $1 ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/myv.json b/extensions/TimedMediaHandler/i18n/myv.json new file mode 100644 index 00000000..35b195ae --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/myv.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Botuzhaleny-sodamo" + ] + }, + "timedmedia-more": "Š”ŠµŠ“Šµ Š»Š°Š¼Š¾...", + "timedmedia-dismiss": "ŠŠµŠŗŃŃŠ°Š¼Ń", + "timedmedia-download": "Š¢Š°ŃŠ³Š°Š¼Š¾ ŃŠ°Š¹Š»Š°", + "timedmedia-play-media": "Š”ŠµŠ“ŃŠ¼Š¾ Š¼ŠµŠ“ŠøŃ", + "timedmedia-desc-link": "Š¢Šµ ŃŠ°Š¹Š»Š°Š“Š¾Š½ŃŃ", + "timedmedia-source-file": "$1 Š»ŠøŃŃŠ¼Š°ŠæŃŃ" +} diff --git a/extensions/TimedMediaHandler/i18n/mzn.json b/extensions/TimedMediaHandler/i18n/mzn.json new file mode 100644 index 00000000..f383daec --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/mzn.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Ł
ŲŚ©" + ] + }, + "timedmedia-no-player-js": "ŲØŁŲ®Ų“ŁŁŁŪŲ Ų¬Ų§ŁŲ§ Ų§Ų³Ś©Ų±ŪŁ¾ŲŖ ŁŁŲ±Ł
Ų§ŁŲ²Ų§Ų± Ų“Ł
Ł ŲØŲ±ŁŲ²Ų± ŲÆŁŁ ŁŲ¹Ų§Ł ŁŪāŪŁŲ ŪŲ§ Ų“Ł
Ł ŲØŲ±ŁŲ²Ų± Ų§ŪŁ ŁŲ±Ł
Ų§ŁŲ²Ų§Ų± Ų±Ł Ų³Ų§Ł¾ŁŲ±ŲŖ ŁŚ©Ų§ŁŲÆŁ.<br />\nŲ“Ł
Ų§ ŲŖŁŁŲÆŪ <a href=\"$1\">Ų§ŪŁ ŁŪŲÆŪŁ Ų±Ł ŲÆŲ§ŁŁŁŲÆ</a> Ł ŪŲ§ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Ų§ŲŖŲ§ Ł¾ŁŪŲ±</a> Ų§ŪŁ ŁŪŲÆŪŁ Ų±Ł ŁŲ§Ų±Ų“ŪāŪŁ ŁŲ³ŁŁ ŲÆŲ§ŁŁŁŲÆ ŁŲ§Ś©ŁŪŁ.", + "timedmedia-source-file": "$1 Ł
ŲØŲÆŲ£", + "timedmedia-source-audio-file-desc": "Ų§ŲµŁŪ $1 Ł¾Ų±ŁŁŲÆŁ ( $2 )" +} diff --git a/extensions/TimedMediaHandler/i18n/nah.json b/extensions/TimedMediaHandler/i18n/nah.json new file mode 100644 index 00000000..5c41b6ca --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/nah.json @@ -0,0 +1,12 @@ +{ + "@metadata": { + "authors": [ + "Fluence", + "Taresi" + ] + }, + "timedmedia-more": "Huehca Åmpa...", + "timedmedia-download": "TictemÅz tlahcuilÅlli", + "timedmedia-desc-link": "InÄ«n tlahcuilÅltechcopa", + "timedmedia-source-file": "$1 mÄyalli" +} diff --git a/extensions/TimedMediaHandler/i18n/nap.json b/extensions/TimedMediaHandler/i18n/nap.json new file mode 100644 index 00000000..c9953c8f --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/nap.json @@ -0,0 +1,122 @@ +{ + "@metadata": { + "authors": [ + "C.R.", + "Chelin", + "Candalua" + ] + }, + "timedmedia-desc": "Gestore p' 'e file audio, video e teste temporizzate, cu 'e formate supportate pe WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "File audio Ogg $1, $2", + "timedmedia-ogg-short-video": "File video Ogg $1, $2", + "timedmedia-ogg-short-general": "File multimediale Ogg $1, $2", + "timedmedia-ogg-long-audio": "File audio Ogg $1, durata $2, $3", + "timedmedia-ogg-long-video": "File video Ogg $1, durata $2, dimenziune $4Ć$5 pixel, $3", + "timedmedia-ogg-long-multiplexed": "File multiplexed audie e video Ogg $1, lunghezze $2, $4 x $5 pixel, $3 in totale", + "timedmedia-ogg-long-general": "File media Ogg, lunghezze $2, $3", + "timedmedia-ogg-long-error": "Ogg file invalide: $1", + "timedmedia-ogg-long-no-streams": "File multimediale Ogg. AttenziĆ²: nun ĆØ stato ricanusciuto nisciuno codec ausato ind'a stu file.", + "timedmedia-webm-short-video": "WebM $1 file video, $2", + "timedmedia-webm-long-video": "File WebM audio/video, $1, lunghezze $2, $4 Ć $5 pixel, $3 in totale", + "timedmedia-flac-short-audio": "File audio FLAC, $1", + "timedmedia-flac-long-audio": "File audio FLAC, lunghezze $1, in totale $2", + "timedmedia-wav-short-audio": "File audio WAV, $1", + "timedmedia-wav-long-audio": "File audio WAV, lunghezze $1, in totale $2", + "timedmedia-wav-pcm-required": "Putite surtanto carrecĆ WAV 'e tipo PCM (Codece 'e Modulazione Pulsate).", + "timedmedia-mp4-short-video": "MP4 $1 file video, $2", + "timedmedia-mp4-long-video": "File MP4 audio/video, $1, lunghezze $2, $4 Ć $5 pixel, $3 in totale", + "timedmedia-no-player-js": "Spiacente, 'o browser vuosto tene 'o JavaScript stutato o nun tĆØne nu secutore suppurtato.<br />\nPutite <a href=\"$1\">scarrecĆ 'o video</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">scarrecĆ nu secutore</a> pe' putĆØ miette 'o play Ć“ video int' 'o browser vuosto.", + "timedmedia-more": "Ato...", + "timedmedia-dismiss": "Chiure", + "timedmedia-download": "Scarreca 'o file", + "timedmedia-play-media": "Secuta 'u media", + "timedmedia-desc-link": "'Mfurmaziune ncopp'a stu file", + "timedmedia-oggThumb-version": "OggHandler vulesse 'a verziona 'e oggThumb $1 o cchiĆ¹ nnanz.", + "timedmedia-oggThumb-failed": "oggThumn ha fallite a ccriĆ 'e miniature.", + "timedmedia-status-header": "Stato d' 'a codifeca", + "timedmedia-update-status": "Agghiuorna 'o stato d' 'a codifeca", + "timedmedia-status": "Stato", + "timedmedia-status-unknown": "Stato scanusciuto", + "timedmedia-transcodebitrate": "Bitrate", + "timedmedia-transcodeduration": "Tiempo 'e codifeca", + "timedmedia-transcodeinfo": "Furmato", + "timedmedia-actions": "Aziune", + "timedmedia-direct-link": "Scarreca", + "timedmedia-not-ready": "Nun ĆØ pronto", + "timedmedia-completed-on": "$1 fernuto", + "timedmedia-error-on": "Errore dint' 'o $1", + "timedmedia-started-transcode": "Accummenciato $1 fa. $2", + "timedmedia-percent-done": "CchiĆ¹ o meno $1% fatto", + "timedmedia-in-job-queue": "Ghiuonta a 'a Fatica misa ncĆ³ra $1 fĆ ", + "timedmedia-unknown-target-size": "Diminziona 'e destinazione scanusciuta, $1 encoded", + "timedmedia-days": "{{PLURAL:$1|1 juorno|$1 ghiuorne}}", + "timedmedia-hours": "{{PLURAL:$1|n'ora|$1 ore}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuto|$1 minute}}", + "timedmedia-seconds": "{{PLURAL:$1|1 secondo|$1 seconde}}", + "timedmedia-reset": "Azzere 'a transcodifeca", + "timedmedia-reset-confirm": "Resettanno sta transcodifica tuttuquante 'e file ch'esisteno mĆ² (si ce stanno), e po' azzeccasse 'a transcodifica int'a 'o codece d' 'a fatica. Se pigliasse nu poco 'e tiempo pe' putĆ© ffĆ 'o re-transcode. <br /><br />\nSite sicuro/a ca vulite ghƬ annanze?", + "timedmedia-reset-error": "Errore pe' tramente ca se steva azzeranno 'a fatica 'e transcodifeca.", + "timedmedia-source-file": "$1 funte", + "timedmedia-source-file-desc": "File origgenale $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "File origgenale $1 ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg video cu banda vascia (160P)", + "timedmedia-derivative-desc-240p.ogv": "Ogg video ca se putesse mannĆ pe' webstreaming (240P)", + "timedmedia-derivative-desc-360p.ogv": "Ogg video ca se putesse mannĆ pe' webstreaming (360P)", + "timedmedia-derivative-desc-480p.ogv": "Ogg video ca se putesse mannĆ pe' webstreaming (480P)", + "timedmedia-derivative-desc-720p.ogv": "Ogg video 'e qualitĆ auta scarrecabbele (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Video Ogg scarrecabbele 'n Full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "Flusso web WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "Flusse web WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "Flusse web WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "Ogg video 'e qualitĆ auta scarrecabbele WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "Video Ogg scarrecabbele 'n Full HD WebM (1080P)", + "timedmedia-derivative-desc-2160p.webm": "WebM scarrecabbele 'n Full 4K (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "Flusse web WebM VP9 (360P)", + "timedmedia-derivative-desc-480p.vp9.webm": "Flusse web WebM (480P)", + "timedmedia-derivative-desc-720p.vp9.webm": "Flusse HD WebM VP9 (720P)", + "timedmedia-derivative-desc-1080p.vp9.webm": "Flusse Full HD WebM VP9 (1080P)", + "timedmedia-derivative-desc-2160p.vp9.webm": "WebM VP9 'e qualitĆ Full 4K (2160P)", + "timedmedia-derivative-desc-320p.mp4": "Semprice pe' ll'apparicchie MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Flusse web WebM (480P)", + "timedmedia-derivative-desc-720p.mp4": "QualitĆ HD MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4 'e qualitĆ Full HD (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "MP4 'e qualitĆ Full 4K (2160P)", + "timedmedia-subtitle-new": "CrƬa na traduzione o cagna chella esistente", + "timedmedia-subtitle-new-desc": "Sceglie na lengua e clicca 'o buttone '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "VĆ je", + "timedmedia-subtitle-language": "$1 ($2) sottotitele", + "timedmedia-subtitle-no-video": "Nun ce stanno video ssuocie ch' 'e sottotitole d' 'e paggene 'e mĆ².", + "timedmedia-subtitle-no-subtitles": "Nun ce stanno mĆ² sottotitule dint'a $1 pe' stu video, putite [{{fullurl:{{FULLPAGENAME}}|action=cagnĆ }} 'a paggena] pe' putĆØ azzeccĆ chiste.", + "timedmedia-subtitle-remote": "'O testo temporizzate pe' stu file fuje ospitato ncopp'a $1", + "timedmedia-subtitle-remote-link": "Putite [$1 vedĆ© 'a paggena 'e descrizione] 'e stu file ncopp'a $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 video}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 video Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 video WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodifica|$1 transcodifiche}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodifica|$1 transcodifiche}} in esecuzzione", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodifica|$1 transcodifiche}} in coda", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 guastaje transcodifeca|$1 guastaje 'e transcodifiche}}", + "timedmedia-file": "File", + "timedmedia-audios": "{{PLURAL:$1|$1 file audio}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 file audio Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 file audio FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 file audio WAV}}", + "right-transcode-reset": "Appiccia n'ata vota 'e transcodifiche guaste 'e video ca songo state mise dint'a cĆ³ra 'e fatiche n'ata vota", + "right-transcode-status": "Vide [[Special:TimedMediaHandler|'e nfurmaziune ncopp' 'a transcodifeca 'e mĆ²]]", + "action-transcode-status": "vide 'o stato 'e transcodifeca 'e mo", + "orphanedtimedtext": "Paggene TimedText (sottotitule) urfanielle", + "orphanedtimedtext-summary": "Elenco 'e pagine [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] ca nun teneno 'o file currispunnente.", + "orphanedtimedtext-unsupported": "Sta paggena speciale ĆØ surtanto suppurtata dint' 'e database MySQL.", + "orphanedtimedtext-notimedtext": "'O TimedText (sottotitule) nun songo abbiĆ te dint'a stu wiki.", + "apihelp-query+transcodestatus-description": "Piglia 'o stato 'e transcodifeca pe' na paggena data.", + "apihelp-query+transcodestatus-example-1": "Piglia 'o stato transcode pe' [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "Spanne imageinfo pe' putĆØ nzertĆ 'e nfurmaziune fonte 'e video (derivative)", + "apihelp-query+videoinfo-param-prop": "Che nfurmaziune se pigliasse 'o video:\n;timestamp:Azzecca 'a timestamp p' 'e verziune carrecate.\n;user:Azzecca l'utente c'avesse fatto l'upload dint'a verziona 'e video.\n;userid:Azzecca l'ID utente ca carrecaje sta verziona 'e video.\n;comment:Nu cummento ncopp' 'a verziona.\n;parsedcomment:Passa-scagna 'o cummento dint'a verziona.\n;canonicaltitle:Azzecca 'o titulo canonico 'e stu file 'e video.\n;url:Mpizzasse n'URL dint'o video e 'a paggena 'e descriziona.\n;size:Azzeccasse 'a pesantezza d' 'o file comm'a nu valore 'n byte, l'auto e 'o luongo suojo. 'O cunt' 'e paggene e 'a durata songo azzeccate si apprecabbele.\n;dimensions:Aliasse pe diminziona.\n;sha1:Azzecca nu hash SHA-1 p' 'o video video.\n;mime:Azzecca 'o tipo MIME d' 'o video.\n;thumbmime:Azzecca 'o tipo MIME p' 'o video thumbnail (servesse n'url e 'o param $1urlwidth).\n;mediatype:Azzecca 'o tipo 'e media dint' 'o video.\n;metadata:Elenca 'e metadate Exif p' 'a verziona d' 'o video.\n;commonmetadata:Elenca nu furmat' 'e file generico 'e metadate p' 'a verziona d' 'o video.\n;extmetadata:Elenca 'e date furmattate metadata cumbinate 'a fonte differente. 'E risultate songo HTML furmattate.\n;archivename:Azzecca 'o filename (nomm' 'e file) 'e sta verziona archivio pe' verziune ca nun fossero ll'urdema.\n;bitdepth:Azzecca 'o prufunno 'e bit d' 'a verziona.\n;uploadwarning:Ausato p' 'a paggena [[Special:Upload]] pe' se pigliĆ nfurmaziune ncopp'a nu file ch'esiste mĆ². Nun ce buĆ² stu coso pe' putĆØ ausĆ 'o file for' 'o core 'e MediaWiki.\n;derivatives:Azzecca n'array 'e furmate differente cu qualitĆ e verziune 'audio o video ca fosse mĆ² a disposizione.", + "apihelp-query+videoinfo-example-1": "Arrepiglia mĆ² 'e nfurmaziune ncopp' 'o [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "Utente c' 'o deritto 'e 'transcode-reset' putessero resettĆ e secutĆ n'ata vota na fatica 'e transcodifeca.", + "apihelp-transcodereset-param-title": "'O titolo d' 'o file media.", + "apihelp-transcodereset-param-transcodekey": "'A chiave 'e transcodifeca ca vulite re-appicciĆ . Arrepiglia mĆ² [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "Re-appiccia tuttuquante transcodes pe' [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "Re-appiccia 'a chiave 'e transcodifeca '360_560kbs.webm' pe' [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/nb.json b/extensions/TimedMediaHandler/i18n/nb.json new file mode 100644 index 00000000..7a32ec0a --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/nb.json @@ -0,0 +1,105 @@ +{ + "@metadata": { + "authors": [ + "Danmichaelo", + "Laaknor", + "Nghtwlkr" + ] + }, + "timedmedia-desc": "HĆ„ndteringsprogram for lyd, video og tidsbestemt tekst, med formatstĆøtte for WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 lydfil, $2", + "timedmedia-ogg-short-video": "Ogg $1 videofil, $2", + "timedmedia-ogg-short-general": "Ogg $1 mediefil, $2", + "timedmedia-ogg-long-audio": "Ogg $1 lydfil, lengde $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videofil, lengde $2, $4Ć$5 piksler, $3", + "timedmedia-ogg-long-multiplexed": "Sammensatt ogg lyd-/videofil, $1, lengde $2, $4Ć$5 piksler, $3 til sammen", + "timedmedia-ogg-long-general": "Ogg mediefil, lengde $2, $3", + "timedmedia-ogg-long-error": "Ugyldig Ogg-fil: $1", + "timedmedia-ogg-long-no-streams": "Ogg-mediafil. Advarsel: Ingen av omkoderne brukt i denne filen ble gjenkjent.", + "timedmedia-webm-short-video": "WebM $1 videofil, $2", + "timedmedia-webm-long-video": "WebM lyd-/videofil, $1, lengde $2, $4 Ć $5 piksler, $3 til sammen", + "timedmedia-flac-short-audio": "FLAC-lydfil, $1", + "timedmedia-flac-long-audio": "FLAC-lydfil, varighet $1, $2 totalt", + "timedmedia-wav-short-audio": "WAV-lydfil, $1", + "timedmedia-wav-long-audio": "WAV-lydfil, varighet $1, $2 totalt", + "timedmedia-wav-pcm-required": "Du kan kun laste opp PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "MP4 $1 videofil, $2", + "timedmedia-mp4-long-video": "MP4-fil for lyd/video, $1, lengde $2, $4 Ć $5 piksler, $3 totalt", + "timedmedia-no-player-js": "Beklager, nettleseren din har enten deaktivert JavaScript eller har ingen stĆøttet spiller.<br />\nDu kan <a href=\"$1\">laste ned klippet</a> eller <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">laste ned en spiller</a> for Ć„ spille av klippet i nettleseren din.", + "timedmedia-more": "Mer ā¦", + "timedmedia-dismiss": "Lukk", + "timedmedia-download": "Last ned fil", + "timedmedia-play-media": "Spill av media", + "timedmedia-desc-link": "Om denne filen", + "timedmedia-oggThumb-version": "OggHandler krever oggThumb versjon $1 eller senere.", + "timedmedia-oggThumb-failed": "oggThumb klarte ikke Ć„ opprette miniatyrbildet.", + "timedmedia-status-header": "Omkodingsstatus", + "timedmedia-update-status": "Oppdater omkodingsstatus", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Ukjent status", + "timedmedia-transcodeinfo": "Beskrivelse", + "timedmedia-actions": "Handlinger", + "timedmedia-direct-link": "Last ned utgave", + "timedmedia-not-ready": "Ikke klar", + "timedmedia-completed-on": "Omkoding ferdig $1", + "timedmedia-error-on": "Omkoding feilet den $1", + "timedmedia-started-transcode": "Omkoding startet for $1 siden. $2", + "timedmedia-percent-done": "Rundt $1% ferdig", + "timedmedia-in-job-queue": "Lagt til i jobbkĆø for $1 siden", + "timedmedia-unknown-target-size": "Ukjent mĆ„lstĆørrelse, $1 ferdig kodet", + "timedmedia-days": "{{PLURAL:$1|1 dag|$1 dager}}", + "timedmedia-hours": "{{PLURAL:$1|1 time|$1 timer}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minutt|$1 minutter}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekund|$1 sekunder}}", + "timedmedia-reset": "Nullstill omkoding", + "timedmedia-reset-confirm": "Nullstilling av denne omkodingsjobben vil slette eksisterende filer (hvis det er noen), og gjeninnsette omkodingsjobben i jobbkĆøen. Dette vil naturligvis ta noe tid.<br /><br />\nEr du sikker pĆ„ at du Ćønsker Ć„ fortsette?", + "timedmedia-reset-error": "Det oppsto en feil ved forsĆøk pĆ„ Ć„ nullstille omkodingsjobben.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 kilde", + "timedmedia-source-file-desc": "Original $1-fil, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Original $1-fil ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg-video for lav bĆ„ndbredde (160P)", + "timedmedia-derivative-desc-360p.ogv": "Nett-strĆømbar Ogg-video (360P)", + "timedmedia-derivative-desc-480p.ogv": "Nett-strĆømbar Ogg-video (480P)", + "timedmedia-derivative-desc-720p.ogv": "HĆøykvalitets nedlastbar Ogg-video (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Nedlastbar Ogg-video i full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "Nett-strĆømbar WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "Nett-strĆømbar WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "Nett-strĆømbar WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "HĆøykvalitets nedlastbar WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "Nedlastbar WebM-video i full HD (1080P)", + "timedmedia-derivative-desc-320p.mp4": "Mobilvennlig MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Nett-strĆømbar MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD-kvalitet MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4-video i full HD (1080P)", + "timedmedia-subtitle-new": "Opprett ny oversettelse eller rediger eksisterende", + "timedmedia-subtitle-new-desc": "Velg sprĆ„k eller trykk pĆ„ '''{{int:Timedmedia-subtitle-new-go}}'''-knappen", + "timedmedia-subtitle-new-go": "KjĆør", + "timedmedia-subtitle-language": "$1 ($2) undertekster", + "timedmedia-subtitle-no-video": "Det finnes ingen video koblet til den aktuelle undertekstsiden", + "timedmedia-subtitle-no-subtitles": "Det er for Ćøyeblikket ingen undertekster pĆ„ $1 for denne videoen. Du kan [{{fullurl:{{FULLPAGENAME}}|action=edit}} redigere denne siden] for Ć„ legge de til", + "timedmedia-subtitle-remote": "Undertekster (timed text) for denne filen befinner seg pĆ„ $1", + "timedmedia-subtitle-remote-link": "Du kan [$1 vise beskrivelsessiden] for denne filen pĆ„ $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 videoer}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg-video|$1 Ogg-videoer}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM-video|$1 WebM-videoer}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 omkoding|$1 omkodinger}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 pĆ„gĆ„ende omkoding|$1 pĆ„gĆ„ende omkodinger}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 omkoding|$1 omkodinger}} i kĆø", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 omkoding|$1 omkodinger}} feilet", + "timedmedia-file": "Fil", + "timedmedia-audios": "{{PLURAL:$1|$1 lydfil|$1 lydfiler}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg-lydfil|$1 Ogg-lydfiler}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC-lydfil|$1 FLAC-lydfiler}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV-lydfil|$1 WAV-lydfiler}}", + "right-transcode-reset": "Nullstill feilede eller omkodede videoer sĆ„ de blir gjeninnsatt i jobbkĆøen.", + "right-transcode-status": "Vis [[Special:TimedMediaHandler|informasjon om pĆ„gĆ„ende omkodinger]]", + "action-transcode-status": "vise pĆ„gĆ„ende omkodingsstatus", + "orphanedtimedtext": "ForeldrelĆøse TimedText-sider", + "orphanedtimedtext-summary": "Liste over [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]]-sider som ikke har tilknytning til noen fil.", + "orphanedtimedtext-unsupported": "Denne spesialsiden er kun stĆøttet for MySQL-databaser.", + "orphanedtimedtext-notimedtext": "TimedText er ikke pĆ„skrudd pĆ„ denne wikien.", + "apihelp-query+transcodestatus-description": "Hent transkodingsstatus for en gitt filside.", + "apihelp-query+transcodestatus-example-1": "Hent transkodingsstatus for [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/nds-nl.json b/extensions/TimedMediaHandler/i18n/nds-nl.json new file mode 100644 index 00000000..f785cf7c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/nds-nl.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Servien" + ] + }, + "timedmedia-desc": "Haandelt audio, video en ondertitels aof mit ondersteuning veur WebM, Ogg Theora, Vorbis en srt", + "timedmedia-ogg-short-audio": "Ogg $1 geluudsbestaand, $2", + "timedmedia-ogg-short-video": "Ogg $1 videobestaand, $2", + "timedmedia-ogg-short-general": "Ogg $1 mediabestaand, $2", + "timedmedia-ogg-long-audio": "Ogg $1 geluudsbestaand, lengte $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videobestaand, lengte $2, $4Ć$5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "Ogg-emultiplext geluuds-/videobestaand, $1, lengte $2, $4Ć$5 pixels, $3 totaal", + "timedmedia-ogg-long-general": "Ogg-mediabestaand, lengte $2, $3", + "timedmedia-ogg-long-error": "Ongeldig Ogg-bestaand: $1", + "timedmedia-no-player-js": "Joew systeem hef JavaScript uutstaon of der is gien ondersteunde mediaspeuler.<br />\nJe kunnen <a href=\"$1\">de klip neerlaojen</a> of <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">n mediaspeuler neerlaojen</a> um de klip aof te speulen in joew webkieker.", + "timedmedia-more": "Meer...", + "timedmedia-dismiss": "Sluten", + "timedmedia-download": "Bestaand neerlaojen", + "timedmedia-desc-link": "Over dit bestaand", + "timedmedia-source-file": "Bron van $1", + "timedmedia-source-audio-file-desc": "Oorspronkelik $1-bestaand ($2)", + "timedmediahandler": "Timed Media Handler" +} diff --git a/extensions/TimedMediaHandler/i18n/nds.json b/extensions/TimedMediaHandler/i18n/nds.json new file mode 100644 index 00000000..b8404001 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/nds.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Slomox" + ] + }, + "timedmedia-desc": "StĆ¼Ć¼rprogramm fƶr Ogg-Theora- un Vorbis Datein, mitsamt en Afspeler in JavaScript", + "timedmedia-ogg-short-audio": "Ogg-$1-Toondatei, $2", + "timedmedia-ogg-short-video": "Ogg-$1-Videodatei, $2", + "timedmedia-ogg-short-general": "Ogg-$1-Mediendatei, $2", + "timedmedia-ogg-long-audio": "Ogg-$1-Toondatei, $2 lang, $3", + "timedmedia-ogg-long-video": "Ogg-$1-Videodatei, $2 lang, $4Ć$5 Pixels, $3", + "timedmedia-ogg-long-multiplexed": "Ogg-Multiplexed-Audio-/Video-Datei, $1, $2 lang, $4Ć$5 Pixels, $3 alltohoop", + "timedmedia-ogg-long-general": "Ogg-Mediendatei, $2 lang, $3", + "timedmedia-ogg-long-error": "Kaputte Ogg-Datei: $1", + "timedmedia-more": "Mehr...", + "timedmedia-dismiss": "Dichtmaken", + "timedmedia-download": "Datei dalladen", + "timedmedia-desc-link": "Ćver disse Datei" +} diff --git a/extensions/TimedMediaHandler/i18n/ne.json b/extensions/TimedMediaHandler/i18n/ne.json new file mode 100644 index 00000000..acf3a5d1 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ne.json @@ -0,0 +1,25 @@ +{ + "@metadata": { + "authors": [ + "ą¤øą¤°ą„ą¤ ą¤ą„ą¤®ą¤¾ą¤° ą¤¢ą¤ą¤¾ą¤²", + "ą¤¬ą¤æą¤Ŗą„ą¤²ą¤¬ ą¤ą¤Øą¤Øą„ą¤¦", + "NehalDaveND", + "ą¤°ą¤¾ą¤® ą¤Ŗą„ą¤°ą¤øą¤¾ą¤¦ ą¤ą„ą¤¶ą„" + ] + }, + "timedmedia-ogg-short-audio": "Ogg $1 ą¤§ą„ą¤µą¤Øą¤æ ą¤«ą¤¾ą¤ą¤², $2", + "timedmedia-ogg-short-video": "Ogg $1 ą¤µą¤æą¤”ą¤æą¤Æą„ ą¤«ą¤¾ą¤ą¤², $2", + "timedmedia-ogg-short-general": "Ogg $1 ą¤®ą„ą¤”ą¤æą¤Æą¤¾ ą¤«ą¤¾ą¤ą¤², $2", + "timedmedia-no-player-js": "ą¤®ą¤¾ą¤« ą¤ą¤°ą„ą¤Øą„ą¤¹ą„ą¤²ą¤¾, ą¤¤ą¤Ŗą¤¾ą¤ą¤ą¤ą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤°ą¤®ą¤¾ ą¤Æą¤¾ ą¤¤ ą¤ą¤¾ą¤µą¤¾ą¤øą„ą¤ą„ą¤°ą¤æą¤Ŗą„ą¤ ą¤
ą¤ą„ą¤·ą¤® ą¤ ą¤Æą¤¾ ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤ą„ą¤Ø ą„¤<br />\ną¤¤ą¤Ŗą¤¾ą¤ą¤ <a href=\"$1\">ą¤ą„ą¤²ą¤æą¤Ŗą¤²ą¤¾ą¤ ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤°ą„ą¤Ø ą¤øą¤ą„ą¤Øą„ą¤¹ą„ą¤Øą„ą¤ ą¤
ą¤„ą¤µą¤¾ ą¤ą„ą¤²ą¤æą¤Ŗą¤²ą¤¾ą¤ ą¤ą¤«ą„ą¤Øą„ ą¤¬ą„ą¤°ą¤¾ą¤ą¤ą¤°ą¤®ą¤¾ ą¤ą¤²ą¤¾ą¤ą¤Øą¤ą„ ą¤²ą¤¾ą¤ą¤æ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¤ą¤ ą¤Ŗą„ą¤²ą„ą¤Æą¤° ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤”</a> ą¤ą¤°ą„ą¤Ø ą¤øą¤ą„ą¤Øą„ ą¤¹ą„ą¤Øą„ą¤ ą„¤", + "timedmedia-more": "ą¤„ą¤Ŗ...", + "timedmedia-dismiss": "ą¤¬ą¤Øą„ą¤§ ą¤ą¤°ą„ą¤Øą„", + "timedmedia-download": "ą¤”ą¤¾ą¤ą¤Øą¤²ą„ą¤” ą¤ą¤°ą„ą¤Øą„ ą¤«ą¤¾ą¤ą¤²", + "timedmedia-status": "ą¤øą„ą¤„ą¤æą¤¤ą¤æ", + "timedmedia-status-unknown": "ą¤
ą¤ą„ą¤ą¤¾ą¤¤ ą¤øą„ą¤„ą¤æą¤¤ą¤æ", + "timedmedia-actions": "ą¤ą¤¾ą¤°ą„ą¤Æą¤¹ą¤°ą„", + "timedmedia-source-file": "$1 ą¤¶ą„ą¤°ą„ą¤¤", + "timedmedia-source-file-desc": "ą¤®ą„ą¤² $1 ą¤«ą¤¾ą¤ą¤², $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ą¤®ą„ą¤² $1 ą¤«ą¤¾ą¤ą¤² ($2)", + "timedmedia-subtitle-new-go": "ą¤ą¤¾ą¤Øą„", + "timedmedia-file": "ą¤«ą¤¾ą¤ą¤²" +} diff --git a/extensions/TimedMediaHandler/i18n/nl.json b/extensions/TimedMediaHandler/i18n/nl.json new file mode 100644 index 00000000..cfe2115f --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/nl.json @@ -0,0 +1,108 @@ +{ + "@metadata": { + "authors": [ + "McDutchie", + "SPQRobin", + "Siebrand", + "Romaine" + ] + }, + "timedmedia-desc": "Handelt audio, video en ondertitels af met ondersteuning voor WebM, Ogg Theora, Vorbis en srt", + "timedmedia-ogg-short-audio": "Ogg $1 geluidsbestand, $2", + "timedmedia-ogg-short-video": "Ogg $1 videobestand, $2", + "timedmedia-ogg-short-general": "Ogg $1 mediabestand, $2", + "timedmedia-ogg-long-audio": "Ogg $1 geluidsbestand, lengte $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videobestand, lengte $2, $4Ć$5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "Ogg gemultiplexed geluids/videobestand, $1, lengte $2, $4Ć$5 pixels, $3 totaal", + "timedmedia-ogg-long-general": "Ogg mediabestand, lengte $2, $3", + "timedmedia-ogg-long-error": "Ongeldig Ogg-bestand: $1", + "timedmedia-webm-short-video": "WebM $1 videobestand, $2", + "timedmedia-webm-long-video": "WebM audio/videobestand, $1, lengte $2, $4x$5 pixels, $3 totaal", + "timedmedia-flac-short-audio": "FLAC-audiobestand, $1", + "timedmedia-flac-long-audio": "FLAC-audiobestand, lengte $1, $2 gemiddeld", + "timedmedia-wav-short-audio": "WAV-audiobestand, $1", + "timedmedia-wav-long-audio": "WAV-audiobestand, lengte $1, $2 gemiddeld", + "timedmedia-wav-pcm-required": "U kunt alleen PCM (Pulse Code Modulation) WAV uploaden.", + "timedmedia-mp4-short-video": "MP4 $1 videobestand, $2", + "timedmedia-mp4-long-video": "MP4 audio/videobestand, $1, lengte $2, $4x$5 pixels, $3 totaal", + "timedmedia-no-player-js": "Uw systeem heeft JavaScript uitgeschakeld of er is geen ondersteunde mediaspeler.<br />\nU kunt <a href=\"$1\">de clip downloaden</a> of <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">een mediaspeler downloaden</a> om de clip af te spelen in uw browser.", + "timedmedia-more": "Meerā¦", + "timedmedia-dismiss": "Sluiten", + "timedmedia-download": "Bestand downloaden", + "timedmedia-play-media": "Media afspelen", + "timedmedia-desc-link": "Over dit bestand", + "timedmedia-oggThumb-version": "OggHandler vereist oggThumb versie $1 of hoger.", + "timedmedia-oggThumb-failed": "oggThumb kon geen miniatuur aanmaken.", + "timedmedia-status-header": "Conversiestatus", + "timedmedia-update-status": "Conversiestatus bijwerken", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Onbekende status", + "timedmedia-transcodeinfo": "Beschrijving van afgeleide conversie", + "timedmedia-actions": "Handelingen", + "timedmedia-direct-link": "Afgeleid werk downloaden", + "timedmedia-not-ready": "Niet klaar", + "timedmedia-completed-on": "Conversie voltooid op $1", + "timedmedia-error-on": "Fout in de conversie om $1", + "timedmedia-started-transcode": "De conversie is $1 geleden begonnen. $2", + "timedmedia-percent-done": "Ongeveer $1% afgerond", + "timedmedia-in-job-queue": "$1 geleden toegevoegd aan de Job queue", + "timedmedia-unknown-target-size": "Onbekende doelgrootte, $1 gecodeerd", + "timedmedia-days": "{{PLURAL:$1|1 dag|$1 dagen}}", + "timedmedia-hours": "{{PLURAL:$1|1 uur|$1 uur}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuut|$1 minuten}}", + "timedmedia-seconds": "{{PLURAL:$1|1 seconde|$1 seconden}}", + "timedmedia-reset": "Transcodering opnieuw instellen", + "timedmedia-reset-confirm": "Door de transcodering opnieuw in te stellen worden alle bestanden bestanden (als aanwezig) verwijderd en de transcodering wordt opnieuw toegevoegd aan de wachtrij. Transcoderen kost tijd.<br /><br />\nWeet u zeker dat u wilt doorgaan?", + "timedmedia-reset-error": "Er is een fout opgetreden tijdens het opnieuw instellen van de transcoderingstaak.", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Bron van $1", + "timedmedia-source-file-desc": "Origineel $1-bestand, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Origineel $1-bestand ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160P", + "timedmedia-derivative-desc-160p.ogv": "Lage bandbreedte Ogg video (160P)", + "timedmedia-derivative-360p.ogv": "Ogg 360P", + "timedmedia-derivative-desc-360p.ogv": "Te webstreamen Ogg video (360P)", + "timedmedia-derivative-480p.ogv": "Ogg 480P", + "timedmedia-derivative-desc-480p.ogv": "Te webstreamen Ogg video (480P)", + "timedmedia-derivative-720p.ogv": "Ogg 720P", + "timedmedia-derivative-desc-720p.ogv": "Hoge kwaliteit downloadbare Ogg video (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Full HD downloadbare Ogg video (1080P)", + "timedmedia-derivative-desc-160p.webm": "Web streamable WebM (160P)", + "timedmedia-derivative-360p.webm": "WebM 360P", + "timedmedia-derivative-desc-360p.webm": "Te webstreamen WebM (360P)", + "timedmedia-derivative-480p.webm": "WebM 480P", + "timedmedia-derivative-desc-480p.webm": "Te webstreamen WebM (480P)", + "timedmedia-derivative-720p.webm": "WebM 720P", + "timedmedia-derivative-desc-720p.webm": "Hoge kwaliteit downloadbare WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "Full HD downloadbare WebM (1080P)", + "timedmedia-derivative-desc-320p.mp4": "Apparaatvriendelijke MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Te webstreamen MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD-kwaliteit MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "Full HD-kwaliteit MP4 (1080P)", + "timedmedia-subtitle-new": "Nieuw vertaling maken of bestaande bewerken", + "timedmedia-subtitle-new-desc": "Selecteer een taal en klik op de knop '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "OK", + "timedmedia-subtitle-language": "Ondertitels in $1 ($2)", + "timedmedia-subtitle-no-video": "Er is geen video gekoppeld aan de huidige ondertitelpagina", + "timedmedia-subtitle-no-subtitles": "Er zijn op het moment geen ondertitels in het $1 voor deze video. U kunt [{{fullurl:{{FULLPAGENAME}}|action=edit}} deze pagina bewerken] om ze toe te voegen", + "timedmedia-subtitle-remote": "De ondertitels voor dit bestand komen van $1", + "timedmedia-subtitle-remote-link": "U kunt de [$1 beschrijvingspagina voor dit bestand] bekijken op $2", + "timedmediahandler": "Timed Media Handler", + "timedmedia-videos": "{{PLURAL:$1|Ć©Ć©n video|$1 video's}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|Ć©Ć©n Oggvideo|$1 Oggvideo's}}", + "timedmedia-webm-videos": "{{PLURAL:$1|Ć©Ć©n WebM-video|$1 WebM-video's}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|Ć©Ć©n transcodering|$1 transcoderingen}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|Ć©Ć©n lopende transcodering|$1 lopende transcoderingen}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|Ć©Ć©n transcodering|$1 transcoderingen}} in de wachtrij", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|Ć©Ć©n mislukte transcodering|$1 mislukte transcoderingen}}", + "timedmedia-file": "Bestand", + "timedmedia-audios": "{{PLURAL:$1|$1 audiobestand|$1 audiobestanden}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg audiobestand|$1 Ogg audiobestanden}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC audiobestand|$1 FLAC audiobestanden}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV audiobestand|$1 WAV audiobestanden}}", + "right-transcode-reset": "Video's waarvoor transcoderen mislukt is of die al getranscodeerd zijn opnieuw in de jobqueue plaatsen.", + "right-transcode-status": "[[Special:TimedMediaHandler|Gegevens over de huidige transcoderingsactiviteit]] bekijken", + "action-transcode-status": "huidige transcoderingsstatus te bekijken" +} diff --git a/extensions/TimedMediaHandler/i18n/nn.json b/extensions/TimedMediaHandler/i18n/nn.json new file mode 100644 index 00000000..cc6a3761 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/nn.json @@ -0,0 +1,41 @@ +{ + "@metadata": { + "authors": [ + "Eirik", + "Harald Khan", + "Njardarlogar", + "Ranveig" + ] + }, + "timedmedia-desc": "Handteringsprogram for ljod, video og tidbunden tekst, med formatstĆøtte for WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1-lydfil, $2", + "timedmedia-ogg-short-video": "Ogg $1-videofil, $2", + "timedmedia-ogg-short-general": "Ogg $1-mediafil, $2", + "timedmedia-ogg-long-audio": "Ogg $1-lydfil, lengd $2, $3", + "timedmedia-ogg-long-video": "Ogg $1-videofil, lengd $2, $4Ć$5 pikslar, $3", + "timedmedia-ogg-long-multiplexed": "Samansett ogg lyd-/videofil, $1, lengd $2, $4Ć$5 pikslar, $3 til saman", + "timedmedia-ogg-long-general": "Ogg mediafil, lengd $2, $3", + "timedmedia-ogg-long-error": "Ugyldig Ogg-fil: $1", + "timedmedia-no-player-js": "Orsak. Nettleseren din har anten ikkje JavaScript aktiv eller har ingen stĆøtta spelar.<br />\nDu kan <a href=\"$1\">laste ned klippet</a> eller <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">laste ned ein spelar</a> for Ć„ spele av klippet i nettlesaren din.", + "timedmedia-more": "Meir...", + "timedmedia-dismiss": "Lat att", + "timedmedia-download": "Last ned fila", + "timedmedia-play-media": "Spel av media", + "timedmedia-desc-link": "Om denne fila", + "timedmedia-actions": "Handlingar", + "timedmedia-not-ready": "Ikkje ferdig", + "timedmedia-days": "{{PLURAL:$1|1 dag|$1 dagar}}", + "timedmedia-hours": "{{PLURAL:$1|1 time|$1 timar}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minutt|$1 minutt}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekund|$1 sekund}}", + "timedmedia-source-file": "$1-kjelde", + "timedmedia-source-file-desc": "Opphavleg $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Opphavleg $1-fil ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg-video med lĆ„g bandbreidd (160P)", + "timedmedia-derivative-desc-360p.ogv": "Ogg-video som kan strĆøymast pĆ„ nett (360P)", + "timedmedia-derivative-desc-480p.ogv": "Ogg-video som kan strĆøymast pĆ„ nett (480P)", + "timedmedia-derivative-desc-720p.ogv": "Ogg-video av hĆøg kvalitet som kan lastast ned (720P)", + "timedmedia-subtitle-new": "Lag ny omsetjing eller endra eksisterande", + "timedmedia-subtitle-new-desc": "Byt ut '''$1'''-delen med [[:en:ISO 639|sprĆ„kkoden]] din og trykk pĆ„ '''{{int:Timedmedia-subtitle-new-go}}'''-knappen", + "timedmedia-subtitle-new-go": "GĆ„" +} diff --git a/extensions/TimedMediaHandler/i18n/oc.json b/extensions/TimedMediaHandler/i18n/oc.json new file mode 100644 index 00000000..892307d8 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/oc.json @@ -0,0 +1,31 @@ +{ + "@metadata": { + "authors": [ + "Cedric31" + ] + }, + "timedmedia-desc": "SupĆ²rt pels fichiĆØrs Ogg Theora e Vorbis, amb un lector Javascript", + "timedmedia-ogg-short-audio": "FichiĆØr son Ogg $1, $2", + "timedmedia-ogg-short-video": "FichiĆØr vidĆØo Ogg $1, $2", + "timedmedia-ogg-short-general": "FichiĆØr mĆØdia Ogg $1, $2", + "timedmedia-ogg-long-audio": "FichiĆØr son Ogg $1, durada $2, $3", + "timedmedia-ogg-long-video": "FichiĆØr vidĆØo Ogg $1, durada $2, $4Ć$5 pixĆØls, $3", + "timedmedia-ogg-long-multiplexed": "FichiĆØr multiplexat Ć udio/vidĆØo Ogg, $1, durada $2, $4Ć$5 pixĆØls, $3", + "timedmedia-ogg-long-general": "FichiĆØr mĆØdia Ogg, durada $2, $3", + "timedmedia-ogg-long-error": "FichiĆØr Ogg invalid : $1", + "timedmedia-webm-short-video": "FichiĆØr vidĆØo WebM $1, $2", + "timedmedia-webm-long-video": "FichiĆØr Ć udio/vidĆØo WebM, $1, longor $2, $4 x $5 pixĆØls, $3 l'ensemble", + "timedmedia-flac-short-audio": "FichiĆØr Ć udio FLAC, $1", + "timedmedia-flac-long-audio": "FichiĆØr Ć udio FLAC, durada $1, debit $2 sus lāensemble", + "timedmedia-wav-short-audio": "FichiĆØr Ć udio WAV, $1", + "timedmedia-no-player-js": "O planhĆØm, siĆ” vĆ²stre navigador a JavaScript de desactivat, siĆ” dispausa pas de cap de lector de pres en carga.<br />\nPodĆØtz <a href=\"$1\">telecargar lo clip</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">telecargar un lector</a> per legir lo clip dins vĆ²stre navigador.", + "timedmedia-more": "Maiā¦", + "timedmedia-dismiss": "Tampar", + "timedmedia-download": "Telecargar lo fichiĆØr", + "timedmedia-desc-link": "A prepaus d'aqueste fichiĆØr", + "timedmedia-source-file": "Font $1", + "timedmedia-source-audio-file-desc": "FichiĆØr original $1 ($2)", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-file": "FichiĆØr", + "right-transcode-reset": "ReĆÆnicializar las vidĆØos en fracĆ s o transcodadas per que siĆ”n inseridas tornamai dins la fila dels trabalhs" +} diff --git a/extensions/TimedMediaHandler/i18n/olo.json b/extensions/TimedMediaHandler/i18n/olo.json new file mode 100644 index 00000000..7e3ad6b5 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/olo.json @@ -0,0 +1,18 @@ +{ + "@metadata": { + "authors": [ + "Mashoi7" + ] + }, + "timedmedia-no-player-js": "Pahakse mielekse sinun livaimes libo JavaScript ei ole kƤytƶs, libo sit ei ole tuvettuu soitindu.<br />\nVoit <a href=\"$1\">lad'd'ata palan</a> libo <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">lad'd'ata soittimen</a> ku soittua pala sinun livaimes.", + "timedmedia-more": "EnƤmbi...", + "timedmedia-dismiss": "Salbua", + "timedmedia-play-media": "Soita medii", + "timedmedia-desc-link": "TƤh failah nƤh", + "timedmedia-status": "Stuatussu", + "timedmedia-status-unknown": "Tundematoi stuatussu", + "timedmedia-source-file": "$1 lƤhteh", + "timedmedia-source-audio-file-desc": "AlguperƤine $1 failu ($2)", + "timedmedia-subtitle-new-go": "Mene", + "timedmedia-file": "Failu" +} diff --git a/extensions/TimedMediaHandler/i18n/or.json b/extensions/TimedMediaHandler/i18n/or.json new file mode 100644 index 00000000..c2df361d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/or.json @@ -0,0 +1,85 @@ +{ + "@metadata": { + "authors": [ + "Jnanaranjan Sahu", + "Psubhashish" + ] + }, + "timedmedia-desc": "ą¬
ą¬”ą¬æą¬, ą¬ą¬æą¬”ą¬¼ą¬æą¬ ą¬ą¬¬ą¬ ą¬øą¬¾ą¬®ąą¬æą¬ ą¬²ąą¬ą¬¾ ą¬ąą¬”ą¬æą¬ ą¬Ŗą¬¾ą¬ą¬ ą±ąą¬¬ą¬ą¬®, ą¬ą¬ą¬æą¬ą¬æ ą¬„ą¬æą¬ą¬°ą¬¾, ą¬ąą¬°ą¬¬ą¬æą¬ø, ą¬ą¬øą¬ą¬°ą¬ą¬æ (WebM, Ogg Theora, Vorbis, srt) ą¬øą¬¹ą¬¾ąą¬¤ą¬¾ ą¬„ą¬æą¬¬ą¬¾ ą¬Ŗą¬°ą¬æą¬ą¬¾ą¬³ą¬Øą¬¾ ą¬ą¬¾ą¬°ą", + "timedmedia-ogg-short-audio": "Ogg $1 ą¬¶ą¬¬ąą¬¦ ą¬«ą¬¾ą¬ą¬², $2", + "timedmedia-ogg-short-video": "Ogg $1 ą¬ą¬æą¬”ą¬¼ą¬æą¬ ą¬«ą¬¾ą¬ą¬², $2", + "timedmedia-ogg-short-general": "Ogg $1 ą¬®ą¬æą¬”ą¬¼ą¬æą¬ ą¬«ą¬¾ą¬ą¬², $2", + "timedmedia-ogg-long-audio": "Ogg $1 ą¬¶ą¬¬ąą¬¦ ą¬«ą¬¾ą¬ą¬², ą¬²ą¬®ąą¬¬ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 ą¬ą¬æą¬”ą¬¼ą¬æą¬, ą¬²ą¬®ąą¬¬ $2, $4Ć$5 ą¬Ŗą¬æą¬ąą¬øąą¬², $3", + "timedmedia-ogg-long-multiplexed": "Ogg ą¬®ą¬²ą¬ą¬æą¬Ŗąą¬²ąą¬ąą¬ø ą¬§ąą±ą¬Øą¬æ/ą¬ą¬æą¬¤ąą¬° ą¬«ą¬¾ą¬ą¬², $1, ą¬²ą¬®ąą¬¬ $2, $4Ć$5 ą¬Ŗą¬æą¬ąą¬øąą¬², ą¬®ąą¬ $3", + "timedmedia-ogg-long-general": "Ogg ą¬®ą¬æą¬”ą¬¼ą¬æą¬ ą¬«ą¬¾ą¬ą¬², ą¬²ą¬®ąą¬¬ $2, $3", + "timedmedia-ogg-long-error": "ą¬
ą¬¬ąą¬§ ogg ą¬«ą¬¾ą¬ą¬²: $1", + "timedmedia-webm-short-video": "Ogg $1 ą¬ą¬æą¬”ą¬¼ą¬æą¬ ą¬«ą¬¾ą¬ą¬², $2", + "timedmedia-webm-long-video": "ogg ą¬
ą¬”ą¬æą¬/ą¬ą¬æą¬”ą¬¼ą¬æą¬ ą¬«ą¬¾ą¬ą¬², $1, ą¬²ą¬®ąą¬¬ $2, $4Ć$5 ą¬Ŗą¬æą¬ąą¬øąą¬², ą¬®ąą¬ $3", + "timedmedia-mp4-short-video": "MP4 $1 ą¬ą¬æą¬”ą¬¼ą¬æą¬ ą¬«ą¬¾ą¬ą¬², $2", + "timedmedia-mp4-long-video": "MP4 ą¬
ą¬”ą¬æą¬/ą¬ą¬æą¬”ą¬¼ą¬æą¬ ą¬«ą¬¾ą¬ą¬², $1, ą¬²ą¬®ąą¬¬ $2, $4Ć$5 ą¬Ŗą¬æą¬ąą¬øąą¬², ą¬®ąą¬ $3", + "timedmedia-no-player-js": "ą¬¦ąą¬ąą¬¤ą¬, ą¬ą¬Ŗą¬£ą¬ąą¬ ą¬¬ąą¬°ą¬¾ą¬ą¬ą¬°ą¬°ą ą¬ą¬¾ą¬ą¬¾ą¬øąą¬ąą¬°ą¬æą¬Ŗąą¬ ą¬
ą¬ą¬³ ą¬¹ąą¬ą¬Æą¬¾ą¬ą¬ą¬æ ą¬ą¬æą¬®ąą¬¬ą¬¾ ą¬ą¬æą¬ą¬æ ą¬ą¬¾ą¬Ŗą¬ą¬¾ą¬ą¬„ą¬æą¬¬ą¬¾ ą¬Ŗąą¬²ąą¬ą¬° ą¬Øą¬¾ą¬¹ą¬æą¬ ą„¤ <br />\ną¬ą¬Ŗą¬£ ą¬ą¬¹ą¬æ ą¬ą¬æą¬”ą¬¼ą¬æą¬ą¬ą¬æą¬ą ą¬ą¬Ŗą¬£ą¬ąą¬ ą¬¬ąą¬°ą¬¾ą¬ą¬ą¬°ą¬°ą ą¬ą¬²ą¬¾ą¬ą¬¬ą¬¾ ą¬Ŗą¬¾ą¬ą¬<a href=\"$1\">ą¬ą¬æą¬”ą¬æą¬ ą¬ąą¬²ą¬æą¬Ŗą¬ą¬æą¬ą ą¬”ą¬¾ą¬ą¬Øą¬²ąą¬” ą¬ą¬°ą¬æą¬Ŗą¬¾ą¬°ą¬æą¬¬ą</a> ą¬ą¬æą¬®ąą¬¬ą¬¾ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¬ą¬æą¬”ą¬¼ą¬æą¬ ą¬Ŗąą¬²ąąą¬¾ą¬° ą¬®ą¬§ąą ą¬”ą¬¾ą¬ą¬Øą¬²ąą¬” ą¬ą¬°ą¬æą¬Ŗą¬¾ą¬°ą¬æą¬¬ą</a> ą„¤", + "timedmedia-more": "ą¬
ą¬§ą¬æą¬...", + "timedmedia-dismiss": "ą¬¬ą¬Øąą¬¦ ą¬ą¬°ą¬æą¬¬ą", + "timedmedia-download": "ą¬«ą¬¾ą¬ą¬² ą¬”ą¬¾ą¬ą¬Øą¬²ąą¬”ą¬¼", + "timedmedia-play-media": "ą¬®ąą¬”ą¬æą¬ą¬ą¬æą¬ą ą¬ą¬²ąą¬ą¬¬ą", + "timedmedia-desc-link": "ą¬ą¬¹ą¬æ ą¬«ą¬¾ą¬ą¬² ą¬¬ą¬æą¬·ąą¬°ą", + "timedmedia-oggThumb-version": "oggą¬Ŗą¬°ą¬æą¬ą¬¾ą¬³ą¬Øą¬¾ą¬ą¬¾ą¬°ą $1 ą¬øą¬ą¬øąą¬ą¬°ą¬£ ą¬ą¬æą¬®ąą¬¬ą¬¾ ą¬¤ą¬¾ą¬ ą ą¬Øąą¬¤ą¬Øą¬¤ą¬® oggą¬„ą¬®ąą¬¬ą¬Øąą¬² ą¬ą¬¬ą¬¶ąąą¬ ą¬ą¬°ą", + "timedmedia-oggThumb-failed": "oggThumb ą¬ąą¬ą¬ą¬¬ą¬æ ą¬¤ą¬æą¬ą¬°ą¬æ ą¬ą¬°ą¬æą¬Ŗą¬¾ą¬°ą¬æą¬²ą¬¾ ą¬Øą¬¾ą¬¹ą¬æą¬ ą„¤", + "timedmedia-status-header": "ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬
ą¬¬ą¬øąą¬„ą¬¾", + "timedmedia-update-status": "ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬
ą¬¬ą¬øąą¬„ą¬¾ ą¬
ą¬Ŗą¬”ąą¬ ą¬ą¬°ą¬æą¬¬ą", + "timedmedia-status": "ą¬
ą¬¬ą¬øąą¬„ą¬¾", + "timedmedia-status-unknown": "ą¬
ą¬ą¬£ą¬¾ ą¬
ą¬¬ą¬øąą¬„ą¬¾", + "timedmedia-transcodeinfo": "ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬ą¬ą¬Øą¬° ą¬¬ą¬æą¬¬ą¬°ą¬£ą", + "timedmedia-actions": "ą¬ą¬¾ą¬®ą¬øą¬¬ą", + "timedmedia-direct-link": "ą¬ą¬¾ą¬ą¬ą¬ąą¬”ą¬æą¬ą ą¬”ą¬¾ą¬ą¬Øą¬²ąą¬” ą¬ą¬°ą¬æą¬¬ą", + "timedmedia-not-ready": "ą¬Ŗąą¬°ą¬øąą¬¤ąą¬¤ ą¬¹ąą¬ą¬Øą¬¾ą¬¹ą¬æą¬", + "timedmedia-completed-on": "$1 ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬¶ąą¬·ą¬¹ąą¬²ą¬¾", + "timedmedia-error-on": "$1 ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”ą¬°ą ą¬
ą¬øąą¬¬ą¬æą¬§ą¬¾ ą„¤", + "timedmedia-started-transcode": "ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” $1ą¬°ą ą¬ą¬°ą¬®ąą¬ ą¬¹ąą¬²ą¬¾ ą„¤ $2", + "timedmedia-percent-done": "ą¬¹ą¬¾ą¬°ą¬¾ą¬¹ą¬¾ą¬°ą¬æ $1% ą¬øą¬°ą¬æą¬ą¬æ", + "timedmedia-in-job-queue": "$1 ą¬Ŗąą¬°ąą¬¬ą¬°ą ą¬ą¬¾ą¬®ą¬°ą ą¬Æąą¬”ą¬¾ą¬ą¬²ą¬¾", + "timedmedia-unknown-target-size": "ą¬
ą¬ą¬£ą¬¾ ą¬ą¬ą¬¾ą¬°, $1 ą¬ą¬Øą¬ąą¬” ą¬¹ąą¬²ą¬¾", + "timedmedia-days": "{{PLURAL:$1|$1 ą¬¦ą¬æą¬Ø|$1 ą¬¦ą¬æą¬Øą¬ąą¬”ą¬æą¬}}", + "timedmedia-hours": "($1 {{PLURAL:$1|ą¬ą¬£ąą¬ą¬¾| ą¬ą¬£ąą¬ą¬¾}})", + "timedmedia-minutes": "$1 {{PLURAL:$1|ą¬®ą¬æą¬Øą¬æą¬|ą¬®ą¬æą¬Øą¬æą¬ą¬ąą¬”ą¬æą¬}}", + "timedmedia-seconds": "{{PLURAL:$1|ą¬øąą¬ąą¬£ąą¬”|ą¬øąą¬ą¬£ąą¬”}}", + "timedmedia-reset": "ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬Ŗąą¬Øą¬ą¬øąą¬„ą¬¾ą¬Ŗą¬Ø ą¬ą¬°ą¬æą¬¬ą", + "timedmedia-reset-confirm": "ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬Ŗąą¬Øą¬ą¬øąą¬„ą¬¾ą¬Ŗą¬Øą¬¾ ą¬ą¬°ą¬æą¬¬ą¬¾ą¬¦ąą¬µą¬¾ą¬°ą¬¾ ą¬
ą¬ą¬°ąą¬„ą¬æą¬¬ą¬¾ ą¬«ą¬¾ą¬ą¬² ą¬¹ą¬ą¬æą¬Æą¬æą¬¬, ą¬ą¬¬ą¬ ą¬ą¬¹ą¬¾ ą¬Ŗąą¬°ą¬ąą¬°ą¬æąą¬¾ą¬°ą ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”ą¬ą ą¬ą¬ą¬„ą¬°ą ą¬Æąą¬”ą¬æą¬¦ąą¬¬ ą„¤ ą¬ą¬¹ą¬¾ ą¬Ŗąą¬Øą¬ ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬Ŗą¬¾ą¬ą¬ ą¬ą¬æą¬ą¬æ ą¬øą¬®ą ą¬Øąą¬¬ ą„¤\ną¬ą¬Ŗą¬£ ą¬Ŗąą¬°ą¬ąą¬°ą¬æąą¬¾ą¬ą ą¬ą¬¾ą¬²ąą¬°ą¬ą¬æą¬¬ą¬¾ ą¬Ŗą¬¾ą¬ą¬ ą¬Øą¬æą¬¶ąą¬ą¬æą¬¤ ?", + "timedmedia-reset-error": "ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬Ŗąą¬Øą¬ą¬øąą¬„ą¬¾ą¬Ŗą¬Ø ą¬ą¬°ą¬æą¬¬ą¬¾ą¬°ą ą¬
ą¬øąą¬¬ą¬§ą¬¾ ą¬ą¬Ŗąą¬ą¬æą¬²ą¬¾", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 ą¬ą¬¤ąą¬ø", + "timedmedia-source-file-desc": "ą¬®ąą¬³ $1 ą¬«ą¬¾ą¬ą¬², $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ą¬®ąą¬³ $1 ą¬«ą¬¾ą¬ą¬² ($2)", + "timedmedia-derivative-desc-160p.ogv": "ą¬ą¬® ą¬¬ąąą¬¾ą¬£ąą¬”ą±ą¬æą¬„ ogg ą¬ą¬æą¬”ą¬¼ą¬æą¬ (160P)", + "timedmedia-derivative-desc-360p.ogv": "ą±ąą¬¬ą¬°ą ą¬øą¬æą¬§ą¬¾ą¬ą¬¾ą¬²ą¬æą¬²ą¬¾ ą¬ą¬³ą¬æ Ogg ą¬ą¬æą¬”ą¬æą¬ (360p)", + "timedmedia-derivative-desc-480p.ogv": "ą±ąą¬¬ą¬°ą ą¬øą¬æą¬§ą¬¾ą¬ą¬¾ą¬²ą¬æą¬²ą¬¾ ą¬ą¬³ą¬æ Ogg ą¬ą¬æą¬”ą¬æą¬ (480p)", + "timedmedia-derivative-desc-720p.ogv": "ą±ąą¬¬ą¬°ą ą¬øą¬æą¬§ą¬¾ą¬ą¬¾ą¬²ą¬æą¬²ą¬¾ ą¬ą¬³ą¬æ Ogg ą¬ą¬æą¬”ą¬æą¬ (720p)", + "timedmedia-derivative-desc-160p.webm": "ą±ąą¬¬ą¬°ą ą¬øą¬æą¬§ą¬¾ą¬ą¬¾ą¬²ą¬æą¬²ą¬¾ ą¬ą¬³ą¬æ WebM ą¬ą¬æą¬”ą¬æą¬ (160p)", + "timedmedia-derivative-desc-360p.webm": "ą±ąą¬¬ą¬°ą ą¬øą¬æą¬§ą¬¾ą¬ą¬¾ą¬²ą¬æą¬²ą¬¾ ą¬ą¬³ą¬æ WebM ą¬ą¬æą¬”ą¬æą¬ (360p)", + "timedmedia-derivative-desc-480p.webm": "ą±ąą¬¬ą¬°ą ą¬øą¬æą¬§ą¬¾ą¬ą¬¾ą¬²ą¬æą¬²ą¬¾ ą¬ą¬³ą¬æ WebM ą¬ą¬æą¬”ą¬æą¬ (480p)", + "timedmedia-derivative-desc-720p.webm": "ą¬ą¬² ą¬Ŗąą¬°ą¬ą¬¾ą¬°ą¬„ą¬æą¬¬ą¬¾ ą¬ą¬¬ą¬ ą¬”ą¬¾ą¬ą¬Øą¬²ąą¬” ą¬¹ąą¬ą¬Ŗą¬¾ą¬°ąą¬„ą¬æą¬¬ą¬¾ WebM(720P)", + "timedmedia-derivative-desc-320p.mp4": "ą¬Æą¬Øąą¬¤ąą¬°-ą¬øą¬¹ą¬¾ąą¬ ą¬ą¬®ą¬Ŗą¬æ4(320P)", + "timedmedia-derivative-desc-480p.mp4": "ą±ąą¬¬ą¬°ą ą¬øą¬æą¬§ą¬¾ą¬ą¬¾ą¬²ą¬æą¬²ą¬¾ ą¬ą¬³ą¬æ MP4 ą¬ą¬æą¬”ą¬æą¬ (480p)", + "timedmedia-derivative-desc-720p.mp4": "ą¬ą¬ą¬”ą¬¼ą¬æ ą¬Ŗąą¬°ą¬ą¬¾ą¬°ą¬° MP4 (720P)", + "timedmedia-subtitle-new": "ą¬Øąą¬ ą¬
ą¬Øąą¬¬ą¬¾ą¬¦ ą¬ą¬°ą¬®ąą¬ ą¬ą¬°ą¬æą¬¬ą ą¬ą¬æą¬®ąą¬¬ą¬¾ ą¬ą¬ą¬°ąą¬„ą¬æą¬¬ą¬¾ ą¬
ą¬Øąą¬¬ą¬¾ą¬¦ą¬ą ą¬¬ą¬¦ą¬³ą¬¾ą¬ą¬¬ą", + "timedmedia-subtitle-new-desc": "ą¬ą¬¾ą¬·ą¬¾ ą¬ąą¬Ø ą¬ą¬°ą¬Øąą¬¤ą ą¬ą¬¬ą¬ {{int:Timedmedia-subtitle-new-go}}'''ą¬¬ą¬ą¬Ø ą¬¦ą¬¬ą¬¾ą¬Øąą¬¤ą", + "timedmedia-subtitle-new-go": "ą¬Æą¬æą¬¬ą", + "timedmedia-subtitle-language": "$1 ($2) ą¬øą¬¬ą¬ą¬¾ą¬ą¬ą¬²", + "timedmedia-subtitle-no-video": "ą¬¬ą¬°ąą¬¤ą¬®ą¬¾ą¬Øą¬° ą¬øą¬¬ą¬ą¬¾ą¬ą¬ą¬² ą¬Ŗąą¬·ąą¬ ą¬¾ ą¬øą¬¹ ą¬ąą¬£ą¬øą¬æ ą¬ą¬æą¬”ą¬æą¬ ą¬øą¬ą¬¶ąą¬³ą¬æą¬·ąą¬ ą¬Øą¬¾ą¬¹ą¬æą¬", + "timedmedia-subtitle-no-subtitles": "ą¬¬ą¬°ąą¬¤ą¬®ą¬¾ą¬Ø $1ą¬°ą ą¬ą¬¹ą¬æ ą¬ą¬æą¬”ą¬æą¬ ą¬Ŗą¬¾ą¬ą¬ ą¬ąą¬£ą¬øą¬æ ą¬øą¬¬ą¬ą¬¾ą¬ą¬ą¬² ą¬Øą¬¾ą¬¹ą¬æą¬, ą¬ą¬Ŗą¬£ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ą¬¬ą¬¦ą¬³ą¬¾ą¬] ą¬ą¬¹ą¬¾ą¬ą ą¬Æąą¬”ą¬æ ą¬Ŗą¬¾ą¬°ą¬æą¬¬ą", + "timedmedia-subtitle-remote": "ą¬ą¬¹ą¬æ ą¬«ą¬¾ą¬ą¬² ą¬Ŗą¬¾ą¬ą¬ ą¬øą¬¾ą¬®ąą¬æą¬ ą¬²ąą¬ą¬¾ą¬ąą¬”ą¬æą¬ $1ą¬°ą ą¬
ą¬ą¬æ", + "timedmedia-subtitle-remote-link": "ą¬ą¬Ŗą¬£ $2ą¬°ą ą¬„ą¬æą¬¬ą¬¾ ą¬ą¬¹ą¬æ ą¬«ą¬¾ą¬ą¬² ą¬Ŗą¬¾ą¬ą¬ [$1 ą¬¬ą¬æą¬¬ą¬°ą¬£ą ą¬Ŗąą¬·ąą¬ ą¬¾ ą¬¦ąą¬ą¬æą¬Ŗą¬¾ą¬°ą¬æą¬¬ą]", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 ą¬ą¬æą¬”ą¬æą¬|$1 ą¬ą¬æą¬”ą¬æą¬ ą¬ąą¬”ą¬æą¬}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg ą¬ą¬æą¬”ą¬æą¬|$1 Ogg ą¬ą¬æą¬”ą¬æą¬ ą¬ąą¬”ą¬æą¬}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM ą¬ą¬æą¬”ą¬æą¬|$1 WebM ą¬ą¬æą¬”ą¬æą¬ ą¬ąą¬”ą¬æą¬}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”|$1 ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”ą¬ąą¬”ą¬æą¬}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 ą¬ą¬¾ą¬²ąą¬„ą¬æą¬¬ą¬¾ ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”|$1 ą¬ą¬¾ą¬²ąą¬„ą¬æą¬¬ą¬¾ ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”ą¬ąą¬”ą¬æą¬}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 ą¬§ą¬¾ą¬”ą¬æą¬°ą ą¬„ą¬æą¬¬ą¬¾ ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”|$1 ą¬§ą¬¾ą¬”ą¬æą¬°ą ą¬„ą¬æą¬¬ą¬¾ ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”ą¬ąą¬”ą¬æą¬}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 ą¬¬ą¬æą¬«ą¬³ ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”|$1 ą¬¬ą¬æą¬«ą¬³ ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬”ą¬ąą¬”ą¬æą¬}}", + "timedmedia-file": "ą¬«ą¬¾ą¬ą¬²", + "right-transcode-reset": "ą¬¬ą¬æą¬«ą¬³ ą¬¹ąą¬ą¬„ą¬æą¬¬ą¬¾ ą¬ą¬æą¬®ąą¬¬ą¬¾ ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬ą¬æą¬”ą¬æą¬ą¬ąą¬”ą¬æą¬ ą¬Ŗąą¬Øą¬ą¬øąą¬„ą¬¾ą¬Ŗą¬Ø ą¬ą¬°ą¬æą¬¬ą ą¬Æą¬¾ą¬¹ą¬¾ą¬«ą¬³ą¬°ąą¬ą¬æ ą¬øąą¬ąą¬”ą¬æą¬ ą¬Ŗąą¬£ą¬æ ą¬Ŗąą¬°ą¬ąą¬°ą¬æąą¬¾ą¬ą¬°ą¬£ ą¬¹ąą¬¬ ą„¤", + "right-transcode-status": "[[Special:TimedMediaHandler|ą¬ą¬¬ąą¬ą¬¾ą¬° ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬ą¬¤ą¬æą¬¬ą¬æą¬§ą¬æ]] ą¬¦ąą¬ą¬æą¬¬ą", + "action-transcode-status": "ą¬ą¬¬ąą¬ą¬¾ą¬° ą¬ąą¬°ą¬¾ą¬Øąą¬øą¬ąą¬” ą¬øąą¬„ą¬æą¬¤ą¬æ ą¬¦ąą¬ą¬æą¬¬ą" +} diff --git a/extensions/TimedMediaHandler/i18n/os.json b/extensions/TimedMediaHandler/i18n/os.json new file mode 100644 index 00000000..b5da6ba3 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/os.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Amikeco" + ] + }, + "timedmedia-more": "Š¤ŃŠ»Š“ƦŃā¦", + "timedmedia-download": "Š¤Š°Š¹Š» Ʀъ±Š°Š²Š³Ć¦Š½" +} diff --git a/extensions/TimedMediaHandler/i18n/pa.json b/extensions/TimedMediaHandler/i18n/pa.json new file mode 100644 index 00000000..80ffc841 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/pa.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Gman124", + "Babanwalia", + "Satdeep gill" + ] + }, + "timedmedia-no-player-js": "ąØ®ą©ąØąØ«ąØ¼ ąØąØ°ąØØąØ¾, ąØąØ¾ąØ ąØ¤ąØ¾ąØ ąØ¤ą©ąØ¹ąØ¾ąØ”ą© ąØ¬ąØ°ąØ¾ąØąØąØ¼ąØ° ąØą©±ąØ¤ą© ąØąØ¾ąØµąØ¾ąØøąØą©ąØ°ąØæąØŖąØ ąØąØ¾ąØ²ą© ąØØąØ¹ą©ąØ ąØąØ¾ąØ ąØ«ąØ¼ąØæąØ° ąØą©ąØ ąØ¹ą©ąØ° ąØøąØ¹ąØ¾ąØąØ ąØŖąØ²ą©ąØ
ąØ° ąØ®ą©ąØą©ąØ¦ ąØØąØ¹ą©ąØ ąØ¹ą©ą„¤<br />\nąØ¤ą©ąØøą©ąØ <a href=\"$1\">ąØąØ²ąØæą©±ąØŖ ąØ”ąØ¾ąØąØØąØ²ą©ąØ” ąØąØ° ąØøąØąØ¦ą© ąØ¹ą©</a> ąØąØ¾ąØ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ąØą©ąØ ąØŖąØ²ą©ąØ
ąØ° ąØ”ąØ¾ąØąØØąØ²ą©ąØ” ąØąØ°ąØą©</a> ąØąØ¹ ąØąØ²ąØæą©±ąØŖ ąØąØŖąØ£ą© ąØ¬ąØ°ąØ¾ąØąØąØ¼ąØ° ąØµąØæą©±ąØ ąØąØ²ąØ¾ ąØøąØąØ¦ą© ąØ¹ą©ą„¤", + "timedmedia-more": "ąØ¹ą©ąØ°...", + "timedmedia-source-file": "$1 ąØøąØ°ą©ąØ¤", + "timedmedia-source-audio-file-desc": "ąØ®ą©ąØ² $1 ąØ«ąØ¼ąØ¾ąØąØ² ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/pdc.json b/extensions/TimedMediaHandler/i18n/pdc.json new file mode 100644 index 00000000..d213f28c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/pdc.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Xqt" + ] + }, + "timedmedia-more": "Mehrā¦", + "timedmedia-download": "Feil runnerlaade" +} diff --git a/extensions/TimedMediaHandler/i18n/pfl.json b/extensions/TimedMediaHandler/i18n/pfl.json new file mode 100644 index 00000000..f4d3bbb6 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/pfl.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Manuae" + ] + }, + "timedmedia-no-player-js": "Endwedda hoschd JavaScript abgschdeld odda de Browsa hodd kƤ unnaschdizdi Abschbielsofdwaa.<br />\nKonschd <a href=\"$1\">de Glibb runnalaade</a> odda Ƥ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Abschbielsofdwaa</a> umde Glibb oagugge zu kenne.", + "timedmedia-source-file": "$1 Gwell", + "timedmedia-source-audio-file-desc": "Uaschbringlischi $1-Dadai ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/pl.json b/extensions/TimedMediaHandler/i18n/pl.json new file mode 100644 index 00000000..cbd0fac5 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/pl.json @@ -0,0 +1,101 @@ +{ + "@metadata": { + "authors": [ + "Ankry", + "Chrumps", + "Derbeth", + "Faren", + "Leinad", + "Matma Rex", + "Przemub", + "Rzuwig", + "Sp5uhe" + ] + }, + "timedmedia-desc": "ObsÅuga plikĆ³w audio, wideo i napisĆ³w filmowych w formatach WebM, Ogg Theora, Vorbis i srt", + "timedmedia-ogg-short-audio": "Plik dÅŗwiÄkowy Ogg $1, $2", + "timedmedia-ogg-short-video": "Plik wideo Ogg $1, $2", + "timedmedia-ogg-short-general": "Plik multimedialny Ogg $1, $2", + "timedmedia-ogg-long-audio": "plik dÅŗwiÄkowy Ogg $1, dÅugoÅÄ $2, $3", + "timedmedia-ogg-long-video": "plik wideo Ogg $1, dÅugoÅÄ $2, rozdzielczoÅÄ $4Ć$5, $3", + "timedmedia-ogg-long-multiplexed": "plik audio/wideo Ogg, $1, dÅugoÅÄ $2, rozdzielczoÅÄ $4Ć$5, ogĆ³Åem $3", + "timedmedia-ogg-long-general": "plik multimedialny Ogg, dÅugoÅÄ $2, $3", + "timedmedia-ogg-long-error": "niepoprawny plik Ogg: $1", + "timedmedia-webm-short-video": "WebM $1 plik wideo, $2", + "timedmedia-webm-long-video": "WebM plik audio-wideo, $1, dÅugoÅÄ $2, $4 Ć $5 pikseli, ogĆ³Åem $3", + "timedmedia-flac-short-audio": "Plik audio FLAC, $1", + "timedmedia-flac-long-audio": "Plik dÅŗwiÄkowy FLAC, dÅugoÅÄ $1, przepÅywnoÅÄ $2", + "timedmedia-wav-short-audio": "Plik audio WAV, $1", + "timedmedia-wav-long-audio": "Plik dÅŗwiÄkowy WAV, dÅugoÅÄ $1, przepÅywnoÅÄ $2", + "timedmedia-no-player-js": "Niestety, Twoja przeglÄ
darka ma wyÅÄ
czonÄ
obsÅugÄ JavaScript lub nie wspiera odtwarzania.<br />\nMożesz <a href=\"$1\">pobraÄ plik</a> lub <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">pobraÄ odtwarzacz</a> pozwalajÄ
cy oglÄ
daÄ wideo w przeglÄ
darce.", + "timedmedia-more": "WiÄcej...", + "timedmedia-dismiss": "Zamknij", + "timedmedia-download": "Pobierz plik", + "timedmedia-play-media": "OdtwĆ³rz plik multimedialny", + "timedmedia-desc-link": "WÅaÅciwoÅci pliku", + "timedmedia-oggThumb-version": "OggHandler wymaga oggThumb w wersji $1 lub pĆ³Åŗniejszej.", + "timedmedia-oggThumb-failed": "oggThumb nie udaÅo siÄ utworzyÄ miniaturki.", + "timedmedia-status-header": "Status konwersji", + "timedmedia-update-status": "Zaktualizuj status konwersji", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "Status nieznany", + "timedmedia-transcodeduration": "Czas kodowania", + "timedmedia-transcodeinfo": "Format", + "timedmedia-actions": "Operacje", + "timedmedia-direct-link": "Pobierz", + "timedmedia-not-ready": "Niegotowe", + "timedmedia-completed-on": "UkoÅczono $1", + "timedmedia-error-on": "BÅÄ
d o $1", + "timedmedia-started-transcode": "Konwersja rozpoczÄÅa siÄ $1 temu. $2", + "timedmedia-percent-done": "UkoÅczono ok. $1%", + "timedmedia-in-job-queue": "Dodano do kolejki $1 temu", + "timedmedia-unknown-target-size": "Rozmiar docelowy nieznany, $1 zakodowane", + "timedmedia-days": "$1 {{PLURAL:$1|dzieÅ|dni}}", + "timedmedia-hours": "$1 {{PLURAL:$1|godzina|godziny|godzin}}", + "timedmedia-minutes": "$1 {{PLURAL:$1|minuta|minuty|minut}}", + "timedmedia-seconds": "$1 {{PLURAL:$1|sekunda|sekundy|sekund}}", + "timedmedia-reset": "Resetuj konwersjÄ", + "timedmedia-reset-confirm": "Reset konwersji spowoduje usuniÄcie obecnego pliku (jeżeli takowy istnieje) i doda jÄ
ponownie do kolejki. Zabierze to trochÄ czasu. <br /><br />\nCzy na pewno chcesz kontynuowaÄ?", + "timedmedia-reset-error": "BÅÄ
d w resecie konwersji.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "ŹrĆ³dÅo $1", + "timedmedia-source-file-desc": "Oryginalny plik $1, $2 x $3 ($4)", + "timedmedia-source-audio-file-desc": "Oryginalny plik $1 ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg video o niskiej przepustowoÅci (160P)", + "timedmedia-derivative-desc-360p.ogv": "Ogg video o przepustowoÅci sieciowej (360P)", + "timedmedia-derivative-desc-480p.ogv": "Ogg video o przepustowoÅci sieciowej (480P)", + "timedmedia-derivative-desc-720p.ogv": "Ogg video o wysokiej jakoÅci (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Do pobrania wideo Ogg z Full HD (1080p)", + "timedmedia-derivative-desc-160p.webm": "WebM w jakoÅci sieciowej (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM w jakoÅci sieciowej (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM w jakoÅci sieciowej (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM o wysokiej jakoÅci (720P)", + "timedmedia-derivative-desc-1080p.webm": "Do pobrania WebM Full HD (1080p)", + "timedmedia-derivative-desc-320p.mp4": "MP4 odpowiednie dla tego urzÄ
dzenia (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 w jakoÅci sieciowej (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 w jakoÅci HD (720P)", + "timedmedia-derivative-desc-1080p.mp4": "JakoÅci Full HD (1080p) MP4", + "timedmedia-subtitle-new": "UtwĆ³rz nowe tÅumaczenie lub edytuj istniejÄ
ce", + "timedmedia-subtitle-new-go": "PrzejdÅŗ", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 film|$1 filmy|$1 filmĆ³w}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 film Ogg|$1 filmy Ogg|$1 filmĆ³w Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 film WebM|$1 filmy WebM|$1 filmĆ³w WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transkodowanie|$1 transkodowania|$1 transkodowaÅ}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 trwajÄ
ce transkodowanie|$1 trwajÄ
ce transkodowania|$1 trwajÄ
cych transkodowaÅ}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transkodowanie|$1 transkodowania|$1 transkodowaÅ}} w kolejce", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 nieudane transkodowanie|$1 nieudane transkodowania|$1 nieudanych transkodowaÅ}}", + "timedmedia-file": "Plik", + "timedmedia-audios": "{{PLURAL:$1|$1 plik dÅŗwiÄkowy|$1 pliki dÅŗwiÄkowe|plikĆ³w dÅŗwiÄkowych}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 plik dÅŗwiÄkowy|$1 pliki dÅŗwiÄkowe|plikĆ³w dÅŗwiÄkowych}} Ogg", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 plik dÅŗwiÄkowy|$1 pliki dÅŗwiÄkowe|plikĆ³w dÅŗwiÄkowych}} FLAC", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 plik dÅŗwiÄkowy|$1 pliki dÅŗwiÄkowe|plikĆ³w dÅŗwiÄkowych}} WAV", + "right-transcode-reset": "Resetowanie bÅÄdnych lub transkodowanych filmĆ³w, ktĆ³re zostaÅy ponownie umieszczone w kolejce zadaÅ", + "right-transcode-status": "PodglÄ
d [[Special:TimedMediaHandler|informacji o aktualnym statusie transkodowania]]", + "action-transcode-status": "zobaczenia aktualnego statusu transkodowania", + "orphanedtimedtext": "Osierocone strony TimedText", + "orphanedtimedtext-unsupported": "To strona specjalna jest obsÅugiwana tylko przez bazy danych MySQL.", + "orphanedtimedtext-notimedtext": "TimedText nie jest wÅÄ
czony w tej wiki.", + "apihelp-query+videoinfo-example-1": "Pobierz informacji o [[:File:Folgers.ogv]]", + "apihelp-transcodereset-param-title": "TytuÅ pliku multimedialnego." +} diff --git a/extensions/TimedMediaHandler/i18n/pms.json b/extensions/TimedMediaHandler/i18n/pms.json new file mode 100644 index 00000000..62681327 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/pms.json @@ -0,0 +1,96 @@ +{ + "@metadata": { + "authors": [ + "BorichĆØt", + "BĆØrto 'd SĆØra", + "DragonĆ²t", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "timedmedia-desc": "Gestor pĆ«r ij son, filmĆ e test a sincronisĆ , con manteniment dij formĆ pĆ«r WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Registrassion Ogg $1, $2", + "timedmedia-ogg-short-video": "Film Ogg $1, $2", + "timedmedia-ogg-short-general": "Archivi Multimojen Ogg $1, $2", + "timedmedia-ogg-long-audio": "Registrassion Ogg $1, ch'a dura $2, $3", + "timedmedia-ogg-long-video": "Film Ogg $1, ch'a dura $2, formĆ $4Ć$5 px, $3", + "timedmedia-ogg-long-multiplexed": "Archivi audio/video multiplessĆ Ogg, $1, ch'a dura $2, formĆ $4Ć$5 px, $3 an tut", + "timedmedia-ogg-long-general": "Archivi multimojen Ogg, ch'a dura $2, $3", + "timedmedia-ogg-long-error": "Archivi ogg nen bon: $1", + "timedmedia-webm-short-video": "Archivi filmĆ WebM $1, $2", + "timedmedia-webm-long-video": "WebM archivi sonor/filmĆ , $1, longheur $2, $4 x $5 pontin, $3 an tut", + "timedmedia-flac-short-audio": "Archivi sonor FLAC, $1", + "timedmedia-flac-long-audio": "Archivi sonor FLAC, durĆ $1, ritm $2 an sĆ«l total", + "timedmedia-wav-short-audio": "Archivi sonor WAV, $1", + "timedmedia-wav-long-audio": "Archivi sonor WAV, durĆ $1, $2 sĆ«l total", + "timedmedia-wav-pcm-required": "A peul mach cariĆ© dij WAV PCM (Modolassion d'ampulsion codificĆ ).", + "timedmedia-mp4-short-video": "Archivi filmĆ MP4 $1, $2", + "timedmedia-mp4-long-video": "MP4 archivi sonor/filmĆ , $1, longheur $2, $4 x $5 pontin, $3 an tut", + "timedmedia-no-player-js": "Darmagi, sĆ² navigador a l'ha JavaScript disabilitĆ o a manten pa Ć«l riprodutor.<br />\nA peul <a href=\"$1\">dĆ«scariĆ© la senĆ«tta</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">dĆ«scariĆ© un riprodutor</a> pĆ«r visualisĆ© la senĆ«tta su sĆ² navigador.", + "timedmedia-more": "DĆ« pƬ...", + "timedmedia-dismiss": "sĆ«rĆ©", + "timedmedia-download": "DĆ«scariĆ© l'archivi", + "timedmedia-play-media": "Lese Ć«l mojen", + "timedmedia-desc-link": "RĆ«sgoard a st'archivi", + "timedmedia-oggThumb-version": "OggHandler a ciama la version $1 d'oggThumb o pi agiornĆ .", + "timedmedia-oggThumb-failed": "oggThumb a l'ha falƬ a creĆ© la figurin-a.", + "timedmedia-status-header": "StatĆ¹ Ć«d trascodƬfica", + "timedmedia-update-status": "AgiornĆ© lĆ« statĆ¹ Ć«d trascodƬfica", + "timedmedia-status": "Stat", + "timedmedia-status-unknown": "Stat pa conossĆ¹", + "timedmedia-transcodeinfo": "Descrission derivĆ da la trascodƬfica", + "timedmedia-actions": "Assion", + "timedmedia-direct-link": "DĆ«scariĆ© Ć«l derivĆ ", + "timedmedia-not-ready": "Pa pront", + "timedmedia-completed-on": "TrascodƬfica completĆ $1", + "timedmedia-error-on": "Eror ant la trascodƬfica Ć«d $1", + "timedmedia-started-transcode": "TrascodƬfica ancaminĆ $1 fĆ . $2", + "timedmedia-percent-done": "Sirca $1% fĆ it", + "timedmedia-in-job-queue": "GiontĆ a la coa dij Travaj $1 fĆ ", + "timedmedia-unknown-target-size": "Dimension Ć«d la destinassion pa conossĆ¹a, $1 codificĆ ", + "timedmedia-days": "{{PLURAL:$1|1 di|$1 di}}", + "timedmedia-hours": "{{PLURAL:$1|1 ora|$1 ore}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuta|$1 minute}}", + "timedmedia-seconds": "{{PLURAL:$1|1 second|$1 second}}", + "timedmedia-reset": "AmpostĆ© torna la trascodƬfica", + "timedmedia-reset-confirm": "AmpostĆ© torna sa trascodƬfica a tramuderĆ tut archivi esistent (s'a-i na j'Ć©) e a gionterĆ torna la trascodƬfica a la coa dij travaj. A-i andrĆ dĆ«l temp a trascodifichĆ© torna. <br /><br />\nĆ-lo sigur Ć«d vorĆØj continuĆ©?", + "timedmedia-reset-error": "Eror an ampostand torna Ć«l travaj Ć«d trascodƬfica.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 sorziss", + "timedmedia-source-file-desc": "Archivi original $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Archivi original $1 ($2)", + "timedmedia-derivative-desc-160p.ogv": "LarghĆ«ssa Ć«d banda bassa Ogg video (160P)", + "timedmedia-derivative-desc-360p.ogv": "Web streamable Ogg video (360P)", + "timedmedia-derivative-desc-480p.ogv": "FilmĆ Ogg lesƬbil an continuĆ an sl'aragnĆ (480P)", + "timedmedia-derivative-desc-720p.ogv": "FilmĆ Ogg dĆ«scariĆ bil d'Ć uta qualitĆ (720P)", + "timedmedia-derivative-desc-160p.webm": "WebM lesƬbil an continuĆ an sl'aragnĆ (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM lesƬbil an continuĆ an sl'aragnĆ (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM lesƬbil an continuĆ an sl'aragnĆ (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM dĆ«scariĆ bil d'Ć uta qualitĆ (720P)", + "timedmedia-derivative-desc-320p.mp4": "Dispositiv compatƬbil MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 lesƬbil an continuĆ an sl'aragnĆ (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 an qualitĆ HD (720P)", + "timedmedia-subtitle-new": "CreĆ© na neuva tradussion o modifichene un-a esistenta", + "timedmedia-subtitle-new-desc": "Ch'a selession-a la lenga e ch'a sgnaca an sĆ«l boton '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Va", + "timedmedia-subtitle-language": "$1 ($2) sot-tƬtoj", + "timedmedia-subtitle-no-video": "A-i Ć© gnun filmĆ associĆ con la pagina corenta dĆ«l sot-tƬtol", + "timedmedia-subtitle-no-subtitles": "A-i Ć© al moment gnun sot-tƬtoj an $1 pĆ«r Ć«s filmĆ , a peul [{{fullurl:{{FULLPAGENAME}}|action=edit}} modifichĆ© costa pĆ gina] pĆ«r gionteje", + "timedmedia-subtitle-remote": "Ćl test previst pĆ«r cost archivi a l'Ć© ospitĆ dzor $1", + "timedmedia-subtitle-remote-link": "A peul [$1 vĆ«dde la pĆ gina Ć«d descrission] Ć«d s'archivi dzor $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 filmĆ }}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 filmĆ Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 filmĆ WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 trascodƬfica|$1 trascodƬfiche}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 trascodƬfica|$1 trascodƬfiche}} an esecussion", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 trascodƬfica|$1 trascodƬfiche}} an coa", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 trascodƬfica falƬa|$1 trascodƬfiche falƬe}}", + "timedmedia-file": "Archivi", + "timedmedia-audios": "{{PLURAL:$1|$1 archivi sonor}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 archivi sonor Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 archivi sonor FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 archivi sonor WAV}}", + "right-transcode-reset": "AmpostĆ© torna ij filmĆ falƬ o trascodificĆ pĆ«r ch'a sio torna anserƬ ant la coa dij travaj.", + "right-transcode-status": "Smon-e [[Special:TimedMediaHandler|l'anformassion a propĆ²sit Ć«d l'ativitĆ corenta Ć«d trascodƬfica]]", + "action-transcode-status": "varda lĆ« stat Ć«d trascodƬfica corent" +} diff --git a/extensions/TimedMediaHandler/i18n/pnb.json b/extensions/TimedMediaHandler/i18n/pnb.json new file mode 100644 index 00000000..3ff940e9 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/pnb.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Khalid Mahmood" + ] + }, + "timedmedia-no-player-js": "ŲŖŁŲ§ŚŪ ŲØŲ±Ų§Ų¤Ų²Ų± ŲŖŪ Ų¬Ų§ŁŲ§Ų³Ś©Ų±Ł¾Ł¹ Ś©Ł
ŁŪŪŚŗ Ś©Ų± Ų±ŪŲ§ ŪŲ§ ŁŪŲ± ŪŁŲ± Ł¾ŁŲ¦ŪŲ± ŁŪŪŚŗ <br />\nŲŖŲ³ŪŚŗ <a href=\"$1\">Ś©ŁŁ¾ ŚŲ§Ų¤ŁŁŁŚ Ś©Ų±Ų³Ś©ŲÆŪ Ų§Ł</a> ŪŲ§ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŪŲ§ Ų§Ł¾ŁŪ ŲØŲ±Ų§Ų¤Ų²Ų± ŁŚ Ś©ŁŁ¾ ŚŁŲ§Ł ŁŲ¦Ū Ł¾ŁŪŲ¦Ų± ŚŲ§Ų¤ŁŁŁŚ Ś©Ų±Ł</a> .", + "timedmedia-source-file": "$1 Ł
ŚŚ¾", + "timedmedia-source-audio-file-desc": "Ų§ŲµŁŪ$1 ŁŲ§Ų¦Ł ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/ps.json b/extensions/TimedMediaHandler/i18n/ps.json new file mode 100644 index 00000000..f602ceb3 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ps.json @@ -0,0 +1,29 @@ +{ + "@metadata": { + "authors": [ + "Ahmed-Najib-Biabani-Ibrahimkhel" + ] + }, + "timedmedia-ogg-short-audio": "Ogg $1 ŲŗŚŁŲ²Ł ŲÆŁŲŖŁŁŲ $2", + "timedmedia-ogg-short-video": "Ogg $1 ŁŁŚŁŁŁŁ ŲÆŁŲŖŁŁŲ $2", + "timedmedia-ogg-short-general": "Ogg $1 Ų±Ų³ŁŁŲ²Ł ŲÆŁŲŖŁŁŲ $2", + "timedmedia-no-player-js": "ŲØŲ®ŚŁŁ ŲÆŪ ŁŁŲ ŁŲ§ Ų®Ł Ų³ŲŖŲ§Ų³Ū Ł¾Ł Ś©ŲŖŁŁ
Ł ŲØŲ§ŁŲÆŪ Ų¬Ų§ŁŲ§Ų³Ś©Ų±ŪŁ¾Ł¼ ŁŲ§ŚŲ§Ų±Ł ŲÆŪ Ų§Ł ŁŲ§ ŁŁ
ŲŖŲ§Ų³Ū Ś©ŁŁ
Ł
ŁŲ§ŲŖŚŁŪ ŲŗŚŁŁŚ©Ū ŁŁ ŁŲ±Ū.<br />\nŲŖŲ§Ų³Ū <a href=\"$1\">Ś©ŁŪŁ¾ ŚŚ©ŲŖŁ Ś©ŁŁŪ Ų“Ų¦</a> Ų§Ł ŁŲ§ ŁŁ
ŁŁ ŲÆŲ§Ų³Ū <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŲŗŚŁŁŚ©Ū ŚŚ©ŲŖŁ Ś©ŚŲ¦</a> ŚŪ Ś©ŁŪŁ¾ Ł¾Ł Ś©ŲŖŁŁ
Ł ŲØŲ§ŁŲÆŪ ŁŲŗŚŁŁ.", + "timedmedia-more": "ŁŁŲ±...", + "timedmedia-dismiss": "ŲŖŚŁ", + "timedmedia-download": "ŲÆŁŲŖŁŁ ŚŚ©ŲŖŁ Ś©ŁŁ", + "timedmedia-play-media": "Ų±Ų³ŁŪ ŲŗŚŁŁ", + "timedmedia-desc-link": "ŲÆ ŁŁ
ŲÆŪ ŲÆŁŲŖŁŪ Ł¾Ł Ų§ŚŁ", + "timedmedia-status": "ŲÆŲ±ŁŚ", + "timedmedia-transcodeinfo": "ŲØŚ¼Ł", + "timedmedia-actions": "ŚŲ§Ų±Ū", + "timedmedia-direct-link": "ŚŚ©ŲŖŁ Ś©ŁŁ", + "timedmedia-days": "{{PLURAL:$1|1 ŁŲ±Ś|$1 ŁŲ±ŚŪ}}", + "timedmedia-hours": "{{PLURAL:$1|1 ŚÆŚŪ|$1 ŚÆŚŪ}}", + "timedmedia-minutes": "{{PLURAL:$1|1 ŲÆŁŁŁŁ|ŲÆŁŁŁŪ}}", + "timedmedia-source-file": "$1 Ų³Ų±ŚŁŁŁ", + "timedmedia-source-audio-file-desc": "Ų§ŲµŁŁ $1 ŲÆŁŲŖŁŁ ($2)", + "timedmedia-subtitle-new-go": "ŁŲ±ŚŁ", + "timedmedia-videos": "{{PLURAL:$1|$1 ŁŁŚŁŁ|$1 ŁŁŚŁŁŚÆŲ§ŁŪ}}", + "timedmedia-file": "ŲÆŁŲŖŁŁ", + "timedmedia-audios": "{{PLURAL:$1|$1 ŲŗŚŁŲ²Ł ŲÆŁŲŖŁŁ|$1 ŲŗŚŁŲ²Ū ŲÆŁŲŖŁŪ}}" +} diff --git a/extensions/TimedMediaHandler/i18n/pt-br.json b/extensions/TimedMediaHandler/i18n/pt-br.json new file mode 100644 index 00000000..99b96b5e --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/pt-br.json @@ -0,0 +1,40 @@ +{ + "@metadata": { + "authors": [ + "Eduardo.mps", + "Giro720", + "Luckas", + "Opraco", + "Guilhermemau", + "Fasouzafreitas" + ] + }, + "timedmedia-desc": "Manipulador para arquivos Ogg Theora e Vorbis, com reprodutor JavaScript", + "timedmedia-ogg-short-audio": "Arquivo de Ć”udio Ogg $1, $2", + "timedmedia-ogg-short-video": "Arquivo de vĆdeo Ogg $1, $2", + "timedmedia-ogg-short-general": "Arquivo multimĆdia Ogg $1, $2", + "timedmedia-ogg-long-audio": "arquivo de Ć”udio Ogg $1, $2 de duraĆ§Ć£o, $3", + "timedmedia-ogg-long-video": "VĆdeo Ogg $1, $2 de duraĆ§Ć£o, $4Ć$5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "Ćudio/vĆdeo Ogg multifacetado, $1, $2 de duraĆ§Ć£o, $4Ć$5 pixels, $3 no todo", + "timedmedia-ogg-long-general": "MultimĆdia Ogg, $2 de duraĆ§Ć£o, $3", + "timedmedia-ogg-long-error": "Arquivo ogg invĆ”lido: $1", + "timedmedia-no-player-js": "Desculpe, seu navegador ou estĆ” com JavaScript desabilitado ou nĆ£o tem nenhum \"player\" suportado.<br />\nVocĆŖ pode <a href=\"$1\">descarregar o clipe</a> ou <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">descarregar um \"player\"</a> para executar o clipe em seu navegador.", + "timedmedia-more": "Mais...", + "timedmedia-dismiss": "Fechar", + "timedmedia-download": "Descarregar arquivo", + "timedmedia-desc-link": "Sobre este arquivo", + "timedmedia-oggThumb-version": "O oggHandler requer o oggThumb versĆ£o $1 ou posterior.", + "timedmedia-oggThumb-failed": "O oggThumb nĆ£o conseguiu criar a miniatura.", + "timedmedia-actions": "AƧƵes", + "timedmedia-days": "{{PLURAL:$1|1 dia|$1 dias}}", + "timedmedia-hours": "{{PLURAL:$1|1 hora|$1 horas}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuto|$1 minutos}}", + "timedmedia-seconds": "{{PLURAL:$1|1 segundo|$1 segundos}}", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Fonte $1", + "timedmedia-source-audio-file-desc": "Arquivo $1 original ($2)", + "timedmedia-derivative-desc-1080p.webm": "WebM para download de Full HD (1080p)", + "timedmedia-derivative-desc-1080p.mp4": "Qualidade total do HD MP4 (1080 P)", + "timedmedia-subtitle-new-go": "Ir", + "timedmedia-file": "Arquivo" +} diff --git a/extensions/TimedMediaHandler/i18n/pt.json b/extensions/TimedMediaHandler/i18n/pt.json new file mode 100644 index 00000000..379e2271 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/pt.json @@ -0,0 +1,102 @@ +{ + "@metadata": { + "authors": [ + "Giro720", + "Hamilton Abreu", + "Luckas", + "Malafaya", + "Opraco", + "Vitorvicentevalente", + "Waldir", + "555", + "Tooguether", + "Macofe", + "FĆŗlvio" + ] + }, + "timedmedia-desc": "Tratamento de Ć”udio, vĆdeo e legendagem, nos formatos WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ćudio Ogg $1, $2", + "timedmedia-ogg-short-video": "VĆdeo Ogg $1, $2", + "timedmedia-ogg-short-general": "MultimĆ©dia Ogg $1, $2", + "timedmedia-ogg-long-audio": "Ć”udio Ogg $1, $2 de duraĆ§Ć£o, $3", + "timedmedia-ogg-long-video": "VĆdeo Ogg $1, $2 de duraĆ§Ć£o, $4Ć$5 pixels, $3", + "timedmedia-ogg-long-multiplexed": "Ćudio/vĆdeo Ogg multifacetado, $1, $2 de duraĆ§Ć£o, $4Ć$5 pixels, $3 no todo", + "timedmedia-ogg-long-general": "MultimĆ©dia Ogg, $2 de duraĆ§Ć£o, $3", + "timedmedia-ogg-long-error": "Ficheiro ogg invĆ”lido: $1", + "timedmedia-ogg-long-no-streams": "Arquivo de mĆdia OGG. Aviso: Nenhum dos codecs utilizados neste arquivo sĆ£o reconhecidos.", + "timedmedia-webm-short-video": "VĆdeo WebM $1, $2", + "timedmedia-webm-long-video": "Ćudio/vĆdeo WebM, $1, $2 de duraĆ§Ć£o, $4 Ć $5 pixels, $3 no todo", + "timedmedia-flac-short-audio": "Ficheiro de Ć”udio FLAC, $1", + "timedmedia-flac-long-audio": "Ficheiro de Ć”udio FLAC, duraĆ§Ć£o $1, $2", + "timedmedia-wav-short-audio": "Ficheiro de Ć”udio WAV, $1", + "timedmedia-wav-long-audio": "Ficheiro de Ć”udio WAV, duraĆ§Ć£o $1, $2", + "timedmedia-mp4-short-video": "VĆdeo MP4 $1, $2", + "timedmedia-mp4-long-video": "Ćudio/vĆdeo MP$, $1, duraĆ§Ć£o $2, $4 Ć $5 pixels, $3", + "timedmedia-no-player-js": "Desculpe, mas ou o seu navegador estĆ” com o JavaScript desactivado ou nĆ£o tem nenhum dos leitores suportados.<br />\nPode fazer a <a href=\"$1\">descarga do vĆdeo</a> ou o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">de um leitor</a> para assistir ao vĆdeo no seu navegador.", + "timedmedia-more": "Mais...", + "timedmedia-dismiss": "Fechar", + "timedmedia-download": "Fazer descarga do ficheiro", + "timedmedia-play-media": "Reproduzir conteĆŗdo", + "timedmedia-desc-link": "Sobre este ficheiro", + "timedmedia-oggThumb-version": "O oggHandler requer a versĆ£o $1 do oggThumb ou posterior.", + "timedmedia-oggThumb-failed": "O oggThumb nĆ£o conseguiu criar a miniatura.", + "timedmedia-status-header": "Estado da transcodificaĆ§Ć£o", + "timedmedia-update-status": "Actualizar o estado da transcodificaĆ§Ć£o", + "timedmedia-status": "Estado", + "timedmedia-status-unknown": "Estado desconhecido", + "timedmedia-transcodeinfo": "Formato", + "timedmedia-actions": "AcƧƵes", + "timedmedia-direct-link": "Descarregar", + "timedmedia-not-ready": "Ainda nĆ£o estĆ” pronto", + "timedmedia-completed-on": "ConcluĆda a $1", + "timedmedia-error-on": "Erro em $1", + "timedmedia-started-transcode": "Iniciou hĆ” $1. $2", + "timedmedia-percent-done": "O progresso Ć© cerca de $1%", + "timedmedia-in-job-queue": "Adicionado Ć fila de tarefas hĆ” $1", + "timedmedia-unknown-target-size": "DimensĆ£o do destino desconhecida; $1 codificados", + "timedmedia-days": "{{PLURAL:$1|1 dia|$1 dias}}", + "timedmedia-hours": "{{PLURAL:$1|1 hora|$1 horas}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuto|$1 minutos}}", + "timedmedia-seconds": "{{PLURAL:$1|1 segundo|$1 segundos}}", + "timedmedia-reset": "Reiniciar transcodificaĆ§Ć£o", + "timedmedia-reset-confirm": "Reiniciar esta transcodificaĆ§Ć£o elimina qualquer ficheiro existente e volta a adicionar a transcodificaĆ§Ć£o Ć fila de tarefas. A nova transcodificaĆ§Ć£o irĆ” demorar algum tempo. <br /><br />Tem a certeza de que pretende continuar?", + "timedmedia-reset-error": "Ocorreu um erro ao reiniciar a tarefa de transcodificaĆ§Ć£o", + "timedmedia-source-file": "Fonte $1", + "timedmedia-source-file-desc": "Ficheiro $1 original, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Ficheiro $1 original ($2)", + "timedmedia-derivative-desc-160p.ogv": "VĆdeo Ogg de baixa largura de banda (160P)", + "timedmedia-derivative-desc-360p.ogv": "VĆdeo Ogg para web streaming (360P)", + "timedmedia-derivative-desc-480p.ogv": "VĆdeo Ogg para web streaming (480P)", + "timedmedia-derivative-desc-720p.ogv": "VĆdeo Ogg de alta qualidade para download (720 P)", + "timedmedia-derivative-desc-360p.webm": "WebM para web streaming (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM para web streaming (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM de alta qualidade para download (720P)", + "timedmedia-derivative-desc-720p.mp4": "Qualidade HD MP4 (720P)", + "timedmedia-subtitle-new": "Criar nova traduĆ§Ć£o ou editar existente", + "timedmedia-subtitle-new-desc": "Seleccione o idioma e pressione o botĆ£o '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Enviar", + "timedmedia-subtitle-language": "Legendas em $1 ($2)", + "timedmedia-subtitle-no-video": "NĆ£o existe nenhum vĆdeo associado Ć actual pĆ”gina de legendas", + "timedmedia-subtitle-no-subtitles": "Neste momento nĆ£o existem legendas em $1 para este vĆdeo. Pode [{{fullurl:{{FULLPAGENAME}}|action=edit}} editar a pĆ”gina] e adicionĆ”-las.", + "timedmedia-subtitle-remote": "A legenda para este ficheiro estĆ” hospedada em $1", + "timedmedia-subtitle-remote-link": "Pode [$1 ver a pĆ”gina de descriĆ§Ć£o] para este ficheiro em $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 vĆdeo|$1 vĆdeos}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 vĆdeo ogg|$1 vĆdeos ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 vĆdeo WebM|$1 vĆdeos WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodificaĆ§Ć£o|$1 transcodificaƧƵes}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodificaĆ§Ć£o em andamento|$1 transcodificaƧƵes em andamento}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodificaĆ§Ć£o em espera|$1 transcodificaƧƵes em espera}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transcodificaĆ§Ć£o falhada|$1 transcodificaƧƵes falhadas}}", + "timedmedia-file": "Ficheiro", + "timedmedia-audios": "{{PLURAL:$1|$1 ficheiro de Ć”udio|$1 ficheiros de Ć”udio}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 ficheiro de Ć”udio Ogg|$1 ficheiros de Ć”udio Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 ficheiro de Ć”udio FLAC|$1 ficheiros de Ć”udio FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 ficheiro de Ć”udio WAV|$1 ficheiros de Ć”udio WAV}}", + "right-transcode-status": "Ver [[Special:TimedMediaHandler|informaĆ§Ć£o sobre a actividade actual de transcodificaĆ§Ć£o]]", + "action-transcode-status": "ver o estado actual de transcodificaĆ§Ć£o", + "orphanedtimedtext": "PĆ”ginas Legendagem Ć³rfĆ£s", + "orphanedtimedtext-summary": "Lista de pĆ”ginas [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] que nĆ£o tĆŖm um ficheiro correspondente.", + "orphanedtimedtext-unsupported": "Esta pĆ”gina especial sĆ³ Ć© suportada nas bases de dados MySQL.", + "orphanedtimedtext-notimedtext": "O domĆnio Legendagem nĆ£o estĆ” habilitado nesta wiki." +} diff --git a/extensions/TimedMediaHandler/i18n/qqq.json b/extensions/TimedMediaHandler/i18n/qqq.json new file mode 100644 index 00000000..4fe17fe8 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/qqq.json @@ -0,0 +1,172 @@ +{ + "@metadata": { + "authors": [ + "Aotake", + "BrokenArrow", + "EugeneZelenko", + "Fryed-peach", + "Jon Harald SĆøby", + "Meno25", + "Minh Nguyen", + "Mormegil", + "Purodha", + "Raymond", + "Shirayuki", + "Siebrand", + "Umherirrender", + "ģė¼", + "Liuxinyu970226", + "Amire80", + "Robby" + ] + }, + "extensionname-timedmedia": "{{optional}}", + "timedmedia-desc": "{{desc|name=Timed Media Handler|url=https://www.mediawiki.org/wiki/Extension:TimedMediaHandler}}", + "timedmedia-ogg-short-audio": "File details for Ogg sound (audio) files, short version.\nParameters:\n* $1 - stream type name. Any one of the following: Vorbis, Speex, FLAC\n* $2 - duration of the sound/audio (localized) - e.g. 1m34s\n{{Related|Timedmedia-ogg-short}}", + "timedmedia-ogg-short-video": "File details for Ogg video files, short version.\nParameters:\n* $1 - stream type name: Theora\n* $2 - duration of the video (localized) - e.g. 1m34s\n{{Related|Timedmedia-ogg-short}}", + "timedmedia-ogg-short-general": "File details for generic (non-audio, non-video) Ogg files, short version.\nParameters:\n* $1 - stream type name\n* $2 - duration of the media (localized) - e.g. 1m34s\n{{Related|Timedmedia-ogg-short}}", + "timedmedia-ogg-long-audio": "File details for Ogg sound (audio) files, long version.\n\nShown after the filename in the image description page.\n\nParameters:\n* $1 - stream type name. Any one of the following: Vorbis, Speex, FLAC\n* $2 - duration of the sound (localized) - e.g. 1m34s\n* $3 - bit-rate of the sound (localized) - e.g. 97kbps\n{{Related|Timedmedia-ogg-long}}", + "timedmedia-ogg-long-video": "File details for Ogg video files, long version.\n\nShown after the filename in the image description page.\n\nParameters:\n* $1 - stream type name: Theora\n* $2 - duration of the video (localized) - e.g. 1m34s\n* $3 - bit-rate of the video (localized) - e.g. 97kbps\n* $4 - width of the video (in pixels)\n* $5 - height of the video (in pixels)\n{{Related|Timedmedia-ogg-long}}", + "timedmedia-ogg-long-multiplexed": "{{doc-important|Start with a lowercase letter, unless the first word is \"Ogg\".}}\nFile details for Ogg multiplexed audio/video files, long version.\n\nShown after the filename in the image description page.\n\nParameters:\n* $1 - stream type names, slash-separated - e.g. Theora/Vorbis\n* $2 - duration (localized) - e.g. 1m34s\n* $3 - bit-rate (localized) - e.g. 97kbps\n* $4 - width of the video (in pixels)\n* $5 - height of the video (in pixels)\n{{Related|Timedmedia-ogg-long}}", + "timedmedia-ogg-long-general": "File details for Ogg generic (non-video, non-audio) files, long version.\n\nShown after the filename in the image description page.\n\nParameters:\n* $1 - (Unused)\n* $2 - duration (localized) - e.g. 1m34s\n* $3 - bit-rate (localized) - e.g. 97kbps\n{{Related|Timedmedia-ogg-long}}", + "timedmedia-ogg-long-error": "Used as error message. Parameters:\n* $1 - error message. e.g. File not found, invalid stream, etc.", + "timedmedia-ogg-long-no-streams": "Similar to {{msg-mw|timedmedia-ogg-long-error}}. Used as the long description for an ogg media file if there are no streams in the file using a recognized codec. This can be caused by an invalid ogg file, or by one using an obscure type of data (e.g. dirac video with no audio).", + "timedmedia-webm-short-video": "File details for WebM video files, short version.\nParameters:\n* $1 - stream type names (slash separated) - e.g. Vorbis/VP8\n* $2 - duration of the video (localized) - e.g. 1m34s\nSee also:\n* {{msg-mw|Timedmedia-webm-long-video}}", + "timedmedia-webm-long-video": "File details for WebM multiplexed audio/video files, long version.\n\nShown after the filename in the image description page.\n\nParameters:\n* $1 - stream type names (slash separated) - e.g. Vorbis/VP8\n* $2 - duration (localized) - e.g. 1m34s\n* $3 - bit-rate (localized) - e.g. 97kbps\n* $4 - width of the video (in pixels)\n* $5 - height of the video (in pixels)\nSee also:\n* {{msg-mw|Timedmedia-webm-short-video}}", + "timedmedia-flac-short-audio": "File details for FLAC audio files, short version.\nParameters:\n* $1 - duration of the audio (localized) - e.g. 1m34s\n\nPrimarily used on [[Special:Search]] results pages, i.e.\n https://commons.wikimedia.org/w/index.php?title=Special%3ASearch&profile=advanced&search=What%27s+a+love+dart&fulltext=Search&ns6=1&profile=advanced\n\nSee also:\n* {{msg-mw|Timedmedia-flac-long-audio}}\n* {{msg-mw|Timedmedia-ogg-short-audio}}", + "timedmedia-flac-long-audio": "File details for FLAC files, long version.\n\nShown after the filename in the image description page.\n\nParameters:\n* $1 - duration (localized) - e.g. 1m34s\n* $2 - bit-rate (localized) - e.g. 97kbps\nSee also:\n* {{msg-mw|Timedmedia-flac-short-audio}}", + "timedmedia-wav-short-audio": "File details for WAV audio files, short version.\nParameters:\n* $1 - duration of the audio (localized) - e.g. 1m34s\nSee also:\n* {{msg-mw|Timedmedia-wav-long-audio}}", + "timedmedia-wav-long-audio": "File details for WAV files, long version.\nShown after the filename in the image description page.\n\nParameters:\n* $1 - duration of the audio (localized) - e.g. 1m34s\n* $2 - bit-rate (localized) - e.g. 97kbps\nSee also:\n* {{msg-mw|Timedmedia-wav-short-audio}}", + "timedmedia-wav-pcm-required": "Message shown at upload if user tries to upload a WAV file using a codec that is not PCM", + "timedmedia-mp4-short-video": "File details for MP4 video files, short version.\nParameters:\n* $1 - stream type names (slash separated) - e.g. AAC/h.264\n* $2 - duration of the video (localized) - e.g. 1m34s\nSee also:\n* {{msg-mw|Timedmedia-mp4-long-video}}", + "timedmedia-mp4-long-video": "File details for MP4 multiplexed audio/video files, long version.\n\nShown after the filename in the image description page.\n\nParameters:\n* $1 - stream type names (slash separated) - e.g. AAC/h.264\n* $2 - duration (localized) - e.g. 1m34s\n* $3 - bit-rate (localized) - e.g. 97kbps\n* $4 - width of the video (in pixels)\n* $5 - height of the video (in pixels)\nSee also:\n* {{msg-mw|Timedmedia-mp4-short-video}}", + "timedmedia-no-player-js": "Used as fallback text displayed for browsers without js and without video tag support.\n\nParameters:\n* $1 - media source URL", + "timedmedia-more": "Unused at this time.\n{{Identical|More...}}", + "timedmedia-dismiss": "Unused at this time.\n{{Identical|Close}}", + "timedmedia-download": "Used as tooltip for the Download button.\n{{Identical|Download}}", + "timedmedia-play-media": "Used as tooltip for the link.", + "timedmedia-desc-link": "Unused at this time.\n{{Identical|About this file}}", + "timedmedia-oggThumb-version": "Used as error message when the specified option is invalid. Parameters:\n* $1 - version number \"0.9\" (hard-coded)", + "timedmedia-oggThumb-failed": "{{doc-important|Do not translate <code>oggThumb</code>.}}\nUsed as error message when executing oggThumb.", + "timedmedia-status-header": "Used as section heading.", + "timedmedia-update-status": "Used as text for the link which is used to purge.", + "timedmedia-status": "Used as column header.\n{{Identical|Status}}", + "timedmedia-status-unknown": "Used as status message on error.\n{{Identical|Unknown status}}", + "timedmedia-transcodebitrate": "A table column header for description of transcode bitrate", + "timedmedia-transcodeduration": "A table column header for description of transcode encoding time", + "timedmedia-transcodeinfo": "A table column header for description of Transcode derivative\n{{Identical|Format}}", + "timedmedia-actions": "Used as column header.\n{{Identical|Action}}", + "timedmedia-direct-link": "Used as column header.\n{{Identical|Download}}", + "timedmedia-not-ready": "State of a given transcode job being not yet complete or not yet ready", + "timedmedia-completed-on": "Completed transcode message. Parameters:\n* $1 - the timestamp (time and date) that the transcode was completed", + "timedmedia-error-on": "Parameters:\n* $1 - timestamp", + "timedmedia-started-transcode": "Status update for Transcodes. Parameters:\n* $1 - time passed since transcoded started (e.g. \"{{int:timedmedia-minutes|1}}{{int:comma-separator}}{{int:timedmedia-seconds|42}}\"), uses the following messages:\n** {{msg-mw|Timedmedia-days}}\n** {{msg-mw|Timedmedia-hours}}\n** {{msg-mw|Timedmedia-minutes}}\n** {{msg-mw|Timedmedia-seconds}}\n** {{msg-mw|Comma-separator}}\n* $2 - percentage of transcode complete", + "timedmedia-percent-done": "Commented out at this time.\n\nStatus update for Transcodes. Parameters:\n* $1 - percentage of the file transcoded so far\nSee also:\n* {{msg-mw|timedmedia-unknown-target-size}}", + "timedmedia-in-job-queue": "Shown on the file description page in the {{msg-mw|timedmedia-status-header}} section.\n\nParameters:\n* $1 - the time the media has been in the job queue (e.g. \"{{int:timedmedia-minutes|1}}{{int:comma-separator}}{{int:timedmedia-seconds|42}}\"), uses the following messages:\n** {{msg-mw|Timedmedia-days}}\n** {{msg-mw|Timedmedia-hours}}\n** {{msg-mw|Timedmedia-minutes}}\n** {{msg-mw|Timedmedia-seconds}}\n** {{msg-mw|Comma-separator}}", + "timedmedia-unknown-target-size": "Commented out at this time.\n\nStatus update for Transcodes. Parameters:\n* $1 - the number of bytes of the file transcoded so far (localized)\nSee also:\n* {{msg-mw|Timedmedia-percent-done}}", + "timedmedia-days": "Used as the duration, as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-in-job-queue}}\n* {{msg-mw|Timedmedia-started-transcode}}\nParameters:\n* $1 - number of days\n{{Related|Timedmedia-days}}\n{{Identical|Day}}", + "timedmedia-hours": "Used as the duration, as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-in-job-queue}}\n* {{msg-mw|Timedmedia-started-transcode}}\nParameters:\n* $1 - number of hours\n{{Related|Timedmedia-days}}\n{{Identical|Hour}}", + "timedmedia-minutes": "Used as the duration, as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-in-job-queue}}\n* {{msg-mw|Timedmedia-started-transcode}}\nParameters:\n* $1 - minutes\n{{Related|Timedmedia-days}}\n{{Identical|Minute}}", + "timedmedia-seconds": "Used as the duration, as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-in-job-queue}}\n* {{msg-mw|Timedmedia-started-transcode}}\nParameters:\n* $1 - number of seconds\n{{Related|Timedmedia-days}}\n{{Identical|Second}}", + "timedmedia-reset": "Used as action link text and as dialog title.\n\nThe contents of the dialog is {{msg-mw|Timedmedia-reset-confirm}}.", + "timedmedia-reset-confirm": "Used as confirmation message in the dialog which has the title {{msg-mw|Timedmedia-reset}}.", + "timedmedia-reset-error": "Used as generic error message.", + "timedmedia-ogg": "{{optional}}\nUsed as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-source-audio-file-desc}}\n* {{msg-mw|Timedmedia-source-file-desc}}\n* {{msg-mw|Timedmedia-source-file}}", + "timedmedia-webm": "{{optional}}\nUsed as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-source-audio-file-desc}}\n* {{msg-mw|Timedmedia-source-file-desc}}\n* {{msg-mw|Timedmedia-source-file}}", + "timedmedia-mp4": "{{Optional}}\nUsed as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-source-audio-file-desc}}\n* {{msg-mw|Timedmedia-source-file-desc}}\n* {{msg-mw|Timedmedia-source-file}}", + "timedmedia-wav": "{{Optional}}\nUsed as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-source-audio-file-desc}}\n* {{msg-mw|Timedmedia-source-file-desc}}\n* {{msg-mw|Timedmedia-source-file}}", + "timedmedia-flac": "{{Optional}}\n\nUsed as <code>$1</code> in the following messages:\n* {{msg-mw|Timedmedia-source-audio-file-desc}}\n* {{msg-mw|Timedmedia-source-file-desc}}\n* {{msg-mw|Timedmedia-source-file}}", + "timedmedia-source-file": "The source file. Parameters:\n* $1 - file type; any one of the following messages:\n** {{msg-mw|Timedmedia-ogg}}\n** {{msg-mw|Timedmedia-webm}}\n** {{msg-mw|Timedmedia-mp4}}\n** {{msg-mw|Timedmedia-flac}}\n** {{msg-mw|Timedmedia-wav}}\nSee also:\n* {{msg-mw|Timedmedia-source-audio-file-desc}}\n* {{msg-mw|Timedmedia-source-file-desc}}\n{{Identical|Source}}", + "timedmedia-source-file-desc": "Source file description. This is a file title in the primary source attributes of a timed media file. I can look like \"''Original Ogg file, 640 Ć 480 (10 Mbps)''\".\n\nParameters:\n* $1 - file type; any one of the following messages:\n** {{msg-mw|Timedmedia-ogg}}\n** {{msg-mw|Timedmedia-webm}}\n** {{msg-mw|Timedmedia-mp4}}\n** {{msg-mw|Timedmedia-flac}}\n** {{msg-mw|Timedmedia-wav}}\n* $2 - resolution width\n* $3 - resolution height\n* $4 - human readable bitrate\nSee also:\n* {{msg-mw|Timedmedia-source-audio-file-desc}} - for audio file", + "timedmedia-source-audio-file-desc": "Source file description. Parameters:\n* $1 - file type; any one of the following messages:\n** {{msg-mw|Timedmedia-ogg}}\n** {{msg-mw|Timedmedia-webm}}\n** {{msg-mw|Timedmedia-mp4}}\n** {{msg-mw|Timedmedia-flac}}\n** {{msg-mw|Timedmedia-wav}}\n* $2 - human readable bitrate\nSee also:\n* {{msg-mw|Timedmedia-source-file-desc}} - for video file", + "timedmedia-derivative-160p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-160p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-240p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-240p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-360p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-360p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-480p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-480p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-720p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-720p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-1080p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-1080p.ogv": "{{optional}} A type of media format encoding", + "timedmedia-derivative-160p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-160p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-360p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-360p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-480p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-480p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-720p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-720p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-1080p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-1080p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-2160p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-2160p.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-360p.vp9.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-360p.vp9.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-480p.vp9.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-480p.vp9.webm": "A type of media format encoding", + "timedmedia-derivative-720p.vp9.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-720p.vp9.webm": "A type of media format encoding", + "timedmedia-derivative-1080p.vp9.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-1080p.vp9.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-2160p.vp9.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-2160p.vp9.webm": "{{optional}} A type of media format encoding", + "timedmedia-derivative-320p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-320p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-480p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-480p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-720p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-720p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-1080p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-1080p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-2160p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-desc-2160p.mp4": "{{optional}} A type of media format encoding", + "timedmedia-derivative-ogg": "{{optional}} Short form of a media format.", + "timedmedia-derivative-desc-ogg": "{{optional}} Media format.", + "timedmedia-derivative-opus": "{{optional}} Short form of a media format.", + "timedmedia-derivative-desc-opus": "{{optional}} Media format.", + "timedmedia-derivative-mp3": "{{optional}} Short form of a media format.", + "timedmedia-derivative-desc-mp3": "{{optional}} Media format.", + "timedmedia-derivative-m4a": "{{optional}} Short form of a media format.", + "timedmedia-derivative-desc-m4a": "{{optional}} Media format.", + "timedmedia-subtitle-new": "Used as page title.", + "timedmedia-subtitle-new-desc": "Refers to {{msg-mw|Timedmedia-subtitle-new-go}}.", + "timedmedia-subtitle-new-go": "Used as label for the Submit button.\n\nPreceded by (and used in) the description {{msg-mw|Timedmedia-subtitle-new-desc}}.\n{{Identical|Go}}", + "timedmedia-subtitle-language": "Subtitle names. Parameters are:\n* $1 - subtitle language\n* $2 - subtitle key\n{{Identical|Subtitle}}", + "timedmedia-subtitle-no-video": "Message for a TimedText page without an associated video file", + "timedmedia-subtitle-no-subtitles": "Parameters:\n* $1 is a language name.", + "timedmedia-subtitle-remote": "Used as page title. Parameters:\n* $1 - the display name of the repository\nThe page body for this page title is:\n* {{msg-mw|timedmedia-subtitle-remote-link}}", + "timedmedia-subtitle-remote-link": "Used as page body. Parameters:\n* $1 - the description URL of the file\n* $2 - the display name of the repository\nThe page title for this message is:\n* {{msg-mw|timedmedia-subtitle-remote}}", + "timedmediahandler": "{{doc-special|TimedMediaHandler}}", + "timedmedia-videos": "Number of videos on [[Special:TimedMediaHandler]]. Parameters:\n* $1 - number of videos\n{{Related|Timedmedia-format-type}}\n{{Identical|Video}}", + "timedmedia-ogg-videos": "Number of Ogg videos on [[Special:TimedMediaHandler]]. Parameters:\n* $1 - number of videos\n{{Related|Timedmedia-format-type}}", + "timedmedia-webm-videos": "Number of WebM videos on [[Special:TimedMediaHandler]]. Parameters:\n* $1 - number of videos\n{{Related|Timedmedia-format-type}}", + "timedmedia-derivative-state-transcodes": "Number of transcodes. Parameters:\n* $1 - number of transcodes", + "timedmedia-derivative-state-active": "currently active transcoes\nParameters are:\n* $1 number of transcodes", + "timedmedia-derivative-state-queued": "queued transcode jobs\nParameters are:\n* $1 number of transcodes", + "timedmedia-derivative-state-failed": "failed transcode jobs\nParameters are:\n* $1 number of transcodes", + "timedmedia-file": "Used as table column header.\n{{Identical|File}}", + "timedmedia-audios": "Number of audio files on [[Special:TimedMediaHandler]]. Parameters:\n* $1 - number of audio files\n{{Related|Timedmedia-format-type}}", + "timedmedia-ogg-audios": "Number of ogg audio files, displayed on [[Special:TimedMediaHandler]]. Parameters:\n* $1 - the number of files\n{{Related|Timedmedia-format-type}}", + "timedmedia-flac-audios": "Number of FLAC audio files, displayed on [[Special:TimedMediaHandler]]. Parameters:\n* $1 - the number of files\n{{Related|Timedmedia-format-type}}", + "timedmedia-wav-audios": "Number of WAV audio files, displayed on [[Special:TimedMediaHandler]]. Parameters:\n* $1 - the number of files\n{{Related|Timedmedia-format-type}}", + "right-transcode-reset": "{{doc-right|transcode-reset}}", + "right-transcode-status": "{{doc-right|transcode-status}}", + "action-transcode-status": "{{doc-action|transcode-status}}", + "orphanedtimedtext": "{{doc-special|OrphanedTimedText}}", + "orphanedtimedtext-summary": "Summary of Special:OrphanedTimedText.", + "orphanedtimedtext-unsupported": "Shown if Special:OrphanedTimedText isn't supported for the current database back-end.", + "orphanedtimedtext-notimedtext": "Shown on Special:OrphanedTimedText if the TimedText namespace is disabled on that wiki (i.e. $wgEnableLocalTimedText is set to false). Note, do not use <nowiki>{{ns:TimedText}}</nowiki> in this message.", + "apihelp-query+transcodestatus-description": "{{doc-apihelp-description|query+transcodestatus}}", + "apihelp-query+transcodestatus-example-1": "{{doc-apihelp-example|query+transcodestatus}}", + "apihelp-query+videoinfo-description": "{{doc-apihelp-description|query+videoinfo}}", + "apihelp-query+videoinfo-param-prop": "{{doc-apihelp-param|query+videoinfo|prop}}", + "apihelp-query+videoinfo-example-1": "{{doc-apihelp-example|query+videoinfo}}", + "apihelp-transcodereset-description": "{{doc-apihelp-description|transcodereset}}", + "apihelp-transcodereset-param-title": "{{doc-apihelp-param|transcodereset|title}}", + "apihelp-transcodereset-param-transcodekey": "{{doc-apihelp-param|transcodereset|transcodekey}}", + "apihelp-transcodereset-example-1": "{{doc-apihelp-example|transcodereset}}", + "apihelp-transcodereset-example-2": "{{doc-apihelp-example|transcodereset}}" +} diff --git a/extensions/TimedMediaHandler/i18n/qu.json b/extensions/TimedMediaHandler/i18n/qu.json new file mode 100644 index 00000000..4942568f --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/qu.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "AlimanRuna" + ] + }, + "timedmedia-no-player-js": "Way way, wamp'unaykipiqa JavaScript nisqaman ama nisqam icha q'imisqa purichiq manam kanchu.<br />\n<a href=\"$1\">Widyuta chaqnamuyta</a> icha <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">purichiqta chaqnamuyta</a> atinki widyuta wamp'unaykipi purichinaykipaq.", + "timedmedia-more": "Astawan...", + "timedmedia-dismiss": "Wichq'ay", + "timedmedia-download": "WillaƱiqita chaqnamuy", + "timedmedia-desc-link": "Kay willaƱiqimanta", + "timedmedia-source-file": "$1 pukyu", + "timedmedia-source-audio-file-desc": "Qallariy $1 willaƱiqi ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/ro.json b/extensions/TimedMediaHandler/i18n/ro.json new file mode 100644 index 00000000..4162d861 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ro.json @@ -0,0 +1,93 @@ +{ + "@metadata": { + "authors": [ + "Firilacroco", + "KlaudiuMihaila", + "Mihai", + "Minisarm", + "Stelistcristi", + "ImGelu" + ] + }, + "timedmedia-desc": "Gestionar pentru fiČiere audio, video Či subtitrÄri sincronizate, cu suport pentru formatele WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "fiČier audio ogg $1, $2", + "timedmedia-ogg-short-video": "fiČier video ogg $1, $2", + "timedmedia-ogg-short-general": "fiČier media ogg $1, $2", + "timedmedia-ogg-long-audio": "fiČier audio ogg $1, lungime $2, $3", + "timedmedia-ogg-long-video": "fiČier video ogg $1, lungime $2, $4Ć$5 pixeli, $3", + "timedmedia-ogg-long-multiplexed": "fiČier multiplexat audio/video ogg, $1, lungime $2, $4Ć$5 pixeli, $3", + "timedmedia-ogg-long-general": "fiČier media ogg, lungime $2, $3", + "timedmedia-ogg-long-error": "fiČier ogg incorect: $1", + "timedmedia-webm-short-video": "fiČier video WebM $1, $2", + "timedmedia-webm-long-video": "fiČier audio/video WebM, $1, lungime $2, $4 Ć $5 pixeli, $3 per ansamblu", + "timedmedia-flac-short-audio": "fiČier audio FLAC, $1", + "timedmedia-flac-long-audio": "fiČier audio FLAC, lungime $1, $2 per ansmablu", + "timedmedia-mp4-short-video": "fiČier video MP4 $1, $2", + "timedmedia-mp4-long-video": "fiČier audio/video MP4, $1, lungime $2, $4 Ć $5 pixeli, $3 per ansamblu", + "timedmedia-no-player-js": "Ne pare rÄu, Ć®nsÄ navigatorul dumneavoastrÄ fie are JavaScript dezactivat, fie nu conČine niciun player suportat.<br />\nPuteČi <a href=\"$1\">descÄrca clipul</a> sau puteČi <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">descÄrca un player</a> pentru a-l reda direct Ć®n navigator.", + "timedmedia-more": "Mai multā¦", + "timedmedia-dismiss": "Ćnchide", + "timedmedia-download": "DescarcÄ fiČierul", + "timedmedia-play-media": "RedÄ fiČierul media", + "timedmedia-desc-link": "Despre acest fiČier", + "timedmedia-oggThumb-version": "OggHandler necesitÄ oggThumb, versiunea $1 sau mai recentÄ.", + "timedmedia-oggThumb-failed": "oggThumb nu a reuČit sÄ creeze miniatura.", + "timedmedia-status-header": "Starea codificÄrii", + "timedmedia-update-status": "ActualizeazÄ starea codificÄrii", + "timedmedia-status": "Stare", + "timedmedia-status-unknown": "Stare necunoscutÄ", + "timedmedia-transcodebitrate": "RatÄ de bit", + "timedmedia-transcodeinfo": "Format", + "timedmedia-actions": "AcČiuni", + "timedmedia-direct-link": "DescarcÄ", + "timedmedia-not-ready": "Nu este gata", + "timedmedia-completed-on": "Finalizat $1", + "timedmedia-error-on": "Eroare la $1", + "timedmedia-started-transcode": "PornitÄ acum $1. $2", + "timedmedia-percent-done": "Aproximativ $1% finalizat", + "timedmedia-in-job-queue": "AdÄugat la Čirul de sarcini acum $1", + "timedmedia-unknown-target-size": "Dimensiune finalÄ necunoscutÄ, $1 codificaČi", + "timedmedia-days": "{{PLURAL:$1|o zi|$1 zile|$1 de zile}}", + "timedmedia-hours": "{{PLURAL:$1|o orÄ|$1 ore|$1 de ore}}", + "timedmedia-minutes": "{{PLURAL:$1|un minut|$1 minute|$1 de minute}}", + "timedmedia-seconds": "{{PLURAL:$1|o secundÄ|$1 secunde|$1 de secunde}}", + "timedmedia-reset": "ReiniČializeazÄ codificarea", + "timedmedia-reset-confirm": "ReiniČializarea acestei codificÄri va elimina orice fiČier existent (dacÄ existÄ) Či va readÄuga codificarea la Čirul de sarcini. Va dura ceva timp pentru a recodifica. <br /><br />\nSunteČi sigur cÄ doriČi sÄ continuaČi?", + "timedmedia-reset-error": "Eroare la reiniČializarea codificÄrii.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "SursÄ $1", + "timedmedia-source-file-desc": "FiČier $1 original, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "FiČier $1 original ($2)", + "timedmedia-derivative-desc-160p.ogv": "Videoclip Ogg cu lÄČime de bandÄ micÄ (160P)", + "timedmedia-derivative-desc-360p.ogv": "Videoclip Ogg pentru redare pe web (360P)", + "timedmedia-derivative-desc-480p.ogv": "Videoclip Ogg pentru redare pe web (480P)", + "timedmedia-derivative-desc-720p.ogv": "Videoclip Ogg descÄrcabil, de Ć®naltÄ calitate (720P)", + "timedmedia-derivative-desc-160p.webm": "WebM pentru redare pe web (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM pentru redare pe web (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM pentru redare pe web (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM descÄrcabil, de Ć®naltÄ calitate (720P)", + "timedmedia-derivative-480p.vp9.webm": "VP9 480P", + "timedmedia-derivative-desc-320p.mp4": "MP4 prietenos cu dispozitivele (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 pentru redare pe web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 de calitate HD (720P)", + "timedmedia-subtitle-new": "Creare traducere nouÄ sau modificare una existentÄ", + "timedmedia-subtitle-new-desc": "AlegeČi limba Či apÄsaČi butonul '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Du-te", + "timedmedia-subtitle-language": "Subtitrare Ć®n $1 ($2)", + "timedmedia-subtitle-no-video": "Nu existÄ niciun videoclip asociat cu pagina curentÄ de subtitrare", + "timedmedia-subtitle-no-subtitles": "Nu existÄ Ć®n acest moment subtitrÄri Ć®n limba $1 pentru acest videoclip. PuteČi [{{fullurl:{{FULLPAGENAME}}|action=edit}} modifica aceastÄ paginÄ] pentru a le adÄuga.", + "timedmedia-subtitle-remote": "Subtitrarea sincronizatÄ a acestui fiČier este gÄzduitÄ la $1", + "timedmedia-subtitle-remote-link": "PuteČi [$1 vizualiza pagina descriptivÄ] a acestui fiČier la $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 videoclip|$1 videoclipuri|$1 de videoclipuri}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 videoclip Ogg|$1 videoclipuri Ogg|$1 de videoclipuri Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 videoclip WebM|$1 videoclipuri WebM|$1 de videoclipuri WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 codificare|$1 codificÄri|$1 de codificÄri}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 codificare Ć®n curs|$1 codificÄri Ć®n curs|$1 de codificÄri Ć®n curs}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 codificare Ć®n aČteptare|$1 codificÄri Ć®n aČteptare|$1 de codificÄri Ć®n aČteptare}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 codificare eČuatÄ|$1 codificÄri eČuate|$1 de codificÄri eČuate}}", + "timedmedia-file": "FiČier", + "right-transcode-reset": "ReiniČializeazÄ videoclipuri nereuČit codificate pentru ca acestea sÄ fie readÄugate la Čirul de sarcini.", + "right-transcode-status": "VizualizeazÄ [[Special:TimedMediaHandler|informaČii despre activitatea curentÄ de codificare]]", + "action-transcode-status": "vizualizaČi statutul actual al codificÄrii" +} diff --git a/extensions/TimedMediaHandler/i18n/roa-tara.json b/extensions/TimedMediaHandler/i18n/roa-tara.json new file mode 100644 index 00000000..a972d6b7 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/roa-tara.json @@ -0,0 +1,91 @@ +{ + "@metadata": { + "authors": [ + "Joetaras" + ] + }, + "timedmedia-desc": "Gestore pe le file audio, video e teste temporizzate, cu le formate supportate pe WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "File audie Ogg $1, $2", + "timedmedia-ogg-short-video": "File video Ogg $1, $2", + "timedmedia-ogg-short-general": "File media Ogg $1, $2", + "timedmedia-ogg-long-audio": "File audie Ogg $1, lunghezze $2, $3", + "timedmedia-ogg-long-video": "File video Ogg $1, lunghezze $2, $4 x $5 pixel, $3", + "timedmedia-ogg-long-multiplexed": "File multiplexed audie e video Ogg $1, lunghezze $2, $4 x $5 pixel, $3 in totale", + "timedmedia-ogg-long-general": "File media Ogg, lunghezze $2, $3", + "timedmedia-ogg-long-error": "Ogg file invalide: $1", + "timedmedia-webm-short-video": "WebM $1 file video, $2", + "timedmedia-webm-long-video": "File WebM audio/video, $1, lunghezze $2, $4 Ć $5 pixel, $3 in totale", + "timedmedia-flac-short-audio": "File audio FLAC, $1", + "timedmedia-flac-long-audio": "File audio FLAC, lunghezze $1, in totale $2", + "timedmedia-wav-short-audio": "File audio WAV, $1", + "timedmedia-wav-long-audio": "File audio WAV, lunghezze $1, in totale $2", + "timedmedia-wav-pcm-required": "Tu puĆØ sulamende carecĆ WAV de tipe PCM (Codece de Modulazione Pulsate).", + "timedmedia-mp4-short-video": "MP4 $1 file video, $2", + "timedmedia-mp4-long-video": "File MP4 audio/video, $1, lunghezze $2, $4 Ć $5 pixel, $3 in totale", + "timedmedia-no-player-js": "Ne dispiace, 'u browser tune tĆØne 'u JavaScript disabbilitate o non ge tĆØne 'n'esecutore supportate.<br />\nTu puĆØ <a href=\"$1\">scarecĆ 'u video</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">scarecĆ 'n'esecutore</a> pe 'ndrucĆ 'u video sus a 'u browser tune.", + "timedmedia-more": "De cchiĆ¹...", + "timedmedia-dismiss": "Chiude", + "timedmedia-download": "Scareche stu file", + "timedmedia-play-media": "Esegue 'u media", + "timedmedia-desc-link": "'Mbormaziune sus a stu file", + "timedmedia-oggThumb-version": "OggHandler vole 'a versine de oggThumb $1 o cchiĆ¹ ierte.", + "timedmedia-oggThumb-failed": "oggThumn ha fallite a ccrejĆ le miniature.", + "timedmedia-status-header": "State d'a codifeche", + "timedmedia-update-status": "Aggiorne 'u state d'a codifeche", + "timedmedia-status": "State", + "timedmedia-status-unknown": "State scanusciute", + "timedmedia-transcodebitrate": "Bitrate", + "timedmedia-transcodeduration": "Tiembe de codifiche", + "timedmedia-transcodeinfo": "Formate", + "timedmedia-actions": "Aziune", + "timedmedia-direct-link": "Scareche", + "timedmedia-not-ready": "Non g'ĆØ pronde", + "timedmedia-completed-on": "Combletate $1", + "timedmedia-error-on": "Errore sus a $1", + "timedmedia-started-transcode": "Accumenzate $1 fĆ . $2", + "timedmedia-percent-done": "CchiĆ¹ o mene $1% fatte", + "timedmedia-in-job-queue": "Aggiunde a 'a FatƬe in code $1 fĆ ", + "timedmedia-unknown-target-size": "Dimenzione d'a destinazione scanusciute, $1 codificate", + "timedmedia-days": "{{PLURAL:$1|1 sciurne|$1 sciurne}}", + "timedmedia-hours": "{{PLURAL:$1|1 ore|$1 ore}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minute|$1 minute}}", + "timedmedia-seconds": "{{PLURAL:$1|1 seconde|$1 seconde}}", + "timedmedia-reset": "Azzere 'a transcodifeche", + "timedmedia-reset-confirm": "Stoche azzere sta transcodifiche ca adda luĆ ogne file esistende (ce presende), e pĆ² aggiunge 'a transcodifiche jndr'Ć code d'a fatƬe. CchiĆ¹ vote accumenze 'a transcodifiche. <br /><br />\nSƬ secure ca vuĆØ ccu vvĆØ nnande?", + "timedmedia-reset-error": "Errore mendre ste azzerave 'a fatƬe de transcodifiche.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 sorgende", + "timedmedia-source-file-desc": "File origgenale $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "File origgenale $1 ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg video cu banda vasce (160P)", + "timedmedia-derivative-desc-360p.ogv": "Ogg video cu streaming web (360P)", + "timedmedia-derivative-desc-480p.ogv": "Ogg video cu streaming web (480P)", + "timedmedia-derivative-desc-720p.ogv": "Ogg video de qualitate ierte scarecabbele (720P)", + "timedmedia-derivative-desc-160p.webm": "Flusse web WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "Flusse web WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "Flusse web WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM de qualitate ierte scarecabbele (720P)", + "timedmedia-derivative-desc-320p.mp4": "Dispositive-amiche MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Streaming web MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "Qualitate HD MP4 (720P)", + "timedmedia-subtitle-new": "Ccreje 'na traduziona nove o ne cange une esistende", + "timedmedia-subtitle-new-desc": "Scacchie 'na lĆØnghe e cazze 'u buttone '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "VĆ©je", + "timedmedia-subtitle-language": "$1 ($2) sottotitele", + "timedmedia-subtitle-no-video": "Non ge stonne video associate cu 'u sottotitole d'a pĆ gene de mĆ²", + "timedmedia-subtitle-no-subtitles": "Non ge stonne sottotitole pe mĆ² jndr'Ć $1 pe stu video, tu puĆØ [{{fullurl:{{FULLPAGENAME}}|action=edit}} cangiĆ sta pĆ gene] o aggiungerle", + "timedmedia-subtitle-remote": "'U teste temborizzate pe stu file jĆØ ospitate sus a $1", + "timedmedia-subtitle-remote-link": "Tu puĆØ [$1 'ndrucĆ 'a pĆ gene de descrizione] pe stu file sus a $2", + "timedmediahandler": "Gestore TimedMedia", + "timedmedia-videos": "{{PLURAL:$1|$1 video}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Video Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 Video WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodifiche}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodifiche in esecuzione}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodifiche in code}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transcodifiche fallite}}", + "timedmedia-file": "File", + "right-transcode-reset": "Azzeramende fallite o le video transcodificate onne state sckaffate cchiĆ¹ de 'na vote jndr'Ć code d'a fatƬe.", + "right-transcode-status": "'Ndruche [[Special:TimedMediaHandler|le 'mbormaziune sus a l'attivitĆ de transcodifiche de mĆ²]]", + "action-transcode-status": "'ndruche 'u state de mĆ² d'a transcodifeche" +} diff --git a/extensions/TimedMediaHandler/i18n/ru.json b/extensions/TimedMediaHandler/i18n/ru.json new file mode 100644 index 00000000..d4bf8e64 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ru.json @@ -0,0 +1,111 @@ +{ + "@metadata": { + "authors": [ + "Ahonc", + "Amire80", + "Eleferen", + "Kaganer", + "Kalan", + "Kv75", + "MaxSem", + "Okras", + "ŠŠ»ŠµŠŗŃŠ°Š½Š“Ń Š”ŠøŠ³Š°ŃŃŠ²", + "NBS" + ] + }, + "timedmedia-desc": "ŠŠ±ŃŠ°Š±Š¾ŃŃŠøŠŗ Š“Š»Ń Š°ŃŠ“ŠøŠ¾, Š²ŠøŠ“ŠµŠ¾ Šø ŃŃŠ±ŃŠøŃŃŠ¾Š², Ń ŠæŠ¾Š“Š“ŠµŃŠ¶ŠŗŠ¾Š¹ ŃŠ¾ŃŠ¼Š°ŃŠ¾Š²: WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "ŠŠ²ŃŠŗŠ¾Š²Š¾Š¹ ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-video": "ŠŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-general": "ŠŠµŠ“ŠøŠ°ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-long-audio": "ŠŠ²ŃŠŗŠ¾Š²Š¾Š¹ ŃŠ°Š¹Š» Ogg $1, Š“Š»ŠøŃŠµŠ»ŃŠ½Š¾ŃŃŃ $2, $3", + "timedmedia-ogg-long-video": "Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg $1, Š“Š»ŠøŃŠµŠ»ŃŠ½Š¾ŃŃŃ $2, $4 Ć $5 {{PLURAL:$5|ŠæŠøŠŗŃŠµŠ»Ń|ŠæŠøŠŗŃŠµŠ»Ń|ŠæŠøŠŗŃŠµŠ»ŠµŠ¹}}, $3", + "timedmedia-ogg-long-multiplexed": "Š¼ŃŠ»ŃŃŠøŠæŠ»ŠµŠŗŃŠ½ŃŠ¹ Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ŃŠ°Š¹Š» Ogg, $1, Š“Š»ŠøŃŠµŠ»ŃŠ½Š¾ŃŃŃ $2, $4 Ć $5 {{PLURAL:$5|ŠæŠøŠŗŃŠµŠ»Ń|ŠæŠøŠŗŃŠµŠ»Ń|ŠæŠøŠŗŃŠµŠ»ŠµŠ¹}}, $3 Š²ŃŠµŠ³Š¾", + "timedmedia-ogg-long-general": "Š¼ŠµŠ“ŠøŠ°ŃŠ°Š¹Š» Ogg, Š“Š»ŠøŃŠµŠ»ŃŠ½Š¾ŃŃŃ $2, $3", + "timedmedia-ogg-long-error": "Š½ŠµŠæŃŠ°Š²ŠøŠ»ŃŠ½ŃŠ¹ Ogg-ŃŠ°Š¹Š»: $1", + "timedmedia-ogg-long-no-streams": "ŠŃŠ»ŃŃŠøŠ¼ŠµŠ“ŠøŠ°-ŃŠ°Š¹Š» ogg. ŠŃŠµŠ“ŃŠæŃŠµŠ¶Š“ŠµŠ½ŠøŠµ: ŠŠø Š¾Š“ŠøŠ½ ŠøŠ· ŠŗŠ¾Š“ŠµŠŗŠ¾Š², ŠøŃŠæŠ¾Š»ŃŠ·ŃŠµŠ¼ŃŃ
Š² ŃŃŠ¾Š¼ ŃŠ°Š¹Š»Šµ, Š½Šµ Š¾ŠæŃŠµŠ“ŠµŠ»ŃŠ½.", + "timedmedia-webm-short-video": "WebM $1 Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š», $2", + "timedmedia-webm-long-video": "WebM Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ ŃŠ°Š¹Š», $1, ŠæŃŠ¾Š“Š¾Š»Š¶ŠøŃŠµŠ»ŃŠ½Š¾ŃŃŃ $2, $4 Ć $5 {{PLURAL:$5|ŠæŠøŠŗŃŠµŠ»Ń|ŠæŠøŠŗŃŠµŠ»Ń|ŠæŠøŠŗŃŠµŠ»ŠµŠ¹}}, Š²ŃŠµŠ³Š¾ $3", + "timedmedia-flac-short-audio": "ŠŃŠ“ŠøŠ¾ŃŠ°Š¹Š» FLAC, $1", + "timedmedia-flac-long-audio": "ŠŃŠ“ŠøŠ¾ŃŠ°Š¹Š» FLAC, Š“Š»ŠøŠ½Š° ā $1, Š±ŠøŃŃŠµŠ¹Ń ā $2", + "timedmedia-wav-short-audio": "ŠŃŠ“ŠøŠ¾ŃŠ°Š¹Š» WAV, $1", + "timedmedia-wav-long-audio": "ŠŃŠ“ŠøŠ¾ŃŠ°Š¹Š» WAV, Š“Š»ŠøŠ½Š° ā $1, Š±ŠøŃŃŠµŠ¹Ń ā $2", + "timedmedia-wav-pcm-required": "ŠŃ Š¼Š¾Š¶ŠµŃŠµ Š·Š°Š³ŃŃŠ·ŠøŃŃ ŃŠ¾Š»ŃŠŗŠ¾ PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "MP4 $1 Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š», $2", + "timedmedia-mp4-long-video": "ŠŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ŃŠ°Š¹Š» MP4 $1, Š“Š»ŠøŠ½Š° ā $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ»ŠµŠ¹, Š±ŠøŃŃŠµŠ¹Ń ā $3", + "timedmedia-no-player-js": "Š ŃŠ¾Š¶Š°Š»ŠµŠ½ŠøŃ, Š² Š²Š°ŃŠµŠ¼ Š±ŃŠ°ŃŠ·ŠµŃŠµ Š¾ŃŠŗŠ»ŃŃŃŠ½ JavaScript, ŠøŠ»Šø Š½Šµ ŠøŠ¼ŠµŠµŃŃŃ ŃŃŠµŠ±ŃŠµŠ¼Š¾Š³Š¾ ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń.<br />\nŠŃ Š¼Š¾Š¶ŠµŃŠµ <a href=\"$1\">Š·Š°Š³ŃŃŠ·ŠøŃŃ ŃŠ¾Š»ŠøŠŗ</a> ŠøŠ»Šø <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š·Š°Š³ŃŃŠ·ŠøŃŃ ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń</a> Š“Š»Ń Š²Š¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŠ“ŠµŠ½ŠøŃ ŃŠ¾Š»ŠøŠŗŠ° Š² Š±ŃŠ°ŃŠ·ŠµŃŠµ.", + "timedmedia-more": "ŠŠ¾Š»ŃŃŠµā¦", + "timedmedia-dismiss": "Š”ŠŗŃŃŃŃ", + "timedmedia-download": "ŠŠ°Š³ŃŃŠ·ŠøŃŃ ŃŠ°Š¹Š»", + "timedmedia-play-media": "ŠŠ¾ŃŠæŃŠ¾ŠøŠ·Š²ŠµŃŃŠø Š¼ŠµŠ“ŠøŠ°ŃŠ°Š¹Š»", + "timedmedia-desc-link": "ŠŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŃ Š¾Š± ŃŃŠ¾Š¼ ŃŠ°Š¹Š»Šµ", + "timedmedia-oggThumb-version": "OggHandler ŃŃŠµŠ±ŃŠµŃ oggThumb Š²ŠµŃŃŠøŠø $1 ŠøŠ»Šø Š±Š¾Š»ŠµŠµ ŠæŠ¾Š·Š“Š½ŠµŠ¹.", + "timedmedia-oggThumb-failed": "oggThumb Š½Šµ ŃŠ“Š°Š»Š¾ŃŃ ŃŠ¾Š·Š“Š°ŃŃ Š¼ŠøŠ½ŠøŠ°ŃŃŃŃ.", + "timedmedia-status-header": "Š”Š¾ŃŃŠ¾ŃŠ½ŠøŠµ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ", + "timedmedia-update-status": "ŠŠ±Š½Š¾Š²ŠøŃŃ ŃŃŠ°ŃŃŃ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ", + "timedmedia-status": "Š”Š¾ŃŃŠ¾ŃŠ½ŠøŠµ", + "timedmedia-status-unknown": "ŠŠµŠøŠ·Š²ŠµŃŃŠ½Š¾Šµ ŃŠ¾ŃŃŠ¾ŃŠ½ŠøŠµ", + "timedmedia-transcodeinfo": "Š¤Š¾ŃŠ¼Š°Ń", + "timedmedia-actions": "ŠŠµŠ¹ŃŃŠ²ŠøŃ", + "timedmedia-direct-link": "Š”ŠŗŠ°ŃŠ°ŃŃ", + "timedmedia-not-ready": "ŠŠµ Š³Š¾ŃŠ¾Š²", + "timedmedia-completed-on": "ŠŠ°Š²ŠµŃŃŠµŠ½Š¾ $1", + "timedmedia-error-on": "ŠŃŠøŠ±ŠŗŠ° $1", + "timedmedia-started-transcode": "ŠŠ°ŠæŃŃŠµŠ½Š¾ $1 Š½Š°Š·Š°Š“. $2", + "timedmedia-percent-done": "ŠŃŠøŠ¼ŠµŃŠ½Š¾ $1% Š²ŃŠæŠ¾Š»Š½ŠµŠ½Š¾", + "timedmedia-in-job-queue": "ŠŠ¾Š±Š°Š²Š»ŠµŠ½Š¾ Š² Š¾ŃŠµŃŠµŠ“Ń Š·Š°Š“Š°Š½ŠøŠ¹ $1 Š½Š°Š·Š°Š“", + "timedmedia-unknown-target-size": "ŠŠµŠøŠ·Š²ŠµŃŃŠ½ŃŠ¹ ŃŠµŠ»ŠµŠ²Š¾Š¹ ŃŠ°Š·Š¼ŠµŃ, $1 ŠæŃŠø ŠŗŠ¾Š“ŠøŃŠ¾Š²ŠŗŠµ", + "timedmedia-days": "{{PLURAL:$1|$1 Š“ŠµŠ½Ń|$1 Š“Š½Ń|$1 Š“Š½ŠµŠ¹}}", + "timedmedia-hours": "{{PLURAL:$1|$1 ŃŠ°Ń|$1 ŃŠ°ŃŠ°|$1 ŃŠ°ŃŠ¾Š²}}", + "timedmedia-minutes": "{{PLURAL:$1|$1 Š¼ŠøŠ½ŃŃŠ°|$1 Š¼ŠøŠ½ŃŃŃ|$1 Š¼ŠøŠ½ŃŃ}}", + "timedmedia-seconds": "{{PLURAL:$1|$1 ŃŠµŠŗŃŠ½Š“Š°|$1 ŃŠµŠŗŃŠ½Š“Ń|$1 ŃŠµŠŗŃŠ½Š“}}", + "timedmedia-reset": "ŠŠµŃŠµŠ·Š°ŠæŃŃŠŗ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ", + "timedmedia-reset-confirm": "ŠŠµŃŠµŠ·Š°ŠæŃŃŠŗ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ ŃŠ“Š°Š»ŠøŃ ŃŃŃŠµŃŃŠ²ŃŃŃŠøŠ¹ ŃŠ°Š¹Š» (ŠµŃŠ»Šø Š¾Š½ ŃŃŃŠµŃŃŠ²ŃŠµŃ), Šø Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠµ Š²Š½Š¾Š²Ń Š±ŃŠ“ŠµŃ Š“Š¾Š±Š°Š²Š»ŠµŠ½Š¾ Š² Š¾ŃŠµŃŠµŠ“Ń Š·Š°Š“Š°Š½ŠøŠ¹. ŠŠ¾Š²ŃŠ¾ŃŠ½Š¾Šµ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠµ Š·Š°Š¹Š¼ŠµŃ Š½ŠµŠŗŠ¾ŃŠ¾ŃŠ¾Šµ Š²ŃŠµŠ¼Ń. <br /><br />\nŠŃ ŃŠ²ŠµŃŠµŠ½Ń, ŃŃŠ¾ Ń
Š¾ŃŠøŃŠµ ŠæŃŠ¾Š“Š¾Š»Š¶ŠøŃŃ?", + "timedmedia-reset-error": "ŠŃŠøŠ±ŠŗŠ° ŠæŃŠø ŠæŠµŃŠµŠ·Š°ŠæŃŃŠŗŠµ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "ŠŃŃŠ¾ŃŠ½ŠøŠŗ $1", + "timedmedia-source-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š» $1 ŃŠ°Š¹Š»Š°, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š»ŃŠ½ŃŠ¹ $1-ŃŠ°Š¹Š» ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg-Š²ŠøŠ“ŠµŠ¾ Š½ŠøŠ·ŠŗŠ¾Š³Š¾ ŠŗŠ°ŃŠµŃŃŠ²Š° (160p)", + "timedmedia-derivative-desc-360p.ogv": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Š¾Šµ Ogg-Š²ŠøŠ“ŠµŠ¾ (360p)", + "timedmedia-derivative-desc-480p.ogv": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Š¾Šµ Ogg-Š²ŠøŠ“ŠµŠ¾ (480p)", + "timedmedia-derivative-desc-720p.ogv": "Ogg-Š²ŠøŠ“ŠµŠ¾ Š²ŃŃŠ¾ŠŗŠ¾Š³Š¾ ŠŗŠ°ŃŠµŃŃŠ²Š° (720p)", + "timedmedia-derivative-desc-1080p.ogv": "Š”ŠŗŠ°ŃŠøŠ²Š°ŠµŠ¼Š¾Šµ Ogg-Š²ŠøŠ“ŠµŠ¾ Š² ŃŠ¾ŃŠ¼Š°ŃŠµ Full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Š¾Šµ WebM-Š²ŠøŠ“ŠµŠ¾ (160p)", + "timedmedia-derivative-desc-360p.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Š¾Šµ WebM-Š²ŠøŠ“ŠµŠ¾ (360p)", + "timedmedia-derivative-desc-480p.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Š¾Šµ WebM-Š²ŠøŠ“ŠµŠ¾ (480p)", + "timedmedia-derivative-desc-720p.webm": "WebM-Š²ŠøŠ“ŠµŠ¾ Š²ŃŃŠ¾ŠŗŠ¾Š³Š¾ ŠŗŠ°ŃŠµŃŃŠ²Š° (720p)", + "timedmedia-derivative-desc-1080p.webm": "Š”ŠŗŠ°ŃŠøŠ²Š°ŠµŠ¼Š¾Šµ WebM-Š²ŠøŠ“ŠµŠ¾ Š² ŃŠ¾ŃŠ¼Š°ŃŠµ Full HD (1080P)", + "timedmedia-derivative-desc-320p.mp4": "ŠŠ“Š°ŠæŃŠøŃŠ¾Š²Š°Š½Š½ŃŠ¹ Š“Š»Ń ŃŃŃŃŠ¾Š¹ŃŃŠ²Š° MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Š¾Šµ MP4-Š²ŠøŠ“ŠµŠ¾ (480p)", + "timedmedia-derivative-desc-720p.mp4": "MP4 Š² HD-ŠŗŠ°ŃŠµŃŃŠ²Šµ (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4-Š²ŠøŠ“ŠµŠ¾ Š² ŃŠ¾ŃŠ¼Š°ŃŠµ Full HD (1080P)", + "timedmedia-subtitle-new": "Š”Š¾Š·Š“Š°ŃŃ Š½Š¾Š²ŃŠ¹ ŠæŠµŃŠµŠ²Š¾Š“ ŠøŠ»Šø ŃŠµŠ“Š°ŠŗŃŠøŃŠ¾Š²Š°ŃŃ ŃŃŃŠµŃŃŠ²ŃŃŃŠøŠ¹", + "timedmedia-subtitle-new-desc": "ŠŃŠ±ŠµŃŠøŃŠµ ŃŠ·ŃŠŗ Šø Š½Š°Š¶Š¼ŠøŃŠµ ŠŗŠ½Š¾ŠæŠŗŃ '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "ŠŃŠæŠ¾Š»Š½ŠøŃŃ", + "timedmedia-subtitle-language": "$1 ($2) ŃŃŠ±ŃŠøŃŃŃ", + "timedmedia-subtitle-no-video": "ŠŠµŃ Š²ŠøŠ“ŠµŠ¾, ŃŠ²ŃŠ·Š°Š½Š½Š¾Š³Š¾ Ń ŃŠµŠŗŃŃŠµŠ¹ ŃŃŃŠ°Š½ŠøŃŠµŠ¹ ŃŃŠ±ŃŠøŃŃŠ¾Š²", + "timedmedia-subtitle-no-subtitles": "Š Š½Š°ŃŃŠ¾ŃŃŠµŠµ Š²ŃŠµŠ¼Ń Š½ŠµŃ ŃŃŠ±ŃŠøŃŃŠ¾Š² Š½Š° $1 Š“Š»Ń ŃŃŠ¾Š³Š¾ Š²ŠøŠ“ŠµŠ¾, ŠŃ Š¼Š¾Š¶ŠµŃŠµ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ŠøŠ·Š¼ŠµŠ½ŠøŃŃ ŃŃŃ ŃŃŃŠ°Š½ŠøŃŃ] Š“Š»Ń ŠøŃ
Š“Š¾Š±Š°Š²Š»ŠµŠ½ŠøŃ", + "timedmedia-subtitle-remote": "Š”ŃŠ±ŃŠøŃŃŃ Š“Š»Ń ŃŃŠ¾Š³Š¾ ŃŠ°Š¹Š»Š° ŃŠ°Š·Š¼ŠµŃŠµŠ½Ń Š½Š° $1", + "timedmedia-subtitle-remote-link": "ŠŃ Š¼Š¾Š¶ŠµŃŠµ [$1 ŠæŠ¾ŃŠ¼Š¾ŃŃŠµŃŃ ŃŃŃŠ°Š½ŠøŃŃ Š¾ŠæŠøŃŠ°Š½ŠøŃ] ŃŃŠ¾Š³Š¾ ŃŠ°Š¹Š»Š° Š½Š° $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "$1 Š²ŠøŠ“ŠµŠ¾{{PLURAL:$1|ŃŠ°Š¹Š»|ŃŠ°Š¹Š»Š°|ŃŠ°Š¹Š»Š¾Š²}}", + "timedmedia-ogg-videos": "$1 Ogg Š²ŠøŠ“ŠµŠ¾{{PLURAL:$1|ŃŠ°Š¹Š»|ŃŠ°Š¹Š»Š°|ŃŠ°Š¹Š»Š¾Š²}}", + "timedmedia-webm-videos": "$1 WebM Š²ŠøŠ“ŠµŠ¾{{PLURAL:$1|ŃŠ°Š¹Š»|ŃŠ°Š¹Š»Š°|ŃŠ°Š¹Š»Š¾Š²}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠµ|$1 Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ|$1 Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠ¹}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 Š·Š°ŠæŃŃŠµŠ½Š½Š¾Šµ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠµ|$1 Š·Š°ŠæŃŃŠµŠ½Š½ŃŃ
Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ|$1 Š·Š°ŠæŃŃŠµŠ½Š½ŃŃ
Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠ¹}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 ŠæŠ¾ŃŃŠ°Š²Š»ŠµŠ½Š½Š¾Šµ Š² Š¾ŃŠµŃŠµŠ“Ń Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠµ|$1 ŠæŠ¾ŃŃŠ°Š²Š»ŠµŠ½Š½ŃŃ
Š² Š¾ŃŠµŃŠµŠ“Ń Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ|$1 ŠæŠ¾ŃŃŠ°Š²Š»ŠµŠ½Š½ŃŃ
Š² Š¾ŃŠµŃŠµŠ“Ń Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠ¹}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 Š½ŠµŃŠ“Š°Š²ŃŠµŠµŃŃ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠµ|$1 Š½ŠµŃŠ“Š°Š²ŃŠøŃ
ŃŃ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ|$1 Š½ŠµŃŠ“Š°Š²ŃŠøŃ
ŃŃ Š“ŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŠ¹}}", + "timedmedia-file": "Š¤Š°Š¹Š»", + "timedmedia-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š°|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š¾Š²Ģ}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š» Ogg|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š° Ogg|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š¾Š² Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š» FLAC|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š° FLAC|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š¾Š² FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š» WAV|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š° WAV|$1 Š°ŃŠ“ŠøŠ¾ŃŠ°Š¹Š»Š¾Š² WAV}}", + "right-transcode-reset": "ŃŠ±ŃŠ¾Ń Š½ŠµŃŠ“Š°Š²ŃŠøŃ
ŃŃ ŠøŠ»Šø ŃŃŠ°Š½ŃŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½Š½ŃŃ
Š²ŠøŠ“ŠµŠ¾, ŃŃŠ¾Š±Ń Š¾Š½Šø Š²ŃŃŠ°Š»Šø Š² Š¾ŃŠµŃŠµŠ“Ń Š·Š°Š“Š°Š½ŠøŠ¹ ŃŠ½Š¾Š²Š°", + "right-transcode-status": "ŠæŃŠ¾ŃŠ¼Š¾ŃŃ [[Special:TimedMediaHandler|ŠøŠ½ŃŠ¾ŃŠ¼Š°ŃŠøŠø Š¾ ŃŠµŠŗŃŃŠµŠ¼ Ń
Š¾Š“Šµ ŠæŠµŃŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ]]", + "action-transcode-status": "ŠæŃŠ¾ŃŠ¼Š¾ŃŃ ŃŠµŠŗŃŃŠµŠ³Š¾ ŃŃŠ°ŃŃŃŠ° ŠæŠµŃŠµŠŗŠ¾Š“ŠøŃŠ¾Š²Š°Š½ŠøŃ", + "orphanedtimedtext": "ŠŠ¾ŃŠµŃŃŠ½Š½ŃŠµ ŃŃŃŠ°Š½ŠøŃŃ TimedText", + "orphanedtimedtext-summary": "Š”ŠæŠøŃŠ¾Šŗ ŃŃŃŠ°Š½ŠøŃ [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]], ŠŗŠ¾ŃŠ¾ŃŃŠµ Š½Šµ ŠøŠ¼ŠµŃŃ ŃŠ¾Š¾ŃŠ²ŠµŃŃŃŠ²ŃŃŃŠµŠ³Š¾ ŃŠ°Š¹Š»Š°.", + "orphanedtimedtext-unsupported": "ŠŃŠ¾ ŃŠæŠµŃŃŃŃŠ°Š½ŠøŃŠ° ŠæŠ¾Š“Š“ŠµŃŠ¶ŠøŠ²Š°ŠµŃŃŃ ŃŠ¾Š»ŃŠŗŠ¾ Š“Š»Ń Š±Š°Š· Š“Š°Š½Š½ŃŃ
MySQL.", + "orphanedtimedtext-notimedtext": "TimedText Š½Šµ Š²ŠŗŠ»ŃŃŠµŠ½ Š² ŃŃŠ¾Š¹ Š²ŠøŠŗŠø.", + "apihelp-transcodereset-param-title": "ŠŠ°Š³Š¾Š»Š¾Š²Š¾Šŗ Š¼ŠµŠ“ŠøŠ°ŃŠ°Š¹Š»Š°." +} diff --git a/extensions/TimedMediaHandler/i18n/rue.json b/extensions/TimedMediaHandler/i18n/rue.json new file mode 100644 index 00000000..66934a9c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/rue.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Gazeb" + ] + }, + "timedmedia-more": "ŠŠµŃŠµ...", + "timedmedia-dismiss": "ŠŠ°ŠæŠµŃŃŠø", + "timedmedia-file": "Š¤Š°Š¹Š»" +} diff --git a/extensions/TimedMediaHandler/i18n/sa.json b/extensions/TimedMediaHandler/i18n/sa.json new file mode 100644 index 00000000..f3634735 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sa.json @@ -0,0 +1,19 @@ +{ + "@metadata": { + "authors": [ + "Shubha", + "NehalDaveND" + ] + }, + "timedmedia-more": "ą¤
ą¤§ą¤æą¤ą¤®ą„.....", + "timedmedia-dismiss": "ą¤Ŗą¤æą¤¦ą¤§ą¤¾ą¤¤ą„", + "timedmedia-download": "ą¤øą¤ą„ą¤ą¤æą¤ą¤¾ą¤Æą¤¾ą¤ ą¤
ą¤µą¤¾ą¤°ą„ą¤Ŗą¤£ą¤®ą„", + "timedmedia-desc-link": "ą¤
ą¤øą„ą¤Æą¤¾ą¤ ą¤øą¤ą„ą¤ą¤æą¤ą¤¾ą¤Æą¤¾ą¤ ą¤µą¤æą¤·ą¤Æą„", + "timedmedia-status": "ą¤øą„ą¤„ą¤æą¤¤ą¤æą¤", + "timedmedia-status-unknown": "ą¤
ą¤ą„ą¤ą¤¾ą¤¤ą¤øą„ą¤„ą¤æą¤¤ą¤æą¤", + "timedmedia-actions": "ą¤ą„ą¤°ą¤æą¤Æą¤¾ą¤", + "timedmedia-source-file": "$1 ą¤øą„ą¤°ą„ą¤¤ą¤", + "timedmedia-source-audio-file-desc": "ą¤®ą„ą¤²ą¤®ą„ $1 ą¤øą¤ą„ą¤ą¤æą¤ą¤¾ ($2)", + "timedmedia-subtitle-new-go": "ą¤ą¤®ą„ą¤Æą¤¤ą¤¾ą¤®ą„", + "timedmedia-file": "ą¤øą¤ą„ą¤ą¤æą¤ą¤¾" +} diff --git a/extensions/TimedMediaHandler/i18n/sah.json b/extensions/TimedMediaHandler/i18n/sah.json new file mode 100644 index 00000000..0bee4097 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sah.json @@ -0,0 +1,23 @@ +{ + "@metadata": { + "authors": [ + "HalanTul" + ] + }, + "timedmedia-desc": "ŠŠ±ŃŠ°Š±Š¾ŃŃŠøŠŗ ŃŠ°Š¹Š»Š¾Š² Ogg Theora Šø Vorbis Ń ŠøŃŠæŠ¾Š»ŃŠ·Š¾Š²Š°Š½ŠøŠµŠ¼ JavaScript-ŠæŃŠ¾ŠøŠ³ŃŃŠ²Š°ŃŠµŠ»Ń", + "timedmedia-ogg-short-audio": "ŠŠ²ŃŠŗŠ¾Š²Š¾Š¹ ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-video": "ŠŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-general": "ŠŠµŠ“ŠøŠ°-ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-long-audio": "Š·Š²ŃŠŗŠ¾Š²Š¾Š¹ ŃŠ°Š¹Š» Ogg $1, ŃŅ»ŃŠ½Š° $2, $3", + "timedmedia-ogg-long-video": "Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg $1, ŃŅ»ŃŠ½Š° $2, $4Ć$5 ŠæŠøŠøŠŗŃŃŠ»Š»ŃŃŃ
, $3", + "timedmedia-ogg-long-multiplexed": "Š¼ŃŠ»ŃŃŠøŠæŠ»ŠµŠŗŃŠ½ŃŠ¹ Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg, $1, ŃŅ»ŃŠ½Š° $2, $4Ć$5 ŠæŠøŠøŠŗŃŃŠ»Š»ŃŃŃ
, Š±Š°ŃŃŃŠ° $3", + "timedmedia-ogg-long-general": "Š¼ŠµŠ“ŠøŠ°-ŃŠ°Š¹Š» Ogg, ŃŅ»ŃŠ½Š° $2, $3", + "timedmedia-ogg-long-error": "ŃŃŃŅ»Š° Ogg-ŃŠ°Š¹Š»: $1", + "timedmedia-no-player-js": "Š„Š¾Š¼Š¾Š¹ŃŠ¾Ń
ŠøŅ»ŠøŠ½, Š±ŃŠ°ŃŠ·ŠµŃŠ³Š°Ń JavaScript Š°ŃŠ°Š°ŃŃŠ»Š»Š° ŃŃŠ»Š“ŃŠ°Ń, ŃŠ±ŃŃŃŃ Š¾Š½Ń ŅÆŠ»ŃŠ»ŃŃŃŃ ŃŃŃŠøŠ» ŃŃŠ¾Ń
ŃŠ±ŠøŃ.<br />\nŠŠ½ <a href=\"$1\">ŃŠ¾Š»ŠøŠ³Ń Ń
Š°ŃŠ°Š¹Š“Š°Š½Š°Š½ ŃŠ»Š°Š½ ŠŗÓ©ŃŅÆÓ©Ń
Ń
ŅÆŠ½</a> Š±ŠøŠøŃŃŃ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š¾Š¾Š½Š½ŃŠ¾ŃŠ¾Ń ŃŃŃŠøŠ»Šø Ń
Š°ŃŠ°Š¹Š“Š°Š½Š°Š½</a> Š±ŃŠ°ŃŠ·ŠµŃŠ³Š°Ń ŠŗÓ©ŃŅÆÓ©Ń
Ń
ŅÆŠ½ ŃÓ©Šæ.", + "timedmedia-more": "ÓØŃŃÓ©...", + "timedmedia-dismiss": "ŠŠøŃŃŃŃ/ŃŠ°Šæ", + "timedmedia-download": "ŠŠøŠ»ŃŠ½Šø Ń
Š°ŃŠ°Š¹Š“Š°Š°", + "timedmedia-desc-link": "ŠŃ Š±ŠøŠ»Ń ŃŃŅ»ŃŠ½Š°Š½", + "timedmedia-source-file": "Š«Š»ŃŠ»Š»ŃŠ±ŃŃ ŃŠøŃŃ $1", + "timedmedia-source-audio-file-desc": "ŠŃŠøŅ„Š½ŃŃŃ
$1-Š±ŠøŠ»Ń ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/scn.json b/extensions/TimedMediaHandler/i18n/scn.json new file mode 100644 index 00000000..77993f87 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/scn.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "Pippinu", + "Sarvaturi" + ] + }, + "timedmedia-no-player-js": "Purtroppu lu tĆ² browser o havi lu JavaScript disattivatu o nun havi nuddu litturi suppurtatu.<br />\nTi poi <a href=\"$1\">scarricari lu spizzuni</a> o puru <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">scarricari nu litturi</a> p'arriprudĆ¹ciri lu spizzuni ntĆ“ tĆ² browser.", + "timedmedia-source-file": "Surgenti $1", + "timedmedia-source-audio-file-desc": "File $1 origginali ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/sco.json b/extensions/TimedMediaHandler/i18n/sco.json new file mode 100644 index 00000000..a05c7efb --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sco.json @@ -0,0 +1,16 @@ +{ + "@metadata": { + "authors": [ + "John Reid", + "AmaryllisGardener" + ] + }, + "timedmedia-ogg-long-no-streams": "Ogg media file. Warnishment: Nane o the codecs uised in this file ar recognized.", + "timedmedia-no-player-js": "Sorry, yer brouser either haes JavaScript disabled or daes nae hae ony supportit player.<br />\nYe can <a href=\"$1\">dounload the clip</a> or <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">dounload a player</a> tae play the clip in yer brouser.", + "timedmedia-source-file": "$1 soorce", + "timedmedia-source-audio-file-desc": "Oreeginal $1 file ($2)", + "timedmedia-audios": "{{PLURAL:$1|$1 audio file|$1 audio files}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg audio file|$1 Ogg audio files}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC audio file|$1 FLAC audio files}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV audio file|$1 WAV audio files}}" +} diff --git a/extensions/TimedMediaHandler/i18n/sdh.json b/extensions/TimedMediaHandler/i18n/sdh.json new file mode 100644 index 00000000..d4ff6455 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sdh.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Kurdbuddha" + ] + }, + "timedmedia-file": "Ł¾ŪŚŚÆŪ" +} diff --git a/extensions/TimedMediaHandler/i18n/sgs.json b/extensions/TimedMediaHandler/i18n/sgs.json new file mode 100644 index 00000000..702050e7 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sgs.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Hugo.arg" + ] + }, + "timedmedia-download": "AtsÄsiÅstÄ faila", + "timedmedia-source-file": "$1 kÄlmie", + "timedmedia-source-audio-file-desc": "PÄrms $1 skvarmou ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/shn.json b/extensions/TimedMediaHandler/i18n/shn.json new file mode 100644 index 00000000..5e27c963 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/shn.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Saimawnkham" + ] + }, + "timedmedia-source-file": "įįįŗįįįį $1", + "timedmedia-source-audio-file-desc": "į¾į¢įįįįįŗįįįįÆį¼įŗįø $1 į¾į¢įį ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/shy-latn.json b/extensions/TimedMediaHandler/i18n/shy-latn.json new file mode 100644 index 00000000..ec64ab0c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/shy-latn.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Vikoula5" + ] + }, + "timedmedia-days": "{{PLURAL:$1|1 ass|$1 ussan}}" +} diff --git a/extensions/TimedMediaHandler/i18n/si.json b/extensions/TimedMediaHandler/i18n/si.json new file mode 100644 index 00000000..05795ef3 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/si.json @@ -0,0 +1,85 @@ +{ + "@metadata": { + "authors": [ + "ą¶±ą¶±ą·ą¶Æą·ą¶øą·ą¶ą·ą¶»ą·", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ", + "Susith Chandira Gts", + "ą·ą¶»ą·ą¶" + ] + }, + "timedmedia-desc": "Ogg Theora ą·ą· Vorbis ą¶ą·ą¶±ą· ą·ą¶³ą·ą· ą·ą·ą·ą¶»ą·ą·ą¶±ą¶ŗ, ą¶¢ą·ą·ą·ą·ą·ą¶ą·āą¶»ą·ą¶“ą·ą¶§ą· ą¶“ą·ą¶½ą·ą¶ŗą¶»ą· ą·ą¶øą¶", + "timedmedia-ogg-short-audio": "Ogg $1 ą·ą·āą¶»ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, $2", + "timedmedia-ogg-short-video": "Ogg $1 ą¶Æą·ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, $2", + "timedmedia-ogg-short-general": "Ogg $1 ą¶øą·ą¶°ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, $2", + "timedmedia-ogg-long-audio": "Ogg $1 ą·ą·āą¶»ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, ą¶“ą·āą¶»ą·ą¶»ą·ą¶ą¶±ą¶ŗ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 ą¶Æą·ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, ą¶“ą·āą¶»ą·ą¶»ą·ą¶ą¶±ą¶ŗ $2, $4Ć$5 ą¶“ą·ą¶ą·ą·ą¶½ą·, $3", + "timedmedia-ogg-long-multiplexed": "Ogg ą¶¶ą·ą·ą¶“ą¶®ą¶ą·ą¶»ą¶ ą·ą·āą¶»ą·ą·āą¶ŗ/ą¶Æą·ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, $1, ą¶“ą·āą¶»ą·ą¶»ą·ą¶ą¶±ą¶ŗ $2, $4Ć$5 ą¶“ą·ą¶ą·ą·ą¶½ą·, $3 ą·ą¶øą·ą·ą¶", + "timedmedia-ogg-long-general": "Ogg ą¶øą·ą¶°ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, ą¶“ą·āą¶»ą·ą¶»ą·ą¶ą¶±ą¶ŗ $2, $3", + "timedmedia-ogg-long-error": "ą¶
ą¶±ą·ą¶ą·ą¶ ogg ą¶ą·ą¶±ą·ą·: $1", + "timedmedia-webm-short-video": "WebM $1 ą·ą·ą¶Æą·ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, $2", + "timedmedia-webm-long-video": "WebM ą·ą·āą¶»ą·ą·āą¶ŗ/ą¶Æą·ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, $1, ą¶Æą·ą¶ $2, $4 Ć $5 ą¶“ą·ą¶ą·ą·ą¶½ą·, $3 ą·ą¶øą·ą·ą¶®ą¶ŗ", + "timedmedia-mp4-short-video": "MP4 $1 ą¶Æą·ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, $2", + "timedmedia-mp4-long-video": "MP4 ą·ą·āą¶»ą·ą·āą¶ŗ/ą¶Æą·ą·ą·āą¶ŗ ą¶ą·ą¶±ą·ą·, $1, ą¶Æą·ą¶ $2, $4 Ć $5 ą¶“ą·ą¶ą·ą·ą¶½ą·, $3 ą·ą¶øą·ą·ą¶®ą¶ŗ", + "timedmedia-no-player-js": "ą·ą¶øą·ą·ą¶±ą·ą¶±, ą¶ą¶¶ą· ą¶ą·ą·ą·ą¶ą¶ŗą· ą¶¢ą·ą·ą·ą·ą·ą¶ą·āą¶»ą·ą¶“ą·ą¶§ą· ą¶
ą¶ą·āą¶»ą·ą¶ŗ ą·ą· ą¶ą¶ ą¶±ą·ą¶ą·ą·ą¶ą· ą¶ą·ą·ą·ą¶Æą· ą¶
ą¶±ą·ą¶ą·āą¶»ą·ą¶ŗ ą¶Æą¶ą·ą·ą¶± ą¶“ą·ą¶½ą·ą¶ŗą¶»ą¶ŗą¶ą· ą¶ą¶¶ ą·ą¶ą·ą· ą¶±ą·ą¶.<br />\ną¶ą¶¶ą· ą¶ą·ą·ą·ą¶ą¶ŗą·ą·ą· ą·ą·ą¶©ą·ą¶ŗą·ą· ą¶°ą·ą·ą¶±ą¶ŗ ą¶ą·ą¶»ą·ą¶øą¶§ <a href=\"$1\">ą·ą·ą¶©ą·ą¶ŗą·ą· ą¶¶ą·ą¶ą¶ ą¶ą·ą¶»ą·ą¶ø</a> ą·ą· <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą¶“ą·ą¶½ą·ą¶ŗą¶»ą¶ŗ ą¶¶ą·ą¶ą¶ ą¶ą·ą¶»ą·ą¶ø</a> ą·ą·ą¶Æą· ą¶ą·
ą·ą·ą¶ą·ą¶ŗ.", + "timedmedia-more": "ą¶ą¶ą·ą¶»ą·ą¶ŗā¦", + "timedmedia-dismiss": "ą·ą·ą¶±ą·ą¶±", + "timedmedia-download": "ą¶ą·ą¶±ą·ą· ą¶¶ą· ą¶ą¶±ą·ą¶±", + "timedmedia-play-media": "ą¶øą·ą¶°ą·āą¶ŗ ą·ą¶ŗą¶±ą·ą¶±", + "timedmedia-desc-link": "ą¶øą·ą¶ø ą¶ą·ą¶±ą·ą· ą¶“ą·ą·
ą·ą¶¶ą¶³", + "timedmedia-oggThumb-version": "OggHandler ą·ą¶³ą·ą· oggThumb $1 ą·ą¶ą·ą·ą¶ą¶»ą¶«ą¶ŗ ą·ą· ą¶
ą¶½ą·ą¶ą· ą¶ą¶ą¶ą· ą¶
ą·ą·ą·ą·ą¶ŗ.", + "timedmedia-oggThumb-failed": "ą·ą¶ą¶ą·ą·ą·ą¶“ą·ą¶ą¶ŗ ą¶ą·ą¶±ą·ą¶øą¶§ oggThumb ą¶
ą·ą¶øą¶ą·ą·ą·ą¶ŗ.", + "timedmedia-status-header": "Transcode ą¶ą¶ą·ą·ą¶ŗ", + "timedmedia-update-status": "transcode ą¶ą¶ą·ą·ą¶ŗ ą¶ŗą·ą·ą¶ą·ą¶ą·ą¶½ą·ą¶± ą¶ą¶»ą¶±ą·ą¶±", + "timedmedia-status": "ą¶ą¶ą·ą·ą¶ŗ", + "timedmedia-status-unknown": "ą¶±ą·ą¶Æą¶±ą·ą¶±ą· ą¶ą¶ą·ą·ą¶ŗ", + "timedmedia-transcodeinfo": "Transcode ą·ą·āą¶ŗą·ą¶ą·ą¶“ą¶±ą·ą¶± ą·ą·ą·ą·ą¶ą¶»ą¶ŗ", + "timedmedia-actions": "ą¶ą·ą¶»ą·ą¶ŗą¶ŗą¶±ą·", + "timedmedia-direct-link": "ą·ą·āą¶ŗą·ą¶ą·ą¶“ą¶±ą·ą¶±ą¶ŗ ą¶¶ą·ą¶ą¶±ą·ą¶±", + "timedmedia-not-ready": "ą·ą·ą¶Æą·ą¶±ą¶øą· ą¶±ą·ą¶", + "timedmedia-completed-on": "$1 transcode ą·ą¶øą·ą¶“ą·ą¶»ą·ą¶« ą¶ą¶»ą¶± ą¶½ą¶Æą·", + "timedmedia-error-on": "$1 ą·ą· transcode ą¶Æą·ą·ą¶ŗą¶ą·.", + "timedmedia-started-transcode": "$1 ą¶“ą·ą¶» Transcode ą¶ą¶»ą¶øą·ą¶· ą¶ą¶»ą¶± ą¶½ą¶Æą·. $2", + "timedmedia-percent-done": "$1% ą¶“ą¶øą¶« ą¶ą·ą¶»ą¶ŗą·", + "timedmedia-in-job-queue": "$1 ą¶“ą·ą¶» ą¶ą·ą¶ą·āą¶ŗ ą¶“ą·ą¶½ą¶§ ą¶ą¶ą· ą¶ą¶»ą¶± ą¶½ą¶Æą·", + "timedmedia-unknown-target-size": "ą¶±ą·ą¶Æą¶±ą·ą¶±ą· ą¶ą¶½ą¶ą·ą¶ą¶ą¶ ą¶“ą·āą¶»ą¶øą·ą¶«ą¶ŗ, $1 ą¶ą·ą¶ą·ą¶ą¶ą¶±ą¶ŗ ą¶ą¶»ą¶± ą¶½ą¶Æą·", + "timedmedia-days": "{{PLURAL:$1|ą¶Æą·ą·|$1 ą¶Æą·ą·ą·}}", + "timedmedia-hours": "{{PLURAL:$1|ą¶“ą·ą¶ŗ|$1 ą¶“ą·ą¶ŗ}}", + "timedmedia-minutes": "{{PLURAL:$1|ą¶øą·ą¶±ą·ą¶ą·ą¶ą·ą·|$1 ą¶øą·ą¶±ą·ą¶ą·ą¶ą·}}", + "timedmedia-seconds": "{{PLURAL:$1|ą¶ą¶ą·ą¶“ą¶»ą¶ŗ|$1 ą¶ą¶ą·ą¶“ą¶»}}", + "timedmedia-reset": "transcode ą¶ŗą·
ą· ą·ą¶ą·ą¶±ą·ą¶±", + "timedmedia-reset-error": "transcode ą¶ą·ą¶ą·āą¶ŗ ą¶ŗą·
ą· ą·ą·ą¶ą·ą·ą¶øą· ą¶Æą·ą·ą¶ŗ.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 ą¶øą·ą¶½ą·ą·ą·āą¶»ą¶ŗ", + "timedmedia-source-file-desc": "ą¶±ą·ą¶ŗą¶ø $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ą¶±ą·ą¶ŗą¶ø $1 ą¶ą·ą¶±ą·ą· ($2)", + "timedmedia-derivative-desc-160p.ogv": "ą¶
ą·ą¶ø ą¶ą¶½ą·ą¶“ ą¶“ą·
ą¶½ Ogg ą·ą·ą¶Æą·ą·ą·āą¶ŗ (160P)", + "timedmedia-derivative-desc-360p.ogv": "ą¶¢ą·ą¶½ ą·ą·āą¶»ą·ą¶ą¶øą¶ŗ Ogg ą·ą·ą¶©ą·ą¶ŗą·ą· (360P)", + "timedmedia-derivative-desc-480p.ogv": "ą¶¢ą·ą¶½ ą·ą·āą¶»ą·ą¶ą¶øą¶ŗ Ogg ą·ą·ą¶©ą·ą¶ŗą·ą· (480P)", + "timedmedia-derivative-desc-720p.ogv": "ą¶ą·ą·ą· ą¶ą·ą¶«ą¶ą·ą·ą¶ŗą· ą¶¶ą·ą¶ą¶ą·ą·ą¶ą· Ogg ą·ą·ą¶©ą·ą¶ŗą·ą· (720P)", + "timedmedia-derivative-desc-1080p.ogv": "ą¶¶ą·ą¶ą¶ ą¶ą·
ą·ą·ą¶ą· Full HD Ogg ą·ą·ą¶©ą·ą¶ŗą· ą¶“ą¶§ (1080P)", + "timedmedia-derivative-desc-160p.webm": "ą¶¢ą·ą¶½ ą·ą·āą¶»ą·ą¶ą¶øą¶ŗ WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "ą¶¢ą·ą¶½ ą·ą·āą¶»ą·ą¶ą¶øą¶ŗ WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "ą¶¢ą·ą¶½ ą·ą·āą¶»ą·ą¶ą¶øą¶ŗ WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "ą¶ą·ą·ą· ą¶ą·ą¶«ą¶ą·ą·ą¶ŗą· ą¶¶ą·ą¶ą¶ą·ą·ą¶ą· WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "ą¶¶ą·ą¶ą¶ ą¶ą·
ą·ą·ą¶ą· Full HD WebM (1080P)", + "timedmedia-derivative-desc-320p.mp4": "ą¶ą¶“ą·ą¶ą¶-ą·ą·ą¶ą¶ą·ą¶øą· MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "ą¶¢ą·ą¶½ ą·ą·āą¶»ą·ą¶ą¶øą¶ŗ MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD ą¶ą·ą¶«ą¶ą·ą·ą¶ŗą· MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "Full HD ą¶ą¶ą·ą·ą¶ŗą· MP4 (1080P)", + "timedmedia-subtitle-new": "ą¶±ą· ą¶“ą¶»ą·ą·ą¶»ą·ą¶ą¶±ą¶ŗą¶ą· ą¶ą¶±ą¶±ą·ą¶± ą·ą· ą¶“ą·ą¶ą·ą¶±ą· ą¶ą¶ą¶ą· ą·ą¶ą·ą·ą¶ą¶»ą¶«ą¶ŗ ą¶ą¶»ą¶±ą·ą¶±", + "timedmedia-subtitle-new-go": "ą¶ŗą¶±ą·ą¶±", + "timedmedia-subtitle-language": "$1 ($2) ą¶ą¶“ą·ą·ą¶»ą·ą·", + "timedmedia-subtitle-no-video": "ą·ą¶ą·ą¶øą¶±ą· ą¶ą¶“ą·ą·ą¶»ą·ą· ą¶“ą·ą¶§ą·ą· ą·ą¶øą¶ ą¶ą·ą·ą·ą¶Æą· ą·ą·ą¶©ą·ą¶ŗą·ą·ą¶ą· ą·ą¶øą·ą¶¶ą¶±ą·ą¶° ą¶±ą·ą·ą·.", + "timedmedia-subtitle-remote": "ą¶øą·ą¶ø ą¶ą·ą¶±ą·ą· ą·ą¶³ą·ą· ą¶ą·ą¶½ą·ą¶ ą¶“ą·ą·
$1 ą·ą· ą·ą¶ą·ą¶ą·ą¶» ą¶½ą¶¶ą· ą¶ą¶", + "timedmedia-subtitle-remote-link": "ą¶ą¶¶ą¶§ ą¶øą·ą¶ø ą¶ą·ą¶±ą·ą· ą·ą¶³ą·ą· [$1 ą·ą·ą·ą·ą¶ą¶» ą¶“ą·ą¶§ą·ą·] $2 ą·ą·ą¶Æą· ą¶¶ą¶½ą·ą¶ą¶ ą·ą·ą¶", + "timedmediahandler": "ą¶ą·ą¶½ą·ą¶ą¶øą·ą¶°ą·āą¶ŗą·ą·ą·ą¶»ą·ą¶±ą¶ŗ", + "timedmedia-videos": "{{PLURAL:$1|ą·ą·ą¶©ą·ą¶ŗą·}} $1 ą¶ą·", + "timedmedia-ogg-videos": "{{PLURAL:$1|Ogg ą·ą·ą¶©ą·ą¶ŗą·}} $1 ą¶ą·", + "timedmedia-webm-videos": "{{PLURAL:$1|WebM ą·ą·ą¶©ą·ą¶ŗą·}} $1 ą¶ą·", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcode|$1 transcodes}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|ą¶°ą·ą·ą¶±ą¶ŗ ą·ą¶± transcode}} $1", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|ą¶“ą·ą·
ą¶ą·ą·ą·ą· ą¶ą¶ą· transcode}} $1", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|ą¶
ą·ą¶øą¶ą· ą·ą· transcode}} $1", + "timedmedia-file": "ą¶ą·ą¶±ą·ą·", + "action-transcode-status": "ą·ą¶ą·ą¶øą¶±ą· ą¶
ą¶±ą· ą¶½ą·ą¶ą·ą¶øą· ą¶ą¶ą·ą·ą¶ŗ ą¶±ą¶»ą¶¹ą¶±ą·ą¶±" +} diff --git a/extensions/TimedMediaHandler/i18n/sk.json b/extensions/TimedMediaHandler/i18n/sk.json new file mode 100644 index 00000000..0a1480c4 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sk.json @@ -0,0 +1,25 @@ +{ + "@metadata": { + "authors": [ + "Helix84", + "TomĆ”Å”Polonec", + "Wizzard" + ] + }, + "timedmedia-desc": "Obsluha sĆŗborov Ogg Theora a Vorbis s JavaScriptovĆ½m prehrĆ”vaÄom", + "timedmedia-ogg-short-audio": "ZvukovĆ½ sĆŗbor ogg $1, $2", + "timedmedia-ogg-short-video": "Video sĆŗbor ogg $1, $2", + "timedmedia-ogg-short-general": "MultimediĆ”lny sĆŗbor ogg $1, $2", + "timedmedia-ogg-long-audio": "ZvukovĆ½ sĆŗbor ogg $1, dÄŗžka $2, $3", + "timedmedia-ogg-long-video": "Video sĆŗbor ogg $1, dÄŗžka $2, $4Ć$5 pixelov, $3", + "timedmedia-ogg-long-multiplexed": "MultiplexovanĆ½ zvukovĆ½/video sĆŗbor ogg, $1, dÄŗžka $2, $4Ć$5 pixelov, $3 celkom", + "timedmedia-ogg-long-general": "MultimediĆ”lny sĆŗbor ogg, dÄŗžka $2, $3", + "timedmedia-ogg-long-error": "NeplatnĆ½ sĆŗbor ogg: $1", + "timedmedia-no-player-js": "Je nĆ”m ľĆŗto, ale vĆ”Å” prehliadaÄ mĆ” buÄ vypnutĆ½ JavaScript, alebo nemĆ”te žiadny podporovanĆ½ prehrĆ”vaÄ.<br />\nMĆ“Å¾ete si <a href=\"$1\">stiahnuÅ„ klip</a> alebo si <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">stiahnuÅ„ prehrĆ”vaÄ</a>, ktorĆ½m si klip prehrajete v prehliadaÄi.", + "timedmedia-more": "viac...", + "timedmedia-dismiss": "ZatvoriÅ„", + "timedmedia-download": "StiahnuÅ„ sĆŗbor", + "timedmedia-desc-link": "O tomto sĆŗbore", + "timedmedia-source-file": "Zdroj $1", + "timedmedia-source-audio-file-desc": "PĆ“vodnĆ½ sĆŗbor $1 ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/sl.json b/extensions/TimedMediaHandler/i18n/sl.json new file mode 100644 index 00000000..d298dd7a --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sl.json @@ -0,0 +1,96 @@ +{ + "@metadata": { + "authors": [ + "Dbc334", + "Eleassar", + "Rzuwig" + ] + }, + "timedmedia-desc": "Upravljavec zvoka, videa in Äasovnega besedila s podprtimi oblikami WebM, Ogg Theora, Vorbis in SubRip", + "timedmedia-ogg-short-audio": "avdiodatoteka Ogg $1, $2", + "timedmedia-ogg-short-video": "Videodatoteka Ogg $1, $2", + "timedmedia-ogg-short-general": "Predstavnostna datoteka Ogg $1, $2", + "timedmedia-ogg-long-audio": "avdiodatoteka Ogg $1, dolžine $2, $3", + "timedmedia-ogg-long-video": "videodatoteka ogg $1, dolžine $2, $4Ā ĆĀ $5Ā pik, $3", + "timedmedia-ogg-long-multiplexed": "multipleksna avdio-/videodatoteka Ogg, $1, dolžine $2, $4 Ć $5 pik, skupaj $3", + "timedmedia-ogg-long-general": "predstavnostna datoteka Ogg, dolžine $2, $3", + "timedmedia-ogg-long-error": "Neveljavna datoteka Ogg: $1", + "timedmedia-webm-short-video": "Videodatoteka WebM $1, $2", + "timedmedia-webm-long-video": "Avdio-/videodatoteka WebM, $1, dolžine $2, $4 Ć $5 pik, skupaj $3", + "timedmedia-flac-short-audio": "Datoteka z zvokom FLAC, $1", + "timedmedia-flac-long-audio": "Datoteka z zvokom FLAC, dolžine $1, skupno $2", + "timedmedia-wav-short-audio": "Datoteka z zvokom WAV, $1", + "timedmedia-wav-long-audio": "Datoteka z zvokom WAV, dolžine $1, skupno $2", + "timedmedia-wav-pcm-required": "Naložite lahko samo PCM (Pulse Code Modulation) WAV.", + "timedmedia-mp4-short-video": "Videodatoteka MP4 $1, $2", + "timedmedia-mp4-long-video": "Avdio-/videodatoteka MP4, $1, dolžine $2, $4 Ć $5 pik, skupaj $3", + "timedmedia-no-player-js": "Oprostite, vaÅ” brskalnik ima onemogoÄen JavaScript ali pa nima nobenega podprtega predvajalnika.<br />\nPosnetek lahko <a href=\"$1\">snamete</a> ali <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">prenesete predvajalnik</a> za predvajanje posnetka v svojem brskalniku.", + "timedmedia-more": "VeÄ ...", + "timedmedia-dismiss": "Zapri", + "timedmedia-download": "Prenesi", + "timedmedia-play-media": "Predvajaj", + "timedmedia-desc-link": "O datoteki", + "timedmedia-oggThumb-version": "OggHandler potrebuje oggThumb razliÄice $1 ali veÄ.", + "timedmedia-oggThumb-failed": "OggThumbu ni uspelo ustvariti predogledne sliÄice.", + "timedmedia-status-header": "Stanje prekodiranja", + "timedmedia-update-status": "Posodobi stanje prekodiranja", + "timedmedia-status": "Stanje", + "timedmedia-status-unknown": "Neznano stanje", + "timedmedia-transcodeinfo": "Oblika", + "timedmedia-actions": "Dejanja", + "timedmedia-direct-link": "Prenos", + "timedmedia-not-ready": "Ni pripravljeno", + "timedmedia-completed-on": "KonÄano $1", + "timedmedia-error-on": "Napaka dne $1", + "timedmedia-started-transcode": "ZaÄeto pred $1. $2", + "timedmedia-percent-done": "KonÄanih približno $1 %", + "timedmedia-in-job-queue": "Dodano v Äakalno vrsto pred $1", + "timedmedia-unknown-target-size": "Neznana ciljna velikost, prekodirano $1", + "timedmedia-days": "$1 {{PLURAL:$1|dan|dneva|dnevi|dni}}", + "timedmedia-hours": "$1 {{PLURAL:$1|ura|uri|ure|ur}}", + "timedmedia-minutes": "$1 {{PLURAL:$1|minuta|minuti|minute|minut}}", + "timedmedia-seconds": "$1 {{PLURAL:$1|sekunda|sekundi|sekunde|sekund}}", + "timedmedia-reset": "Ponastavi prekodiranje", + "timedmedia-reset-confirm": "Ob ponastavitvi tega prekodiranja se bodo izbrisale vse obstojeÄe datoteke (Äe obstajajo), prekodiranje pa se bo ponovno dodalo v Äakalno vrsto. Ponovno prekodiranje bo vzelo nekaj Äasa. <br /><br />Ste prepriÄani, da želite nadaljevati?", + "timedmedia-reset-error": "Napaka pri ponastavljanju prekodiranja.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "vir $1", + "timedmedia-source-file-desc": "Izvirna datoteka $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Izvirna datoteka $1 ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160P", + "timedmedia-derivative-desc-160p.ogv": "Video Ogg za majhno pasovno Å”irino (160P)", + "timedmedia-derivative-desc-360p.ogv": "Spletni pretoÄni video Ogg (360P)", + "timedmedia-derivative-desc-480p.ogv": "Spletni pretoÄni video Ogg (480P)", + "timedmedia-derivative-desc-720p.ogv": "Visokokakovostni prenosni video Ogg (720P)", + "timedmedia-derivative-desc-160p.webm": "Spletni pretoÄni WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM za pretakanje preko spleta (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM za pretakanje preko spleta (480P)", + "timedmedia-derivative-desc-720p.webm": "Visokokakovostni WebM za prenos (720P)", + "timedmedia-derivative-desc-320p.mp4": "Napravam prijazni MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Spletni pretoÄni WebM (160P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 kakovosti HD (720P)", + "timedmedia-subtitle-new": "Ustvarite nov prevod ali uredite obstojeÄega", + "timedmedia-subtitle-new-desc": "Izberite jezik in pritisnite gumb '''{{int:Timedmedia-subtitle-new-go}}'''.", + "timedmedia-subtitle-new-go": "Pojdi", + "timedmedia-subtitle-language": "podnapisi v jeziku: $1 ($2)", + "timedmedia-subtitle-no-video": "S trenutno podnaslovno stranjo ni povezan noben videoposnetek", + "timedmedia-subtitle-no-subtitles": "V jeziku $1 trenutno ni nobenih podnapisov za ta video; stran lahko [{{fullurl:{{FULLPAGENAME}}|action=edit}} odprete za urejanje] in jih dodate.", + "timedmedia-subtitle-remote": "Äasovno besedilo datoteke gostuje na $1", + "timedmedia-subtitle-remote-link": "[$1 Ogledate si lahko opisno stran] datoteke na $2", + "timedmediahandler": "Upravljavec Äasovne predstavnosti", + "timedmedia-videos": "{{PLURAL:$1|$ video|$ videa|$ videi|$ videov}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 video Ogg|$1 videa Ogg|$1 videi Ogg|$1 videov Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 video WebM|$1 videa WebM|$1 videi WebM|$1 videov WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|eno prekodiranje|dve prekodiranji|$1 prekodiranja|$1 prekodiranj}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|eno tekoÄe prekodiranje|dve tekoÄi prekodiranji|$1 prekodiranja|$1 prekodiranj}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|eno ÄakajoÄe prekodiranje|dve ÄakajoÄi prekodiranji|$1 ÄakajoÄa prekodiranja|$1 ÄakajoÄih prekodiranj}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|eno neuspelo prekodiranje|dve neuspeli prekodiranji|$1 neuspela prekodiranja|$1 neuspelih prekodiranj}}", + "timedmedia-file": "Datoteka:", + "timedmedia-audios": "$1 {{PLURAL:$1|zvoÄna datoteka|zvoÄni datoteki|zvoÄne datoteke|zvoÄnih datotek}}", + "timedmedia-ogg-audios": "$1 {{PLURAL:$1|zvoÄna datoteka|zvoÄni datoteki|zvoÄne datoteke|zvoÄnih datotek}} Ogg", + "timedmedia-flac-audios": "$1 {{PLURAL:$1|zvoÄna datoteka|zvoÄni datoteki|zvoÄne datoteke|zvoÄnih datotek}} FLAC", + "timedmedia-wav-audios": "$1 {{PLURAL:$1|zvoÄna datoteka|zvoÄni datoteki|zvoÄne datoteke|zvoÄnih datotek}} WAV", + "right-transcode-reset": "Ponastavitev neuspelih ali pretvorjenih videov, da so ponovno vstavljeni v Äakalno vrsto opravil", + "right-transcode-status": "Ogled [[Special:TimedMediaHandler|informacij o trenutni dejavnosti pretvarjanja]]", + "action-transcode-status": "ogled trenutnega stanja pretvorbe" +} diff --git a/extensions/TimedMediaHandler/i18n/sq.json b/extensions/TimedMediaHandler/i18n/sq.json new file mode 100644 index 00000000..bad879c1 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sq.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Dori", + "Liridon" + ] + }, + "timedmedia-ogg-short-audio": "SkedĆ« zanore Ogg $1, $2", + "timedmedia-ogg-short-video": "SkedĆ« pamore Ogg $1, $2", + "timedmedia-ogg-short-general": "SkedĆ« mediatike Ogg $1, $2", + "timedmedia-ogg-long-audio": "SkedĆ« zanore Ogg $1, kohĆ«zgjatja $2, $3", + "timedmedia-ogg-long-video": "SkedĆ« pamore Ogg $1, kohĆ«zgjatja $2, $4Ć$5 pixel, $3", + "timedmedia-no-player-js": "Na vjen keq, browser-i juaj ose ka tĆ« Ƨaktivizuar JavaScript ose nuk ka mbĆ«shtetje pĆ«r ndonjĆ« player.<br />\nJu mund tĆ« <a href=\"$1\">shkarkoni klipin</a> ose <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">shkarkoni njĆ« player</a> pĆ«r tĆ« luajtur klipin nĆ« shfletuesin tuaj.", + "timedmedia-more": "MĆ« shumĆ«...", + "timedmedia-dismiss": "Mbylle", + "timedmedia-download": "Shkarko skedĆ«n", + "timedmedia-desc-link": "Rreth kĆ«saj skede", + "timedmedia-source-file": "$1 burimi", + "timedmedia-source-audio-file-desc": "Skedari $1 orgjinal ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/sr-ec.json b/extensions/TimedMediaHandler/i18n/sr-ec.json new file mode 100644 index 00000000..b6a3a4df --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sr-ec.json @@ -0,0 +1,55 @@ +{ + "@metadata": { + "authors": [ + "Milicevic01", + "Millosh", + "Rancher", + "Sasa Stefanovic", + "ŠŠøŃ
Š°ŃŠ»Š¾ ŠŠ½ŃŠµŠ»ŠŗŠ¾Š²ŠøŃ" + ] + }, + "timedmedia-desc": "ŠŠ±ŃŠ°ŃŠøŠ²Š°Ń Š·Š° Š·Š²ŃŠŗ, Š²ŠøŠ“ŠµŠ¾ Šø ŃŃŠŗŠ»Š°ŃŠµŠ½Šø ŃŠµŠŗŃŃ, Ń ŠæŠ¾Š“ŃŃŠŗŠ¾Š¼ Š·Š° ŃŠ¾ŃŠ¼Š°ŃŠµ WebM, Ogg Theora, Vorbis Šø SRT", + "timedmedia-ogg-short-audio": "Ogg $1 Š·Š²ŃŃŠ½Š° Š“Š°ŃŠ¾ŃŠµŠŗŠ°, $2", + "timedmedia-ogg-short-video": "Ogg $1 Š²ŠøŠ“ŠµŠ¾-ŃŠ½ŠøŠ¼Š°Šŗ, $2.", + "timedmedia-ogg-short-general": "Ogg $1 Š¼ŠµŠ“ŠøŃŃŠŗŠ° Š“Š°ŃŠ¾ŃŠµŠŗŠ°, $2.", + "timedmedia-ogg-long-audio": "Ogg $1 Š·Š²ŃŃŠ½Š° Š“Š°ŃŠ¾ŃŠµŠŗŠ°, ŃŃŠ°ŃŠ°ŃŠµ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 Š²ŠøŠ“ŠµŠ¾-ŃŠ½ŠøŠ¼Š°Šŗ, ŃŃŠ°ŃŠ°ŃŠµ $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ»Š°, $3.", + "timedmedia-ogg-long-multiplexed": "ŠŃŠ»ŃŠøŠæŠ»ŠµŠŗŃŠøŃŠ°Š½Šø .ogg Š°ŃŠ“ŠøŠ¾/Š²ŠøŠ“ŠµŠ¾ ŃŠ½ŠøŠ¼Š°Šŗ, $1, ŃŃŠ°ŃŠ°ŃŠµ $2, $4 Ć $5 ŠæŠøŠŗŃŠµŠ»Š°, $3.", + "timedmedia-ogg-long-general": "Ogg Š¼ŠµŠ“ŠøŃŃŠŗŠ° Š“Š°ŃŠ¾ŃŠµŠŗŠ°, ŃŃŠ°ŃŠ°ŃŠµ $2, $3.", + "timedmedia-ogg-long-error": "ŠŠµŠøŃŠæŃŠ°Š²Š½Š° .ogg Š“Š°ŃŠ¾ŃŠµŠŗŠ°: $1.", + "timedmedia-no-player-js": "ŠŠ°Š¾ Š½Š°Š¼ ŃŠµ, Š°Š»Šø Š²Š°ŃŠµŠ¼ ŠæŃŠµŠ³Š»ŠµŠ“Š°ŃŃ ŃŠµ Š¾Š½ŠµŠ¼Š¾Š³ŃŃŠµŠ½Š° ŃŠ°Š²Š°ŃŠŗŃŠøŠæŃŠ° ŠøŠ»Šø Š½ŠµŠ¼Š°ŃŠµ Š¾Š“Š³Š¾Š²Š°ŃŠ°ŃŃŃŠø ŠæŠ»ŠµŃŠµŃ.<br />\nŠŠ¾Š¶ŠµŃŠµ <a href=\"$1\">ŠæŃŠµŃŠ·ŠµŃŠø ŠŗŠ»ŠøŠæ</a> ŠøŠ»Šø <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŠæŃŠµŃŠ·ŠµŃŠø ŠæŠ»ŠµŃŠµŃ</a> Š“Š° ŃŠµŠæŃŠ¾Š“ŃŠŗŃŃŠµŃŠµ ŠŗŠ»ŠøŠæ Ń Š²Š°ŃŠµŠ¼ ŠæŃŠµŠ³Š»ŠµŠ“Š°ŃŃ.", + "timedmedia-more": "ŠŠøŃŠµ...", + "timedmedia-dismiss": "ŠŠ°ŃŠ²Š¾ŃŠø", + "timedmedia-download": "ŠŃŠµŃŠ·Š¼Šø Š“Š°ŃŠ¾ŃŠµŠŗŃ", + "timedmedia-desc-link": "ŠŠ¾Š“Š°ŃŠø Š¾ Š¾Š²Š¾Ń Š“Š°ŃŠ¾ŃŠµŃŠø", + "timedmedia-days": "{{PLURAL:$1|1 Š“Š°Š½|$1 Š“Š°Š½Š°}}", + "timedmedia-hours": "{{PLURAL:$1|1 ŃŠ°Ń|$1 ŃŠ°ŃŠ°|$1 ŃŠ°ŃŠø}}", + "timedmedia-minutes": "{{PLURAL:$1|1 Š¼ŠøŠ½ŃŃ|$1 Š¼ŠøŠ½ŃŃŠ°}}", + "timedmedia-seconds": "{{PLURAL:$1|1 ŃŠµŠŗŃŠ½Š“|$1 ŃŠµŠŗŃŠ½Š“Šµ|$1 ŃŠµŠŗŃŠ½Š“Šø}}", + "timedmedia-reset": "ŠŠ¾Š½ŠøŃŃŠø ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ", + "timedmedia-reset-confirm": "ŠŠ¾Š½ŠøŃŃŠ°Š²Š°ŃŠµ Š¾Š²Š¾Š³ ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠ° ŃŠµ ŃŠŗŠ»Š¾Š½ŠøŃŠø ŠæŠ¾ŃŃŠ¾ŃŠµŃŃ Š“Š°ŃŠ¾ŃŠµŠŗŃ (Š°ŠŗŠ¾ ŠæŠ¾ŃŃŠ¾ŃŠø) Šø Š²ŃŠ°ŃŠøŃŠø ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ Š½Š° ŃŠæŠøŃŠ°Šŗ Š·Š°Š“Š°ŃŠ°ŠŗŠ°. ŠŠ²Š° ŃŠ°Š“ŃŠ° Š¼Š¾Š¶Šµ Š“Š° ŠæŠ¾ŃŃŠ°ŃŠµ. <br /><br />\nŠŠµŠ»ŠøŃŠµ Š»Šø Š“Š° Š½Š°ŃŃŠ°Š²ŠøŃŠµ?", + "timedmedia-reset-error": "ŠŃŠµŃŠŗŠ° ŠæŃŠø ŠæŠ¾Š½ŠøŃŃŠ°Š²Š°ŃŃ Š·Š°Š“Š°ŃŠ°ŠŗŠ° Š·Š° ŠæŃŠµŠŗŠ¾Š“ŠøŃŠ°ŃŠµ.", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-flac": "FLAC", + "timedmedia-source-file": "ŠŠ·Š²Š¾ŃŠ½Šø $1", + "timedmedia-source-file-desc": "ŠŠ·Š²Š¾ŃŠ½Šø $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Š¢ŠøŠæ Š“Š°ŃŠ¾ŃŠµŠŗŠµ $1 ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160Šæ", + "timedmedia-derivative-desc-160p.ogv": "ŠŠøŃŠŗŠ¾ŠæŃŠ¾ŠæŃŃŠ½Šø .ogg Š²ŠøŠ“ŠµŠ¾ (160Šæ)", + "timedmedia-derivative-360p.ogv": "Ogg 360Šæ", + "timedmedia-derivative-desc-360p.ogv": "Ogg Š²ŠøŠ“ŠµŠ¾ Š·Š° ŠµŠ¼ŠøŃŠ¾Š²Š°ŃŠµ (360Šæ)", + "timedmedia-derivative-480p.ogv": "Ogg 480Šæ", + "timedmedia-derivative-desc-480p.ogv": "Ogg Š²ŠøŠ“ŠµŠ¾ Š·Š° ŠµŠ¼ŠøŃŠ¾Š²Š°ŃŠµ (480Šæ)", + "timedmedia-derivative-720p.ogv": "Ogg 720Šæ", + "timedmedia-derivative-desc-720p.ogv": "ŠŠøŃŠ¾ŠŗŠ¾ŠŗŠ²Š°Š»ŠøŃŠµŃŠ½Šø .ogg Š²ŠøŠ“ŠµŠ¾ Š·Š° ŠæŃŠµŃŠ·ŠøŠ¼Š°ŃŠµ (720Šæ)", + "timedmedia-derivative-360p.webm": "WebM 360Šæ", + "timedmedia-derivative-desc-360p.webm": "WebM Š·Š° ŠµŠ¼ŠøŃŠ¾Š²Š°ŃŠµ (360Šæ)", + "timedmedia-derivative-480p.webm": "WebM 480Šæ", + "timedmedia-derivative-desc-480p.webm": "WebM Š·Š° ŠµŠ¼ŠøŃŠ¾Š²Š°ŃŠµ (480Šæ)", + "timedmedia-derivative-720p.webm": "WebM 720Šæ", + "timedmedia-derivative-desc-720p.webm": "ŠŠøŃŠ¾ŠŗŠ¾ŠŗŠ²Š°Š»ŠøŃŠµŃŠ½Šø WebM Š·Š° ŠæŃŠµŃŠ·ŠøŠ¼Š°ŃŠµ (720Šæ)", + "timedmedia-subtitle-language": "$1 ($2) ŃŠøŃŠ»Š¾Š²Šø", + "timedmedia-subtitle-no-video": "ŠŠµŠ¼Š° Š²ŠøŠ“ŠµŠ¾-ŃŠ½ŠøŠ¼Š°ŠŗŠ° ŠæŠ¾Š²ŠµŠ·Š°Š½ŠøŃ
ŃŠ° ŃŠµŠŗŃŃŠ¾Š¼ ŃŃŃŠ°Š½ŠøŃŠ¾Š¼ Ń ŃŠøŃŠ»Š¾Š²ŠøŠ¼Š°", + "timedmedia-subtitle-no-subtitles": "Š¢ŃŠµŠ½ŃŃŠ½Š¾ Š½ŠµŠ¼Š° $1 ŃŠøŃŠ»Š¾Š²Š° Š·Š° Š¾Š²Š°Ń Š²ŠøŠ“ŠµŠ¾-ŃŠ½ŠøŠ¼Š°Šŗ. ŠŠ¾Š¶ŠµŃŠµ Š“Š° ŠøŃ
Š“Š¾Š“Š°ŃŠµ ŃŠ°ŠŗŠ¾ ŃŃŠ¾ ŃŠµŃŠµ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ŃŃŠµŠ“ŠøŃŠø ŃŃŃŠ°Š½ŠøŃŃ]" +} diff --git a/extensions/TimedMediaHandler/i18n/sr-el.json b/extensions/TimedMediaHandler/i18n/sr-el.json new file mode 100644 index 00000000..936e1e92 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sr-el.json @@ -0,0 +1,53 @@ +{ + "@metadata": { + "authors": [ + "Michaello", + "Milicevic01", + "Rancher" + ] + }, + "timedmedia-desc": "ObraÄivaÄ za zvuk, video i usklaÄeni tekst, s podrÅ”kom za formate WebM, Ogg Theora, Vorbis i SRT", + "timedmedia-ogg-short-audio": "Ogg $1 zvuÄna datoteka, $2", + "timedmedia-ogg-short-video": "Ogg $1 video-snimak, $2.", + "timedmedia-ogg-short-general": "Ogg $1 medijska datoteka, $2.", + "timedmedia-ogg-long-audio": "Ogg $1 zvuÄna datoteka, dužina $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 video-snimak, trajanje $2, $4 Ć $5 piksela, $3.", + "timedmedia-ogg-long-multiplexed": "Multipleksirani .ogg audio/video snimak, $1, trajanje $2, $4 Ć $5 piksela, $3.", + "timedmedia-ogg-long-general": "Ogg medijska datoteka, dužina $2, $3.", + "timedmedia-ogg-long-error": "Neispravna .ogg datoteka: $1.", + "timedmedia-no-player-js": "Žao nam je, ali vaÅ”em pregledaÄu je onemoguÄena javaskripta ili nemate odgovarajuÄi plejer.<br />\nMožete <a href=\"$1\">preuzeti klip</a> ili <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">preuzeti plejer</a> da reprodukujete klip u vaÅ”em pregledaÄu.", + "timedmedia-more": "ViÅ”e...", + "timedmedia-dismiss": "Zatvori", + "timedmedia-download": "Preuzmi datoteku", + "timedmedia-desc-link": "Podaci o ovoj datoteci", + "timedmedia-days": "{{PLURAL:$1|1 dan|$1 dana}}", + "timedmedia-hours": "{{PLURAL:$1|1 sat|$1 sata|$1 sati}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minut|$1 minuta}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekund|$1 sekunde|$1 sekundi}}", + "timedmedia-reset": "PoniÅ”ti prekodiranje", + "timedmedia-reset-confirm": "PoniÅ”tavanje ovog prekodiranja Äe ukloniti postojeÄu datoteku (ako postoji) i vratiti prekodiranje na spisak zadataka. Ova radnja može da potraje. <br /><br />\nŽelite li da nastavite?", + "timedmedia-reset-error": "GreÅ”ka pri poniÅ”tavanju zadataka za prekodiranje.", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-source-file": "Izvorni $1", + "timedmedia-source-file-desc": "Izvorni $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Tip datoteke $1 ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160p", + "timedmedia-derivative-desc-160p.ogv": "Niskopropusni .ogg video (160p)", + "timedmedia-derivative-360p.ogv": "Ogg 360p", + "timedmedia-derivative-desc-360p.ogv": "Ogg video za emitovanje (360p)", + "timedmedia-derivative-480p.ogv": "Ogg 480p", + "timedmedia-derivative-desc-480p.ogv": "Ogg video za emitovanje (480p)", + "timedmedia-derivative-720p.ogv": "Ogg 720p", + "timedmedia-derivative-desc-720p.ogv": "Visokokvalitetni .ogg video za preuzimanje (720p)", + "timedmedia-derivative-360p.webm": "WebM 360p", + "timedmedia-derivative-desc-360p.webm": "WebM za emitovanje (360p)", + "timedmedia-derivative-480p.webm": "WebM 480p", + "timedmedia-derivative-desc-480p.webm": "WebM za emitovanje (480p)", + "timedmedia-derivative-720p.webm": "WebM 720p", + "timedmedia-derivative-desc-720p.webm": "Visokokvalitetni WebM za preuzimanje (720p)", + "timedmedia-subtitle-language": "$1 ($2) titlovi", + "timedmedia-subtitle-no-video": "Nema video-snimaka povezanih sa tekuÄom stranicom s titlovima", + "timedmedia-subtitle-no-subtitles": "Trenutno nema $1 titlova za ovaj video-snimak. Možete da ih dodate tako Å”to Äete [{{fullurl:{{FULLPAGENAME}}|action=edit}} urediti stranicu]", + "timedmedia-file": "Datoteka" +} diff --git a/extensions/TimedMediaHandler/i18n/stq.json b/extensions/TimedMediaHandler/i18n/stq.json new file mode 100644 index 00000000..9657a896 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/stq.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Pyt" + ] + }, + "timedmedia-desc": "Stjuurengsprogramm foar Ogg Theora- un Vorbis-DoatƤie, inklusive n JavaScript-Ouspielsoftware", + "timedmedia-ogg-short-audio": "Ogg-$1-AudiodoatƤi, $2", + "timedmedia-ogg-short-video": "Ogg-$1-VideodoatƤi, $2", + "timedmedia-ogg-short-general": "Ogg-$1-MediadoatƤi, $2", + "timedmedia-ogg-long-audio": "Ogg-$1-AudiodoatƤi, Loangte: $2, $3", + "timedmedia-ogg-long-video": "Ogg-$1-VideodoatƤi, Loangte: $2, $4Ć$5 Pixel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg-Audio-/Video-DoatƤi, $1, Loangte: $2, $4Ć$5 Pixel, $3", + "timedmedia-ogg-long-general": "Ogg-MediadoatƤi, Loangte: $2, $3", + "timedmedia-ogg-long-error": "Uungultige Ogg-DoatƤi: $1", + "timedmedia-more": "Optione ā¦", + "timedmedia-dismiss": "Sluute", + "timedmedia-download": "DoatƤi spiekerje", + "timedmedia-desc-link": "Uur disse DoatƤi" +} diff --git a/extensions/TimedMediaHandler/i18n/su.json b/extensions/TimedMediaHandler/i18n/su.json new file mode 100644 index 00000000..2fddd5c2 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/su.json @@ -0,0 +1,19 @@ +{ + "@metadata": { + "authors": [ + "Kandar" + ] + }, + "timedmedia-ogg-short-audio": "Koropak sora $1 ogg, $2", + "timedmedia-ogg-short-video": "Koropak vidĆ©o $1 ogg, $2", + "timedmedia-ogg-short-general": "Koropak mĆ©dia $1 ogg, $2", + "timedmedia-ogg-long-audio": "Koropak sora $1 ogg, lilana $2, $3", + "timedmedia-ogg-long-video": "Koropak vidĆ©o $1 ogg, lilana $2, $4Ć$5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "Koropak sora/vidĆ©o ogg multiplĆ©ks, $1, lilana $2, $4Ć$5 piksel, $3 gembleng", + "timedmedia-ogg-long-general": "Koropak mĆ©dia ogg, lilana $2, $3", + "timedmedia-ogg-long-error": "Koropak ogg teu valid: $1", + "timedmedia-more": "Lianna...", + "timedmedia-dismiss": "Tutup", + "timedmedia-download": "Bedol", + "timedmedia-desc-link": "Ngeunaan ieu koropak" +} diff --git a/extensions/TimedMediaHandler/i18n/sv.json b/extensions/TimedMediaHandler/i18n/sv.json new file mode 100644 index 00000000..dbba4c91 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sv.json @@ -0,0 +1,125 @@ +{ + "@metadata": { + "authors": [ + "Ainali", + "Jon Harald SĆøby", + "Jopparn", + "Lejonel", + "Lokal Profil", + "Rotsee", + "Skalman", + "WikiPhoenix", + "Abbedabb" + ] + }, + "timedmedia-desc": "Hanterare fƶr ljud-, video- och tidsbestƤmd text, med stƶd fƶr format WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "Ogg $1 ljudfil, $2", + "timedmedia-ogg-short-video": "Ogg $1 videofil, $2", + "timedmedia-ogg-short-general": "Ogg $1 mediafil, $2", + "timedmedia-ogg-long-audio": "Ogg $1 ljudfil, lƤngd $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 videofil, lƤngd $2, $4Ć$5 pixel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg multiplexad ljud/video-fil, $1, lƤngd $2, $4Ć$5 pixel, $3 totalt", + "timedmedia-ogg-long-general": "Ogg mediafil, lƤngd $2, $3", + "timedmedia-ogg-long-error": "Felaktig Ogg-fil: $1", + "timedmedia-ogg-long-no-streams": "Ogg-mediafil. Varning: Ingen av de omkodare som anvƤnds i denna fil kunde identifieras.", + "timedmedia-webm-short-video": "WebM $1 videofil, $2", + "timedmedia-webm-long-video": "WebM-fil fƶr ljud/video, $1, lƤngd $2, $4 Ć $5 pixlar, $3 totalt", + "timedmedia-flac-short-audio": "FLAC-ljudfil, $1", + "timedmedia-flac-long-audio": "FLAC-ljudfil, lƤngd $1, $2 totalt", + "timedmedia-wav-short-audio": "WAV-ljudfil, $1", + "timedmedia-wav-long-audio": "WAV-ljudfil, lƤngd $1, $2 total", + "timedmedia-wav-pcm-required": "Du kan enbart ladda upp PCM (Pulskodsmodulerad) WAV", + "timedmedia-mp4-short-video": "MP4 $1 videofil, $2", + "timedmedia-mp4-long-video": "MP4-fil fƶr ljud/video, $1, lƤngd $2, $4 Ć $5 pixlar, $3 totalt", + "timedmedia-no-player-js": "TyvƤrr, din webblƤsare har antingen JavaScript inaktiverat eller inte nĆ„gon spelare som stƶds.<br />\nDu kan <a href=\"$1\">ladda ner klippet</a> eller <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">hƤmta en spelare</a> fƶr att spela upp klippet i din webblƤsare.", + "timedmedia-more": "Mer...", + "timedmedia-dismiss": "StƤng", + "timedmedia-download": "Ladda ner filen", + "timedmedia-play-media": "Spela upp media", + "timedmedia-desc-link": "Om filen", + "timedmedia-oggThumb-version": "OggHandler krƤver oggThumb version $1 eller senare.", + "timedmedia-oggThumb-failed": "oggThumb misslyckades med att skapa miniatyrbilden.", + "timedmedia-status-header": "Transkodningsstatus", + "timedmedia-update-status": "Uppdatera transkodningsstatus", + "timedmedia-status": "Status", + "timedmedia-status-unknown": "OkƤnd status", + "timedmedia-transcodebitrate": "Bithastighet", + "timedmedia-transcodeduration": "Kodningstid", + "timedmedia-transcodeinfo": "Format", + "timedmedia-actions": "Ć
tgƤrder", + "timedmedia-direct-link": "Ladda ned", + "timedmedia-not-ready": "Inte redo", + "timedmedia-completed-on": "Slutfƶrdes $1", + "timedmedia-error-on": "Fel $1", + "timedmedia-started-transcode": "Startade $1 sedan. $2", + "timedmedia-percent-done": "UngefƤr $1% klar", + "timedmedia-in-job-queue": "Lades till i jobbkƶn fƶr $1sedan", + "timedmedia-unknown-target-size": "OkƤnd mĆ„lstorlek, $1-kodad", + "timedmedia-days": "{{PLURAL:$1|1 dag|$1 dagar}}", + "timedmedia-hours": "{{PLURAL:$1|1 timme|$1 timmar}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minut|$1 minuter}}", + "timedmedia-seconds": "{{PLURAL:$1|1 sekund|$1 sekunder}}", + "timedmedia-reset": "NollstƤll transkodningen", + "timedmedia-reset-confirm": "NollstƤllning av denna transkodning tar bort alla befintliga filer (om nƤrvarande), och lƤgger Ć„ter till transkodningen till jobbkƶn. Det kommer att ta tid att om-transkoda.<br /><br />\nĆr du sƤker pĆ„ att du vill fortsƤtta?", + "timedmedia-reset-error": "Fel i nollstƤllningen av transkod-jobbet.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 KƤlla", + "timedmedia-source-file-desc": "Ursprunglig $1-fil, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Ursprunglig $1-fil ($2)", + "timedmedia-derivative-desc-160p.ogv": "LĆ„g bandbredd Ogg-video (160P)", + "timedmedia-derivative-desc-360p.ogv": "Webbstrƶmningsbar Ogg-video (360P)", + "timedmedia-derivative-desc-480p.ogv": "Webbstrƶmningsbar Ogg-video (480P)", + "timedmedia-derivative-desc-720p.ogv": "Hƶgkvalitets nedladdningsbar Ogg-video (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Nedladdningsbar Ogg-video i full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "Webbstrƶmningsbar WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "Webbstrƶmningsbar WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "Webbstrƶmningsbar WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "Hƶgkvalitets nedladdningsbar WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "Nedladdningsbar WebM i full HD (1080P)", + "timedmedia-derivative-360p.vp9.webm": "VP9 360P", + "timedmedia-derivative-480p.vp9.webm": "VP9 480P", + "timedmedia-derivative-720p.vp9.webm": "VP9 720P", + "timedmedia-derivative-1080p.vp9.webm": "VP9 1080P", + "timedmedia-derivative-desc-320p.mp4": "EnhetsvƤnlig MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "Webbstrƶmningsbar MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "HD-kvalitet MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4 med kvalitet i full HD (1080P)", + "timedmedia-subtitle-new": "Skapa ny ƶversƤttning eller redigera befintlig", + "timedmedia-subtitle-new-desc": "VƤlj sprĆ„k och tryck pĆ„ knappen '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "GĆ„", + "timedmedia-subtitle-language": "$1 ($2) undertexter", + "timedmedia-subtitle-no-video": "Det finns ingen video som Ƥr associerade med den aktuella undertextssidan", + "timedmedia-subtitle-no-subtitles": "Det finns fƶr nƤrvarande ingen textning pĆ„ $1 fƶr denna video, du kan [{{fullurl:{{FULLPAGENAME}}|action=edit}} redigera denna sida] fƶr att lƤgga till dem", + "timedmedia-subtitle-remote": "Undertexter (timed text) fƶr denna fil finns pĆ„ $1", + "timedmedia-subtitle-remote-link": "Du kan [$1 visa beskrivningssidan] fƶr denna fil pĆ„ $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 videoklipp|$1 videoklipp}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg-video|$1 Ogg-videor}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM-video|$1 WebM-videor}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transkodning|$1 transkodningar}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 aktiv transkodning|$1 aktiva transkodningar}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 kƶad transkodning|$1 kƶade transkodningar}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 misslyckad transkodning|$1 misslyckade transkodningar}}", + "timedmedia-file": "Fil", + "timedmedia-audios": "{{PLURAL:$1|$1 ljudfil|$1 ljudfiler}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg-ljudfil|$1 Ogg-ljudfiler}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC-ljudfil|$1 FLAC-ljudfiler}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV-ljudfil|$1 WAV-ljudfiler}}", + "right-transcode-reset": "Ć
terstƤll misslyckade eller transkodade videor sĆ„ att de Ć„ter infogas i jobbkƶn.", + "right-transcode-status": "Visa [[Special:TimedMediaHandler|information om den aktuella transkodningsaktivitetet]]", + "action-transcode-status": "visa den aktuella transkodningsstatusen", + "orphanedtimedtext": "FƶrƤldralƶsa TimedText-sidor", + "orphanedtimedtext-summary": "Lista ƶver [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] sidor som inte har en motsvarande fil.", + "orphanedtimedtext-unsupported": "Denna special-sida har bara stƶd pĆ„ MySQL-databaser.", + "orphanedtimedtext-notimedtext": "TimedText Ƥr inte aktiverat pĆ„ denna wiki.", + "apihelp-query+transcodestatus-description": "HƤmta transkodningsstatusen fƶr en viss filsida.", + "apihelp-query+transcodestatus-example-1": "HƤmta transkodningsstatusen fƶr [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "Utƶkar imageinfo till att inkludera kƤllinformation fƶr video (derivat)", + "apihelp-query+videoinfo-param-prop": "Vilken videoinformation att hƤmta:\n;timestamp:LƤgger till tidsstƤmpeln fƶr den uppladdade versionen.\n;user:LƤgger till anvƤndaren som laddade upp videoversionen.\n;userid:LƤgger till anvƤndar-ID:et som laddade upp videoversionen.\n;comment:Kommentar fƶr versionen.\n;parsedcomment:Tolka kommentaren fƶr versionen.\n;canonicaltitle:LƤgger till den kanoniska titeln fƶr videofilen.\n;url:Ger URL:en till videon och beskrivningssidan.\n;size:LƤgger till storleken pĆ„ videon i bytes, dess hƶjd och vidd. Sidantal och varaktighet om applicerbart.\n;dimensions:Alias fƶr size.\n;sha1:LƤgger till SHA-1-hash fƶr videon.\n;mime:LƤgger till MIME-typ fƶr videon.\n;thumbmime:LƤgger till MIME-typ fƶr videons miniatyr (krƤver url och parametern $1urlwidth).\n;mediatype:LƤgger till mediatyp fƶr videon.\n;metadata:Listar Exif-metadata fƶr versionen av videon.\n;commonmetadata:Listar filformatgenerisk metadata fƶr versionen av videon.\n;extmetadata:Listar formaterad metadata kombinerad frĆ„n flera kƤllor. Resultaten Ƥr HTML-formaterade.\n;archivename:LƤgger till filnamn fƶr arkivversionen fƶr icke-senaste versioner.\n;bitdepth:LƤgger till bitdjup fƶr versionen.\n;uploadwarning:AnvƤnds av [[Special:Upload]]-sidan fƶr att fĆ„ information om en existerande fil. Ej avsedd fƶr bruk utanfƶr Mediawiki core.\n;derivatives:LƤgger till en lista fƶr de olika format- och kvalitetsversionerna fƶr en audio- eller videofil som Ƥr tillgƤngliga.", + "apihelp-query+videoinfo-example-1": "HƤmta information om [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "AnvƤndare med \"transcode-reset\"-rƤttigheten kan Ć„terstƤlla och kƶra om ett transkodningsjobb.", + "apihelp-transcodereset-param-title": "Mediefilens titel.", + "apihelp-transcodereset-param-transcodekey": "Den transkodningsnyckel du ƶnskar Ć„terstƤlla. HƤmta frĆ„n [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "Ć
terstƤll alla transkodningar fƶr [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "Ć
terstƤll \"360_560kbs.webm\"-transkodningsnyckeln fƶr [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/sw.json b/extensions/TimedMediaHandler/i18n/sw.json new file mode 100644 index 00000000..51d86efc --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/sw.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Stephenwanjau" + ] + }, + "timedmedia-download": "Pakua faili", + "timedmedia-desc-link": "Kuhusu faili hii", + "timedmedia-status": "Hali", + "timedmedia-actions": "Vitendo", + "timedmedia-not-ready": "Haiko tayari", + "timedmedia-subtitle-new-go": "Nenda", + "timedmedia-file": "Faili" +} diff --git a/extensions/TimedMediaHandler/i18n/szl.json b/extensions/TimedMediaHandler/i18n/szl.json new file mode 100644 index 00000000..105eeaa9 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/szl.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Krol111" + ] + }, + "timedmedia-source-file": "ZdrzÅÆdÅo ($1)", + "timedmedia-source-audio-file-desc": "Uoryginalny plik $1 ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/ta.json b/extensions/TimedMediaHandler/i18n/ta.json new file mode 100644 index 00000000..69410ef5 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ta.json @@ -0,0 +1,32 @@ +{ + "@metadata": { + "authors": [ + "Balajijagadesh", + "Karthi.dr", + "Shanmugamp7", + "ą®®ą®¤ą®©ą®¾ą®¹ą®°ą®©ąÆ", + "Jayarathina" + ] + }, + "timedmedia-ogg-long-general": "Ogg ą®ą®ą® ą®ąÆą®ŖąÆą®ŖąÆ, ą®ØąÆą®³ą®®ąÆ $2 , $3", + "timedmedia-ogg-long-error": "ą®ąÆą®²ąÆą®²ą®¾ą®¤ ogg ą®ąÆą®ŖąÆą®ŖąÆ: $1", + "timedmedia-no-player-js": "ą®®ą®©ąÆą®©ą®æą®ąÆą®ą®µąÆą®®ąÆ, ą®ą®ąÆą®ą®³ąÆ ą®ą®²ą®¾ą®µą®æą®Æą®æą®²ąÆ ą®ą®¾ą®µą®¾ą®øąÆą®ą®æą®°ą®æą®ŖąÆą®ąÆ ą®®ąÆą®ą®ąÆą®ą®ŖąÆą®Ŗą®ąÆą®ą®æą®°ąÆą®ąÆą®ą®æą®©ąÆą®±ą®¤ąÆ ą®
ą®²ąÆą®²ą®¤ąÆ ą®¤ą®ąÆą®ØąÆą®¤ ą®ą®Æą®ąÆą®ą®æ ą®ą®²ąÆą®²ąÆ.<br />\ną®ØąÆą®ąÆą®ą®³ąÆ <a href=\"$1\">ą®ą®ąÆą®ąÆą®ŖąÆą®Ŗą®æą®©ąÆ ą®¤ą®°ą®µą®æą®°ą®ąÆą®ą®®ąÆ ą®ąÆą®ÆąÆą®Æą®²ą®¾ą®®ąÆ</a> ą®
ą®²ąÆą®²ą®¤ąÆ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą®¤ą®ąÆą®ØąÆą®¤ ą®ą®Æą®ąÆą®ą®æą®Æą®æą®©ąÆ ą®¤ą®°ą®µą®æą®°ą®ąÆą®ą®®ąÆ ą®ąÆą®ÆąÆą®¤ąÆ</a> ą®ą®¤ą®©ąÆ ą®ą®ąÆą®ą®³ąÆ ą®ą®²ą®¾ą®µą®æą®Æą®æą®²ąÆ ą®ą®ąÆą®ą®²ą®¾ą®®ąÆ.", + "timedmedia-more": "ą®®ąÆą®²ąÆą®®ąÆ...", + "timedmedia-dismiss": "ą®®ąÆą®ąÆą®", + "timedmedia-download": "ą®ąÆą®ŖąÆą®ŖąÆ ą®Ŗą®¤ą®æą®µą®æą®±ą®ąÆą®ą®®ąÆ ą®ąÆą®ÆąÆ", + "timedmedia-play-media": "ą®ą®ą®ą®¤ąÆą®¤ąÆ ą®ą®ą®µą®æą®ąÆ", + "timedmedia-desc-link": "ą®ą®ØąÆą®¤ą®ąÆ ą®ąÆą®ŖąÆą®ŖąÆą®ŖąÆ ą®Ŗą®±ąÆą®±ą®æ", + "timedmedia-status": "ą®Øą®æą®²ąÆ", + "timedmedia-status-unknown": "ą®
ą®±ą®æą®Æą®ŖąÆą®Ŗą®ą®¾ą®¤ ą®Øą®æą®²ąÆ", + "timedmedia-actions": "ą®ąÆą®Æą®²ąÆą®ą®³ąÆ", + "timedmedia-not-ready": "ą®¤ą®Æą®¾ą®°ą®¾ą® ą®ą®²ąÆą®²ąÆ", + "timedmedia-percent-done": "ą®ą®±ą®¤ąÆą®¤ą®¾ą®“ $1% ą®®ąÆą®ą®æą®ØąÆą®¤ą®¤ąÆ", + "timedmedia-mp4": "ą®ą®®ąÆą®Ŗą®æ4", + "timedmedia-source-file": "$1 ą®®ąÆą®²ą®®ąÆ", + "timedmedia-source-file-desc": "ą®®ąÆą®² $1, $2 Ć $3 ($4)", + "timedmedia-subtitle-new": "ą®ŖąÆą®¤ą®æą®Æ ą®®ąÆą®“ą®æą®ŖąÆą®Æą®°ąÆą®ŖąÆą®ŖąÆ ą®ą®°ąÆą®µą®¾ą®ąÆą®ą®µąÆą®®ąÆ ą®
ą®²ąÆą®²ą®¤ąÆ ą®ą®³ąÆą®³ą®¤ąÆą®¤ąÆ ą®¤ąÆą®ąÆą®ąÆą®ą®µąÆą®®ąÆ", + "timedmedia-subtitle-new-go": "ą®ąÆą®²ąÆ", + "timedmedia-subtitle-language": "$1 ($2) ą®¤ąÆą®£ąÆą®¤ąÆą®¤ą®²ąÆą®ŖąÆą®ŖąÆą®ąÆą®ą®³ąÆ", + "timedmedia-videos": "{{PLURAL:$1|$1 ą®ą®¾ą®£ąÆą®³ą®æ|$1 ą®ą®¾ą®£ąÆą®³ą®æą®ą®³ąÆ}}", + "timedmedia-file": "ą®ąÆą®ŖąÆą®ŖąÆ" +} diff --git a/extensions/TimedMediaHandler/i18n/tcy.json b/extensions/TimedMediaHandler/i18n/tcy.json new file mode 100644 index 00000000..622447e7 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tcy.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "VASANTH S.N." + ] + }, + "timedmedia-source-file": "$1 ą²®ą³ą²²", + "timedmedia-source-audio-file-desc": "ą²®ą³ą²² $1 ą²ą²”ą²¤ ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/te.json b/extensions/TimedMediaHandler/i18n/te.json new file mode 100644 index 00000000..96cc2e73 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/te.json @@ -0,0 +1,37 @@ +{ + "@metadata": { + "authors": [ + "Kiranmayee", + "Veeven", + "ą°µą±ą°ą°¾ą°øą°¤ą±ą°Æ", + "ą°°ą°¹ą±ą°®ą°¾ą°Øą±ą°¦ą±ą°¦ą±ą°Øą±" + ] + }, + "timedmedia-ogg-short-audio": "Ogg $1 ą°¶ą±ą°°ą°¾ą°µą±ą°Æą° ą°«ą±ą°²ą±, $2", + "timedmedia-ogg-short-video": "Ogg $1 ą°µą±ą°”ą°æą°Æą± ą°«ą±ą°²ą±, $2", + "timedmedia-ogg-short-general": "Ogg $1 ą°®ą±ą°”ą°æą°Æą°¾ ą°«ą±ą°²ą±, $2", + "timedmedia-ogg-long-audio": "Ogg $1 ą°¶ą±ą°°ą°µą°£ ą°«ą±ą°²ą±, ą°Øą°æą°”ą°æą°µą°æ $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 ą°µą±ą°”ą°æą°Æą± ą°«ą±ą°²ą±, ą°Øą°æą°”ą°æą°µą°æ $2, $4Ć$5 ą°Ŗą°æą°ą±ą°øą±ą°³ą±ą°³ą±, $3", + "timedmedia-ogg-long-multiplexed": "ą°ą°ą± ą°®ą°²ą±ą°ą°æą°Ŗą±ą°²ą±ą°ą±ą°øą±ą°”ą± ą°¶ą±ą°°ą°µą°£/ą°¦ą±ą°¶ą±ą°Æą° ą°«ą±ą°²ą±, $1, ą°Øą°æą°”ą°æą°µą°æ $2, $4Ć$5 ą°Ŗą°æą°ą±ą°øą±ą°³ą±ą°³ą±, $3 ą°®ą±ą°¤ą±ą°¤ą°", + "timedmedia-ogg-long-general": "Ogg ą°®ą±ą°”ą°æą°Æą°¾ ą°«ą±ą°²ą±, ą°Øą°æą°”ą°æą°µą°æ $2, $3", + "timedmedia-ogg-long-error": "ą°¤ą°Ŗą±ą°Ŗą±ą°”ą± ogg ą°«ą±ą°²ą±: $1", + "timedmedia-no-player-js": "ą°ą±ą°·ą°®ą°æą°ą°ą°¾ą°²ą°æ, ą°®ą± ą°µą°æą°¹ą°¾ą°°ą°æą°£ą°æą°²ą± ą°ą°¾ą°µą°¾ą°øą±ą°ą±ą°°ą°æą°Ŗą±ą°ą± ą°
ą°ą±ą°¤ą°Øą°ą°ą°¾ ą°ą°ą°¦ą°æ ą°²ą±ą°¦ą°¾ ą°®ą± ą°µą°æą°¹ą°¾ą°°ą°æą°£ą°æą°ą°æ ą°¤ą°ą°æą°Ø ą°¦ą±ą°¶ą±ą°Æą°ą°¾ą°²ą°ą° ą°
ą°ą°¦ą±ą°¬ą°¾ą°ą±ą°²ą± ą°²ą±ą°¦ą±.<br />\ną°®ą±ą°°ą± <a href=\"$1\">ą°®ą±ą°°ą± ą°µą±ą°”ą°æą°Æą± ą°ą±ą°²ą°æą°Ŗą± ą°Øą°æ ą°¦ą°æą°ą°ą±ą°ą±ą°µą°ą±ą°ą±</a> ą°²ą±ą°¦ą°¾ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ą°¦ą±ą°¶ą±ą°Æą°ą°¾ą°²ą°ą°¾ą°Øą±ą°Øą°æ</a> ą°¦ą°æą°ą°Ŗą±ą°ą±ą°Øą°æ ą° ą°µą±ą°”ą°æą°Æą± ą°ą±ą°²ą°æą°Ŗą± ą°Øą± ą°®ą± ą°µą°æą°¹ą°¾ą°°ą°æą°£ą°æą°²ą± ą°ą±ą°”ą°µą°ą±ą°ą±.", + "timedmedia-more": "ą°®ą°°ą°æą°Øą±ą°Øą°æ...", + "timedmedia-dismiss": "ą°®ą±ą°øą°æą°µą±ą°Æą°æ", + "timedmedia-download": "ą°«ą±ą°²ą±ą°Øą°æ ą°¦ą°æą°ą±ą°®ą°¤ą°æ ą°ą±ą°øą±ą°ą±ą°ą°”ą°æ", + "timedmedia-desc-link": "ą° ą°«ą±ą°²ą± ą°ą±ą°°ą°æą°ą°ą°æ", + "timedmedia-status": "ą°øą±ą°„ą°æą°¤ą°æ", + "timedmedia-status-unknown": "ą°¤ą±ą°²ą°æą°Æą°Øą°æ ą°øą±ą°„ą°æą°¤ą°æ", + "timedmedia-actions": "ą°ą°°ą±ą°Æą°²ą±", + "timedmedia-days": "{{PLURAL:$1|1 ą°°ą±ą°ą±|$1 ą°°ą±ą°ą±ą°²ą±}}", + "timedmedia-hours": "{{PLURAL:$1|1 ą°ą°ą°|$1 ą°ą°ą°ą°²ą±}}", + "timedmedia-minutes": "{{PLURAL:$1|1 ą°Øą°æą°®ą°æą°·ą°|$1 ą°Øą°æą°®ą°æą°·ą°¾ą°²ą±}}", + "timedmedia-seconds": "{{PLURAL:$1|1 ą°ą±ą°·ą°£ą°|$1 ą°ą±ą°·ą°£ą°¾ą°²ą±}}", + "timedmedia-source-file": "$1 ą°®ą±ą°²ą°", + "timedmedia-source-file-desc": "ą°
ą°øą°²ą± $1 ą°¦ą°øą±ą°¤ą±ą°°ą°, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ą°
ą°øą°²ą± $1 ą°¦ą°øą±ą°¤ą±ą°°ą° ($2)", + "timedmedia-subtitle-new-go": "ą°µą±ą°³ą±ą°³ą±", + "timedmedia-subtitle-language": "$1 ($2) ą°ą°Ŗą°¶ą±ą°°ą±ą°·ą°æą°ą°²ą±", + "timedmedia-videos": "{{PLURAL:$1|$1 ą°µą±ą°”ą°æą°Æą±|$1 ą°µą±ą°”ą°æą°Æą±ą°²ą±}}", + "timedmedia-file": "ą°¦ą°øą±ą°¤ą±ą°°ą°" +} diff --git a/extensions/TimedMediaHandler/i18n/tg-cyrl.json b/extensions/TimedMediaHandler/i18n/tg-cyrl.json new file mode 100644 index 00000000..abfda498 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tg-cyrl.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Ibrahim" + ] + }, + "timedmedia-desc": "ŠŠ° Š“Š°ŃŃŠ³ŠøŃŠ°Š½Š“Š°Šµ Š±Š°ŃŠ¾Šø ŠæŠ°ŃŠ²Š°Š½Š“Š°Ņ³Š¾Šø Ogg Theora Š²Š° Vorbis, Š±Š¾ ŠæŠ°Ń
ŃŠŗŃŠ½Š°Š½Š“Š°Šø JavaScript", + "timedmedia-ogg-short-audio": "Ogg $1 ŠæŠ°ŃŠ²Š°Š½Š“Š°Šø ŃŠ°Š²ŃÓ£, $2", + "timedmedia-ogg-short-video": "Ogg $1 ŠæŠ°ŃŠ²Š°Š½Š“Š°Šø Š½Š°Š²Š¾ŃÓ£, $2", + "timedmedia-ogg-short-general": "Ogg $1 ŠæŠ°ŃŠ²Š°Š½Š“Š°Šø ŃŠ°ŃŠ¾Š½Š°, $2", + "timedmedia-ogg-long-audio": "Ogg $1 ŠæŠ°ŃŠ²Š°Š½Š“Š°Šø ŃŠ°Š²ŃÓ£, ŃÓÆŠ» $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 ŠæŠ°ŃŠ²Š°Š½Š“Š°Šø Š½Š°Š²Š¾ŃÓ£, ŃÓÆŠ» $2, $4Ć$5 ŠæŠøŠŗŃŠµŠ»Ņ³Š¾, $3", + "timedmedia-ogg-long-multiplexed": "ŠŠ°ŃŠ²Š°Š½Š“Š°Šø Ogg ŃŠ°Š²ŃÓ£/Š½Š°Š²Š¾ŃÓ£ ŠæŠµŃŠøŠ“Š°, $1, ŃÓÆŠ» $2, $4Ć$5 ŠæŠøŠŗŃŠµŠ»Ņ³Š¾, Š“Š°Ń Š¼Š°Ņ·Š¼ÓÆŃ $3", + "timedmedia-ogg-long-general": "ŠŠ°ŃŠ²Š°Š½Š“Š°Šø ŃŠ°ŃŠ¾Š½Š°Šø Ogg, ŃÓÆŠ» $2, $3", + "timedmedia-ogg-long-error": "ŠŠ°ŃŠ²Š°Š½Š“Š°Šø ŅŠ°Š¹ŃŠøŠ¼ŠøŅ·Š¾Š·Šø ogg: $1", + "timedmedia-more": "ŠŠµŃŃŠ°Ń...", + "timedmedia-dismiss": "ŠŠ°ŃŃŠ°Š½", + "timedmedia-download": "ŠŠ¾ŃŠ³ŠøŃŠøŠø ŠæŠ°ŃŠ²Š°Š½Š“Š°", + "timedmedia-desc-link": "ŠŠ°Ń Š±Š¾ŃŠ°Šø ŠøŠ½ ŠæŠ°ŃŠ²Š°Š½Š“Š°" +} diff --git a/extensions/TimedMediaHandler/i18n/tg-latn.json b/extensions/TimedMediaHandler/i18n/tg-latn.json new file mode 100644 index 00000000..b32a59aa --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tg-latn.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Liangent" + ] + }, + "timedmedia-desc": "Ba dastgirandae baroi parvandahoi Ogg Theora va Vorbis, bo paxÅkunandai JavaScript", + "timedmedia-ogg-short-audio": "Ogg $1 parvandai savtÄ«, $2", + "timedmedia-ogg-short-video": "Ogg $1 parvandai navorÄ«, $2", + "timedmedia-ogg-short-general": "Ogg $1 parvandai rasona, $2", + "timedmedia-ogg-long-audio": "Ogg $1 parvandai savtÄ«, tÅ«l $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 parvandai navorÄ«, tÅ«l $2, $4Ć$5 pikselho, $3", + "timedmedia-ogg-long-multiplexed": "Parvandai Ogg savtÄ«/navorÄ« pecida, $1, tÅ«l $2, $4Ć$5 pikselho, dar maƧmÅ«' $3", + "timedmedia-ogg-long-general": "Parvandai rasonai Ogg, tÅ«l $2, $3", + "timedmedia-ogg-long-error": "Parvandai Ę£ajrimiƧozi ogg: $1", + "timedmedia-more": "BeÅtar...", + "timedmedia-dismiss": "Bastan", + "timedmedia-download": "Borgiriji parvanda", + "timedmedia-desc-link": "Dar borai in parvanda" +} diff --git a/extensions/TimedMediaHandler/i18n/tk.json b/extensions/TimedMediaHandler/i18n/tk.json new file mode 100644 index 00000000..7b0d49a8 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tk.json @@ -0,0 +1,20 @@ +{ + "@metadata": { + "authors": [ + "Hanberke" + ] + }, + "timedmedia-desc": "Ogg Theora we Vorbis faĆ½llary Ć¼Ć§in iÅleĆ½ji, JavaScript pleĆ½eri bilen bilelikde", + "timedmedia-ogg-short-audio": "Ogg $1 ses faĆ½ly, $2", + "timedmedia-ogg-short-video": "Ogg $1 wideo faĆ½ly, $2", + "timedmedia-ogg-short-general": "Ogg $1 media faĆ½ly, $2", + "timedmedia-ogg-long-audio": "Ogg $1 ses faĆ½ly, uzynlyk $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 wideo faĆ½ly, uzynlyk $2, $4Ć$5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg multipleks audio/wideo faĆ½ly, $1, uzynlyk $2, $4Ć$5 piksel, $3 jemi", + "timedmedia-ogg-long-general": "Ogg media faĆ½ly, uzynlyk $2, $3", + "timedmedia-ogg-long-error": "NƤdogry ogg faĆ½ly: $1", + "timedmedia-more": "Has kƶp...", + "timedmedia-dismiss": "Ćap", + "timedmedia-download": "FaĆ½l dĆ¼ÅĆ¼r", + "timedmedia-desc-link": "Bu faĆ½l hakda" +} diff --git a/extensions/TimedMediaHandler/i18n/tl.json b/extensions/TimedMediaHandler/i18n/tl.json new file mode 100644 index 00000000..9aa38812 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tl.json @@ -0,0 +1,84 @@ +{ + "@metadata": { + "authors": [ + "AnakngAraw", + "Sky Harbor" + ] + }, + "timedmedia-desc": "Tagahawak para sa audio, bidyo at inoorasang teksto, na may pagtangkilik ng anyo para sa WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "$1 na talaksang pangtunog ng Ogg, $2", + "timedmedia-ogg-short-video": "$1 talaksang pampalabas (''video'') ng Ogg, $2", + "timedmedia-ogg-short-general": "$1 talaksang pangmidya ng Ogg, $2", + "timedmedia-ogg-long-audio": "$1 talaksang pantunog ng Ogg, haba $2, $3", + "timedmedia-ogg-long-video": "$1 talaksan ng palabas ng Ogg, haba $2, $4Ć$5 mga piksel, $3", + "timedmedia-ogg-long-multiplexed": "magkasanib at nagsasabayang talaksang nadirinig o audio/palabas ng Ogg, $1, haba $2, $4Ć$5 mga piksel, $3 sa kalahatan", + "timedmedia-ogg-long-general": "Talaksang pangmidya ng ''Ogg'', haba $2, $3", + "timedmedia-ogg-long-error": "Hindi tanggap na talaksang ''ogg'': $1", + "timedmedia-webm-short-video": "$1 na talaksan ng bidyo ng WebM, $2", + "timedmedia-webm-long-video": "Talaksang pamparinig/bidyo ng WebM, $1, haba $2, $4 Ć $5 mga piksel, $3 lahat-lahat", + "timedmedia-no-player-js": "Paumahin, ang pantingin-tingin mo ay maaaring may hindi gumaganang JavaScript o walang anumang tinatangkilik na pampaandar.<br />\nMaaari kang <a href=\"$1\">magkargang pababa ng kaputol</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">magkargang pababa ng isang pampaandar</a> upang mapaandar ang kaputol sa loob ng iyong pantingin-tingin.", + "timedmedia-more": "Marami paā¦", + "timedmedia-dismiss": "Isara", + "timedmedia-download": "Ikarga ang talaksan", + "timedmedia-play-media": "Paandarin ang midya", + "timedmedia-desc-link": "Tungkol sa talaksang ito", + "timedmedia-oggThumb-version": "Nangangailangan ang OggHandler ng bersyong $1 o mas luma ng oggThumb.", + "timedmedia-oggThumb-failed": "Nabigong lumikha ang oggThumb ng munting larawan.", + "timedmedia-status-header": "Katayuan ng transkodigo", + "timedmedia-update-status": "Isapanahon ang katayuan ng transkodigo", + "timedmedia-status": "Katayuan", + "timedmedia-status-unknown": "Hindi alam na katayuan", + "timedmedia-transcodeinfo": "Paglalarawan sa hinangong transkodigo", + "timedmedia-actions": "Mga kilos", + "timedmedia-direct-link": "Ikargang paibaba ang hinango", + "timedmedia-not-ready": "Hindi nakahanda", + "timedmedia-completed-on": "Nabuo ang transkodigo noong $1", + "timedmedia-error-on": "Kamalian sa transkodigo noong $1.", + "timedmedia-started-transcode": "Nagsimula ang transkodigo noong $1 na ang nakalilipas. $2", + "timedmedia-percent-done": "Halos $1% na ang natatapos", + "timedmedia-in-job-queue": "Idinagdag sa pila ng Gawain noong $1 na ang nakalilipas", + "timedmedia-unknown-target-size": "Hindi nalalaman na puntiryang sukat, $1 naisakodigo", + "timedmedia-days": "{{PLURAL:$1|araw|$1 mga araw}}", + "timedmedia-hours": "{{PLURAL:$1|horas|$1 mga oras}}", + "timedmedia-minutes": "{{PLURAL:$1|minuto|$1 mga minuto}}", + "timedmedia-seconds": "{{PLURAL:$1|segundo|$1 mga segundo}}", + "timedmedia-reset": "Itakdang muli ang transkodigo", + "timedmedia-reset-confirm": "Ang muling pagtatakda ng transkodigong ito ay magtatanggal ng anumang umiiral na talaksan (kung naroroon), at muling nitong idaragdag ang transkodigo sa pila ng trabaho. Gugugol ito ng ilang panahon upang muling maitranskodigo. <br /><br />\nNakatitiyak ka ba na nais mong magpatuloy?", + "timedmedia-reset-error": "Kamalian sa gawain ng muling pagtatakda ng transkodigo.", + "timedmedia-ogg": "Ogg", + "timedmedia-webm": "WebM", + "timedmedia-source-file": "$1 pinagkukunan", + "timedmedia-source-file-desc": "Orihinal na $1, $2 Ć $3 ( $4)", + "timedmedia-source-audio-file-desc": "Orihinal na talaksang $1 ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160P", + "timedmedia-derivative-desc-160p.ogv": "Mababang lapad ng paha ng bidyo ng Ogg (160P)", + "timedmedia-derivative-360p.ogv": "Ogg 360P", + "timedmedia-derivative-desc-360p.ogv": "Mapapaanod sa Web na bidyo ng Ogg (360P)", + "timedmedia-derivative-480p.ogv": "Ogg 480P", + "timedmedia-derivative-desc-480p.ogv": "Mapapaanod sa Web na bidyo ng Ogg (480P)", + "timedmedia-derivative-720p.ogv": "Ogg 720P", + "timedmedia-derivative-desc-720p.ogv": "Mataas na uri ng bidyo ng Ogg na maikakargang paibaba (720P)", + "timedmedia-derivative-160p.webm": "WebM 160P", + "timedmedia-derivative-desc-160p.webm": "Mapapaanod sa Web na WebM (160P)", + "timedmedia-derivative-360p.webm": "WebM 360P", + "timedmedia-derivative-desc-360p.webm": "Mapapaanod sa Web na WebM (360P)", + "timedmedia-derivative-480p.webm": "WebM 480P", + "timedmedia-derivative-desc-480p.webm": "Mapapaanod sa Web na WebM (480P)", + "timedmedia-derivative-720p.webm": "WebM 720P", + "timedmedia-derivative-desc-720p.webm": "Mataas na uri ng WebM na maikakargang paibaba (720P)", + "timedmedia-subtitle-new": "Lumikha ng bagong salinwika o baguhin ang umiiral na", + "timedmedia-subtitle-new-desc": "Palitan ang bahaging '''$1''' ng iyong [[:en:ISO 639|kodigo ng wika]] at pindutin ang pindutang '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Gawin", + "timedmedia-subtitle-language": "$1 ($2) kabahaging mga pamagat", + "timedmedia-subtitle-no-video": "Walang bidyo na may kaugnayan sa pangkasalukuyang pahina ng kabahaging pamagat", + "timedmedia-subtitle-no-subtitles": "Kasalukuyang walang mga kabahaging pamagat sa loob ng $1 para sa bidyong ito, maaari mong [{{fullurl:{{FULLPAGENAME}}|action=edit}} baguhin ang pahinang ito] upang maidagdag ang mga ito", + "timedmediahandler": "Inoorasang Panghawak ng Midya", + "timedmedia-videos": "{{PLURAL:$1|$1 bidyo|$1 mga bidyo}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 bidyo ng Ogg|$1 mga bidyo ng Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 bidyo ng WebM|$1 mga bidyo ng WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transkodigo|$1 mga transkodigo}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 tumatakbong transkodigo|$1 tumatakbong mga transkodigo}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 nakapilang transkodigo|$1 nakapilang mga transkodigo}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 nabigong transkodigo|$1 nabigong mga transkodigo}}", + "timedmedia-file": "Talaksan" +} diff --git a/extensions/TimedMediaHandler/i18n/tly.json b/extensions/TimedMediaHandler/i18n/tly.json new file mode 100644 index 00000000..8123d4cc --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tly.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Erdemaslancan" + ] + }, + "timedmedia-subtitle-new-go": "ŠŠ°Š²Š°ŃŠ“ŠµŃ" +} diff --git a/extensions/TimedMediaHandler/i18n/tr.json b/extensions/TimedMediaHandler/i18n/tr.json new file mode 100644 index 00000000..e3e00c8f --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tr.json @@ -0,0 +1,80 @@ +{ + "@metadata": { + "authors": [ + "Erkan Yilmaz", + "Incelemeelemani", + "Joseph", + "Mach", + "Runningfridgesrule", + "Srhat", + "Sayginer", + "Stultiwikia", + "Mavrikant" + ] + }, + "timedmedia-desc": "Ses iÅleyicisi, video ve zamanlanmıŠmetin formatları iƧin WebM, Ogg Theora, Vorbis, srt desteÄi", + "timedmedia-ogg-short-audio": "Ogg $1 ses dosyası, $2", + "timedmedia-ogg-short-video": "Ogg $1 video dosyası, $2", + "timedmedia-ogg-short-general": "Ogg $1 medya dosyası, $2", + "timedmedia-ogg-long-audio": "Ogg $1 ses dosyası, sĆ¼re $2, $3", + "timedmedia-ogg-long-video": "Ogg $1 video dosyası, sĆ¼re $2, $4Ć$5 piksel, $3", + "timedmedia-ogg-long-multiplexed": "Ogg Ƨok dĆ¼zeyli ses/video dosyası, $1, sĆ¼re $2, $4Ć$5 piksel, $3 genelde", + "timedmedia-ogg-long-general": "Ogg medya dosyası, sĆ¼re $2, $3", + "timedmedia-ogg-long-error": "GeƧersiz ogg dosyası: $1", + "timedmedia-webm-short-video": "WebM $1 video dosyası, $2", + "timedmedia-webm-long-video": "WebM ses/video dosyası, $1, sĆ¼re $2, $4 Ć $5 piksel, $3 tĆ¼mĆ¼", + "timedmedia-flac-short-audio": "FLAC ses dosyası, $1", + "timedmedia-flac-long-audio": "FLAC ses dosyası, sĆ¼re $1, $2 tĆ¼mĆ¼", + "timedmedia-wav-short-audio": "WAV ses dosyası, $1", + "timedmedia-wav-long-audio": "WAV ses dosyası, sĆ¼re $1, $2 tĆ¼mĆ¼", + "timedmedia-wav-pcm-required": "Yalnızca PCM (Darbeli Kod ModĆ¼lasyonu) WAV yĆ¼kleyebilirsiniz.", + "timedmedia-mp4-short-video": "MP4 $1 video dosyası, $2", + "timedmedia-mp4-long-video": "MP4 ses/video dosyası, $1, sĆ¼re $2, $4 Ć $5 piksel, $3 tĆ¼mĆ¼", + "timedmedia-no-player-js": "ĆzgĆ¼nĆ¼z, tarayıcınızda JavaScript devredıÅı veya yĆ¼klĆ¼ bir oynatıcı yok.<br />\nÄ°sterseniz <a href=\"$1\">klibi indirebilir</a> veya tarayıcınız iƧin <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">oynatıcıyı buradan indirebilirsiniz</a>.", + "timedmedia-more": "Daha...", + "timedmedia-dismiss": "Kapat", + "timedmedia-download": "Dosya indir", + "timedmedia-play-media": "Medyayı oynat", + "timedmedia-desc-link": "Bu dosya hakkında", + "timedmedia-oggThumb-version": "OggHandler $1 veya daha yeni sĆ¼rĆ¼m oggThumb gerektirir.", + "timedmedia-oggThumb-failed": "oggThumb kĆ¼Ć§Ć¼k resim oluÅturamadı.", + "timedmedia-status-header": "Transkodu durumu", + "timedmedia-update-status": "Transkodu durumunu gĆ¼ncelle", + "timedmedia-status": "Durum", + "timedmedia-status-unknown": "Bilinmeyen durum", + "timedmedia-transcodeinfo": "Format", + "timedmedia-actions": "Ä°Ålemler", + "timedmedia-direct-link": "TĆ¼revi indir", + "timedmedia-not-ready": "Hazır deÄil", + "timedmedia-completed-on": "Tamamlanan transkodu $1", + "timedmedia-error-on": "$1 Ć¼zerinde Ƨapraz kodlama hatası", + "timedmedia-started-transcode": "$1 ƶncesinde transkod baÅlangıcı. $2", + "timedmedia-percent-done": "Tamamlanan $1% hakkında", + "timedmedia-in-job-queue": "$1 ƶnce iÅ kuyruÄuna eklendi", + "timedmedia-unknown-target-size": "$1 kodlamasında, bilinmeyen hedef boyutu", + "timedmedia-days": "{{PLURAL:$1|1 gĆ¼n|$1 gĆ¼n}}", + "timedmedia-hours": "{{PLURAL:$1|1 saat|$1 saat}}", + "timedmedia-minutes": "{{PLURAL:$1|1 dakika|$1 dakika}}", + "timedmedia-seconds": "{{PLURAL:$1|1 saniye|$1 saniye}}", + "timedmedia-reset": "Transkodu sıfırla", + "timedmedia-reset-confirm": "Bu transkodu sıfırladıÄınız takdirde (eÄer varsa), mevcut dosyalar kaldırılacak ve yeniden iÅ kuyruÄuna alınacaktır. Bu yeniden kodlama biraz zaman alacaktır.<br /><br />\nDevam etmek istediÄinize emin misiniz?", + "timedmedia-reset-error": "Transkodlama iÅinde sıfırlama hatası.", + "timedmedia-source-file": "$1 kaynaÄı", + "timedmedia-source-file-desc": "Orijinal $1 dosyası, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "Orijinal $1 dosyası ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg videosu dĆ¼ÅĆ¼k bant geniÅliÄi (160P)", + "timedmedia-derivative-desc-1080p.ogv": "Full HD indirilebilir Ogg video (1080P)", + "timedmedia-derivative-desc-1080p.webm": "Full HD indirilebilir WebM (1080P)", + "timedmedia-derivative-desc-1080p.mp4": "Full HD kalitede MP4 (1080P)", + "timedmedia-subtitle-new-go": "Git", + "timedmedia-videos": "{{PLURAL:$1|$1 video|$1 video}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg videosu|$1 Ogg videosu}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM videosu|$1 WebM videosu}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transkod|$1 transkod}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 ƧalıÅan transkod|$1 ƧalıÅan transkod}}", + "timedmedia-file": "Dosya", + "timedmedia-audios": "{{PLURAL:$1|$1 ses dosyası|$1 ses dosyası}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Ogg ses dosyası|$1 Ogg ses dosyası}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 FLAC ses dosyası|$1 FLAC ses dosyası}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 WAV ses dosyası|$1 WAV ses dosyası}}" +} diff --git a/extensions/TimedMediaHandler/i18n/ts.json b/extensions/TimedMediaHandler/i18n/ts.json new file mode 100644 index 00000000..240bfe4c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ts.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "Thuvack" + ] + }, + "timedmedia-more": "Swinwanaā¦", + "timedmedia-dismiss": "Pfala" +} diff --git a/extensions/TimedMediaHandler/i18n/tt-cyrl.json b/extensions/TimedMediaHandler/i18n/tt-cyrl.json new file mode 100644 index 00000000..e9224c6c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tt-cyrl.json @@ -0,0 +1,17 @@ +{ + "@metadata": { + "authors": [ + "ŠŠ»ŃŠ½Š°Ń", + "Derslek" + ] + }, + "timedmedia-no-player-js": "ŠŃŠ·Š³Š°Š½ŃŃŠŗŠ° ŠŗŠ°ŃŃŃ ŃŠµŠ·Š½ŠµŅ£ Š±ŃŠ°ŃŠ·ŠµŃŠ“Š° JavaScript ŃŅÆŠ½Š“ŠµŃŠµŠ»Š³ÓŠ½, ŃŠøŃÓ ŠŗŠøŃÓŠŗŠ»Šµ ŃŠ¹Š½Š°ŃŠŗŃŃ ŃŠŗ.<br />\nŠ”ŠµŠ· <a href=\"$1\">ŃŠ¾Š»ŠøŠŗŠ½Ń</a> Š¹Ó©ŠŗŠ»Šø ŃŠøŃÓ Š°Š½Ń Š±ŃŠ°ŃŠ·ŠµŃŠ“Š° ŃŠ¹Š½Š°ŃŃŃ Ó©ŃŠµŠ½<a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">ŃŠ¹Š½Š°ŃŠŗŃŃ ŠŗŃŃŃŠ¼ŃŠ°</a> Š¹Ó©ŠŗŠ»Šø Š°Š»Š°ŃŃŠ·.", + "timedmedia-more": "Š¢ŃŠ»ŃŃŠ°Šŗ...", + "timedmedia-dismiss": "ŠÆŠ±Ń", + "timedmedia-download": "Š¤Š°Š¹Š»Š½Ń Š°Š»Ń", + "timedmedia-desc-link": "Š¤Š°Š¹Š» ŃŃŃŃŠ½Š“Š° Š¼ÓŠ³ŃŠ»ŅÆŠ¼Š°Ń", + "timedmedia-oggThumb-version": "OggHandler $1 ŃŃŠ°Š¼Š°ŃŃŠ½Š½Š°Š½ Š“Š° ŃŠ³Š°ŃŃŃŠ°Šŗ oggThumb ŃÓŃŠ¼ŠøŠ½Š°ŃŃŠ½ ŃŠ¾ŃŃŠ¹.", + "timedmedia-oggThumb-failed": "oggThumb Š½ŠøŠ³ŠµŠ·ŠµŠ½Š“Ó Š¼ŠøŠ½ŠøŠ°ŃŃŃŠ°Š½Ń ŃŃŠ°Šæ Š±ŃŠ»Š¼Š°Š“Ń.", + "timedmedia-source-file": "$1-Š½ŃŠµ ŃŃŠ³Š°Š½Š°Šŗ", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŠøŠ½Š°Š»Ń $1-ŃŠ°Š¹Š» ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/tzm.json b/extensions/TimedMediaHandler/i18n/tzm.json new file mode 100644 index 00000000..cf77a584 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/tzm.json @@ -0,0 +1,8 @@ +{ + "@metadata": { + "authors": [ + "Tifinaghes" + ] + }, + "timedmedia-mp4": "MP4" +} diff --git a/extensions/TimedMediaHandler/i18n/ug-arab.json b/extensions/TimedMediaHandler/i18n/ug-arab.json new file mode 100644 index 00000000..05e95334 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ug-arab.json @@ -0,0 +1,13 @@ +{ + "@metadata": { + "authors": [ + "Sahran" + ] + }, + "timedmedia-dismiss": "ŁŲ§Ł¾", + "timedmedia-status": "Ś¾Ų§ŁŪŲŖ", + "timedmedia-actions": "Ł
ŪŲ“ŲŗŪŁŲ§ŲŖ", + "timedmedia-not-ready": "ŲŖŪŁŁŲ§Ų± Ų¦ŪŁ
ŪŲ³", + "timedmedia-subtitle-new-go": "ŁŪŲŖŁŪŁ", + "timedmedia-file": "Ś¾ŪŲ¬Ų¬ŪŲŖ" +} diff --git a/extensions/TimedMediaHandler/i18n/uk.json b/extensions/TimedMediaHandler/i18n/uk.json new file mode 100644 index 00000000..a70bd282 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/uk.json @@ -0,0 +1,134 @@ +{ + "@metadata": { + "authors": [ + "AS", + "Ahonc", + "Andriykopanytsia", + "AtUkr", + "Base", + "NickK", + "Olvin", + "Prima klasy4na", + "Steve.rusyn", + "SteveR", + "Š¢ŠµŃŃ", + "ŠŃŠ°", + "Piramidion", + "Dars" + ] + }, + "timedmedia-desc": "ŠŠ±ŃŠ¾Š±Š»ŃŠ²Š°Ń Š“Š»Ń Š°ŃŠ“ŃŠ¾, Š²ŃŠ“ŠµŠ¾ Ń ŃŃŠ±ŃŠøŃŃŃŠ² Š· ŠæŃŠ“ŃŃŠøŠ¼ŠŗŠ¾Ń ŃŠ¾ŃŠ¼Š°ŃŃŠ² WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "ŠŠ²ŃŠŗŠ¾Š²ŠøŠ¹ ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-video": "ŠŃŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-short-general": "Š¤Š°Š¹Š» Ogg $1, $2", + "timedmedia-ogg-long-audio": "Š·Š²ŃŠŗŠ¾Š²ŠøŠ¹ ŃŠ°Š¹Š» Ogg $1, Š“Š¾Š²Š¶ŠøŠ½Š° $2, $3", + "timedmedia-ogg-long-video": "Š²ŃŠ“ŠµŠ¾-ŃŠ°Š¹Š» Ogg $1, Š“Š¾Š²Š¶ŠøŠ½Š° $2, $4Ć$5 ŠæŃŠŗŃŠµŠ»ŃŠ², $3", + "timedmedia-ogg-long-multiplexed": "Š¼ŃŠ»ŃŃŠøŠæŠ»ŠµŠŗŃŠ½ŠøŠ¹ Š°ŃŠ“ŃŠ¾/Š²ŃŠ“ŠµŠ¾-ŃŠ°Š¹Š» ogg, $1, Š“Š¾Š²Š¶ŠøŠ½Š° $2, $4Ć$5 ŠæŃŠŗŃŠµŠ»ŃŠ², $3 ŃŃŃŠ¾Š³Š¾", + "timedmedia-ogg-long-general": "Š¼ŠµŠ“ŃŠ°-ŃŠ°Š¹Š» Ogg, Š“Š¾Š²Š¶ŠøŠ½Š° $2, $3", + "timedmedia-ogg-long-error": "ŠŠµŠæŃŠ°Š²ŠøŠ»ŃŠ½ŠøŠ¹ Ogg-ŃŠ°Š¹Š»: $1", + "timedmedia-ogg-long-no-streams": "ŠŠµŠ“ŃŠ°ŃŠ°Š¹Š» Ogg. ŠŠ°ŃŃŠµŃŠµŠ¶ŠµŠ½Š½Ń: ŠŠµ ŃŠ¾Š·ŠæŃŠ·Š½Š°Š½Š¾ Š¶Š¾Š“ŠµŠ½ Š· ŠŗŠ¾Š“ŠµŠŗŃŠ², Š²ŠøŠŗŠ¾ŃŠøŃŃŠ°Š½ŠøŃ
Ń ŃŃŠ¾Š¼Ń ŃŠ°Š¹Š»Ń.", + "timedmedia-webm-short-video": "WebM $1 Š²ŃŠ“ŠµŠ¾-ŃŠ°Š¹Š», $2", + "timedmedia-webm-long-video": "WebM Š°ŃŠ“ŃŠ¾/Š²ŃŠ“ŠµŠ¾ ŃŠ°Š¹Š», $1, ŃŃŠøŠ²Š°Š»ŃŃŃŃ $2, $4 Ć $5 {{PLURAL:$5|ŠæŃŠŗŃŠµŠ»Ń|ŠæŃŠŗŃŠµŠ»Ń|ŠæŃŠŗŃŠµŠ»ŃŠ²}}, Š²ŃŃŠ¾Š³Š¾ $3", + "timedmedia-flac-short-audio": "FLAC Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»,$1", + "timedmedia-flac-long-audio": "FLAC Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š», ŃŃŠøŠ²Š°Š»ŃŃŃŃ $1, $2 ŃŠ²ŠøŠ“ŠŗŃŃŃŃ", + "timedmedia-wav-short-audio": "ŠŃŠ“ŃŠ¾-ŃŠ°Š¹Š» WAV, $1", + "timedmedia-wav-long-audio": "ŠŃŠ“ŃŠ¾-ŃŠ°Š¹Š» WAV, ŃŃŠøŠ²Š°Š»ŃŃŃŃ $1, $2 ŃŠ²ŠøŠ“ŠŗŃŃŃŃ", + "timedmedia-wav-pcm-required": "ŠŠø Š¼Š¾Š¶ŠµŃŠµ ŃŃŠ»ŃŠŗŠø Š·Š°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø PCM (ŃŠ¼ŠæŃŠ»ŃŃŠ½Š¾-ŠŗŠ¾Š“Š¾Š²Š° Š¼Š¾Š“ŃŠ»ŃŃŃŃ) WAV.", + "timedmedia-mp4-short-video": "MP4 $1 Š²ŃŠ“ŠµŠ¾-ŃŠ°Š¹Š», $2", + "timedmedia-mp4-long-video": "MP4 Š°ŃŠ“ŃŠ¾/Š²ŃŠ“ŠµŠ¾ ŃŠ°Š¹Š», $1, ŃŃŠøŠ²Š°Š»ŃŃŃŃ $2, $4 Ć $5 {{PLURAL:$5|ŠæŃŠŗŃŠµŠ»Ń|ŠæŃŠŗŃŠµŠ»Ń|ŠæŃŠŗŃŠµŠ»ŃŠ²}}, Š²ŃŃŠ¾Š³Š¾ $3", + "timedmedia-no-player-js": "ŠŠ° Š¶Š°Š»Ń, Ń ŠŠ°ŃŠ¾Š¼Ń Š±ŃŠ°ŃŠ·ŠµŃŃ Š²ŠøŠ¼ŠŗŠ½ŠµŠ½Š¾ JavaScript Ń Š½Šµ ŠæŃŠ“ŃŃŠøŠ¼ŃŃŃŃŃŃ Š¶Š¾Š“Š½Š¾Š³Š¾ ŠæŃŠ¾Š³ŃŠ°Š²Š°ŃŠ°.<br />\nŠŠø Š¼Š¾Š¶ŠµŃŠµ <a href=\"$1\">Š·Š°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø ŃŠ¾Š»ŠøŠŗ</a> Š°Š±Š¾ <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">Š·Š°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø ŠæŃŠ¾Š³ŃŠ°Š²Š°Ń</a> Š“Š»Ń Š²ŃŠ“ŃŠ²Š¾ŃŠµŠ½Š½Ń ŃŠ¾Š»ŠøŠŗŃ Ń Š±ŃŠ°ŃŠ·ŠµŃŃ.", + "timedmedia-more": "ŠŃŠ»ŃŃŠµā¦", + "timedmedia-dismiss": "ŠŠ°ŠŗŃŠøŃŠø", + "timedmedia-download": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø ŃŠ°Š¹Š»", + "timedmedia-play-media": "ŠŃŠ“ŃŠ²Š¾ŃŠøŃŠø", + "timedmedia-desc-link": "ŠŠ½ŃŠ¾ŃŠ¼Š°ŃŃŃ ŠæŃŠ¾ ŃŠµŠ¹ ŃŠ°Š¹Š»", + "timedmedia-oggThumb-version": "OggHandler Š²ŠøŠ¼Š°Š³Š°Ń oggThumb Š²ŠµŃŃŃŃ $1 Š°Š±Š¾ Š±ŃŠ»ŃŃ ŠæŃŠ·Š½ŃŠ¾Ń.", + "timedmedia-oggThumb-failed": "oggThumb Š½Šµ Š²Š“Š°Š»Š¾ŃŃ ŃŃŠ²Š¾ŃŠøŃŠø Š¼ŃŠ½ŃŠ°ŃŃŃŃ.", + "timedmedia-status-header": "Š”ŃŠ°ŃŃŃ Š“ŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń", + "timedmedia-update-status": "ŠŠ½Š¾Š²ŠøŃŠø ŃŃŠ°ŃŃŃ Š“ŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń", + "timedmedia-status": "Š”ŃŠ°ŃŃŃ", + "timedmedia-status-unknown": "ŠŠµŠ²ŃŠ“Š¾Š¼ŠøŠ¹ ŃŃŠ°ŃŃŃ", + "timedmedia-transcodebitrate": "ŠŃŃŃŠµŠ¹Ń", + "timedmedia-transcodeduration": "Š§Š°Ń ŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń", + "timedmedia-transcodeinfo": "Š¤Š¾ŃŠ¼Š°Ń", + "timedmedia-actions": "ŠŃŃ", + "timedmedia-direct-link": "ŠŠ°Š²Š°Š½ŃŠ°Š¶ŠøŃŠø", + "timedmedia-not-ready": "ŠŠµ Š³Š¾ŃŠ¾Š²Š¾", + "timedmedia-completed-on": "ŠŠ°Š²ŠµŃŃŠµŠ½Š¾ $1", + "timedmedia-error-on": "ŠŠ¾Š¼ŠøŠ»ŠŗŠ° Š½Š° $1.", + "timedmedia-started-transcode": "Š Š¾Š·ŠæŠ¾ŃŠ°ŃŠ¾ $1 Š½Š°Š·Š°Š“. $2", + "timedmedia-percent-done": "ŠŃŠøŠ±Š»ŠøŠ·Š½Š¾ $1% Š³Š¾ŃŠ¾Š²Š¾", + "timedmedia-in-job-queue": "ŠŠ¾Š“Š°Š½Š¾ Š“Š¾ ŃŠµŃŠ³Šø Š·Š°Š²Š“Š°Š½Ń $1 Š½Š°Š·Š°Š“", + "timedmedia-unknown-target-size": "ŠŠµŠ²ŃŠ“Š¾Š¼ŠøŠ¹ ŃŃŠ»ŃŠ¾Š²ŠøŠ¹ ŃŠ¾Š·Š¼ŃŃ, $1 ŠæŃŠø ŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń", + "timedmedia-days": "$1 {{PLURAL:$1|Š“ŠµŠ½Ń|Š“Š½Ń|Š“Š½ŃŠ²}}", + "timedmedia-hours": "$1 {{PLURAL:$1|Š³Š°Š“ŠøŠ½Ń|Š³Š¾Š“ŠøŠ½Šø|Š³Š¾Š“ŠøŠ½}}", + "timedmedia-minutes": "$1 {{PLURAL:$1|Ń
Š²ŠøŠ»ŠøŠ½Ń|Ń
Š²ŠøŠ»ŠøŠ½Šø|Ń
Š²ŠøŠ»ŠøŠ½}}", + "timedmedia-seconds": "$1 {{PLURAL:$1|ŃŠµŠŗŃŠ½Š“Ń|ŃŠµŠŗŃŠ½Š“Šø|ŃŠµŠŗŃŠ½Š“}}", + "timedmedia-reset": "ŠŠµŃŠµŠ·Š°ŠæŃŃŠŗ Š“ŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń", + "timedmedia-reset-confirm": "ŠŠµŃŠµŠ·Š°ŠæŃŃŠŗ Š“ŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń Š²ŠøŠ“Š°Š»ŠøŃŃ Š½Š°ŃŠ²Š½ŠøŠ¹ ŃŠ°Š¹Š» (ŃŠŗŃŠ¾ Š²ŃŠ½ ŃŃŠ½ŃŃ), Ń Š“ŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń Š·Š½Š¾Š² Š±ŃŠ“Šµ Š“Š¾Š“Š°Š½Š¾ Š² ŃŠµŃŠ³Ń Š·Š°Š²Š“Š°Š½Ń. ŠŠ¾Š²ŃŠ¾ŃŠ½Šµ Š“ŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń Š·Š°Š¹Š¼Šµ ŃŠŗŠøŠ¹ŃŃ ŃŠ°Ń. <br /><br />\nŠŠø ŃŠæŠµŠ²Š½ŠµŠ½Ń, ŃŠ¾ Ń
Š¾ŃŠµŃŠµ ŠæŃŠ¾Š“Š¾Š²Š¶ŠøŃŠø?", + "timedmedia-reset-error": "ŠŠ¾Š¼ŠøŠ»ŠŗŠ° ŠæŃŠø ŠæŠµŃŠµŠ·Š°ŠæŃŃŠŗŃ Š“ŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "ŠŠ¶ŠµŃŠµŠ»Š¾ $1", + "timedmedia-source-file-desc": "ŠŃŠøŠ³ŃŠ½Š°Š»ŃŠ½ŠøŠ¹ $1 ŃŠ°Š¹Š», $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "ŠŃŠøŠ³ŃŠ½Š°Š»ŃŠ½ŠøŠ¹ $1 ŃŠ°Š¹Š» ($2)", + "timedmedia-derivative-desc-160p.ogv": "Ogg-Š²ŃŠ“ŠµŠ¾ Š½ŠøŠ·ŃŠŗŠ¾Ń ŃŠŗŠ¾ŃŃŃ (160P)", + "timedmedia-derivative-desc-240p.ogv": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ Ogg-Š²ŃŠ“ŠµŠ¾ (240P)", + "timedmedia-derivative-desc-360p.ogv": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ Ogg-Š²ŃŠ“ŠµŠ¾ (360P)", + "timedmedia-derivative-desc-480p.ogv": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ Ogg-Š²ŃŠ“ŠµŠ¾ (480P)", + "timedmedia-derivative-desc-720p.ogv": "ŠŠøŃŠ¾ŠŗŠ¾ŃŠŗŃŃŠ½Šµ Ogg-Š²ŃŠ“ŠµŠ¾ (720P) Š“Š»Ń Š·Š°Š²Š°Š½ŃŠ°Š¶ŠµŠ½Š½Ń", + "timedmedia-derivative-desc-1080p.ogv": "Š”ŠŗŠ°ŃŃŠ²Š°Š½Šµ Ogg-Š²ŃŠ“ŠµŠ¾ Ń ŃŠ¾ŃŠ¼Š°ŃŃ Full HD (1080P)", + "timedmedia-derivative-desc-160p.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "ŠŠøŃŠ¾ŠŗŠ¾ŃŠŗŃŃŠ½Šµ WebM (720P) Š“Š»Ń Š·Š°Š²Š°Š½ŃŠ°Š¶ŠµŠ½Š½Ń", + "timedmedia-derivative-desc-1080p.webm": "Š”ŠŗŠ°ŃŃŠ²Š°Š½Šµ WebM-Š²ŃŠ“ŠµŠ¾ Ń ŃŠ¾ŃŠ¼Š°ŃŃ Full HD (1080P)", + "timedmedia-derivative-desc-2160p.webm": "Š”ŠŗŠ°ŃŃŠ²Š°Š½Šµ WebM-Š²ŃŠ“ŠµŠ¾ Ń ŃŠ¾ŃŠ¼Š°ŃŃ Full 4K (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ WebM VP9 (360P)", + "timedmedia-derivative-desc-480p.vp9.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ WebM VP9 (480P)", + "timedmedia-derivative-desc-720p.vp9.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ WebM VP9 Ń ŃŠ¾ŃŠ¼Š°ŃŃ HD (720P)", + "timedmedia-derivative-desc-1080p.vp9.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ WebM VP9 Ń ŃŠ¾ŃŠ¼Š°ŃŃ Full HD (1080P)", + "timedmedia-derivative-desc-2160p.vp9.webm": "ŠŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ WebM-Š²ŃŠ“ŠµŠ¾ Ń ŃŠ¾ŃŠ¼Š°ŃŃ Full 4K (2160P)", + "timedmedia-derivative-desc-320p.mp4": "Š”ŃŠ¼ŃŃŠ½ŠøŠ¹ Š· MP$ (320P) ŠæŃŠøŃŃŃŃŠ¹", + "timedmedia-derivative-desc-480p.mp4": "ŠŠµŠ±-ŠæŠ¾ŃŠ¾ŠŗŠ¾Š²Šµ MP4 (480 Š )", + "timedmedia-derivative-desc-720p.mp4": "MP4 ŃŠŗŠ¾ŃŃŃ HD (720P)", + "timedmedia-derivative-desc-1080p.mp4": "MP4-Š²ŃŠ“ŠµŠ¾ Ń ŃŠ¾ŃŠ¼Š°ŃŃ Full HD (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "MP4-Š²ŃŠ“ŠµŠ¾ Ń ŃŠ¾ŃŠ¼Š°ŃŃ Full 4K (2160P)", + "timedmedia-subtitle-new": "Š”ŃŠ²Š¾ŃŠøŃŠø Š½Š¾Š²ŠøŠ¹ ŠæŠµŃŠµŠŗŠ»Š°Š“ Š°Š±Š¾ Š²ŃŠ“ŃŠµŠ“Š°Š³ŃŠ²Š°ŃŠø ŃŃŠ½ŃŃŃŠøŠ¹", + "timedmedia-subtitle-new-desc": "ŠŠøŠ±ŠµŃŃŃŃ Š¼Š¾Š²Ń ŃŠ° Š½Š°ŃŠøŃŠ½ŃŃŃ '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "ŠŠµŃŠµŠ¹ŃŠø", + "timedmedia-subtitle-language": "$1 ($2) ŃŃŠ±ŃŠøŃŃŠø", + "timedmedia-subtitle-no-video": "ŠŠµŠ¼Š°Ń Š²ŃŠ“ŠµŠ¾, ŠæŠ¾Š²'ŃŠ·Š°Š½Š¾Š³Š¾ Š· ŠæŠ¾ŃŠ¾ŃŠ½Š¾Ń ŃŃŠ¾ŃŃŠ½ŠŗŠ¾Ń ŃŃŠ±ŃŠøŃŃŃŠ²", + "timedmedia-subtitle-no-subtitles": "Š Š“Š°Š½ŠøŠ¹ ŃŠ°Ń Š½ŠµŠ¼Š°Ń ŃŃŠ±ŃŠøŃŃŃŠ² Š½Š° $1 Š“Š»Ń ŃŃŠ¾Š³Š¾ Š²ŃŠ“ŠµŠ¾, ŠŠø Š¼Š¾Š¶ŠµŃŠµ [{{fullurl:{{FULLPAGENAME}}|action=edit}} Š·Š¼ŃŠ½ŠøŃŠø ŃŃ ŃŃŠ¾ŃŃŠ½ŠŗŃ] Š“Š»Ń ŃŃ
Š“Š¾Š“Š°Š²Š°Š½Š½Ń", + "timedmedia-subtitle-remote": "Š¢ŠµŠŗŃŃ Š“Š¾ ŃŃŠ¾Š³Š¾ ŃŠ°Š¹Š»Ń ŃŠ¾Š·Š¼ŃŃŠµŠ½ŠøŠ¹ Š½Š° $1", + "timedmedia-subtitle-remote-link": "ŠŠø Š¼Š¾Š¶ŠµŃŠµ [$1 ŠæŠµŃŠµŠ³Š»ŃŠ½ŃŃŠø Š¾ŠæŠøŃ ŃŃŠ¾ŃŃŠ½ŠŗŠø] Š“Š»Ń ŃŃŠ¾Š³Š¾ ŃŠ°Š¹Š»Ń Š½Š° $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 Š²ŃŠ“ŠµŠ¾}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 Ogg Š²ŃŠ“ŠµŠ¾}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 WebM Š²ŃŠ“ŠµŠ¾}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|1=$1 ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń|$1 ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Ń}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|1=$1 ŠæŃŠ°ŃŃŃŃŃ ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń|$1 ŠæŃŠ°ŃŃŃŃŠøŃ
ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Ń}}", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|1=$1 ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń Š² ŃŠµŃŠ·Ń|$1 ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Ń Š² ŃŠµŃŠ·Ń}}", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|1=$1 Š½ŠµŠ²Š“Š°Š»Ń ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń|$1 Š½ŠµŠ²Š“Š°Š»ŠøŃ
ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Ń}}", + "timedmedia-file": "Š¤Š°Š¹Š»", + "timedmedia-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»ŃŠ²Ģ|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»Šø}}", + "timedmedia-ogg-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š» Ogg|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»ŃŠ² Ogg|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»Šø Ogg}}", + "timedmedia-flac-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š» FLAC|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»ŃŠ² FLAC|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»Šø FLAC}}", + "timedmedia-wav-audios": "{{PLURAL:$1|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š» WAV|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»ŃŠ² WAV|$1 Š°ŃŠ“ŃŠ¾-ŃŠ°Š¹Š»Šø WAV}}", + "right-transcode-reset": "ŃŠŗŠøŠ“Š°Š½Š½Ń Š½ŠµŠ²Š“Š°Š»ŠøŃ
Š°Š±Š¾ ŠæŠµŃŠµŠŗŠ¾Š“Š¾Š²Š°Š½ŠøŃ
Š²ŃŠ“ŠµŠ¾ ŃŠ· ŠæŠ¾Š²ŃŠ¾ŃŠ½ŠøŠ¼ Š·Š°Š½ŠµŃŠµŠ½Š½ŃŠ¼ ŃŃ
Š² ŃŠµŃŠ³Ń Š·Š°Š²Š“Š°Š½Ń", + "right-transcode-status": "ŠæŠµŃŠµŠ³Š»ŃŠ“ [[Special:TimedMediaHandler|ŃŠ½ŃŠ¾ŃŠ¼Š°ŃŃŃ ŠæŃŠ¾ ŠæŠ¾ŃŠ¾ŃŠ½Ń Š“ŃŃŠ»ŃŠ½ŃŃŃŃ Š· ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń]]", + "action-transcode-status": "ŠŠµŃŠµŠ³Š»ŃŠ“ ŠæŠ¾ŃŠ¾ŃŠ½Š¾Š³Š¾ ŃŃŠ°Š½Ń ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń", + "orphanedtimedtext": "Š”ŃŠ¾ŃŃŠ½ŠŗŠø-ŃŠøŃŠ¾ŃŠø TimedText", + "orphanedtimedtext-summary": "Š”ŠæŠøŃŠ¾Šŗ ŃŃŠ¾ŃŃŠ½Š¾Šŗ [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]], ŃŠŗŃ Š½Šµ Š¼Š°ŃŃŃ Š²ŃŠ“ŠæŠ¾Š²ŃŠ“Š½Š¾Š³Š¾ ŃŠ°Š¹Š»Ń.", + "orphanedtimedtext-unsupported": "Š¦Ń ŃŠæŠµŃŃŠ°Š»ŃŠ½Š° ŃŃŠ¾ŃŃŠ½ŠŗŠ° ŠæŃŠ“ŃŃŠøŠ¼ŃŃŃŃŃŃ Š»ŠøŃŠµ Š±Š°Š·Š°Š¼Šø Š“Š°Š½ŠøŃ
MySQL.", + "orphanedtimedtext-notimedtext": "TimedText Š½Šµ ŃŠ²ŃŠ¼ŠŗŠ½ŠµŠ½ŠøŠ¹ Ń ŃŃŠ¹ Š²ŃŠŗŃ.", + "apihelp-query+transcodestatus-description": "ŠŃŃŠøŠ¼Š°ŃŠø ŃŃŠ°Š½ŃŠŗŠ¾Š“-ŃŃŠ°ŃŃŃ Š“Š»Ń Š“Š°Š½Š¾Ń ŃŃŠ¾ŃŃŠ½ŠŗŠø ŃŠ°Š¹Š»Ń.", + "apihelp-query+transcodestatus-example-1": "ŠŃŃŠøŠ¼Š°ŃŠø ŃŃŠ°Š½ŃŠŗŠ¾Š“-ŃŃŠ°ŃŃŃ Š“Š»Ń [[:File:Clip.webm]]", + "apihelp-query+videoinfo-description": "Š Š¾Š·ŃŠøŃŃŃ imageinfo Ń Š²ŠŗŠ»ŃŃŠ°Ń ŃŠ½ŃŠ¾ŃŠ¼Š°ŃŃŃ Š“Š¶ŠµŃŠµŠ»Š° Š²ŃŠ“ŠµŠ¾ (ŠæŠ¾Ń
ŃŠ“Š½Ń)", + "apihelp-query+videoinfo-param-prop": "ŠÆŠŗŃ ŃŠ½ŃŠ¾ŃŠ¼Š°ŃŃŃ ŠæŃŠ¾ Š²ŃŠ“ŠµŠ¾ Š¾ŃŃŠøŠ¼ŃŠ²Š°ŃŠø:\n;timestamp:ŠŠ¾Š“Š°Ń ŃŠ°ŃŠ¾Š²Ń Š¼ŃŃŠŗŃ Š·Š°Š²Š°Š½ŃŠ°Š¶ŠµŠ½Š¾Ń Š²ŠµŃŃŃŃ.\n;user:ŠŠ¾Š“Š°Ń ŠŗŠ¾ŃŠøŃŃŃŠ²Š°ŃŠ°, ŃŠŗŠøŠ¹ Š·Š°Š²Š°Š½ŃŠ°Š¶ŠøŠ² Š²ŠµŃŃŃŃ Š²ŃŠ“ŠµŠ¾.\n;userid:ŠŠ¾Š“Š°Ń ID ŠŗŠ¾ŃŠøŃŃŃŠ²Š°ŃŠ°, ŃŠŗŠøŠ¹ Š·Š°Š²Š°Š½ŃŠ°Š¶ŠøŠ² Š²ŠµŃŃŃŃ Š²ŃŠ“ŠµŠ¾.\n;comment:ŠŠ¾Š¼ŠµŠ½ŃŠ°Ń Š“Š¾ Š²ŠµŃŃŃŃ.\n;parsedcomment:ŠŠ°ŃŃŠøŠ½Š³ ŠŗŠ¾Š¼ŠµŠ½ŃŠ°ŃŃ Š“Š¾ Š²ŠµŃŃŃŃ.\n;canonicaltitle:ŠŠ¾Š“Š°Ń ŠŗŠ°Š½Š¾Š½ŃŃŠ½ŠøŠ¹ Š·Š°Š³Š¾Š»Š¾Š²Š¾Šŗ Š²ŃŠ“ŠµŠ¾ŃŠ°Š¹Š»Ń.\n;url:ŠŠ°Ń URL Š½Š° Š²ŃŠ“ŠµŠ¾ ŃŠ° ŃŃŠ¾ŃŃŠ½ŠŗŃ Š¾ŠæŠøŃŃ.\n;size:ŠŠ¾Š“Š°Ń ŃŠ¾Š·Š¼ŃŃŠø Š²ŃŠ“ŠµŠ¾ Ń Š±Š°Š¹ŃŠ°Ń
, Š¹Š¾Š³Š¾ Š²ŠøŃŠ¾ŃŃ Ń ŃŠøŃŠøŠ½Ń. ŠŠ¾Š¼ŠµŃ ŃŃŠ¾ŃŃŠ½ŠŗŠø Ń ŃŃŠøŠ²Š°Š»ŃŃŃŃ Š“Š¾Š“Š°ŃŃŃŃŃ Š·Š° Š¼Š¾Š¶Š»ŠøŠ²Š¾ŃŃŃ.\n;dimensions:ŠŠ»ŃŠ°Ń ŃŠ¾Š·Š¼ŃŃŃ.\n;sha1:ŠŠ¾Š“Š°Ń Š³ŠµŃ SHA-1 Š²ŃŠ“ŠµŠ¾.\n;mime:ŠŠ¾Š“Š°Ń MIME-ŃŠøŠæ Š²ŃŠ“ŠµŠ¾.\n;thumbmime:ŠŠ¾Š“Š°Ń MIME-ŃŠøŠæ Š¼ŃŠ½ŃŠ°ŃŃŃŠø Š²ŃŠ“ŠµŠ¾ (Š²ŠøŠ¼Š°Š³Š°Ń url Ń ŠæŠ°ŃŠ°Š¼ŠµŃŃ $1urlwidth).\n;mediatype:ŠŠ¾Š“Š°Ń Š¼ŠµŠ“ŃŠ°ŃŠøŠæ Š²ŃŠ“ŠµŠ¾.\n;metadata:ŠŠøŠ²Š¾Š“ŠøŃŃ ŃŠæŠøŃŠ¾Šŗ Exif-Š¼ŠµŃŠ°Š“Š°Š½ŠøŃ
Š²ŠµŃŃŃŃ Š²ŃŠ“ŠµŠ¾.\n;commonmetadata:ŠŠøŠ²Š¾Š“ŠøŃŃ ŃŠæŠøŃŠ¾Šŗ Š¼ŠµŃŠ°Š“Š°Š½ŠøŃ
ŃŠ¾ŃŠ¼Š°ŃŃ ŃŠ°Š¹Š»Ń Š²ŠµŃŃŃŃ Š²ŃŠ“ŠµŠ¾.\n;extmetadata:ŠŠøŠ²Š¾Š“ŠøŃŃ ŃŠæŠøŃŠ¾Šŗ ŃŠ¾ŃŠ¼Š°ŃŠ¾Š²Š°Š½ŠøŃ
Š¼ŠµŃŠ°Š“Š°Š½ŠøŃ
, ŃŠŗŠ¾Š¼Š±ŃŠ½Š¾Š²Š°Š½ŠøŃ
Š· ŠŗŃŠ»ŃŠŗŠ¾Ń
Š“Š¶ŠµŃŠµŠ». Š ŠµŠ·ŃŠ»ŃŃŠ°ŃŠø Š²ŃŠ“ŃŠ¾ŃŠ¼Š°ŃŠ¾Š²Š°Š½Ń Š² HTML.\n;archivename:ŠŠ¾Š“Š°Ń Š½Š°Š·Š²Ń ŃŠ°Š¹Š»Ń Š°ŃŃ
ŃŠ²Š¾Š²Š°Š½Š¾Ń Š²ŠµŃŃŃŃ Š“Š»Ń Š½Šµ Š¾ŃŃŠ°Š½Š½ŃŃ
Š²ŠµŃŃŃŠ¹.\n;bitdepth:ŠŠ¾Š“Š°Ń Š±ŃŃŠ¾Š²Ń Š³Š»ŠøŠ±ŠøŠ½Ń Š²ŠµŃŃŃŃ.\n;uploadwarning:ŠŠøŠŗŠ¾ŃŠøŃŃŠ¾Š²ŃŃŃŃŃŃ ŃŃŠ¾ŃŃŠ½ŠŗŠ¾Ń [[Special:Upload]] Š“Š»Ń Š¾ŃŃŠøŠ¼Š°Š½Š½Ń ŃŠ½ŃŠ¾ŃŠ¼Š°ŃŃŃ ŠæŃŠ¾ Š½Š°ŃŠ²Š½ŠøŠ¹ ŃŠ°Š¹Š». ŠŠµ ŠæŃŠøŠ·Š½Š°ŃŠµŠ½Š¾ Š“Š»Ń Š²ŠøŠŗŠ¾ŃŠøŃŃŠ°Š½Š½Ń ŠæŠ¾Š·Š° ŃŠ“ŃŠ¾Š¼ MediaWiki.\n;derivatives:ŠŠ¾Š“Š°Ń Š¼Š°ŃŠøŠ² Š“Š¾ŃŃŃŠæŠ½ŠøŃ
Š²ŠµŃŃŃŠ¹ ŃŠ½ŃŠ¾Š³Š¾ ŃŠ¾ŃŠ¼Š°ŃŃ Ń ŃŠŗŠ¾ŃŃŃ Š°ŃŠ“ŃŠ¾- ŃŠø Š²ŃŠ“ŠµŠ¾ŃŠ°Š¹Š»Ń.", + "apihelp-query+videoinfo-example-1": "ŠŠøŃŃŠ³ ŃŠ½ŃŠ¾ŃŠ¼Š°ŃŃŃ ŠæŃŠ¾ [[:File:Folgers.ogv]]", + "apihelp-transcodereset-description": "ŠŠ¾ŃŠøŃŃŃŠ²Š°ŃŃ Š· ŠæŃŠ°Š²Š¾Š¼ Ā«transcode-resetĀ» Š¼Š¾Š¶ŃŃŃ ŃŠŗŠøŠ½ŃŃŠø Ń ŠæŠ¾Š²ŃŠ¾ŃŠøŃŠø Š·Š°Š“Š°ŃŃ ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń.", + "apihelp-transcodereset-param-title": "ŠŠ°Š³Š¾Š»Š¾Š²Š¾Šŗ Š¼ŠµŠ“ŃŠ°ŃŠ°Š¹Š»Ń.", + "apihelp-transcodereset-param-transcodekey": "ŠŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°ŃŠø ŠŗŠ»ŃŃ, ŃŠŗŠøŠ¹ ŠŠø Ń
Š¾ŃŠµŃŠµ ŃŠŗŠøŠ½ŃŃŠø. ŠŠøŠ±ŃŃŠŗŠ° Š· [[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]].", + "apihelp-transcodereset-example-1": "Š”ŠŗŠøŠ½ŃŃŠø ŃŃŃ ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń Š“Š»Ń [[:File:Clip.webm]]", + "apihelp-transcodereset-example-2": "Š”ŠŗŠøŠ½ŃŃŠø ŠŗŠ»ŃŃ ŠæŠµŃŠµŠŗŠ¾Š“ŃŠ²Š°Š½Š½Ń Ā«360_560kbs.webmĀ» Š“Š»Ń [[:File:Clip.webm]]" +} diff --git a/extensions/TimedMediaHandler/i18n/ur.json b/extensions/TimedMediaHandler/i18n/ur.json new file mode 100644 index 00000000..7b58606a --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/ur.json @@ -0,0 +1,21 @@ +{ + "@metadata": { + "authors": [ + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ", + "Muhammad Shuaib", + "Ų¹Ų«Ł
Ų§Ł Ų®Ų§Ł Ų“Ų§Ū" + ] + }, + "timedmedia-no-player-js": "Ł
Ų¹Ų°Ų±ŲŖŲ Ų¢Ł¾ Ś©Ū ŲØŲ±Ų§Ų¤Ų²Ų± Ł
ŪŚŗ Ų¬Ų§ŁŲ§Ų³Ś©Ų±Ł¾Ł¹ ŁŲ¹Ų§Ł ŁŪŪŚŗ ŪŲ§ Ś©ŁŲ¦Ū Ł
Ų¹Ų§ŁŁ Ł¾ŁŪŲ¦Ų± Ų“Ų§Ł
Ł ŁŪŪŚŗ ŪŪŪ<br />\nŲ§Ų³ Ś©ŁŁ¾ Ś©Ł Ų§Ł¾ŁŪ ŲØŲ±Ų§Ų¤Ų²Ų± Ł
ŪŚŗ ŚŁŲ§ŁŪ Ś©Ū ŁŪŪ Ų¢Ł¾ <a href=\"$1\">Ś©ŁŁ¾ Ś©Ł ŚŲ§Ų¤ŁŁŁŚ</a> Ś©Ų±ŁŪŚŗ ŪŲ§ </a> or <a href=\"//www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download\">Ł¾ŁŪŲ¦Ų± ŚŲ§Ų¤ŁŁŁŚ</a> Ś©Ų±ŁŪŚŗŪ", + "timedmedia-more": "Ł
Ų²ŪŲÆ...", + "timedmedia-dismiss": "ŲØŁŲÆ", + "timedmedia-download": "ŁŲ§Ų¦Ł ŚŲ§Ų¤Ł ŁŁŚ Ų Ų§ŲŖŲ§Ų±ŁŲ§", + "timedmedia-play-media": "Ś©Ś¾ŪŁŁŪ Ś©Ū Ł
ŪŚŪŲ§", + "timedmedia-desc-link": "Ų§Ų³ ŁŲ§Ų¦Ł Ś©Ū ŲØŲ§Ų±Ū Ł
ŪŚŗ", + "timedmedia-status": "ŲŪŲ«ŪŲŖ", + "timedmedia-status-unknown": "ŁŲ§Ł
Ų¹ŁŁŁ
Ł
ŁŲ§Ł
", + "timedmedia-actions": "Ų§Ų¹Ł
Ų§Ł", + "timedmedia-source-file": "$1 Ł
Ų³ŁŲÆŪ", + "timedmedia-source-audio-file-desc": "Ų§ŲµŁŪ $1 Ł
ŁŁ ($2)", + "timedmedia-file": "ŁŲ§Ų¦Ł" +} diff --git a/extensions/TimedMediaHandler/i18n/vec.json b/extensions/TimedMediaHandler/i18n/vec.json new file mode 100644 index 00000000..c567687b --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/vec.json @@ -0,0 +1,85 @@ +{ + "@metadata": { + "authors": [ + "Candalua", + "GatoSelvadego" + ] + }, + "timedmedia-desc": "Gestor pa' i file audio, video e cĆ³ sototitoÅi; formati suportai: WebM, Ogg Theora, Vorbis, srt", + "timedmedia-ogg-short-audio": "File audio Ogg $1, $2", + "timedmedia-ogg-short-video": "File video Ogg $1, $2", + "timedmedia-ogg-short-general": "File multimedial Ogg $1, $2", + "timedmedia-ogg-long-audio": "File audio Ogg $1, durata $2, $3", + "timedmedia-ogg-long-video": "File video Ogg $1, durata $2, dimensioni $4Ć$5 pixel, $3", + "timedmedia-ogg-long-multiplexed": "File audio/video multiplexed Ogg $1, durata $2, dimensioni $4Ć$5 pixel, conplessivamente $3", + "timedmedia-ogg-long-general": "File multimedial Ogg, durata $2, $3", + "timedmedia-ogg-long-error": "File ogg mƬa valido: $1", + "timedmedia-webm-short-video": "File video WebM $1, $2", + "timedmedia-webm-long-video": "File audio/video WebM $1, durata $2, dimension $4Ć$5 pixel, conplesivamente $3", + "timedmedia-mp4-short-video": "File video MP4 $1, $2", + "timedmedia-mp4-long-video": "File audio/video MP4 $1, durata $2, dimension $4Ć$5 pixel, conplesivamente $3", + "timedmedia-no-player-js": "El to browser el gĆ JavaScript destacĆ , opure no'l gĆ nissun riprodutor suportĆ .<br />\nTe pol <a href=\"$1\">descargar el file multimediale</a> o <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">un riprodutor</a> par farlo 'ndar sul to browser.", + "timedmedia-more": "Altro...", + "timedmedia-dismiss": "Sara", + "timedmedia-download": "Descarga el file", + "timedmedia-play-media": "Riproduxi el file multimediaÅe", + "timedmedia-desc-link": "Informazion su sto file", + "timedmedia-oggThumb-version": "Par OggHandler ghe vole oggThumb version $1 o sucessiva.", + "timedmedia-oggThumb-failed": "oggThumb no'l xe stĆ bon de crear la miniadura.", + "timedmedia-status-header": "Stato transcodifega", + "timedmedia-update-status": "Axorna stato transcodifega", + "timedmedia-status": "Stato", + "timedmedia-status-unknown": "Stato sconosĆ¹o", + "timedmedia-transcodeinfo": "Descrision derivĆ dal Transcodexe", + "timedmedia-actions": "Asion", + "timedmedia-direct-link": "Descarga derivĆ ", + "timedmedia-not-ready": "NĆ³ pronto", + "timedmedia-completed-on": "Transodifega conpletĆ $1", + "timedmedia-error-on": "Eror inte Åa transcodifega so $1.", + "timedmedia-started-transcode": "Transcodifega tacĆ $1 fa. $2", + "timedmedia-percent-done": "$1% sirca conpletĆ ", + "timedmedia-in-job-queue": "XontĆ a Åa coa de laoro $1 fa", + "timedmedia-unknown-target-size": "Dimension de destinasion sconosĆ¹a, $1 codifegĆ ", + "timedmedia-days": "{{PLURAL:$1|1 xorno|$1 xorni}}", + "timedmedia-hours": "{{PLURAL:$1|1 ora|$1 ore}}", + "timedmedia-minutes": "{{PLURAL:$1|1 minuto|$1 minuti}}", + "timedmedia-seconds": "{{PLURAL:$1|1 secondo|$1 secondi}}", + "timedmedia-reset": "Rexeta transcodifega", + "timedmedia-reset-confirm": "Resetando sta transcodifica tuti i file esistenti (se presenti) i sarĆ scancelĆ e la transcodifica la sarĆ de novo zontĆ a la coa de laoro. Ghe vorĆ un po' de tenpo par rifar la transcodifica. <br /><br />\nVuto 'ndar vanti?", + "timedmedia-reset-error": "Eror inte'l resetajo de Åa transcodifega.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Fonte $1", + "timedmedia-source-file-desc": "File orixenaÅe $1, $2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "File originale $1 ($2)", + "timedmedia-derivative-desc-160p.ogv": "Video Ogg a basa larghesa de banda (160P)", + "timedmedia-derivative-desc-360p.ogv": "Video Ogg trasmetibiÅe in streaming via Web (360P)", + "timedmedia-derivative-desc-480p.ogv": "Video Ogg trasmetibiÅe in streaming via Web (480P)", + "timedmedia-derivative-desc-720p.ogv": "Video Ogg descargabiÅe in alta cuaÅitĆ (720P)", + "timedmedia-derivative-desc-160p.webm": "WebM trasmetibiÅe in streaming via Web (160P)", + "timedmedia-derivative-desc-360p.webm": "WebM trasmetibiÅe in streaming via Web (360P)", + "timedmedia-derivative-desc-480p.webm": "WebM trasmetibiÅe in streaming via Web (480P)", + "timedmedia-derivative-desc-720p.webm": "WebM descargabiÅe in alta cuaÅitĆ (720P)", + "timedmedia-derivative-desc-320p.mp4": "MP4 par dispoxitivi conpatibiÅi (320P)", + "timedmedia-derivative-desc-480p.mp4": "MP4 trasmetibiÅe in streaming via Web (480P)", + "timedmedia-derivative-desc-720p.mp4": "MP4 in cuaÅitĆ HD (720P)", + "timedmedia-subtitle-new": "Crear na nova tradusion o canbiar una de cheÅe che ghe xe xĆ ", + "timedmedia-subtitle-new-desc": "Siegli la lengua e struca el boton '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "VĆ ", + "timedmedia-subtitle-language": "$1 ($2) sototitoÅi", + "timedmedia-subtitle-no-video": "NĆ³ ghe xe nisun video asociĆ a l'atuaÅe pĆ jina de i sototitoÅi", + "timedmedia-subtitle-no-subtitles": "NĆ³ ghe xe al momento sototitoÅi in $1 par sto video, xe posibiÅe [{{fullurl:{{FULLPAGENAME}}|action=edit}} canbiar sta pĆ jina] par xontarli", + "timedmedia-subtitle-remote": "I sototitoÅi par sto file i se cata so $1", + "timedmedia-subtitle-remote-link": "Te poi vardar Åa [$1 pĆ jina de descrision] par sto file so $2", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "{{PLURAL:$1|$1 video}}", + "timedmedia-ogg-videos": "{{PLURAL:$1|$1 video Ogg}}", + "timedmedia-webm-videos": "{{PLURAL:$1|$1 video WebM}}", + "timedmedia-derivative-state-transcodes": "{{PLURAL:$1|$1 transcodifega|$1 transcodifeghe}}", + "timedmedia-derivative-state-active": "{{PLURAL:$1|$1 transcodifega|$1 transcodifeghe}} in execusion", + "timedmedia-derivative-state-queued": "{{PLURAL:$1|$1 transcodifega|$1 transcodifeghe}} in coa", + "timedmedia-derivative-state-failed": "{{PLURAL:$1|$1 transcodifega nĆ³ riusia|$1 transcodifeghe nĆ³ riusie}}", + "timedmedia-file": "File", + "right-transcode-reset": "Reinposta i video difetoxi o transcodifegai cusƬ che i posa esar incluxi de novo in coa de laoro.", + "right-transcode-status": "VixuaÅixa [[Special:TimedMediaHandler|informasion so l'atuaÅe ativitĆ de transcodifega]]", + "action-transcode-status": "mostrar l'atuaÅe stato de Åa transcodifega" +} diff --git a/extensions/TimedMediaHandler/i18n/vep.json b/extensions/TimedMediaHandler/i18n/vep.json new file mode 100644 index 00000000..9046204e --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/vep.json @@ -0,0 +1,11 @@ +{ + "@metadata": { + "authors": [ + "ŠŠ³Š¾ŃŃ ŠŃŠ¾Š“ŃŠŗŠøŠ¹" + ] + }, + "timedmedia-more": "Enamba...", + "timedmedia-dismiss": "Peitta", + "timedmedia-download": "JĆ¼gutoitta fail", + "timedmedia-desc-link": "Informacii neciÅ” failas" +} diff --git a/extensions/TimedMediaHandler/i18n/vi.json b/extensions/TimedMediaHandler/i18n/vi.json new file mode 100644 index 00000000..63187717 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/vi.json @@ -0,0 +1,130 @@ +{ + "@metadata": { + "authors": [ + "Minh Nguyen", + "Vinhtantran", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ", + "Trįŗ§n Nguyį»
n Minh Huy", + "Max20091" + ] + }, + "timedmedia-desc": "Bį» trƬnh bĆ y cĆ”c tįŗp tin Ć¢m thanh, video, vĆ phį»„ Äį» hį» trį»£ WebM, Ogg Theora, Vorbis, vĆ srt", + "timedmedia-ogg-short-audio": "Tįŗp tin Ć¢m thanh Ogg $1, $2", + "timedmedia-ogg-short-video": "tįŗp tin video Ogg $1, $2", + "timedmedia-ogg-short-general": "tįŗp tin Ogg $1, $2", + "timedmedia-ogg-long-audio": "tįŗp tin Ć¢m thanh Ogg $1, dĆ i $2, $3", + "timedmedia-ogg-long-video": "tįŗp tin video Ogg $1, dĆ i $2, $4Ć$5 Äiį»m įŗ£nh, $3", + "timedmedia-ogg-long-multiplexed": "tįŗp tin Ogg cĆ³ Ć¢m thanh vĆ video ghĆ©p kĆŖnh, $1, dĆ i $2, $4Ć$5 Äiį»m įŗ£nh, $3 tįŗ„t cįŗ£", + "timedmedia-ogg-long-general": "tįŗp tin phĘ°Ę”ng tiį»n Ogg, dĆ i $2, $3", + "timedmedia-ogg-long-error": "Tįŗp tin Ogg cĆ³ lį»i: $1", + "timedmedia-ogg-long-no-streams": "Tįŗp tin phĘ°Ę”ng tiį»n Ogg. ChĆŗ Ć½: KhĆ“ng cĆ³ cĆ“ng nhįŗn codec nĆ o trong tįŗp tin nĆ y.", + "timedmedia-webm-short-video": "tįŗp tin video WebM $1, $2", + "timedmedia-webm-long-video": "tįŗp tin WebM cĆ³ Ć¢m thanh vĆ video ghĆ©p kĆŖnh, $1, dĆ i $2, $4Ć$5 Äiį»m įŗ£nh, $3 tįŗ„t cįŗ£", + "timedmedia-flac-short-audio": "tįŗp tin Ć¢m thanh FLAC, $1", + "timedmedia-flac-long-audio": "tįŗp tin Ć¢m thanh FLAC, dĆ i $1, $2 tįŗ„t cįŗ£", + "timedmedia-wav-short-audio": "tįŗp tin Ć¢m thanh WAV, $1", + "timedmedia-wav-long-audio": "tįŗp tin Ć¢m thanh WAV, dĆ i $1, $2 tįŗ„t cįŗ£", + "timedmedia-wav-pcm-required": "Bįŗ”n chį» cĆ³ thį» tįŗ£i lĆŖn cĆ”c tįŗp tin WAV PCM (Pulse Code Modulation).", + "timedmedia-mp4-short-video": "tįŗp tin video MP4 $1, $2", + "timedmedia-mp4-long-video": "tįŗp tin Ć¢m thanh/video MP4, $1, dĆ i $2, $4Ć$5 Äiį»m įŗ£nh, $3 tįŗ„t cįŗ£", + "timedmedia-no-player-js": "Rįŗ„t tiįŗæc, hoįŗ·c JavaScript bį» tįŗÆt trong trƬnh duyį»t cį»§a bįŗ”n hoįŗ·c trƬnh duyį»t khĆ“ng cĆ³ trƬnh chĘ”i nĆ o ÄĘ°į»£c hį» trį»£.<br />\nBįŗ”n cĆ³ thį» <a href=\"$1\">tįŗ£i vį» Äoįŗ”n Ć¢m hoįŗ·c Äoįŗ”n video</a> hay <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download?uselang=vi\">tįŗ£i vį» mį»t trƬnh chĘ”i</a> Äį» chĘ”i Äoįŗ”n Ć¢m hoįŗ·c Äoįŗ”n video trong trƬnh duyį»t.", + "timedmedia-more": "ThĆŖm nį»Æaā¦", + "timedmedia-dismiss": "ÄĆ³ng", + "timedmedia-download": "Tįŗ£i tįŗp tin xuį»ng", + "timedmedia-play-media": "ChĘ”i phĘ°Ę”ng tiį»n", + "timedmedia-desc-link": "Chi tiįŗæt cį»§a tįŗp tin nĆ y", + "timedmedia-oggThumb-version": "OggHandler cįŗ§n oggThumb, phiĆŖn bįŗ£n $1 trį» lĆŖn.", + "timedmedia-oggThumb-failed": "oggThumb bį» thįŗ„t bįŗ”i trong viį»c tįŗ”o hƬnh thu nhį».", + "timedmedia-status-header": "Trįŗ”ng thĆ”i chuyį»n mĆ£", + "timedmedia-update-status": "Cįŗp nhįŗt trįŗ”ng thĆ”i chuyį»n mĆ£", + "timedmedia-status": "Trįŗ”ng thĆ”i", + "timedmedia-status-unknown": "Trįŗ”ng thĆ”i khĆ“ng rƵ", + "timedmedia-transcodebitrate": "Tį»c Äį» bit", + "timedmedia-transcodeduration": "Thį»i gian mĆ£ hĆ³a", + "timedmedia-transcodeinfo": "Äį»nh dįŗ”ng", + "timedmedia-actions": "TĆ”c vį»„", + "timedmedia-direct-link": "Tįŗ£i vį»", + "timedmedia-not-ready": "ChĘ°a sįŗµn", + "timedmedia-completed-on": "HoĆ n tįŗ„t vĆ o $1", + "timedmedia-error-on": "Lį»i vĆ o $1", + "timedmedia-started-transcode": "BįŗÆt Äįŗ§u cĆ”ch ÄĆ¢y $1. $2", + "timedmedia-percent-done": "HoĆ n tįŗ„t khoįŗ£ng $1%", + "timedmedia-in-job-queue": "ÄĆ£ thĆŖm vĆ o hĆ ng Äį»£i viį»c cĆ”ch ÄĆ¢y $1", + "timedmedia-unknown-target-size": "Tįŗp tin ÄĆch cĆ³ kĆch thĘ°į»c khĆ“ng rƵ, ÄĆ£ chuyį»n mĆ£ $1", + "timedmedia-days": "$1 ngĆ y", + "timedmedia-hours": "$1 giį»", + "timedmedia-minutes": "$1 phĆŗt", + "timedmedia-seconds": "$1 giĆ¢y", + "timedmedia-reset": "Äįŗ·t lįŗ”i chuyį»n mĆ£", + "timedmedia-reset-confirm": "Viį»c Äįŗ·t lįŗ”i chuyį»n mĆ£ sįŗ½ xĆ³a tįŗp tin nĆ o hiį»n cĆ³, nįŗæu cĆ³, vĆ sįŗ½ lįŗ”i thĆŖm viį»c chuyį»n mĆ£ vĆ o hĆ ng Äį»£i viį»c. Viį»c chuyį»n mĆ£ lįŗ”i sįŗ½ mįŗ„t mį»t chĆŗt thƬ giį».<br /><br />\nBįŗ”n cĆ³ chįŗÆc chįŗÆn muį»n tiįŗæp tį»„c?", + "timedmedia-reset-error": "Lį»i khi Äįŗ·t lįŗ”i viį»c chuyį»n mĆ£.", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "Tįŗp tin $1 gį»c", + "timedmedia-source-file-desc": "tįŗp tin $1 gį»c, $2Ć$3 ($4)", + "timedmedia-source-audio-file-desc": "Tįŗp tin $1 gį»c ($2)", + "timedmedia-derivative-160p.ogv": "Ogg 160p", + "timedmedia-derivative-desc-160p.ogv": "Video Ogg bÄng thĆ“ng thįŗ„p (160p)", + "timedmedia-derivative-desc-240p.ogv": "Video Ogg cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (240p)", + "timedmedia-derivative-360p.ogv": "Ogg 360p", + "timedmedia-derivative-desc-360p.ogv": "Video Ogg cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (360p)", + "timedmedia-derivative-480p.ogv": "Ogg 480p", + "timedmedia-derivative-desc-480p.ogv": "Video Ogg cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (480p)", + "timedmedia-derivative-720p.ogv": "Ogg 720p", + "timedmedia-derivative-desc-720p.ogv": "Video Ogg chįŗ„t lĘ°į»£ng cao cĆ³ thį» tįŗ£i vį» (720p)", + "timedmedia-derivative-1080p.ogv": "Ogg 1080p", + "timedmedia-derivative-desc-1080p.ogv": "Video Ogg HD Äįŗ§y Äį»§ cĆ³ thį» tįŗ£i vį» (1080p)", + "timedmedia-derivative-160p.webm": "WebM 160p", + "timedmedia-derivative-desc-160p.webm": "WebM cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (160p)", + "timedmedia-derivative-360p.webm": "WebM 360p", + "timedmedia-derivative-desc-360p.webm": "WebM cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (360p)", + "timedmedia-derivative-480p.webm": "WebM 480p", + "timedmedia-derivative-desc-480p.webm": "WebM cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (480p)", + "timedmedia-derivative-720p.webm": "WebM 720p", + "timedmedia-derivative-desc-720p.webm": "WebM chįŗ„t lĘ°į»£ng cao cĆ³ thį» tįŗ£i vį» (720p)", + "timedmedia-derivative-1080p.webm": "WebM 1080p", + "timedmedia-derivative-desc-1080p.webm": "WebM HD Äįŗ§y Äį»§ cĆ³ thį» tįŗ£i vį» (1080p)", + "timedmedia-derivative-desc-2160p.webm": "WebM 4K Äįŗ§y Äį»§ cĆ³ thį» tįŗ£i vį» (2160p)", + "timedmedia-derivative-desc-360p.vp9.webm": "WebM VP9 cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (360p)", + "timedmedia-derivative-desc-480p.vp9.webm": "WebM VP9 cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (480p)", + "timedmedia-derivative-desc-720p.vp9.webm": "WebM HD cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (720p)", + "timedmedia-derivative-desc-1080p.vp9.webm": "WebM VP9 HD Äįŗ§y Äį»§ cĆ³ thį» truyį»n dĆ²ng (1080p)", + "timedmedia-derivative-desc-2160p.vp9.webm": "WebM VP9 4K Äįŗ§y Äį»§ cĆ³ thį» truyį»n dĆ²ng (2160p)", + "timedmedia-derivative-320p.mp4": "H.264 320p", + "timedmedia-derivative-desc-320p.mp4": "MP4 thĆch hį»£p vį»i thiįŗæt bį» (320p)", + "timedmedia-derivative-480p.mp4": "H.264 480p", + "timedmedia-derivative-desc-480p.mp4": "MP4 cĆ³ thį» truyį»n dĆ²ng trĆŖn Web (480p)", + "timedmedia-derivative-720p.mp4": "H.264 720p", + "timedmedia-derivative-desc-720p.mp4": "MP4 chįŗ„t lĘ°į»£ng HD (720p)", + "timedmedia-derivative-1080p.mp4": "H.264 1080p", + "timedmedia-derivative-desc-1080p.mp4": "MP4 HD Äįŗ§y Äį»§ (1080p)", + "timedmedia-derivative-desc-2160p.mp4": "MP4 4K Äįŗ§y Äį»§ (2160p)", + "timedmedia-subtitle-new": "Tįŗ”o bįŗ£n dį»ch mį»i hoįŗ·c sį»a Äį»i bįŗ£n dį»ch ÄĆ£ tį»n tįŗ”i", + "timedmedia-subtitle-new-desc": "Chį»n ngĆ“n ngį»Æ vĆ bįŗ„m nĆŗt '''{{int:Timedmedia-subtitle-new-go}}'''", + "timedmedia-subtitle-new-go": "Tįŗ”o", + "timedmedia-subtitle-language": "Tiį»u Äį» $1 ($2)", + "timedmedia-subtitle-no-video": "KhĆ“ng cĆ³ video nĆ o į»©ng vį»i trang tiį»u Äį» nĆ y", + "timedmedia-subtitle-no-subtitles": "Hiį»n khĆ“ng cĆ³ tiį»u Äį» nĆ o cho video nĆ y bįŗ±ng $1. Bįŗ”n cĆ³ thį» [{{fullurl:{{FULLPAGENAME}}|action=edit}} sį»a Äį»i trang nĆ y] Äį» thĆŖm tiį»u Äį».", + "timedmedia-subtitle-remote": "VÄn bįŗ£n Äį»ng bį» cį»§a tįŗp tin nĆ y ÄĘ°į»£c cung cįŗ„p tį»« $1", + "timedmedia-subtitle-remote-link": "Bįŗ”n cĆ³ thį» [$1 xem trang miĆŖu tįŗ£] tįŗp tin nĆ y trĆŖn $2", + "timedmediahandler": "Bį» xį» lĆ½ phĘ°Ę”ng tiį»n Äį»ng bį»", + "timedmedia-videos": "$1 video", + "timedmedia-ogg-videos": "$1 video Ogg", + "timedmedia-webm-videos": "$1 video WebM", + "timedmedia-derivative-state-transcodes": "$1 tįŗp tin chuyį»n mĆ£", + "timedmedia-derivative-state-active": "$1 tįŗp tin Äang chuyį»n mĆ£", + "timedmedia-derivative-state-queued": "$1 tįŗp tin chuyį»n mĆ£ trong hĆ ng Äį»£i", + "timedmedia-derivative-state-failed": "$1 tįŗp tin chuyį»n mĆ£ thįŗ„t bįŗ”i", + "timedmedia-file": "Tįŗp tin", + "timedmedia-audios": "$1 tįŗp tin Ć¢m thanh", + "timedmedia-ogg-audios": "$1 tįŗp tin Ć¢m thanh Ogg", + "timedmedia-flac-audios": "$1 tįŗp tin Ć¢m thanh FLAC", + "timedmedia-wav-audios": "$1 tįŗp tin Ć¢m thanh WAV", + "right-transcode-reset": "Äįŗ·t lįŗ”i cĆ”c video hį»ng hoįŗ·c ÄĆ£ chuyį»n mĆ£ Äį» chĆØn chĆŗng nĆ³ lįŗ”i vĆ o hĆ ng Äį»£i viį»c.", + "right-transcode-status": "Xem [[Special:TimedMediaHandler|thĆ“ng tin vį» hoįŗ”t Äį»ng chuyį»n mĆ£ Äang xįŗ£y ra]]", + "action-transcode-status": "xem trįŗ”ng thĆ”i chuyį»n mĆ£ hiį»n tįŗ”i", + "orphanedtimedtext": "CĆ”c trang TimedText mį» cĆ“i", + "orphanedtimedtext-summary": "Danh sĆ”ch trang [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] khĆ“ng cĆ³ tįŗp tin tĘ°Ę”ng į»©ng.", + "orphanedtimedtext-unsupported": "Trang Äįŗ·c biį»t nĆ y chį» ÄĘ°į»£c hį» trį»£ trĆŖn cĘ” sį» dį»Æ liį»u MySQL.", + "orphanedtimedtext-notimedtext": "TimedText khĆ“ng ÄĘ°į»£c kĆch hoįŗ”t trĆŖn wiki nĆ y.", + "apihelp-transcodereset-param-title": "TĆŖn tįŗp tin phĘ°Ę”ng tiį»n." +} diff --git a/extensions/TimedMediaHandler/i18n/vo.json b/extensions/TimedMediaHandler/i18n/vo.json new file mode 100644 index 00000000..b20db88e --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/vo.json @@ -0,0 +1,14 @@ +{ + "@metadata": { + "authors": [ + "Malafaya", + "Smeira" + ] + }, + "timedmedia-more": "Pluikos...", + "timedmedia-dismiss": "FƤrmĆ¼kƶn", + "timedmedia-download": "DonĆ¼kƶn ragivi", + "timedmedia-desc-link": "TefĆ¼ ragiv at", + "timedmedia-mp4": "MP4", + "timedmedia-source-audio-file-desc": "Ragiv: $1 rigik ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/vro.json b/extensions/TimedMediaHandler/i18n/vro.json new file mode 100644 index 00000000..2222475c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/vro.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "VƵrok" + ] + }, + "timedmedia-no-player-js": "Kah'os om suq vƵrgokaejan JavaScript keelet vai olƵ-Ƶi sul tarvilist nĆ¤Ć¼tƤmistarkvarra.<br />\nSaat <a href=\"$1\">lƵigu alla laatiq</a> vai <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">laatiq alla tarkvara</a>, minka lƵiku vƵrgokaejan nĆ¤Ć¼dƤdƤq.", + "timedmedia-source-file": "LƤteq $1", + "timedmedia-source-audio-file-desc": "AlguperƤne $1-fail ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/wa.json b/extensions/TimedMediaHandler/i18n/wa.json new file mode 100644 index 00000000..81ee357d --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/wa.json @@ -0,0 +1,4 @@ +{ + "@metadata": [], + "timedmedia-dismiss": "ClĆ“re" +} diff --git a/extensions/TimedMediaHandler/i18n/war.json b/extensions/TimedMediaHandler/i18n/war.json new file mode 100644 index 00000000..2b28e939 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/war.json @@ -0,0 +1,9 @@ +{ + "@metadata": { + "authors": [ + "JinJian" + ] + }, + "timedmedia-source-file": "$1 tinitikangan", + "timedmedia-source-audio-file-desc": "Orihinal $1 file ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/wuu.json b/extensions/TimedMediaHandler/i18n/wuu.json new file mode 100644 index 00000000..f61881e2 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/wuu.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Poiuyt" + ] + }, + "timedmedia-no-player-js": "åƹå¼čµ·ļ¼ä½ äøŖęµč§åØē¦ēØä»JavaScriptęåäøä»»ä½ęÆęäøŖęę¾åØć<br />\nä½ åÆ仄<a href=\"$1\">äøč½½ē®åŖēꮵ</a>ę<a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">äøč½½äøåŖęę¾åØ</a>儽åęµč§åØéęę¾ēꮵć", + "timedmedia-source-file": "$1åå§ę件", + "timedmedia-source-audio-file-desc": "åå§$1ę件 ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/xmf.json b/extensions/TimedMediaHandler/i18n/xmf.json new file mode 100644 index 00000000..208dab64 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/xmf.json @@ -0,0 +1,10 @@ +{ + "@metadata": { + "authors": [ + "Silovan" + ] + }, + "timedmedia-no-player-js": "įį„įįį įį įį£įįį į” įįįįįØįį į į JavaScript įįį įį įį į į įį®įįįį£į į įį įįį įįį.<br />\nįį„įį įØįįįįįįį£įį <a href=\"$1\">įįįįįįįį įį įįįįį</a> įįį įį <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">įįįįįįįį įį įį įįį įįį</a> įįįįįįØ įį įį£įįį į” įį į©į„įįįį/įį«įį įį¤įįį.", + "timedmedia-source-file": "į¬į§į£ $1", + "timedmedia-source-audio-file-desc": "įį įįįįįįį $1 į¤įįįį ($2)" +} diff --git a/extensions/TimedMediaHandler/i18n/yi.json b/extensions/TimedMediaHandler/i18n/yi.json new file mode 100644 index 00000000..693e8639 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/yi.json @@ -0,0 +1,15 @@ +{ + "@metadata": { + "authors": [ + "פ××××שע×Ø", + "ą¶“ą·ą·ą¶³ą· ą¶ą·ą·ą·ą¶±ą·ą¶Æ" + ] + }, + "timedmedia-no-player-js": "×× ×ש××××××, ×ײַע×Ø ×××¢××¢×Ø×¢×Ø ×××¢×Ø ××× JavaScript ××××ק××××××Ø× ×××¢×Ø ××× × ××©× ×§××× ×עש××צ×× ×©×¤×××¢×Ø.<br />\n×××Ø ×§×¢× × <a href=\"$1\">××Ø×פ×××× ××¢× ×¤×××ק××פ</a> ×××¢×Ø <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">××Ø×פ×××× × ×©×¤×××¢×Ø</a> ×¦× ×©×¤××× ××¢× ×§××פ ××× ×ײַע×Ø ×××¢××¢×Ø×¢×Ø.", + "timedmedia-dismiss": "ש×××”×", + "timedmedia-download": "××Ø×Öøפ××Öø×× ×עקע", + "timedmedia-status": "×”××Ö·×××”", + "timedmedia-source-file": "$1 ×ק××Ø", + "timedmedia-source-audio-file-desc": "××Ø×××× ×¢××¢ $1 ×עקע ($2)", + "timedmedia-file": "×עקע" +} diff --git a/extensions/TimedMediaHandler/i18n/yue.json b/extensions/TimedMediaHandler/i18n/yue.json new file mode 100644 index 00000000..9cb1e97c --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/yue.json @@ -0,0 +1,24 @@ +{ + "@metadata": { + "authors": [ + "Yueman", + "CRCHF" + ] + }, + "timedmedia-desc": "Ogg Theora å Vorbis ęŖę”å
čēåØļ¼å å JavaScript ęę¾åØ", + "timedmedia-ogg-short-audio": "Ogg $1 č²ęŖļ¼$2", + "timedmedia-ogg-short-video": "Ogg $1 ē«ęŖļ¼$2", + "timedmedia-ogg-short-general": "Ogg $1 åŖęŖļ¼$2", + "timedmedia-ogg-long-audio": "Ogg $1 č²ęŖļ¼é·åŗ¦$2ļ¼$3", + "timedmedia-ogg-long-video": "Ogg $1 ē«ęŖļ¼é·åŗ¦$2ļ¼$4Ć$5åē“ ļ¼$3", + "timedmedia-ogg-long-multiplexed": "Ogg å¤å·„č²ļ¼ē«ęŖļ¼$1ļ¼é·åŗ¦$2ļ¼$4Ć$5åē“ ļ¼ēø½å
±$3", + "timedmedia-ogg-long-general": "Ogg åŖęŖļ¼é·åŗ¦$2ļ¼$3", + "timedmedia-ogg-long-error": "ē”ęå
oggęŖ: $1", + "timedmedia-no-player-js": "å°åä½ļ¼ä½ åēč¦½åØē”éå° JavaScript ęč
ē”ęÆę“å
ęę¾ēØå¼ć<br />\nä½ åÆ仄 <a href=\"$1\">äøč¼ę¢ē</a> ęč
<a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">äøč¼ęę¾ēØå¼</a> ēä½ åēč¦½åØé½åÆ仄ęć", + "timedmedia-more": "ę“å¤...", + "timedmedia-dismiss": "é", + "timedmedia-download": "äøč¼ęŖę”", + "timedmedia-desc-link": "éę¼å¢åęŖę”", + "timedmedia-source-file": "$1 ä¾ęŗęŖ", + "timedmedia-source-audio-file-desc": "åę¬ $1 ęŖę” ļ¼$2ļ¼" +} diff --git a/extensions/TimedMediaHandler/i18n/zh-hans.json b/extensions/TimedMediaHandler/i18n/zh-hans.json new file mode 100644 index 00000000..cd324e67 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/zh-hans.json @@ -0,0 +1,137 @@ +{ + "@metadata": { + "authors": [ + "Byfserag", + "Gaoxuewei", + "Hzy980512", + "Liangent", + "Liuxinyu970226", + "Shizhao", + "Xiaomingyan", + "Yfdyh000", + "ä¹ęč·Øę°Ŗ" + ] + }, + "extensionname-timedmedia": "TimedMediaHandler", + "timedmedia-desc": "é³é¢ćč§é¢ååå¹ēå¤ēēØåŗļ¼ęÆęWebMļ¼Ogg TheoraćVorbisļ¼srtę ¼å¼", + "timedmedia-ogg-short-audio": "Ogg $1声é³ę件ļ¼$2", + "timedmedia-ogg-short-video": "Ogg $1č§é¢ę件ļ¼$2", + "timedmedia-ogg-short-general": "Ogg $1åŖä½ę件ļ¼$2", + "timedmedia-ogg-long-audio": "Ogg $1声é³ę件ļ¼éæåŗ¦$2ļ¼$3", + "timedmedia-ogg-long-video": "Ogg $1č§é¢ę件ļ¼éæåŗ¦$2ļ¼$4 Ć $5åē“ ļ¼$3", + "timedmedia-ogg-long-multiplexed": "Oggå¤å·„声é³/č§é¢ę件ļ¼$1ļ¼éæåŗ¦$2ļ¼$4 Ć $5åē“ ļ¼å
±$3", + "timedmedia-ogg-long-general": "OggåŖä½ę件ļ¼éæåŗ¦$2ļ¼$3", + "timedmedia-ogg-long-error": "ę ęēoggę件ļ¼$1", + "timedmedia-ogg-long-no-streams": "OggåŖä½ę件ćč¦åļ¼ę²”ę认åÆēØäŗę¤ę件ēē¼č§£ē åØć", + "timedmedia-webm-short-video": "WebM $1č§é¢ę件ļ¼$2", + "timedmedia-webm-long-video": "WebMé³é¢/č§é¢ę件ļ¼$1ļ¼éæåŗ¦$2ļ¼$4 Ć $5åē“ ļ¼å
±$3", + "timedmedia-flac-short-audio": "FLACé³é¢ę件ļ¼$1", + "timedmedia-flac-long-audio": "FLACé³é¢ę件ļ¼éæåŗ¦$1ļ¼ē ē$2", + "timedmedia-wav-short-audio": "WAVé³é¢ę件ļ¼$1", + "timedmedia-wav-long-audio": "WAVé³é¢ę件ļ¼ę»å
±éæ$1ļ¼ē ē$2", + "timedmedia-wav-pcm-required": "ęØåŖč½äøä¼ čå²ē¼ē č°å¶ļ¼PCMļ¼WAVć", + "timedmedia-mp4-short-video": "MP4 $1č§é¢ę件ļ¼$2", + "timedmedia-mp4-long-video": "MP4é³é¢/č§é¢ę件ļ¼$1ļ¼éæåŗ¦$2ļ¼$4 Ć $5åē“ ļ¼$3 overall", + "timedmedia-no-player-js": "ę±ęļ¼ęØēęµč§åØē¦ēØäŗJavaScriptęę²”ęä»»ä½åÆęÆęēęę¾åØć<br />\nęØåÆ仄<a href=\"$1\">äøč½½čæäøŖēꮵ</a>ę<a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">äøč½½äøäøŖęę¾åØ</a>仄åØęµč§åØäøęę¾ēꮵć", + "timedmedia-more": "ę“å¤...", + "timedmedia-dismiss": "å
³é", + "timedmedia-download": "äøč½½ę件", + "timedmedia-play-media": "ęę¾åŖä½", + "timedmedia-desc-link": "å
³äŗčÆ„ę件", + "timedmedia-oggThumb-version": "OggHandleréč¦oggThumb $1ęč
ä¹åēēę¬ć", + "timedmedia-oggThumb-failed": "oggThumbęŖč½åå»ŗē¼©ē„å¾ć", + "timedmedia-status-header": "č½¬ē ē¶ę", + "timedmedia-update-status": "ę“ę°č½¬ē ē¶ę", + "timedmedia-status": "ē¶ę", + "timedmedia-status-unknown": "ęŖē„ē¶ę", + "timedmedia-transcodebitrate": "ęÆē¹ē", + "timedmedia-transcodeduration": "ē¼ē ę¶é“", + "timedmedia-transcodeinfo": "ę ¼å¼", + "timedmedia-actions": "ęä½", + "timedmedia-direct-link": "äøč½½", + "timedmedia-not-ready": "ęŖå°±ē»Ŗ", + "timedmedia-completed-on": "å·²å®ę$1", + "timedmedia-error-on": "äŗ$1éčÆÆ", + "timedmedia-started-transcode": "äŗ$1åå¼å§ć$2", + "timedmedia-percent-done": "大ēŗ¦$1%å·²å®ę", + "timedmedia-in-job-queue": "ę·»å å°å·„ä½éååØ$1å", + "timedmedia-unknown-target-size": "ęŖē„ē®ę 大å°ļ¼$1å·²ē¼ē ", + "timedmedia-days": "$1天", + "timedmedia-hours": "{{PLURAL:$1|$1å°ę¶}}", + "timedmedia-minutes": "$1å", + "timedmedia-seconds": "$1ē§", + "timedmedia-reset": "éē½®č½¬ē ", + "timedmedia-reset-confirm": "éē½®č½¬ē å°ä¼å°½åÆč½ē§»é¤ęęē°ęę件ļ¼å¹¶å°å
¶éę°å å
„å°č½¬ē å·„ä½éåćčæå°éč¦äøäŗę¶é“ę„éę°č½¬ē ć<br /><br />\nęØē”®å®č¦ē»§ē»åļ¼", + "timedmedia-reset-error": "éē½®č½¬ē å·„ä½ę¶åēéčÆÆć", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1åå§ę件", + "timedmedia-source-file-desc": "åå§$1ę件ļ¼$2 Ć $3ļ¼$4ļ¼", + "timedmedia-source-audio-file-desc": "åå§$1ę件 ($2)", + "timedmedia-derivative-desc-160p.ogv": "ä½åø¦å®½Oggč§é¢ļ¼160Pļ¼", + "timedmedia-derivative-desc-240p.ogv": "WebęµåŖä½Oggč§é¢ļ¼240Pļ¼", + "timedmedia-derivative-desc-360p.ogv": "WebęµåŖä½Oggč§é¢ļ¼360Pļ¼", + "timedmedia-derivative-desc-480p.ogv": "WebęµåŖä½Oggč§é¢ļ¼480Pļ¼", + "timedmedia-derivative-desc-720p.ogv": "é«ęø
åÆäøč½½Oggč§é¢ļ¼720Pļ¼", + "timedmedia-derivative-desc-1080p.ogv": "å
Øé«ęø
åÆäøč½½ Ogg č§é¢ (1080P)", + "timedmedia-derivative-desc-160p.webm": "WebęµåŖä½WebMļ¼160Pļ¼", + "timedmedia-derivative-desc-360p.webm": "WebęµåŖä½WebMļ¼360Pļ¼", + "timedmedia-derivative-desc-480p.webm": "WebęµåŖä½WebMļ¼480Pļ¼", + "timedmedia-derivative-desc-720p.webm": "é«ęø
åÆäøč½½WebMč§é¢ļ¼720Pļ¼", + "timedmedia-derivative-desc-1080p.webm": "å
Øé«ęø
åÆäøč½½ WebM (1080P)", + "timedmedia-derivative-desc-2160p.webm": "å
Øé«ęø
åÆäøč½½ WebM (2160P)", + "timedmedia-derivative-360p.vp9.webm": "VP9 360P", + "timedmedia-derivative-desc-360p.vp9.webm": "WebęµåŖä½WebM VP9ļ¼360Pļ¼", + "timedmedia-derivative-480p.vp9.webm": "VP9 480P", + "timedmedia-derivative-desc-480p.vp9.webm": "WebęµåŖä½WebM VP9ļ¼480Pļ¼", + "timedmedia-derivative-720p.vp9.webm": "VP9 720P", + "timedmedia-derivative-desc-720p.vp9.webm": "é«ęø
ęµåŖä½WebM VP9ļ¼720Pļ¼", + "timedmedia-derivative-1080p.vp9.webm": "VP9 1080P", + "timedmedia-derivative-desc-1080p.vp9.webm": "å
Øé«ęø
ęµåŖä½WebM VP9ļ¼1080Pļ¼", + "timedmedia-derivative-desc-2160p.vp9.webm": "å
Øé«ęø
ęµåŖä½WebM VP9ļ¼2160Pļ¼", + "timedmedia-derivative-desc-320p.mp4": "č®¾å¤å儽MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "ē½é”µęµåŖä½MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "é«ęø
MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "å
Øé«ęø
ē»č“Ø MP4 (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "å
Øé«ęø
ē»č“Ø MP4 (2160P)", + "timedmedia-derivative-ogg": "Ogg Vorbis", + "timedmedia-derivative-desc-ogg": "Ogg Vorbis", + "timedmedia-derivative-desc-mp3": "MP3", + "timedmedia-subtitle-new": "åå»ŗę°ēæ»čÆęē¼č¾ē°ęēæ»čÆ", + "timedmedia-subtitle-new-desc": "éę©čÆčØē¶åę'''{{int:Timedmedia-subtitle-new-go}}'''ęé®", + "timedmedia-subtitle-new-go": "ęäŗ¤", + "timedmedia-subtitle-language": "$1ļ¼$2ļ¼åå¹", + "timedmedia-subtitle-no-video": "å½ååå¹é”µé¢ę²”ęå
³čēč§é¢", + "timedmedia-subtitle-no-subtitles": "å½åę²”ęčæäøŖč§é¢ē$1åå¹ļ¼ęØåÆ仄[{{fullurl:{{FULLPAGENAME}}|action=edit}} ē¼č¾čæäøŖ锵é¢]仄귻å ", + "timedmedia-subtitle-remote": "ę¬ę件ēåå¹ę件ä½äŗ$1", + "timedmedia-subtitle-remote-link": "ä½ åÆ仄åØ$2ę„ēčÆ„ę件ē[$1 čÆ“ę锵é¢]", + "timedmediahandler": "å®ę¶åŖä½å¤ēēØåŗ", + "timedmedia-videos": "$1äøŖč§é¢", + "timedmedia-ogg-videos": "$1äøŖOggč§é¢", + "timedmedia-webm-videos": "$1äøŖWebMč§é¢", + "timedmedia-derivative-state-transcodes": "$1ę¬”č½¬ē ", + "timedmedia-derivative-state-active": "$1äøŖę£åØčæč”ēč½¬ē ä»»å”", + "timedmedia-derivative-state-queued": "$1äøŖéåäøēč½¬ē ä»»å”", + "timedmedia-derivative-state-failed": "$1ę¬”č½¬ē å¤±č“„", + "timedmedia-file": "ę件", + "timedmedia-audios": "$1äøŖé³é¢ę件", + "timedmedia-ogg-audios": "$1äøŖOggé³é¢ę件", + "timedmedia-flac-audios": "$1äøŖFLACé³é¢ę件", + "timedmedia-wav-audios": "$1äøŖWAVé³é¢ę件", + "right-transcode-reset": "éē½®å·²å¤±č“„ęå·²č½¬ē ēč§é¢å°å
¶åꬔå å
„å°ä½äøéåäøć", + "right-transcode-status": "ę„ē[[Special:TimedMediaHandler|å½åč½¬ē ę“»åØēäæ”ęÆ]]", + "action-transcode-status": "ę„ēå½åēč½¬ē ē¶ę", + "orphanedtimedtext": "å¤ē«ēTimedText锵é¢", + "orphanedtimedtext-summary": "ę²”ęåƹåŗę件ē[[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]]锵é¢ēåč”Øć", + "orphanedtimedtext-unsupported": "ę¤ē¹ę®é”µé¢åŖęÆęMySQLę°ę®åŗć", + "orphanedtimedtext-notimedtext": "TimedTextåØę¤wikięŖåÆēØć", + "apihelp-query+transcodestatus-description": "č·åęå®ę件锵é¢ēč½¬ē ē¶ęć", + "apihelp-query+transcodestatus-example-1": "č·å¾[[:File:Clip.webm]]ēčÆē ē¶ę", + "apihelp-query+videoinfo-description": "ę©å±å¾åäæ”ęÆ仄å
å«č§é¢ęŗļ¼å¾åę„ęŗļ¼äæ”ęÆ", + "apihelp-query+videoinfo-param-prop": "č¦č·åēč§é¢äæ”ęÆļ¼\n;timestamp:äøŗäøä¼ ēę¬ę·»å ę¶é“ę³ć\n;user:ę·»å äøä¼ č§é¢ēę¬ēēØę·ć\n;userid:ę·»å äøä¼ č§é¢ēę¬ēēØę·IDć\n;comment:åƹēę¬ēę³Øéć\n;parsedcomment:č§£ęåƹēę¬ēę³Øéć\n;canonicaltitle:ę·»å č§é¢ę件ēč§čę é¢ć\n;url:ęä¾č³č§é¢ēURLåå
¶čÆ“ę锵é¢ć\n;size:ę·»å č§é¢å¤§å°ļ¼åčļ¼ćé«åŗ¦å宽åŗ¦ćå¦ęéč¦ä¼ę·»å 锵é¢č®”ę°åęē»ę¶é“ć\n;dimensions:大å°å«åć\n;sha1:äøŗč§é¢ę·»å SHA-1ååøå¼ć\n;mime:ę·»å č§é¢ēMIMEē±»åć\n;thumbmime:ę·»å č§é¢ē¼©ē„å¾ēMIMEē±»åļ¼éč¦urlååę°$1urlwidthļ¼ć\n;mediatype:ę·»å č§é¢åŖä½ē±»åć\n;metadata:åäø¾č§é¢ēę¬ēEXIFå
ę°ę®ć\n;commonmetadata:åäø¾ē¹å®ęä»¶ę ¼å¼ēč§é¢ēę¬ēå
ę°ę®ć\n;extmetadata:åäø¾ę ¼å¼åå
ę°ę®\n;archivename:äøŗéęę°ēę¬ę·»å åę”£ēę¬ēę件åć\n;bitdepth:ę·»å ēę¬ēä½ę·±åŗ¦ć\n;uploadwarning:č¢«[[Special:Upload]]锵é¢ä½æēØ仄č·åęå
³ē°ęę件ēäæ”ęÆćäøéēØäŗMediaWikię øåæ仄å¤ä»£ē ć\n;derivatives:ę·»å äøåę ¼å¼ēéµåäøé³é¢ęč§é¢ę件ēåÆēØé«č“Øéēę¬ć", + "apihelp-query+videoinfo-example-1": "ę£ē“¢ęå
³[[:File:Folgers.ogv]]ēäæ”ęÆ", + "apihelp-transcodereset-description": "å
·ęātranscode-resetāęéēēØę·åÆ仄éē½®åéę°čæč”č½¬ē ä»»å”ć", + "apihelp-transcodereset-param-title": "åŖä½ę件ę é¢ć", + "apihelp-transcodereset-param-transcodekey": "ęØåøęéē½®ēč½¬ē å
³é®åćä»[[Special:ApiHelp/query+transcodestatus|action=query&prop=transcodestatus]]č·åć", + "apihelp-transcodereset-example-1": "éē½®[[:File:Clip.webm]]ēęęčÆē ", + "apihelp-transcodereset-example-2": "éē½®[[:File:Clip.webm]]ēā360_560kbs.webmāč½¬ē å
³é®å" +} diff --git a/extensions/TimedMediaHandler/i18n/zh-hant.json b/extensions/TimedMediaHandler/i18n/zh-hant.json new file mode 100644 index 00000000..c80a3438 --- /dev/null +++ b/extensions/TimedMediaHandler/i18n/zh-hant.json @@ -0,0 +1,119 @@ +{ + "@metadata": { + "authors": [ + "Gaoxuewei", + "Justincheng12345", + "Liuxinyu970226", + "Mark85296341", + "Simon Shek", + "LNDDYL", + "Cwlin0416" + ] + }, + "timedmedia-desc": "é³čØćå½±ēčåå¹čēēØå¼ļ¼ęÆę“ēę ¼å¼å
å« WebMļ¼Ogg TheoraćVorbisļ¼srt", + "timedmedia-ogg-short-audio": "Ogg $1 č²é³ęŖę”ļ¼$2", + "timedmedia-ogg-short-video": "Ogg $1 å½±ēęŖļ¼$2", + "timedmedia-ogg-short-general": "Ogg $1 åŖé«ęŖę”ļ¼$2", + "timedmedia-ogg-long-audio": "Ogg $1 č²é³ęŖę”ļ¼é·åŗ¦ $2ļ¼$3", + "timedmedia-ogg-long-video": "Ogg $1 å½±ēęŖę”ļ¼é·åŗ¦ $2ļ¼$4 Ć $5 åē“ ļ¼$3", + "timedmedia-ogg-long-multiplexed": "Ogg å¤å·„é³čØ/å½±ēęŖę”ļ¼$1ļ¼é·åŗ¦ $2ļ¼$4 Ć $5 ē«ē“ ļ¼å
± $3", + "timedmedia-ogg-long-general": "Ogg åŖé«ęŖę”ļ¼é·åŗ¦ $2ļ¼$3", + "timedmedia-ogg-long-error": "ē”ęē Ogg ęŖę”ļ¼$1", + "timedmedia-ogg-long-no-streams": "Ogg åŖé«ęŖę”ć č¦åļ¼ē”ę³č¾Øčę¤ęŖę”äøä½æēØēē·Øē¢¼ć", + "timedmedia-webm-short-video": "WebM $1 å½±ēęŖļ¼$2", + "timedmedia-webm-long-video": "WebM é³čØ/å½±ēęŖę”ļ¼$1ļ¼é·åŗ¦ $2ļ¼$4 Ć $5 ē«ē“ ļ¼å
± $3", + "timedmedia-flac-short-audio": "FLAC é³čØęŖę”ļ¼$1", + "timedmedia-flac-long-audio": "FLAC é³é »ęŖę”ļ¼é·åŗ¦ $1ļ¼å
± $2", + "timedmedia-wav-short-audio": "WAV é³čØęŖę”ļ¼$1", + "timedmedia-wav-long-audio": "WAV é³čØęŖę”ļ¼é·åŗ¦ $1ļ¼å
± $2", + "timedmedia-wav-pcm-required": "ęØå
åÆäøå³ PCM (Pulse Code Modulation) WAVć", + "timedmedia-mp4-short-video": "MP4 $1 å½±ēęŖļ¼$2", + "timedmedia-mp4-long-video": "MP4 é³čØ/å½±ēęŖę”ļ¼$1ļ¼é·åŗ¦ $2ļ¼$4 Ć $5 ē«ē“ ļ¼å
± $3", + "timedmedia-no-player-js": "ę±ęļ¼ęØēēč¦½åØęŖéå JavaScript ęę²ęęÆę“ēęę¾ēØå¼ć<br />\nęØåÆ <a href=\"$1\">äøč¼č©²ēꮵ</a> ę <a href=\"https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:TimedMediaHandler/Client_download\">äøč¼ęę¾åØ</a> 仄åØęØēēč¦½åØäøęę¾ć", + "timedmedia-more": "ę“å¤...", + "timedmedia-dismiss": "éé", + "timedmedia-download": "äøč¼ęŖę”", + "timedmedia-play-media": "ęę¾åŖé«", + "timedmedia-desc-link": "éę¼éåęŖę”", + "timedmedia-oggThumb-version": "OggHandler éč¦ä½æēØ oggThumb ēę¬ $1 ęę“ę°ēēę¬ć", + "timedmedia-oggThumb-failed": "oggThumb å»ŗē«ēø®å失ęć", + "timedmedia-status-header": "č½ē¢¼ēę
", + "timedmedia-update-status": "ę“ę°č½ē¢¼ēę
", + "timedmedia-status": "ēę
", + "timedmedia-status-unknown": "äøęēę
", + "timedmedia-transcodebitrate": "ä½å
ē", + "timedmedia-transcodeduration": "ē·Øē¢¼ęé", + "timedmedia-transcodeinfo": "ę ¼å¼", + "timedmedia-actions": "åä½", + "timedmedia-direct-link": "äøč¼", + "timedmedia-not-ready": "å°ęŖå°±ē·", + "timedmedia-completed-on": "å·²å®ę $1", + "timedmedia-error-on": "ę¼ $1 ē¼ēéÆčŖ¤ć", + "timedmedia-started-transcode": "å·²ę¼ $1 åéå§ć$2", + "timedmedia-percent-done": "大ē“å·²å®ę $1%", + "timedmedia-in-job-queue": "å·²ę¼ $1 åę°å¢č³å·„ä½åŗå", + "timedmedia-unknown-target-size": "äøęē®ęØ大å°ļ¼å·²ē·Øē¢¼ $1", + "timedmedia-days": "$1 天", + "timedmedia-hours": "$1 å°ę", + "timedmedia-minutes": "$1 å", + "timedmedia-seconds": "$1 ē§", + "timedmedia-reset": "éčØč½ē¢¼", + "timedmedia-reset-confirm": "éčØč½ē¢¼ęē§»é¤ęęå·²ååØēęŖę”ļ¼äø¦éę°å°ęŖę”å å
„č½ē¢¼å·„ä½åŗåćééč¦č±č²»äøäŗęéä¾éę°č½ē¢¼ć<br /><br />\nęØē¢ŗå®č¦ē¹¼ēŗåļ¼", + "timedmedia-reset-error": "éčØč½ē¢¼å·„ä½ęē¼ēéÆčŖ¤ć", + "timedmedia-mp4": "MP4", + "timedmedia-source-file": "$1 ä¾ęŗęŖę”", + "timedmedia-source-file-desc": "$1 åå§ęŖę”ļ¼$2 Ć $3 ($4)", + "timedmedia-source-audio-file-desc": "åå§ $1 ęŖę” ($2)", + "timedmedia-derivative-desc-160p.ogv": "ä½é »åƬ Ogg å½±ē (160P)", + "timedmedia-derivative-desc-240p.ogv": "ē¶²ē«åÆäø²ęµ Ogg å½±ē (240P)", + "timedmedia-derivative-desc-360p.ogv": "ē¶²ē«åÆäø²ęµ Ogg å½±ē (360P)", + "timedmedia-derivative-desc-480p.ogv": "ē¶²ē«åÆäø²ęµ Ogg å½±ē (480P)", + "timedmedia-derivative-desc-720p.ogv": "é«ē«č³ŖåÆäøč¼ Ogg å½±ē (720P)", + "timedmedia-derivative-desc-1080p.ogv": "Full HD åÆäøč¼ Ogg å½±å (1080P)", + "timedmedia-derivative-desc-160p.webm": "ē¶²ē«åÆäø²ęµ WebM (160P)", + "timedmedia-derivative-desc-360p.webm": "ē¶²ē«åÆäø²ęµ WebM (360P)", + "timedmedia-derivative-desc-480p.webm": "ē¶²ē«åÆäø²ęµ WebM (480P)", + "timedmedia-derivative-desc-720p.webm": "é«ē«č³ŖåÆäøč¼ WebM (720P)", + "timedmedia-derivative-desc-1080p.webm": "Full HD åÆäøč¼ WebM (1080P)", + "timedmedia-derivative-desc-2160p.webm": "Full HD åÆäøč¼ WebM (2160P)", + "timedmedia-derivative-desc-360p.vp9.webm": "ē¶²ē«åÆäø²ęµ WebM VP9 (360P)", + "timedmedia-derivative-desc-480p.vp9.webm": "ē¶²ē«åÆäø²ęµ WebM VP9 (480P)", + "timedmedia-derivative-desc-720p.vp9.webm": "HD ē¶²ē«åÆäø²ęµ WebM VP9 (720P)", + "timedmedia-derivative-desc-1080p.vp9.webm": "Full HD ē¶²ē«åÆäø²ęµ WebM VP9 (1080P)", + "timedmedia-derivative-desc-2160p.vp9.webm": "Full 4K ē¶²ē«åÆäø²ęµ WebM VP9 (2160P)", + "timedmedia-derivative-desc-320p.mp4": "č”åč£ē½®ęēØ MP4 (320P)", + "timedmedia-derivative-desc-480p.mp4": "ē¶²ē«åÆäø²ęµ MP4 (480P)", + "timedmedia-derivative-desc-720p.mp4": "é«ęø
åč³Ŗ MP4 (720P)", + "timedmedia-derivative-desc-1080p.mp4": "Full HD åč³Ŗ MP4 (1080P)", + "timedmedia-derivative-desc-2160p.mp4": "Full 4K åč³Ŗ MP4 (2160P)", + "timedmedia-subtitle-new": "å»ŗē«ę°ēæ»čÆęē·Øč¼Æē¾ęēæ»čÆ", + "timedmedia-subtitle-new-desc": "č«éøęčŖčØå¾é»éø '''{{int:Timedmedia-subtitle-new-go}}''' ęé", + "timedmedia-subtitle-new-go": "å·č”", + "timedmedia-subtitle-language": "$1 ($2) åå¹", + "timedmedia-subtitle-no-video": "ē®åę²ęčåå¹é é¢ēøéēå½±ēć", + "timedmedia-subtitle-no-subtitles": "ę¤å½±ēē®åę²ę $1 ēåå¹ļ¼ęØåÆ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ē·Øč¼Æę¤é é¢] ä¾å¢å åå¹ć", + "timedmedia-subtitle-remote": "ę¤ęŖę”ēåå¹ä½ę¼ $1", + "timedmedia-subtitle-remote-link": "ęØåÆę¼ $2 ęŖ¢č¦ę¤ęŖę”ē [$1 ęčæ°é é¢]", + "timedmediahandler": "TimedMediaHandler", + "timedmedia-videos": "$1 åå½±ē", + "timedmedia-ogg-videos": "$1 å Ogg å½±ē", + "timedmedia-webm-videos": "$1 å WebM å½±ē", + "timedmedia-derivative-state-transcodes": "$1 åč½ē¢¼å·„ä½", + "timedmedia-derivative-state-active": "$1 åę£åØå·č”ēč½ē¢¼å·„ä½", + "timedmedia-derivative-state-queued": "$1 ååØåŗåäøēč½ē¢¼å·„ä½", + "timedmedia-derivative-state-failed": "$1 ꬔč½ē¢¼å¤±ę", + "timedmedia-file": "ęŖę”", + "timedmedia-audios": "$1 åé³čØęŖę”", + "timedmedia-ogg-audios": "$1 å Ogg é³čØęŖę”", + "timedmedia-flac-audios": "$1 å FLAC é³čØęŖę”", + "timedmedia-wav-audios": "$1 å WAV é³čØęŖę”", + "right-transcode-reset": "éčØ已失ęęå·²č¼ē¢¼ēå½±ēļ¼å°å
¶éę°ęå
„åŗåäøć", + "right-transcode-status": "ęŖ¢č¦ [[Special:TimedMediaHandler|ē®åč½ē¢¼ę“»åēč³čØ]]", + "action-transcode-status": "ęŖ¢č¦ē®åč½ē¢¼ēę
", + "orphanedtimedtext": "å¤ē«ē TimedText é é¢", + "orphanedtimedtext-summary": "ęŖéčÆä»»ä½ęŖę”ē [[{{#special:AllPages/TimedText:}}|{{ns:TimedText}}]] é é¢ęø
å®ć", + "orphanedtimedtext-unsupported": "ę¤ē¹ę®é é¢å
ęÆę“ä½æēØ MySQL č³ęåŗ«ć", + "orphanedtimedtext-notimedtext": "ę¤ Wiki ęŖéå TimedText åč½ć", + "apihelp-query+transcodestatus-description": "åå¾ęå®ęŖę”é é¢ēč½ē¢¼ēę
ć", + "apihelp-query+transcodestatus-example-1": "åå¾ [[:File:Clip.webm]] ēč½ē¢¼ēę
" +} diff --git a/extensions/TimedMediaHandler/libs/getid3/getid3.lib.php b/extensions/TimedMediaHandler/libs/getid3/getid3.lib.php new file mode 100644 index 00000000..16d5318a --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/getid3.lib.php @@ -0,0 +1,1346 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// // +// getid3.lib.php - part of getID3() // +// See readme.txt for more details // +// /// +///////////////////////////////////////////////////////////////// + + +class getid3_lib +{ + + public static function PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8') { + $returnstring = ''; + for ($i = 0; $i < strlen($string); $i++) { + if ($hex) { + $returnstring .= str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT); + } else { + $returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string{$i}) ? $string{$i} : '¤'); + } + if ($spaces) { + $returnstring .= ' '; + } + } + if (!empty($htmlencoding)) { + if ($htmlencoding === true) { + $htmlencoding = 'UTF-8'; // prior to getID3 v1.9.0 the function's 4th parameter was boolean + } + $returnstring = htmlentities($returnstring, ENT_QUOTES, $htmlencoding); + } + return $returnstring; + } + + public static function trunc($floatnumber) { + // truncates a floating-point number at the decimal point + // returns int (if possible, otherwise float) + if ($floatnumber >= 1) { + $truncatednumber = floor($floatnumber); + } elseif ($floatnumber <= -1) { + $truncatednumber = ceil($floatnumber); + } else { + $truncatednumber = 0; + } + if (self::intValueSupported($truncatednumber)) { + $truncatednumber = (int) $truncatednumber; + } + return $truncatednumber; + } + + + public static function safe_inc(&$variable, $increment=1) { + if (isset($variable)) { + $variable += $increment; + } else { + $variable = $increment; + } + return true; + } + + public static function CastAsInt($floatnum) { + // convert to float if not already + $floatnum = (float) $floatnum; + + // convert a float to type int, only if possible + if (self::trunc($floatnum) == $floatnum) { + // it's not floating point + if (self::intValueSupported($floatnum)) { + // it's within int range + $floatnum = (int) $floatnum; + } + } + return $floatnum; + } + + public static function intValueSupported($num) { + // check if integers are 64-bit + static $hasINT64 = null; + if ($hasINT64 === null) { // 10x faster than is_null() + $hasINT64 = is_int(pow(2, 31)); // 32-bit int are limited to (2^31)-1 + if (!$hasINT64 && !defined('PHP_INT_MIN')) { + define('PHP_INT_MIN', ~PHP_INT_MAX); + } + } + // if integers are 64-bit - no other check required + if ($hasINT64 || (($num <= PHP_INT_MAX) && ($num >= PHP_INT_MIN))) { + return true; + } + return false; + } + + public static function DecimalizeFraction($fraction) { + list($numerator, $denominator) = explode('/', $fraction); + return $numerator / ($denominator ? $denominator : 1); + } + + + public static function DecimalBinary2Float($binarynumerator) { + $numerator = self::Bin2Dec($binarynumerator); + $denominator = self::Bin2Dec('1'.str_repeat('0', strlen($binarynumerator))); + return ($numerator / $denominator); + } + + + public static function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) { + // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html + if (strpos($binarypointnumber, '.') === false) { + $binarypointnumber = '0.'.$binarypointnumber; + } elseif ($binarypointnumber{0} == '.') { + $binarypointnumber = '0'.$binarypointnumber; + } + $exponent = 0; + while (($binarypointnumber{0} != '1') || (substr($binarypointnumber, 1, 1) != '.')) { + if (substr($binarypointnumber, 1, 1) == '.') { + $exponent--; + $binarypointnumber = substr($binarypointnumber, 2, 1).'.'.substr($binarypointnumber, 3); + } else { + $pointpos = strpos($binarypointnumber, '.'); + $exponent += ($pointpos - 1); + $binarypointnumber = str_replace('.', '', $binarypointnumber); + $binarypointnumber = $binarypointnumber{0}.'.'.substr($binarypointnumber, 1); + } + } + $binarypointnumber = str_pad(substr($binarypointnumber, 0, $maxbits + 2), $maxbits + 2, '0', STR_PAD_RIGHT); + return array('normalized'=>$binarypointnumber, 'exponent'=>(int) $exponent); + } + + + public static function Float2BinaryDecimal($floatvalue) { + // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html + $maxbits = 128; // to how many bits of precision should the calculations be taken? + $intpart = self::trunc($floatvalue); + $floatpart = abs($floatvalue - $intpart); + $pointbitstring = ''; + while (($floatpart != 0) && (strlen($pointbitstring) < $maxbits)) { + $floatpart *= 2; + $pointbitstring .= (string) self::trunc($floatpart); + $floatpart -= self::trunc($floatpart); + } + $binarypointnumber = decbin($intpart).'.'.$pointbitstring; + return $binarypointnumber; + } + + + public static function Float2String($floatvalue, $bits) { + // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html + switch ($bits) { + case 32: + $exponentbits = 8; + $fractionbits = 23; + break; + + case 64: + $exponentbits = 11; + $fractionbits = 52; + break; + + default: + return false; + break; + } + if ($floatvalue >= 0) { + $signbit = '0'; + } else { + $signbit = '1'; + } + $normalizedbinary = self::NormalizeBinaryPoint(self::Float2BinaryDecimal($floatvalue), $fractionbits); + $biasedexponent = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent + $exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT); + $fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT); + + return self::BigEndian2String(self::Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false); + } + + + public static function LittleEndian2Float($byteword) { + return self::BigEndian2Float(strrev($byteword)); + } + + + public static function BigEndian2Float($byteword) { + // ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic + // http://www.psc.edu/general/software/packages/ieee/ieee.html + // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html + + $bitword = self::BigEndian2Bin($byteword); + if (!$bitword) { + return 0; + } + $signbit = $bitword{0}; + + switch (strlen($byteword) * 8) { + case 32: + $exponentbits = 8; + $fractionbits = 23; + break; + + case 64: + $exponentbits = 11; + $fractionbits = 52; + break; + + case 80: + // 80-bit Apple SANE format + // http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/ + $exponentstring = substr($bitword, 1, 15); + $isnormalized = intval($bitword{16}); + $fractionstring = substr($bitword, 17, 63); + $exponent = pow(2, self::Bin2Dec($exponentstring) - 16383); + $fraction = $isnormalized + self::DecimalBinary2Float($fractionstring); + $floatvalue = $exponent * $fraction; + if ($signbit == '1') { + $floatvalue *= -1; + } + return $floatvalue; + break; + + default: + return false; + break; + } + $exponentstring = substr($bitword, 1, $exponentbits); + $fractionstring = substr($bitword, $exponentbits + 1, $fractionbits); + $exponent = self::Bin2Dec($exponentstring); + $fraction = self::Bin2Dec($fractionstring); + + if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) { + // Not a Number + $floatvalue = false; + } elseif (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction == 0)) { + if ($signbit == '1') { + $floatvalue = '-infinity'; + } else { + $floatvalue = '+infinity'; + } + } elseif (($exponent == 0) && ($fraction == 0)) { + if ($signbit == '1') { + $floatvalue = -0; + } else { + $floatvalue = 0; + } + $floatvalue = ($signbit ? 0 : -0); + } elseif (($exponent == 0) && ($fraction != 0)) { + // These are 'unnormalized' values + $floatvalue = pow(2, (-1 * (pow(2, $exponentbits - 1) - 2))) * self::DecimalBinary2Float($fractionstring); + if ($signbit == '1') { + $floatvalue *= -1; + } + } elseif ($exponent != 0) { + $floatvalue = pow(2, ($exponent - (pow(2, $exponentbits - 1) - 1))) * (1 + self::DecimalBinary2Float($fractionstring)); + if ($signbit == '1') { + $floatvalue *= -1; + } + } + return (float) $floatvalue; + } + + + public static function BigEndian2Int($byteword, $synchsafe=false, $signed=false) { + $intvalue = 0; + $bytewordlen = strlen($byteword); + if ($bytewordlen == 0) { + return false; + } + for ($i = 0; $i < $bytewordlen; $i++) { + if ($synchsafe) { // disregard MSB, effectively 7-bit bytes + //$intvalue = $intvalue | (ord($byteword{$i}) & 0x7F) << (($bytewordlen - 1 - $i) * 7); // faster, but runs into problems past 2^31 on 32-bit systems + $intvalue += (ord($byteword{$i}) & 0x7F) * pow(2, ($bytewordlen - 1 - $i) * 7); + } else { + $intvalue += ord($byteword{$i}) * pow(256, ($bytewordlen - 1 - $i)); + } + } + if ($signed && !$synchsafe) { + // synchsafe ints are not allowed to be signed + if ($bytewordlen <= PHP_INT_SIZE) { + $signMaskBit = 0x80 << (8 * ($bytewordlen - 1)); + if ($intvalue & $signMaskBit) { + $intvalue = 0 - ($intvalue & ($signMaskBit - 1)); + } + } else { + throw new Exception('ERROR: Cannot have signed integers larger than '.(8 * PHP_INT_SIZE).'-bits ('.strlen($byteword).') in self::BigEndian2Int()'); + break; + } + } + return self::CastAsInt($intvalue); + } + + + public static function LittleEndian2Int($byteword, $signed=false) { + return self::BigEndian2Int(strrev($byteword), false, $signed); + } + + + public static function BigEndian2Bin($byteword) { + $binvalue = ''; + $bytewordlen = strlen($byteword); + for ($i = 0; $i < $bytewordlen; $i++) { + $binvalue .= str_pad(decbin(ord($byteword{$i})), 8, '0', STR_PAD_LEFT); + } + return $binvalue; + } + + + public static function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false) { + if ($number < 0) { + throw new Exception('ERROR: self::BigEndian2String() does not support negative numbers'); + } + $maskbyte = (($synchsafe || $signed) ? 0x7F : 0xFF); + $intstring = ''; + if ($signed) { + if ($minbytes > PHP_INT_SIZE) { + throw new Exception('ERROR: Cannot have signed integers larger than '.(8 * PHP_INT_SIZE).'-bits in self::BigEndian2String()'); + } + $number = $number & (0x80 << (8 * ($minbytes - 1))); + } + while ($number != 0) { + $quotient = ($number / ($maskbyte + 1)); + $intstring = chr(ceil(($quotient - floor($quotient)) * $maskbyte)).$intstring; + $number = floor($quotient); + } + return str_pad($intstring, $minbytes, "\x00", STR_PAD_LEFT); + } + + + public static function Dec2Bin($number) { + while ($number >= 256) { + $bytes[] = (($number / 256) - (floor($number / 256))) * 256; + $number = floor($number / 256); + } + $bytes[] = $number; + $binstring = ''; + for ($i = 0; $i < count($bytes); $i++) { + $binstring = (($i == count($bytes) - 1) ? decbin($bytes[$i]) : str_pad(decbin($bytes[$i]), 8, '0', STR_PAD_LEFT)).$binstring; + } + return $binstring; + } + + + public static function Bin2Dec($binstring, $signed=false) { + $signmult = 1; + if ($signed) { + if ($binstring{0} == '1') { + $signmult = -1; + } + $binstring = substr($binstring, 1); + } + $decvalue = 0; + for ($i = 0; $i < strlen($binstring); $i++) { + $decvalue += ((int) substr($binstring, strlen($binstring) - $i - 1, 1)) * pow(2, $i); + } + return self::CastAsInt($decvalue * $signmult); + } + + + public static function Bin2String($binstring) { + // return 'hi' for input of '0110100001101001' + $string = ''; + $binstringreversed = strrev($binstring); + for ($i = 0; $i < strlen($binstringreversed); $i += 8) { + $string = chr(self::Bin2Dec(strrev(substr($binstringreversed, $i, 8)))).$string; + } + return $string; + } + + + public static function LittleEndian2String($number, $minbytes=1, $synchsafe=false) { + $intstring = ''; + while ($number > 0) { + if ($synchsafe) { + $intstring = $intstring.chr($number & 127); + $number >>= 7; + } else { + $intstring = $intstring.chr($number & 255); + $number >>= 8; + } + } + return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT); + } + + + public static function array_merge_clobber($array1, $array2) { + // written by kcŲhireability*com + // taken from http://www.php.net/manual/en/function.array-merge-recursive.php + if (!is_array($array1) || !is_array($array2)) { + return false; + } + $newarray = $array1; + foreach ($array2 as $key => $val) { + if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) { + $newarray[$key] = self::array_merge_clobber($newarray[$key], $val); + } else { + $newarray[$key] = $val; + } + } + return $newarray; + } + + + public static function array_merge_noclobber($array1, $array2) { + if (!is_array($array1) || !is_array($array2)) { + return false; + } + $newarray = $array1; + foreach ($array2 as $key => $val) { + if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) { + $newarray[$key] = self::array_merge_noclobber($newarray[$key], $val); + } elseif (!isset($newarray[$key])) { + $newarray[$key] = $val; + } + } + return $newarray; + } + + + public static function ksort_recursive(&$theArray) { + ksort($theArray); + foreach ($theArray as $key => $value) { + if (is_array($value)) { + self::ksort_recursive($theArray[$key]); + } + } + return true; + } + + public static function fileextension($filename, $numextensions=1) { + if (strstr($filename, '.')) { + $reversedfilename = strrev($filename); + $offset = 0; + for ($i = 0; $i < $numextensions; $i++) { + $offset = strpos($reversedfilename, '.', $offset + 1); + if ($offset === false) { + return ''; + } + } + return strrev(substr($reversedfilename, 0, $offset)); + } + return ''; + } + + + public static function PlaytimeString($seconds) { + $sign = (($seconds < 0) ? '-' : ''); + $seconds = round(abs($seconds)); + $H = (int) floor( $seconds / 3600); + $M = (int) floor(($seconds - (3600 * $H) ) / 60); + $S = (int) round( $seconds - (3600 * $H) - (60 * $M) ); + return $sign.($H ? $H.':' : '').($H ? str_pad($M, 2, '0', STR_PAD_LEFT) : intval($M)).':'.str_pad($S, 2, 0, STR_PAD_LEFT); + } + + + public static function DateMac2Unix($macdate) { + // Macintosh timestamp: seconds since 00:00h January 1, 1904 + // UNIX timestamp: seconds since 00:00h January 1, 1970 + return self::CastAsInt($macdate - 2082844800); + } + + + public static function FixedPoint8_8($rawdata) { + return self::BigEndian2Int(substr($rawdata, 0, 1)) + (float) (self::BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8)); + } + + + public static function FixedPoint16_16($rawdata) { + return self::BigEndian2Int(substr($rawdata, 0, 2)) + (float) (self::BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16)); + } + + + public static function FixedPoint2_30($rawdata) { + $binarystring = self::BigEndian2Bin($rawdata); + return self::Bin2Dec(substr($binarystring, 0, 2)) + (float) (self::Bin2Dec(substr($binarystring, 2, 30)) / pow(2, 30)); + } + + + public static function CreateDeepArray($ArrayPath, $Separator, $Value) { + // assigns $Value to a nested array path: + // $foo = self::CreateDeepArray('/path/to/my', '/', 'file.txt') + // is the same as: + // $foo = array('path'=>array('to'=>'array('my'=>array('file.txt')))); + // or + // $foo['path']['to']['my'] = 'file.txt'; + $ArrayPath = ltrim($ArrayPath, $Separator); + if (($pos = strpos($ArrayPath, $Separator)) !== false) { + $ReturnedArray[substr($ArrayPath, 0, $pos)] = self::CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value); + } else { + $ReturnedArray[$ArrayPath] = $Value; + } + return $ReturnedArray; + } + + public static function array_max($arraydata, $returnkey=false) { + $maxvalue = false; + $maxkey = false; + foreach ($arraydata as $key => $value) { + if (!is_array($value)) { + if ($value > $maxvalue) { + $maxvalue = $value; + $maxkey = $key; + } + } + } + return ($returnkey ? $maxkey : $maxvalue); + } + + public static function array_min($arraydata, $returnkey=false) { + $minvalue = false; + $minkey = false; + foreach ($arraydata as $key => $value) { + if (!is_array($value)) { + if ($value > $minvalue) { + $minvalue = $value; + $minkey = $key; + } + } + } + return ($returnkey ? $minkey : $minvalue); + } + + public static function XML2array($XMLstring) { + if (function_exists('simplexml_load_string') + && function_exists('get_object_vars') + && function_exists('libxml_disable_entity_loader') + ) { + $loader = libxml_disable_entity_loader(true); + $XMLobject = simplexml_load_string($XMLstring); + $return = self::SimpleXMLelement2array($XMLobject); + libxml_disable_entity_loader($loader); + return $return; + } + return false; + } + + public static function SimpleXMLelement2array($XMLobject) { + if (!is_object($XMLobject) && !is_array($XMLobject)) { + return $XMLobject; + } + $XMLarray = (is_object($XMLobject) ? get_object_vars($XMLobject) : $XMLobject); + foreach ($XMLarray as $key => $value) { + $XMLarray[$key] = self::SimpleXMLelement2array($value); + } + return $XMLarray; + } + + + // Allan Hansen <ahŲartemis*dk> + // self::md5_data() - returns md5sum for a file from startuing position to absolute end position + public static function hash_data($file, $offset, $end, $algorithm) { + static $tempdir = ''; + if (!self::intValueSupported($end)) { + return false; + } + switch ($algorithm) { + case 'md5': + $hash_function = 'md5_file'; + $unix_call = 'md5sum'; + $windows_call = 'md5sum.exe'; + $hash_length = 32; + break; + + case 'sha1': + $hash_function = 'sha1_file'; + $unix_call = 'sha1sum'; + $windows_call = 'sha1sum.exe'; + $hash_length = 40; + break; + + default: + throw new Exception('Invalid algorithm ('.$algorithm.') in self::hash_data()'); + break; + } + $size = $end - $offset; + while (true) { + if (GETID3_OS_ISWINDOWS) { + + // It seems that sha1sum.exe for Windows only works on physical files, does not accept piped data + // Fall back to create-temp-file method: + if ($algorithm == 'sha1') { + break; + } + + $RequiredFiles = array('cygwin1.dll', 'head.exe', 'tail.exe', $windows_call); + foreach ($RequiredFiles as $required_file) { + if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) { + // helper apps not available - fall back to old method + break 2; + } + } + $commandline = GETID3_HELPERAPPSDIR.'head.exe -c '.$end.' '.escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $file)).' | '; + $commandline .= GETID3_HELPERAPPSDIR.'tail.exe -c '.$size.' | '; + $commandline .= GETID3_HELPERAPPSDIR.$windows_call; + + } else { + + $commandline = 'head -c'.$end.' '.escapeshellarg($file).' | '; + $commandline .= 'tail -c'.$size.' | '; + $commandline .= $unix_call; + + } + if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { + //throw new Exception('PHP running in Safe Mode - backtick operator not available, using slower non-system-call '.$algorithm.' algorithm'); + break; + } + return substr(`$commandline`, 0, $hash_length); + } + + if (empty($tempdir)) { + // yes this is ugly, feel free to suggest a better way + require_once(dirname(__FILE__).'/getid3.php'); + $getid3_temp = new getID3(); + $tempdir = $getid3_temp->tempdir; + unset($getid3_temp); + } + // try to create a temporary file in the system temp directory - invalid dirname should force to system temp dir + if (($data_filename = tempnam($tempdir, 'gI3')) === false) { + // can't find anywhere to create a temp file, just fail + return false; + } + + // Init + $result = false; + + // copy parts of file + try { + self::CopyFileParts($file, $data_filename, $offset, $end - $offset); + $result = $hash_function($data_filename); + } catch (Exception $e) { + throw new Exception('self::CopyFileParts() failed in getid_lib::hash_data(): '.$e->getMessage()); + } + unlink($data_filename); + return $result; + } + + public static function CopyFileParts($filename_source, $filename_dest, $offset, $length) { + if (!self::intValueSupported($offset + $length)) { + throw new Exception('cannot copy file portion, it extends beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit'); + } + if (is_readable($filename_source) && is_file($filename_source) && ($fp_src = fopen($filename_source, 'rb'))) { + if (($fp_dest = fopen($filename_dest, 'wb'))) { + if (fseek($fp_src, $offset, SEEK_SET) == 0) { + $byteslefttowrite = $length; + while (($byteslefttowrite > 0) && ($buffer = fread($fp_src, min($byteslefttowrite, getID3::FREAD_BUFFER_SIZE)))) { + $byteswritten = fwrite($fp_dest, $buffer, $byteslefttowrite); + $byteslefttowrite -= $byteswritten; + } + return true; + } else { + throw new Exception('failed to seek to offset '.$offset.' in '.$filename_source); + } + fclose($fp_dest); + } else { + throw new Exception('failed to create file for writing '.$filename_dest); + } + fclose($fp_src); + } else { + throw new Exception('failed to open file for reading '.$filename_source); + } + return false; + } + + public static function iconv_fallback_int_utf8($charval) { + if ($charval < 128) { + // 0bbbbbbb + $newcharstring = chr($charval); + } elseif ($charval < 2048) { + // 110bbbbb 10bbbbbb + $newcharstring = chr(($charval >> 6) | 0xC0); + $newcharstring .= chr(($charval & 0x3F) | 0x80); + } elseif ($charval < 65536) { + // 1110bbbb 10bbbbbb 10bbbbbb + $newcharstring = chr(($charval >> 12) | 0xE0); + $newcharstring .= chr(($charval >> 6) | 0xC0); + $newcharstring .= chr(($charval & 0x3F) | 0x80); + } else { + // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb + $newcharstring = chr(($charval >> 18) | 0xF0); + $newcharstring .= chr(($charval >> 12) | 0xC0); + $newcharstring .= chr(($charval >> 6) | 0xC0); + $newcharstring .= chr(($charval & 0x3F) | 0x80); + } + return $newcharstring; + } + + // ISO-8859-1 => UTF-8 + public static function iconv_fallback_iso88591_utf8($string, $bom=false) { + if (function_exists('utf8_encode')) { + return utf8_encode($string); + } + // utf8_encode() unavailable, use getID3()'s iconv_fallback() conversions (possibly PHP is compiled without XML support) + $newcharstring = ''; + if ($bom) { + $newcharstring .= "\xEF\xBB\xBF"; + } + for ($i = 0; $i < strlen($string); $i++) { + $charval = ord($string{$i}); + $newcharstring .= self::iconv_fallback_int_utf8($charval); + } + return $newcharstring; + } + + // ISO-8859-1 => UTF-16BE + public static function iconv_fallback_iso88591_utf16be($string, $bom=false) { + $newcharstring = ''; + if ($bom) { + $newcharstring .= "\xFE\xFF"; + } + for ($i = 0; $i < strlen($string); $i++) { + $newcharstring .= "\x00".$string{$i}; + } + return $newcharstring; + } + + // ISO-8859-1 => UTF-16LE + public static function iconv_fallback_iso88591_utf16le($string, $bom=false) { + $newcharstring = ''; + if ($bom) { + $newcharstring .= "\xFF\xFE"; + } + for ($i = 0; $i < strlen($string); $i++) { + $newcharstring .= $string{$i}."\x00"; + } + return $newcharstring; + } + + // ISO-8859-1 => UTF-16LE (BOM) + public static function iconv_fallback_iso88591_utf16($string) { + return self::iconv_fallback_iso88591_utf16le($string, true); + } + + // UTF-8 => ISO-8859-1 + public static function iconv_fallback_utf8_iso88591($string) { + if (function_exists('utf8_decode')) { + return utf8_decode($string); + } + // utf8_decode() unavailable, use getID3()'s iconv_fallback() conversions (possibly PHP is compiled without XML support) + $newcharstring = ''; + $offset = 0; + $stringlength = strlen($string); + while ($offset < $stringlength) { + if ((ord($string{$offset}) | 0x07) == 0xF7) { + // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x07) << 18) & + ((ord($string{($offset + 1)}) & 0x3F) << 12) & + ((ord($string{($offset + 2)}) & 0x3F) << 6) & + (ord($string{($offset + 3)}) & 0x3F); + $offset += 4; + } elseif ((ord($string{$offset}) | 0x0F) == 0xEF) { + // 1110bbbb 10bbbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) & + ((ord($string{($offset + 1)}) & 0x3F) << 6) & + (ord($string{($offset + 2)}) & 0x3F); + $offset += 3; + } elseif ((ord($string{$offset}) | 0x1F) == 0xDF) { + // 110bbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x1F) << 6) & + (ord($string{($offset + 1)}) & 0x3F); + $offset += 2; + } elseif ((ord($string{$offset}) | 0x7F) == 0x7F) { + // 0bbbbbbb + $charval = ord($string{$offset}); + $offset += 1; + } else { + // error? throw some kind of warning here? + $charval = false; + $offset += 1; + } + if ($charval !== false) { + $newcharstring .= (($charval < 256) ? chr($charval) : '?'); + } + } + return $newcharstring; + } + + // UTF-8 => UTF-16BE + public static function iconv_fallback_utf8_utf16be($string, $bom=false) { + $newcharstring = ''; + if ($bom) { + $newcharstring .= "\xFE\xFF"; + } + $offset = 0; + $stringlength = strlen($string); + while ($offset < $stringlength) { + if ((ord($string{$offset}) | 0x07) == 0xF7) { + // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x07) << 18) & + ((ord($string{($offset + 1)}) & 0x3F) << 12) & + ((ord($string{($offset + 2)}) & 0x3F) << 6) & + (ord($string{($offset + 3)}) & 0x3F); + $offset += 4; + } elseif ((ord($string{$offset}) | 0x0F) == 0xEF) { + // 1110bbbb 10bbbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) & + ((ord($string{($offset + 1)}) & 0x3F) << 6) & + (ord($string{($offset + 2)}) & 0x3F); + $offset += 3; + } elseif ((ord($string{$offset}) | 0x1F) == 0xDF) { + // 110bbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x1F) << 6) & + (ord($string{($offset + 1)}) & 0x3F); + $offset += 2; + } elseif ((ord($string{$offset}) | 0x7F) == 0x7F) { + // 0bbbbbbb + $charval = ord($string{$offset}); + $offset += 1; + } else { + // error? throw some kind of warning here? + $charval = false; + $offset += 1; + } + if ($charval !== false) { + $newcharstring .= (($charval < 65536) ? self::BigEndian2String($charval, 2) : "\x00".'?'); + } + } + return $newcharstring; + } + + // UTF-8 => UTF-16LE + public static function iconv_fallback_utf8_utf16le($string, $bom=false) { + $newcharstring = ''; + if ($bom) { + $newcharstring .= "\xFF\xFE"; + } + $offset = 0; + $stringlength = strlen($string); + while ($offset < $stringlength) { + if ((ord($string{$offset}) | 0x07) == 0xF7) { + // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x07) << 18) & + ((ord($string{($offset + 1)}) & 0x3F) << 12) & + ((ord($string{($offset + 2)}) & 0x3F) << 6) & + (ord($string{($offset + 3)}) & 0x3F); + $offset += 4; + } elseif ((ord($string{$offset}) | 0x0F) == 0xEF) { + // 1110bbbb 10bbbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) & + ((ord($string{($offset + 1)}) & 0x3F) << 6) & + (ord($string{($offset + 2)}) & 0x3F); + $offset += 3; + } elseif ((ord($string{$offset}) | 0x1F) == 0xDF) { + // 110bbbbb 10bbbbbb + $charval = ((ord($string{($offset + 0)}) & 0x1F) << 6) & + (ord($string{($offset + 1)}) & 0x3F); + $offset += 2; + } elseif ((ord($string{$offset}) | 0x7F) == 0x7F) { + // 0bbbbbbb + $charval = ord($string{$offset}); + $offset += 1; + } else { + // error? maybe throw some warning here? + $charval = false; + $offset += 1; + } + if ($charval !== false) { + $newcharstring .= (($charval < 65536) ? self::LittleEndian2String($charval, 2) : '?'."\x00"); + } + } + return $newcharstring; + } + + // UTF-8 => UTF-16LE (BOM) + public static function iconv_fallback_utf8_utf16($string) { + return self::iconv_fallback_utf8_utf16le($string, true); + } + + // UTF-16BE => UTF-8 + public static function iconv_fallback_utf16be_utf8($string) { + if (substr($string, 0, 2) == "\xFE\xFF") { + // strip BOM + $string = substr($string, 2); + } + $newcharstring = ''; + for ($i = 0; $i < strlen($string); $i += 2) { + $charval = self::BigEndian2Int(substr($string, $i, 2)); + $newcharstring .= self::iconv_fallback_int_utf8($charval); + } + return $newcharstring; + } + + // UTF-16LE => UTF-8 + public static function iconv_fallback_utf16le_utf8($string) { + if (substr($string, 0, 2) == "\xFF\xFE") { + // strip BOM + $string = substr($string, 2); + } + $newcharstring = ''; + for ($i = 0; $i < strlen($string); $i += 2) { + $charval = self::LittleEndian2Int(substr($string, $i, 2)); + $newcharstring .= self::iconv_fallback_int_utf8($charval); + } + return $newcharstring; + } + + // UTF-16BE => ISO-8859-1 + public static function iconv_fallback_utf16be_iso88591($string) { + if (substr($string, 0, 2) == "\xFE\xFF") { + // strip BOM + $string = substr($string, 2); + } + $newcharstring = ''; + for ($i = 0; $i < strlen($string); $i += 2) { + $charval = self::BigEndian2Int(substr($string, $i, 2)); + $newcharstring .= (($charval < 256) ? chr($charval) : '?'); + } + return $newcharstring; + } + + // UTF-16LE => ISO-8859-1 + public static function iconv_fallback_utf16le_iso88591($string) { + if (substr($string, 0, 2) == "\xFF\xFE") { + // strip BOM + $string = substr($string, 2); + } + $newcharstring = ''; + for ($i = 0; $i < strlen($string); $i += 2) { + $charval = self::LittleEndian2Int(substr($string, $i, 2)); + $newcharstring .= (($charval < 256) ? chr($charval) : '?'); + } + return $newcharstring; + } + + // UTF-16 (BOM) => ISO-8859-1 + public static function iconv_fallback_utf16_iso88591($string) { + $bom = substr($string, 0, 2); + if ($bom == "\xFE\xFF") { + return self::iconv_fallback_utf16be_iso88591(substr($string, 2)); + } elseif ($bom == "\xFF\xFE") { + return self::iconv_fallback_utf16le_iso88591(substr($string, 2)); + } + return $string; + } + + // UTF-16 (BOM) => UTF-8 + public static function iconv_fallback_utf16_utf8($string) { + $bom = substr($string, 0, 2); + if ($bom == "\xFE\xFF") { + return self::iconv_fallback_utf16be_utf8(substr($string, 2)); + } elseif ($bom == "\xFF\xFE") { + return self::iconv_fallback_utf16le_utf8(substr($string, 2)); + } + return $string; + } + + public static function iconv_fallback($in_charset, $out_charset, $string) { + + if ($in_charset == $out_charset) { + return $string; + } + + // iconv() availble + if (function_exists('iconv')) { + if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) { + switch ($out_charset) { + case 'ISO-8859-1': + $converted_string = rtrim($converted_string, "\x00"); + break; + } + return $converted_string; + } + + // iconv() may sometimes fail with "illegal character in input string" error message + // and return an empty string, but returning the unconverted string is more useful + return $string; + } + + + // iconv() not available + static $ConversionFunctionList = array(); + if (empty($ConversionFunctionList)) { + $ConversionFunctionList['ISO-8859-1']['UTF-8'] = 'iconv_fallback_iso88591_utf8'; + $ConversionFunctionList['ISO-8859-1']['UTF-16'] = 'iconv_fallback_iso88591_utf16'; + $ConversionFunctionList['ISO-8859-1']['UTF-16BE'] = 'iconv_fallback_iso88591_utf16be'; + $ConversionFunctionList['ISO-8859-1']['UTF-16LE'] = 'iconv_fallback_iso88591_utf16le'; + $ConversionFunctionList['UTF-8']['ISO-8859-1'] = 'iconv_fallback_utf8_iso88591'; + $ConversionFunctionList['UTF-8']['UTF-16'] = 'iconv_fallback_utf8_utf16'; + $ConversionFunctionList['UTF-8']['UTF-16BE'] = 'iconv_fallback_utf8_utf16be'; + $ConversionFunctionList['UTF-8']['UTF-16LE'] = 'iconv_fallback_utf8_utf16le'; + $ConversionFunctionList['UTF-16']['ISO-8859-1'] = 'iconv_fallback_utf16_iso88591'; + $ConversionFunctionList['UTF-16']['UTF-8'] = 'iconv_fallback_utf16_utf8'; + $ConversionFunctionList['UTF-16LE']['ISO-8859-1'] = 'iconv_fallback_utf16le_iso88591'; + $ConversionFunctionList['UTF-16LE']['UTF-8'] = 'iconv_fallback_utf16le_utf8'; + $ConversionFunctionList['UTF-16BE']['ISO-8859-1'] = 'iconv_fallback_utf16be_iso88591'; + $ConversionFunctionList['UTF-16BE']['UTF-8'] = 'iconv_fallback_utf16be_utf8'; + } + if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) { + $ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)]; + return self::$ConversionFunction($string); + } + throw new Exception('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset); + } + + + public static function MultiByteCharString2HTML($string, $charset='ISO-8859-1') { + $string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string + $HTMLstring = ''; + + switch ($charset) { + case '1251': + case '1252': + case '866': + case '932': + case '936': + case '950': + case 'BIG5': + case 'BIG5-HKSCS': + case 'cp1251': + case 'cp1252': + case 'cp866': + case 'EUC-JP': + case 'EUCJP': + case 'GB2312': + case 'ibm866': + case 'ISO-8859-1': + case 'ISO-8859-15': + case 'ISO8859-1': + case 'ISO8859-15': + case 'KOI8-R': + case 'koi8-ru': + case 'koi8r': + case 'Shift_JIS': + case 'SJIS': + case 'win-1251': + case 'Windows-1251': + case 'Windows-1252': + $HTMLstring = htmlentities($string, ENT_COMPAT, $charset); + break; + + case 'UTF-8': + $strlen = strlen($string); + for ($i = 0; $i < $strlen; $i++) { + $char_ord_val = ord($string{$i}); + $charval = 0; + if ($char_ord_val < 0x80) { + $charval = $char_ord_val; + } elseif ((($char_ord_val & 0xF0) >> 4) == 0x0F && $i+3 < $strlen) { + $charval = (($char_ord_val & 0x07) << 18); + $charval += ((ord($string{++$i}) & 0x3F) << 12); + $charval += ((ord($string{++$i}) & 0x3F) << 6); + $charval += (ord($string{++$i}) & 0x3F); + } elseif ((($char_ord_val & 0xE0) >> 5) == 0x07 && $i+2 < $strlen) { + $charval = (($char_ord_val & 0x0F) << 12); + $charval += ((ord($string{++$i}) & 0x3F) << 6); + $charval += (ord($string{++$i}) & 0x3F); + } elseif ((($char_ord_val & 0xC0) >> 6) == 0x03 && $i+1 < $strlen) { + $charval = (($char_ord_val & 0x1F) << 6); + $charval += (ord($string{++$i}) & 0x3F); + } + if (($charval >= 32) && ($charval <= 127)) { + $HTMLstring .= htmlentities(chr($charval)); + } else { + $HTMLstring .= '&#'.$charval.';'; + } + } + break; + + case 'UTF-16LE': + for ($i = 0; $i < strlen($string); $i += 2) { + $charval = self::LittleEndian2Int(substr($string, $i, 2)); + if (($charval >= 32) && ($charval <= 127)) { + $HTMLstring .= chr($charval); + } else { + $HTMLstring .= '&#'.$charval.';'; + } + } + break; + + case 'UTF-16BE': + for ($i = 0; $i < strlen($string); $i += 2) { + $charval = self::BigEndian2Int(substr($string, $i, 2)); + if (($charval >= 32) && ($charval <= 127)) { + $HTMLstring .= chr($charval); + } else { + $HTMLstring .= '&#'.$charval.';'; + } + } + break; + + default: + $HTMLstring = 'ERROR: Character set "'.$charset.'" not supported in MultiByteCharString2HTML()'; + break; + } + return $HTMLstring; + } + + + + public static function RGADnameLookup($namecode) { + static $RGADname = array(); + if (empty($RGADname)) { + $RGADname[0] = 'not set'; + $RGADname[1] = 'Track Gain Adjustment'; + $RGADname[2] = 'Album Gain Adjustment'; + } + + return (isset($RGADname[$namecode]) ? $RGADname[$namecode] : ''); + } + + + public static function RGADoriginatorLookup($originatorcode) { + static $RGADoriginator = array(); + if (empty($RGADoriginator)) { + $RGADoriginator[0] = 'unspecified'; + $RGADoriginator[1] = 'pre-set by artist/producer/mastering engineer'; + $RGADoriginator[2] = 'set by user'; + $RGADoriginator[3] = 'determined automatically'; + } + + return (isset($RGADoriginator[$originatorcode]) ? $RGADoriginator[$originatorcode] : ''); + } + + + public static function RGADadjustmentLookup($rawadjustment, $signbit) { + $adjustment = $rawadjustment / 10; + if ($signbit == 1) { + $adjustment *= -1; + } + return (float) $adjustment; + } + + + public static function RGADgainString($namecode, $originatorcode, $replaygain) { + if ($replaygain < 0) { + $signbit = '1'; + } else { + $signbit = '0'; + } + $storedreplaygain = intval(round($replaygain * 10)); + $gainstring = str_pad(decbin($namecode), 3, '0', STR_PAD_LEFT); + $gainstring .= str_pad(decbin($originatorcode), 3, '0', STR_PAD_LEFT); + $gainstring .= $signbit; + $gainstring .= str_pad(decbin($storedreplaygain), 9, '0', STR_PAD_LEFT); + + return $gainstring; + } + + public static function RGADamplitude2dB($amplitude) { + return 20 * log10($amplitude); + } + + + public static function GetDataImageSize($imgData, &$imageinfo=array()) { + static $tempdir = ''; + if (empty($tempdir)) { + // yes this is ugly, feel free to suggest a better way + require_once(dirname(__FILE__).'/getid3.php'); + $getid3_temp = new getID3(); + $tempdir = $getid3_temp->tempdir; + unset($getid3_temp); + } + $GetDataImageSize = false; + if ($tempfilename = tempnam($tempdir, 'gI3')) { + if (is_writable($tempfilename) && is_file($tempfilename) && ($tmp = fopen($tempfilename, 'wb'))) { + fwrite($tmp, $imgData); + fclose($tmp); + $GetDataImageSize = @getimagesize($tempfilename, $imageinfo); + } + unlink($tempfilename); + } + return $GetDataImageSize; + } + + public static function ImageExtFromMime($mime_type) { + // temporary way, works OK for now, but should be reworked in the future + return str_replace(array('image/', 'x-', 'jpeg'), array('', '', 'jpg'), $mime_type); + } + + public static function ImageTypesLookup($imagetypeid) { + static $ImageTypesLookup = array(); + if (empty($ImageTypesLookup)) { + $ImageTypesLookup[1] = 'gif'; + $ImageTypesLookup[2] = 'jpeg'; + $ImageTypesLookup[3] = 'png'; + $ImageTypesLookup[4] = 'swf'; + $ImageTypesLookup[5] = 'psd'; + $ImageTypesLookup[6] = 'bmp'; + $ImageTypesLookup[7] = 'tiff (little-endian)'; + $ImageTypesLookup[8] = 'tiff (big-endian)'; + $ImageTypesLookup[9] = 'jpc'; + $ImageTypesLookup[10] = 'jp2'; + $ImageTypesLookup[11] = 'jpx'; + $ImageTypesLookup[12] = 'jb2'; + $ImageTypesLookup[13] = 'swc'; + $ImageTypesLookup[14] = 'iff'; + } + return (isset($ImageTypesLookup[$imagetypeid]) ? $ImageTypesLookup[$imagetypeid] : ''); + } + + public static function CopyTagsToComments(&$ThisFileInfo) { + + // Copy all entries from ['tags'] into common ['comments'] + if (!empty($ThisFileInfo['tags'])) { + foreach ($ThisFileInfo['tags'] as $tagtype => $tagarray) { + foreach ($tagarray as $tagname => $tagdata) { + foreach ($tagdata as $key => $value) { + if (!empty($value)) { + if (empty($ThisFileInfo['comments'][$tagname])) { + + // fall through and append value + + } elseif ($tagtype == 'id3v1') { + + $newvaluelength = strlen(trim($value)); + foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) { + $oldvaluelength = strlen(trim($existingvalue)); + if (($newvaluelength <= $oldvaluelength) && (substr($existingvalue, 0, $newvaluelength) == trim($value))) { + // new value is identical but shorter-than (or equal-length to) one already in comments - skip + break 2; + } + } + + } elseif (!is_array($value)) { + + $newvaluelength = strlen(trim($value)); + foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) { + $oldvaluelength = strlen(trim($existingvalue)); + if (($newvaluelength > $oldvaluelength) && (substr(trim($value), 0, strlen($existingvalue)) == $existingvalue)) { + $ThisFileInfo['comments'][$tagname][$existingkey] = trim($value); + break 2; + } + } + + } + if (is_array($value) || empty($ThisFileInfo['comments'][$tagname]) || !in_array(trim($value), $ThisFileInfo['comments'][$tagname])) { + $value = (is_string($value) ? trim($value) : $value); + $ThisFileInfo['comments'][$tagname][] = $value; + } + } + } + } + } + + // Copy to ['comments_html'] + foreach ($ThisFileInfo['comments'] as $field => $values) { + if ($field == 'picture') { + // pictures can take up a lot of space, and we don't need multiple copies of them + // let there be a single copy in [comments][picture], and not elsewhere + continue; + } + foreach ($values as $index => $value) { + if (is_array($value)) { + $ThisFileInfo['comments_html'][$field][$index] = $value; + } else { + $ThisFileInfo['comments_html'][$field][$index] = str_replace('�', '', self::MultiByteCharString2HTML($value, $ThisFileInfo['encoding'])); + } + } + } + } + return true; + } + + + public static function EmbeddedLookup($key, $begin, $end, $file, $name) { + + // Cached + static $cache; + if (isset($cache[$file][$name])) { + return (isset($cache[$file][$name][$key]) ? $cache[$file][$name][$key] : ''); + } + + // Init + $keylength = strlen($key); + $line_count = $end - $begin - 7; + + // Open php file + $fp = fopen($file, 'r'); + + // Discard $begin lines + for ($i = 0; $i < ($begin + 3); $i++) { + fgets($fp, 1024); + } + + // Loop thru line + while (0 < $line_count--) { + + // Read line + $line = ltrim(fgets($fp, 1024), "\t "); + + // METHOD A: only cache the matching key - less memory but slower on next lookup of not-previously-looked-up key + //$keycheck = substr($line, 0, $keylength); + //if ($key == $keycheck) { + // $cache[$file][$name][$keycheck] = substr($line, $keylength + 1); + // break; + //} + + // METHOD B: cache all keys in this lookup - more memory but faster on next lookup of not-previously-looked-up key + //$cache[$file][$name][substr($line, 0, $keylength)] = trim(substr($line, $keylength + 1)); + $explodedLine = explode("\t", $line, 2); + $ThisKey = (isset($explodedLine[0]) ? $explodedLine[0] : ''); + $ThisValue = (isset($explodedLine[1]) ? $explodedLine[1] : ''); + $cache[$file][$name][$ThisKey] = trim($ThisValue); + } + + // Close and return + fclose($fp); + return (isset($cache[$file][$name][$key]) ? $cache[$file][$name][$key] : ''); + } + + public static function IncludeDependency($filename, $sourcefile, $DieOnFailure=false) { + global $GETID3_ERRORARRAY; + + if (file_exists($filename)) { + if (include_once($filename)) { + return true; + } else { + $diemessage = basename($sourcefile).' depends on '.$filename.', which has errors'; + } + } else { + $diemessage = basename($sourcefile).' depends on '.$filename.', which is missing'; + } + if ($DieOnFailure) { + throw new Exception($diemessage); + } else { + $GETID3_ERRORARRAY[] = $diemessage; + } + return false; + } + + public static function trimNullByte($string) { + return trim($string, "\x00"); + } + + public static function getFileSizeSyscall($path) { + $filesize = false; + + if (GETID3_OS_ISWINDOWS) { + if (class_exists('COM')) { // From PHP 5.3.15 and 5.4.5, COM and DOTNET is no longer built into the php core.you have to add COM support in php.ini: + $filesystem = new COM('Scripting.FileSystemObject'); + $file = $filesystem->GetFile($path); + $filesize = $file->Size(); + unset($filesystem, $file); + } else { + $commandline = 'for %I in ('.escapeshellarg($path).') do @echo %~zI'; + } + } else { + $commandline = 'ls -l '.escapeshellarg($path).' | awk \'{print $5}\''; + } + if (isset($commandline)) { + $output = trim(`$commandline`); + if (ctype_digit($output)) { + $filesize = (float) $output; + } + } + return $filesize; + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/getid3.php b/extensions/TimedMediaHandler/libs/getid3/getid3.php new file mode 100644 index 00000000..be0dd5f0 --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/getid3.php @@ -0,0 +1,1776 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// // +// Please see readme.txt for more information // +// /// +///////////////////////////////////////////////////////////////// + +// define a constant rather than looking up every time it is needed +if (!defined('GETID3_OS_ISWINDOWS')) { + define('GETID3_OS_ISWINDOWS', (stripos(PHP_OS, 'WIN') === 0)); +} +// Get base path of getID3() - ONCE +if (!defined('GETID3_INCLUDEPATH')) { + define('GETID3_INCLUDEPATH', dirname(__FILE__).DIRECTORY_SEPARATOR); +} + +// attempt to define temp dir as something flexible but reliable +$temp_dir = ini_get('upload_tmp_dir'); +if ($temp_dir && (!is_dir($temp_dir) || !is_readable($temp_dir))) { + $temp_dir = ''; +} +if (!$temp_dir && function_exists('sys_get_temp_dir')) { + // PHP v5.2.1+ + // sys_get_temp_dir() may give inaccessible temp dir, e.g. with open_basedir on virtual hosts + $temp_dir = sys_get_temp_dir(); +} +$temp_dir = realpath($temp_dir); +$open_basedir = ini_get('open_basedir'); +if ($open_basedir) { + // e.g. "/var/www/vhosts/getid3.org/httpdocs/:/tmp/" + $temp_dir = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $temp_dir); + $open_basedir = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $open_basedir); + if (substr($temp_dir, -1, 1) != DIRECTORY_SEPARATOR) { + $temp_dir .= DIRECTORY_SEPARATOR; + } + $found_valid_tempdir = false; + $open_basedirs = explode(PATH_SEPARATOR, $open_basedir); + foreach ($open_basedirs as $basedir) { + if (substr($basedir, -1, 1) != DIRECTORY_SEPARATOR) { + $basedir .= DIRECTORY_SEPARATOR; + } + if (preg_match('#^'.preg_quote($basedir).'#', $temp_dir)) { + $found_valid_tempdir = true; + break; + } + } + if (!$found_valid_tempdir) { + $temp_dir = ''; + } + unset($open_basedirs, $found_valid_tempdir, $basedir); +} +if (!$temp_dir) { + $temp_dir = '*'; // invalid directory name should force tempnam() to use system default temp dir +} +// $temp_dir = '/something/else/'; // feel free to override temp dir here if it works better for your system +define('GETID3_TEMP_DIR', $temp_dir); +unset($open_basedir, $temp_dir); + +// End: Defines + + +class getID3 +{ + // public: Settings + public $encoding = 'UTF-8'; // CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples: ISO-8859-1 UTF-8 UTF-16 UTF-16BE + public $encoding_id3v1 = 'ISO-8859-1'; // Should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'EUC-CN' or 'CP1252' + + // public: Optional tag checks - disable for speed. + public $option_tag_id3v1 = true; // Read and process ID3v1 tags + public $option_tag_id3v2 = true; // Read and process ID3v2 tags + public $option_tag_lyrics3 = true; // Read and process Lyrics3 tags + public $option_tag_apetag = true; // Read and process APE tags + public $option_tags_process = true; // Copy tags to root key 'tags' and encode to $this->encoding + public $option_tags_html = true; // Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities + + // public: Optional tag/comment calucations + public $option_extra_info = true; // Calculate additional info such as bitrate, channelmode etc + + // public: Optional handling of embedded attachments (e.g. images) + public $option_save_attachments = true; // defaults to true (ATTACHMENTS_INLINE) for backward compatibility + + // public: Optional calculations + public $option_md5_data = false; // Get MD5 sum of data part - slow + public $option_md5_data_source = false; // Use MD5 of source file if availble - only FLAC and OptimFROG + public $option_sha1_data = false; // Get SHA1 sum of data part - slow + public $option_max_2gb_check = null; // Check whether file is larger than 2GB and thus not supported by 32-bit PHP (null: auto-detect based on PHP_INT_MAX) + + // public: Read buffer size in bytes + public $option_fread_buffer_size = 32768; + + // Public variables + public $filename; // Filename of file being analysed. + public $fp; // Filepointer to file being analysed. + public $info; // Result array. + public $tempdir = GETID3_TEMP_DIR; + + // Protected variables + protected $startup_error = ''; + protected $startup_warning = ''; + protected $memory_limit = 0; + + const VERSION = '1.9.6-20130603'; + const FREAD_BUFFER_SIZE = 32768; + + const ATTACHMENTS_NONE = false; + const ATTACHMENTS_INLINE = true; + + // public: constructor + public function __construct() { + + // Check for PHP version + $required_php_version = '5.0.5'; + if (version_compare(PHP_VERSION, $required_php_version, '<')) { + $this->startup_error .= 'getID3() requires PHP v'.$required_php_version.' or higher - you are running v'.PHP_VERSION; + return false; + } + + // Check memory + $this->memory_limit = ini_get('memory_limit'); + if (preg_match('#([0-9]+)M#i', $this->memory_limit, $matches)) { + // could be stored as "16M" rather than 16777216 for example + $this->memory_limit = $matches[1] * 1048576; + } elseif (preg_match('#([0-9]+)G#i', $this->memory_limit, $matches)) { // The 'G' modifier is available since PHP 5.1.0 + // could be stored as "2G" rather than 2147483648 for example + $this->memory_limit = $matches[1] * 1073741824; + } + if ($this->memory_limit <= 0) { + // memory limits probably disabled + } elseif ($this->memory_limit <= 4194304) { + $this->startup_error .= 'PHP has less than 4MB available memory and will very likely run out. Increase memory_limit in php.ini'; + } elseif ($this->memory_limit <= 12582912) { + $this->startup_warning .= 'PHP has less than 12MB available memory and might run out if all modules are loaded. Increase memory_limit in php.ini'; + } + + // Check safe_mode off + if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { + $this->warning('WARNING: Safe mode is on, shorten support disabled, md5data/sha1data for ogg vorbis disabled, ogg vorbos/flac tag writing disabled.'); + } + + if (intval(ini_get('mbstring.func_overload')) > 0) { + $this->warning('WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", this may break things.'); + } + + // Check for magic_quotes_runtime + if (function_exists('get_magic_quotes_runtime')) { + if (get_magic_quotes_runtime()) { + return $this->startup_error('magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).'); + } + } + + // Check for magic_quotes_gpc + if (function_exists('magic_quotes_gpc')) { + if (get_magic_quotes_gpc()) { + return $this->startup_error('magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).'); + } + } + + // Load support library + if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) { + $this->startup_error .= 'getid3.lib.php is missing or corrupt'; + } + + if ($this->option_max_2gb_check === null) { + $this->option_max_2gb_check = (PHP_INT_MAX <= 2147483647); + } + + + // Needed for Windows only: + // Define locations of helper applications for Shorten, VorbisComment, MetaFLAC + // as well as other helper functions such as head, tail, md5sum, etc + // This path cannot contain spaces, but the below code will attempt to get the + // 8.3-equivalent path automatically + // IMPORTANT: This path must include the trailing slash + if (GETID3_OS_ISWINDOWS && !defined('GETID3_HELPERAPPSDIR')) { + + $helperappsdir = GETID3_INCLUDEPATH.'..'.DIRECTORY_SEPARATOR.'helperapps'; // must not have any space in this path + + if (!is_dir($helperappsdir)) { + $this->startup_warning .= '"'.$helperappsdir.'" cannot be defined as GETID3_HELPERAPPSDIR because it does not exist'; + } elseif (strpos(realpath($helperappsdir), ' ') !== false) { + $DirPieces = explode(DIRECTORY_SEPARATOR, realpath($helperappsdir)); + $path_so_far = array(); + foreach ($DirPieces as $key => $value) { + if (strpos($value, ' ') !== false) { + if (!empty($path_so_far)) { + $commandline = 'dir /x '.escapeshellarg(implode(DIRECTORY_SEPARATOR, $path_so_far)); + $dir_listing = `$commandline`; + $lines = explode("\n", $dir_listing); + foreach ($lines as $line) { + $line = trim($line); + if (preg_match('#^([0-9/]{10}) +([0-9:]{4,5}( [AP]M)?) +(<DIR>|[0-9,]+) +([^ ]{0,11}) +(.+)$#', $line, $matches)) { + list($dummy, $date, $time, $ampm, $filesize, $shortname, $filename) = $matches; + if ((strtoupper($filesize) == '<DIR>') && (strtolower($filename) == strtolower($value))) { + $value = $shortname; + } + } + } + } else { + $this->startup_warning .= 'GETID3_HELPERAPPSDIR must not have any spaces in it - use 8dot3 naming convention if neccesary. You can run "dir /x" from the commandline to see the correct 8.3-style names.'; + } + } + $path_so_far[] = $value; + } + $helperappsdir = implode(DIRECTORY_SEPARATOR, $path_so_far); + } + define('GETID3_HELPERAPPSDIR', $helperappsdir.DIRECTORY_SEPARATOR); + } + + return true; + } + + public function version() { + return self::VERSION; + } + + public function fread_buffer_size() { + return $this->option_fread_buffer_size; + } + + + // public: setOption + public function setOption($optArray) { + if (!is_array($optArray) || empty($optArray)) { + return false; + } + foreach ($optArray as $opt => $val) { + if (isset($this->$opt) === false) { + continue; + } + $this->$opt = $val; + } + return true; + } + + + public function openfile($filename) { + try { + if (!empty($this->startup_error)) { + throw new getid3_exception($this->startup_error); + } + if (!empty($this->startup_warning)) { + $this->warning($this->startup_warning); + } + + // init result array and set parameters + $this->filename = $filename; + $this->info = array(); + $this->info['GETID3_VERSION'] = $this->version(); + $this->info['php_memory_limit'] = $this->memory_limit; + + // remote files not supported + if (preg_match('/^(ht|f)tp:\/\//', $filename)) { + throw new getid3_exception('Remote files are not supported - please copy the file locally first'); + } + + $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename); + $filename = preg_replace('#(.+)'.preg_quote(DIRECTORY_SEPARATOR).'{2,}#U', '\1'.DIRECTORY_SEPARATOR, $filename); + + // open local file + if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { + // great + } else { + throw new getid3_exception('Could not open "'.$filename.'" (does not exist, or is not a file)'); + } + + $this->info['filesize'] = filesize($filename); + // set redundant parameters - might be needed in some include file + $this->info['filename'] = basename($filename); + $this->info['filepath'] = str_replace('\\', '/', realpath(dirname($filename))); + $this->info['filenamepath'] = $this->info['filepath'].'/'.$this->info['filename']; + + + // option_max_2gb_check + if ($this->option_max_2gb_check) { + // PHP (32-bit all, and 64-bit Windows) doesn't support integers larger than 2^31 (~2GB) + // filesize() simply returns (filesize % (pow(2, 32)), no matter the actual filesize + // ftell() returns 0 if seeking to the end is beyond the range of unsigned integer + $fseek = fseek($this->fp, 0, SEEK_END); + if (($fseek < 0) || (($this->info['filesize'] != 0) && (ftell($this->fp) == 0)) || + ($this->info['filesize'] < 0) || + (ftell($this->fp) < 0)) { + $real_filesize = getid3_lib::getFileSizeSyscall($this->info['filenamepath']); + + if ($real_filesize === false) { + unset($this->info['filesize']); + fclose($this->fp); + throw new getid3_exception('Unable to determine actual filesize. File is most likely larger than '.round(PHP_INT_MAX / 1073741824).'GB and is not supported by PHP.'); + } elseif (getid3_lib::intValueSupported($real_filesize)) { + unset($this->info['filesize']); + fclose($this->fp); + throw new getid3_exception('PHP seems to think the file is larger than '.round(PHP_INT_MAX / 1073741824).'GB, but filesystem reports it as '.number_format($real_filesize, 3).'GB, please report to info@getid3.org'); + } + $this->info['filesize'] = $real_filesize; + $this->warning('File is larger than '.round(PHP_INT_MAX / 1073741824).'GB (filesystem reports it as '.number_format($real_filesize, 3).'GB) and is not properly supported by PHP.'); + } + } + + // set more parameters + $this->info['avdataoffset'] = 0; + $this->info['avdataend'] = $this->info['filesize']; + $this->info['fileformat'] = ''; // filled in later + $this->info['audio']['dataformat'] = ''; // filled in later, unset if not used + $this->info['video']['dataformat'] = ''; // filled in later, unset if not used + $this->info['tags'] = array(); // filled in later, unset if not used + $this->info['error'] = array(); // filled in later, unset if not used + $this->info['warning'] = array(); // filled in later, unset if not used + $this->info['comments'] = array(); // filled in later, unset if not used + $this->info['encoding'] = $this->encoding; // required by id3v2 and iso modules - can be unset at the end if desired + + return true; + + } catch (Exception $e) { + $this->error($e->getMessage()); + } + return false; + } + + // public: analyze file + public function analyze($filename) { + try { + if (!$this->openfile($filename)) { + return $this->info; + } + + // Handle tags + foreach (array('id3v2'=>'id3v2', 'id3v1'=>'id3v1', 'apetag'=>'ape', 'lyrics3'=>'lyrics3') as $tag_name => $tag_key) { + $option_tag = 'option_tag_'.$tag_name; + if ($this->$option_tag) { + $this->include_module('tag.'.$tag_name); + try { + $tag_class = 'getid3_'.$tag_name; + $tag = new $tag_class($this); + $tag->Analyze(); + } + catch (getid3_exception $e) { + throw $e; + } + } + } + if (isset($this->info['id3v2']['tag_offset_start'])) { + $this->info['avdataoffset'] = max($this->info['avdataoffset'], $this->info['id3v2']['tag_offset_end']); + } + foreach (array('id3v1'=>'id3v1', 'apetag'=>'ape', 'lyrics3'=>'lyrics3') as $tag_name => $tag_key) { + if (isset($this->info[$tag_key]['tag_offset_start'])) { + $this->info['avdataend'] = min($this->info['avdataend'], $this->info[$tag_key]['tag_offset_start']); + } + } + + // ID3v2 detection (NOT parsing), even if ($this->option_tag_id3v2 == false) done to make fileformat easier + if (!$this->option_tag_id3v2) { + fseek($this->fp, 0, SEEK_SET); + $header = fread($this->fp, 10); + if ((substr($header, 0, 3) == 'ID3') && (strlen($header) == 10)) { + $this->info['id3v2']['header'] = true; + $this->info['id3v2']['majorversion'] = ord($header{3}); + $this->info['id3v2']['minorversion'] = ord($header{4}); + $this->info['avdataoffset'] += getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length + } + } + + // read 32 kb file data + fseek($this->fp, $this->info['avdataoffset'], SEEK_SET); + $formattest = fread($this->fp, 32774); + + // determine format + $determined_format = $this->GetFileFormat($formattest, $filename); + + // unable to determine file format + if (!$determined_format) { + fclose($this->fp); + return $this->error('unable to determine file format'); + } + + // check for illegal ID3 tags + if (isset($determined_format['fail_id3']) && (in_array('id3v1', $this->info['tags']) || in_array('id3v2', $this->info['tags']))) { + if ($determined_format['fail_id3'] === 'ERROR') { + fclose($this->fp); + return $this->error('ID3 tags not allowed on this file type.'); + } elseif ($determined_format['fail_id3'] === 'WARNING') { + $this->warning('ID3 tags not allowed on this file type.'); + } + } + + // check for illegal APE tags + if (isset($determined_format['fail_ape']) && in_array('ape', $this->info['tags'])) { + if ($determined_format['fail_ape'] === 'ERROR') { + fclose($this->fp); + return $this->error('APE tags not allowed on this file type.'); + } elseif ($determined_format['fail_ape'] === 'WARNING') { + $this->warning('APE tags not allowed on this file type.'); + } + } + + // set mime type + $this->info['mime_type'] = $determined_format['mime_type']; + + // supported format signature pattern detected, but module deleted + if (!file_exists(GETID3_INCLUDEPATH.$determined_format['include'])) { + fclose($this->fp); + return $this->error('Format not supported, module "'.$determined_format['include'].'" was removed.'); + } + + // module requires iconv support + // Check encoding/iconv support + if (!empty($determined_format['iconv_req']) && !function_exists('iconv') && !in_array($this->encoding, array('ISO-8859-1', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'UTF-16'))) { + $errormessage = 'iconv() support is required for this module ('.$determined_format['include'].') for encodings other than ISO-8859-1, UTF-8, UTF-16LE, UTF16-BE, UTF-16. '; + if (GETID3_OS_ISWINDOWS) { + $errormessage .= 'PHP does not have iconv() support. Please enable php_iconv.dll in php.ini, and copy iconv.dll from c:/php/dlls to c:/windows/system32'; + } else { + $errormessage .= 'PHP is not compiled with iconv() support. Please recompile with the --with-iconv switch'; + } + return $this->error($errormessage); + } + + // include module + include_once(GETID3_INCLUDEPATH.$determined_format['include']); + + // instantiate module class + $class_name = 'getid3_'.$determined_format['module']; + if (!class_exists($class_name)) { + return $this->error('Format not supported, module "'.$determined_format['include'].'" is corrupt.'); + } + $class = new $class_name($this); + $class->Analyze(); + unset($class); + + // close file + fclose($this->fp); + + // process all tags - copy to 'tags' and convert charsets + if ($this->option_tags_process) { + $this->HandleAllTags(); + } + + // perform more calculations + if ($this->option_extra_info) { + $this->ChannelsBitratePlaytimeCalculations(); + $this->CalculateCompressionRatioVideo(); + $this->CalculateCompressionRatioAudio(); + $this->CalculateReplayGain(); + $this->ProcessAudioStreams(); + } + + // get the MD5 sum of the audio/video portion of the file - without ID3/APE/Lyrics3/etc header/footer tags + if ($this->option_md5_data) { + // do not calc md5_data if md5_data_source is present - set by flac only - future MPC/SV8 too + if (!$this->option_md5_data_source || empty($this->info['md5_data_source'])) { + $this->getHashdata('md5'); + } + } + + // get the SHA1 sum of the audio/video portion of the file - without ID3/APE/Lyrics3/etc header/footer tags + if ($this->option_sha1_data) { + $this->getHashdata('sha1'); + } + + // remove undesired keys + $this->CleanUp(); + + } catch (Exception $e) { + $this->error('Caught exception: '.$e->getMessage()); + } + + // return info array + return $this->info; + } + + + // private: error handling + public function error($message) { + $this->CleanUp(); + if (!isset($this->info['error'])) { + $this->info['error'] = array(); + } + $this->info['error'][] = $message; + return $this->info; + } + + + // private: warning handling + public function warning($message) { + $this->info['warning'][] = $message; + return true; + } + + + // private: CleanUp + private function CleanUp() { + + // remove possible empty keys + $AVpossibleEmptyKeys = array('dataformat', 'bits_per_sample', 'encoder_options', 'streams', 'bitrate'); + foreach ($AVpossibleEmptyKeys as $dummy => $key) { + if (empty($this->info['audio'][$key]) && isset($this->info['audio'][$key])) { + unset($this->info['audio'][$key]); + } + if (empty($this->info['video'][$key]) && isset($this->info['video'][$key])) { + unset($this->info['video'][$key]); + } + } + + // remove empty root keys + if (!empty($this->info)) { + foreach ($this->info as $key => $value) { + if (empty($this->info[$key]) && ($this->info[$key] !== 0) && ($this->info[$key] !== '0')) { + unset($this->info[$key]); + } + } + } + + // remove meaningless entries from unknown-format files + if (empty($this->info['fileformat'])) { + if (isset($this->info['avdataoffset'])) { + unset($this->info['avdataoffset']); + } + if (isset($this->info['avdataend'])) { + unset($this->info['avdataend']); + } + } + + // remove possible duplicated identical entries + if (!empty($this->info['error'])) { + $this->info['error'] = array_values(array_unique($this->info['error'])); + } + if (!empty($this->info['warning'])) { + $this->info['warning'] = array_values(array_unique($this->info['warning'])); + } + + // remove "global variable" type keys + unset($this->info['php_memory_limit']); + + return true; + } + + + // return array containing information about all supported formats + public function GetFileFormatArray() { + static $format_info = array(); + if (empty($format_info)) { + $format_info = array( + + // Audio formats + + // AC-3 - audio - Dolby AC-3 / Dolby Digital + 'ac3' => array( + 'pattern' => '^\x0B\x77', + 'group' => 'audio', + 'module' => 'ac3', + 'mime_type' => 'audio/ac3', + ), + + // AAC - audio - Advanced Audio Coding (AAC) - ADIF format + 'adif' => array( + 'pattern' => '^ADIF', + 'group' => 'audio', + 'module' => 'aac', + 'mime_type' => 'application/octet-stream', + 'fail_ape' => 'WARNING', + ), + +/* + // AA - audio - Audible Audiobook + 'aa' => array( + 'pattern' => '^.{4}\x57\x90\x75\x36', + 'group' => 'audio', + 'module' => 'aa', + 'mime_type' => 'audio/audible', + ), +*/ + // AAC - audio - Advanced Audio Coding (AAC) - ADTS format (very similar to MP3) + 'adts' => array( + 'pattern' => '^\xFF[\xF0-\xF1\xF8-\xF9]', + 'group' => 'audio', + 'module' => 'aac', + 'mime_type' => 'application/octet-stream', + 'fail_ape' => 'WARNING', + ), + + + // AU - audio - NeXT/Sun AUdio (AU) + 'au' => array( + 'pattern' => '^\.snd', + 'group' => 'audio', + 'module' => 'au', + 'mime_type' => 'audio/basic', + ), + + // AVR - audio - Audio Visual Research + 'avr' => array( + 'pattern' => '^2BIT', + 'group' => 'audio', + 'module' => 'avr', + 'mime_type' => 'application/octet-stream', + ), + + // BONK - audio - Bonk v0.9+ + 'bonk' => array( + 'pattern' => '^\x00(BONK|INFO|META| ID3)', + 'group' => 'audio', + 'module' => 'bonk', + 'mime_type' => 'audio/xmms-bonk', + ), + + // DSS - audio - Digital Speech Standard + 'dss' => array( + 'pattern' => '^[\x02-\x03]ds[s2]', + 'group' => 'audio', + 'module' => 'dss', + 'mime_type' => 'application/octet-stream', + ), + + // DTS - audio - Dolby Theatre System + 'dts' => array( + 'pattern' => '^\x7F\xFE\x80\x01', + 'group' => 'audio', + 'module' => 'dts', + 'mime_type' => 'audio/dts', + ), + + // FLAC - audio - Free Lossless Audio Codec + 'flac' => array( + 'pattern' => '^fLaC', + 'group' => 'audio', + 'module' => 'flac', + 'mime_type' => 'audio/x-flac', + ), + + // LA - audio - Lossless Audio (LA) + 'la' => array( + 'pattern' => '^LA0[2-4]', + 'group' => 'audio', + 'module' => 'la', + 'mime_type' => 'application/octet-stream', + ), + + // LPAC - audio - Lossless Predictive Audio Compression (LPAC) + 'lpac' => array( + 'pattern' => '^LPAC', + 'group' => 'audio', + 'module' => 'lpac', + 'mime_type' => 'application/octet-stream', + ), + + // MIDI - audio - MIDI (Musical Instrument Digital Interface) + 'midi' => array( + 'pattern' => '^MThd', + 'group' => 'audio', + 'module' => 'midi', + 'mime_type' => 'audio/midi', + ), + + // MAC - audio - Monkey's Audio Compressor + 'mac' => array( + 'pattern' => '^MAC ', + 'group' => 'audio', + 'module' => 'monkey', + 'mime_type' => 'application/octet-stream', + ), + +// has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available +// // MOD - audio - MODule (assorted sub-formats) +// 'mod' => array( +// 'pattern' => '^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)', +// 'group' => 'audio', +// 'module' => 'mod', +// 'option' => 'mod', +// 'mime_type' => 'audio/mod', +// ), + + // MOD - audio - MODule (Impulse Tracker) + 'it' => array( + 'pattern' => '^IMPM', + 'group' => 'audio', + 'module' => 'mod', + //'option' => 'it', + 'mime_type' => 'audio/it', + ), + + // MOD - audio - MODule (eXtended Module, various sub-formats) + 'xm' => array( + 'pattern' => '^Extended Module', + 'group' => 'audio', + 'module' => 'mod', + //'option' => 'xm', + 'mime_type' => 'audio/xm', + ), + + // MOD - audio - MODule (ScreamTracker) + 's3m' => array( + 'pattern' => '^.{44}SCRM', + 'group' => 'audio', + 'module' => 'mod', + //'option' => 's3m', + 'mime_type' => 'audio/s3m', + ), + + // MPC - audio - Musepack / MPEGplus + 'mpc' => array( + 'pattern' => '^(MPCK|MP\+|[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0])', + 'group' => 'audio', + 'module' => 'mpc', + 'mime_type' => 'audio/x-musepack', + ), + + // MP3 - audio - MPEG-audio Layer 3 (very similar to AAC-ADTS) + 'mp3' => array( + 'pattern' => '^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\x0B\x10-\x1B\x20-\x2B\x30-\x3B\x40-\x4B\x50-\x5B\x60-\x6B\x70-\x7B\x80-\x8B\x90-\x9B\xA0-\xAB\xB0-\xBB\xC0-\xCB\xD0-\xDB\xE0-\xEB\xF0-\xFB]', + 'group' => 'audio', + 'module' => 'mp3', + 'mime_type' => 'audio/mpeg', + ), + + // OFR - audio - OptimFROG + 'ofr' => array( + 'pattern' => '^(\*RIFF|OFR)', + 'group' => 'audio', + 'module' => 'optimfrog', + 'mime_type' => 'application/octet-stream', + ), + + // RKAU - audio - RKive AUdio compressor + 'rkau' => array( + 'pattern' => '^RKA', + 'group' => 'audio', + 'module' => 'rkau', + 'mime_type' => 'application/octet-stream', + ), + + // SHN - audio - Shorten + 'shn' => array( + 'pattern' => '^ajkg', + 'group' => 'audio', + 'module' => 'shorten', + 'mime_type' => 'audio/xmms-shn', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // TTA - audio - TTA Lossless Audio Compressor (http://tta.corecodec.org) + 'tta' => array( + 'pattern' => '^TTA', // could also be '^TTA(\x01|\x02|\x03|2|1)' + 'group' => 'audio', + 'module' => 'tta', + 'mime_type' => 'application/octet-stream', + ), + + // VOC - audio - Creative Voice (VOC) + 'voc' => array( + 'pattern' => '^Creative Voice File', + 'group' => 'audio', + 'module' => 'voc', + 'mime_type' => 'audio/voc', + ), + + // VQF - audio - transform-domain weighted interleave Vector Quantization Format (VQF) + 'vqf' => array( + 'pattern' => '^TWIN', + 'group' => 'audio', + 'module' => 'vqf', + 'mime_type' => 'application/octet-stream', + ), + + // WV - audio - WavPack (v4.0+) + 'wv' => array( + 'pattern' => '^wvpk', + 'group' => 'audio', + 'module' => 'wavpack', + 'mime_type' => 'application/octet-stream', + ), + + + // Audio-Video formats + + // ASF - audio/video - Advanced Streaming Format, Windows Media Video, Windows Media Audio + 'asf' => array( + 'pattern' => '^\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C', + 'group' => 'audio-video', + 'module' => 'asf', + 'mime_type' => 'video/x-ms-asf', + 'iconv_req' => false, + ), + + // BINK - audio/video - Bink / Smacker + 'bink' => array( + 'pattern' => '^(BIK|SMK)', + 'group' => 'audio-video', + 'module' => 'bink', + 'mime_type' => 'application/octet-stream', + ), + + // FLV - audio/video - FLash Video + 'flv' => array( + 'pattern' => '^FLV\x01', + 'group' => 'audio-video', + 'module' => 'flv', + 'mime_type' => 'video/x-flv', + ), + + // MKAV - audio/video - Mastroka + 'matroska' => array( + 'pattern' => '^\x1A\x45\xDF\xA3', + 'group' => 'audio-video', + 'module' => 'matroska', + 'mime_type' => 'video/x-matroska', // may also be audio/x-matroska + ), + + // MPEG - audio/video - MPEG (Moving Pictures Experts Group) + 'mpeg' => array( + 'pattern' => '^\x00\x00\x01(\xBA|\xB3)', + 'group' => 'audio-video', + 'module' => 'mpeg', + 'mime_type' => 'video/mpeg', + ), + + // NSV - audio/video - Nullsoft Streaming Video (NSV) + 'nsv' => array( + 'pattern' => '^NSV[sf]', + 'group' => 'audio-video', + 'module' => 'nsv', + 'mime_type' => 'application/octet-stream', + ), + + // Ogg - audio/video - Ogg (Ogg-Vorbis, Ogg-FLAC, Speex, Ogg-Theora(*), Ogg-Tarkin(*)) + 'ogg' => array( + 'pattern' => '^OggS', + 'group' => 'audio', + 'module' => 'ogg', + 'mime_type' => 'application/ogg', + 'fail_id3' => 'WARNING', + 'fail_ape' => 'WARNING', + ), + + // QT - audio/video - Quicktime + 'quicktime' => array( + 'pattern' => '^.{4}(cmov|free|ftyp|mdat|moov|pnot|skip|wide)', + 'group' => 'audio-video', + 'module' => 'quicktime', + 'mime_type' => 'video/quicktime', + ), + + // RIFF - audio/video - Resource Interchange File Format (RIFF) / WAV / AVI / CD-audio / SDSS = renamed variant used by SmartSound QuickTracks (www.smartsound.com) / FORM = Audio Interchange File Format (AIFF) + 'riff' => array( + 'pattern' => '^(RIFF|SDSS|FORM)', + 'group' => 'audio-video', + 'module' => 'riff', + 'mime_type' => 'audio/x-wave', + 'fail_ape' => 'WARNING', + ), + + // Real - audio/video - RealAudio, RealVideo + 'real' => array( + 'pattern' => '^(\\.RMF|\\.ra)', + 'group' => 'audio-video', + 'module' => 'real', + 'mime_type' => 'audio/x-realaudio', + ), + + // SWF - audio/video - ShockWave Flash + 'swf' => array( + 'pattern' => '^(F|C)WS', + 'group' => 'audio-video', + 'module' => 'swf', + 'mime_type' => 'application/x-shockwave-flash', + ), + + // TS - audio/video - MPEG-2 Transport Stream + 'ts' => array( + 'pattern' => '^(\x47.{187}){10,}', // packets are 188 bytes long and start with 0x47 "G". Check for at least 10 packets matching this pattern + 'group' => 'audio-video', + 'module' => 'ts', + 'mime_type' => 'video/MP2T', + ), + + + // Still-Image formats + + // BMP - still image - Bitmap (Windows, OS/2; uncompressed, RLE8, RLE4) + 'bmp' => array( + 'pattern' => '^BM', + 'group' => 'graphic', + 'module' => 'bmp', + 'mime_type' => 'image/bmp', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // GIF - still image - Graphics Interchange Format + 'gif' => array( + 'pattern' => '^GIF', + 'group' => 'graphic', + 'module' => 'gif', + 'mime_type' => 'image/gif', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // JPEG - still image - Joint Photographic Experts Group (JPEG) + 'jpg' => array( + 'pattern' => '^\xFF\xD8\xFF', + 'group' => 'graphic', + 'module' => 'jpg', + 'mime_type' => 'image/jpeg', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // PCD - still image - Kodak Photo CD + 'pcd' => array( + 'pattern' => '^.{2048}PCD_IPI\x00', + 'group' => 'graphic', + 'module' => 'pcd', + 'mime_type' => 'image/x-photo-cd', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + + // PNG - still image - Portable Network Graphics (PNG) + 'png' => array( + 'pattern' => '^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A', + 'group' => 'graphic', + 'module' => 'png', + 'mime_type' => 'image/png', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + + // SVG - still image - Scalable Vector Graphics (SVG) + 'svg' => array( + 'pattern' => '(<!DOCTYPE svg PUBLIC |xmlns="http:\/\/www\.w3\.org\/2000\/svg")', + 'group' => 'graphic', + 'module' => 'svg', + 'mime_type' => 'image/svg+xml', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + + // TIFF - still image - Tagged Information File Format (TIFF) + 'tiff' => array( + 'pattern' => '^(II\x2A\x00|MM\x00\x2A)', + 'group' => 'graphic', + 'module' => 'tiff', + 'mime_type' => 'image/tiff', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + + // EFAX - still image - eFax (TIFF derivative) + 'efax' => array( + 'pattern' => '^\xDC\xFE', + 'group' => 'graphic', + 'module' => 'efax', + 'mime_type' => 'image/efax', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + + // Data formats + + // ISO - data - International Standards Organization (ISO) CD-ROM Image + 'iso' => array( + 'pattern' => '^.{32769}CD001', + 'group' => 'misc', + 'module' => 'iso', + 'mime_type' => 'application/octet-stream', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + 'iconv_req' => false, + ), + + // RAR - data - RAR compressed data + 'rar' => array( + 'pattern' => '^Rar\!', + 'group' => 'archive', + 'module' => 'rar', + 'mime_type' => 'application/octet-stream', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // SZIP - audio/data - SZIP compressed data + 'szip' => array( + 'pattern' => '^SZ\x0A\x04', + 'group' => 'archive', + 'module' => 'szip', + 'mime_type' => 'application/octet-stream', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // TAR - data - TAR compressed data + 'tar' => array( + 'pattern' => '^.{100}[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20\x00]{12}[0-9\x20\x00]{12}', + 'group' => 'archive', + 'module' => 'tar', + 'mime_type' => 'application/x-tar', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // GZIP - data - GZIP compressed data + 'gz' => array( + 'pattern' => '^\x1F\x8B\x08', + 'group' => 'archive', + 'module' => 'gzip', + 'mime_type' => 'application/x-gzip', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // ZIP - data - ZIP compressed data + 'zip' => array( + 'pattern' => '^PK\x03\x04', + 'group' => 'archive', + 'module' => 'zip', + 'mime_type' => 'application/zip', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + + // Misc other formats + + // PAR2 - data - Parity Volume Set Specification 2.0 + 'par2' => array ( + 'pattern' => '^PAR2\x00PKT', + 'group' => 'misc', + 'module' => 'par2', + 'mime_type' => 'application/octet-stream', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // PDF - data - Portable Document Format + 'pdf' => array( + 'pattern' => '^\x25PDF', + 'group' => 'misc', + 'module' => 'pdf', + 'mime_type' => 'application/pdf', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // MSOFFICE - data - ZIP compressed data + 'msoffice' => array( + 'pattern' => '^\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1', // D0CF11E == DOCFILE == Microsoft Office Document + 'group' => 'misc', + 'module' => 'msoffice', + 'mime_type' => 'application/octet-stream', + 'fail_id3' => 'ERROR', + 'fail_ape' => 'ERROR', + ), + + // CUE - data - CUEsheet (index to single-file disc images) + 'cue' => array( + 'pattern' => '', // empty pattern means cannot be automatically detected, will fall through all other formats and match based on filename and very basic file contents + 'group' => 'misc', + 'module' => 'cue', + 'mime_type' => 'application/octet-stream', + ), + + ); + } + + return $format_info; + } + + + + public function GetFileFormat(&$filedata, $filename='') { + // this function will determine the format of a file based on usually + // the first 2-4 bytes of the file (8 bytes for PNG, 16 bytes for JPG, + // and in the case of ISO CD image, 6 bytes offset 32kb from the start + // of the file). + + // Identify file format - loop through $format_info and detect with reg expr + foreach ($this->GetFileFormatArray() as $format_name => $info) { + // The /s switch on preg_match() forces preg_match() NOT to treat + // newline (0x0A) characters as special chars but do a binary match + if (!empty($info['pattern']) && preg_match('#'.$info['pattern'].'#s', $filedata)) { + $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; + return $info; + } + } + + + if (preg_match('#\.mp[123a]$#i', $filename)) { + // Too many mp3 encoders on the market put gabage in front of mpeg files + // use assume format on these if format detection failed + $GetFileFormatArray = $this->GetFileFormatArray(); + $info = $GetFileFormatArray['mp3']; + $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; + return $info; + } elseif (preg_match('/\.cue$/i', $filename) && preg_match('#FILE "[^"]+" (BINARY|MOTOROLA|AIFF|WAVE|MP3)#', $filedata)) { + // there's not really a useful consistent "magic" at the beginning of .cue files to identify them + // so until I think of something better, just go by filename if all other format checks fail + // and verify there's at least one instance of "TRACK xx AUDIO" in the file + $GetFileFormatArray = $this->GetFileFormatArray(); + $info = $GetFileFormatArray['cue']; + $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; + return $info; + } + + return false; + } + + + // converts array to $encoding charset from $this->encoding + public function CharConvert(&$array, $encoding) { + + // identical encoding - end here + if ($encoding == $this->encoding) { + return; + } + + // loop thru array + foreach ($array as $key => $value) { + + // go recursive + if (is_array($value)) { + $this->CharConvert($array[$key], $encoding); + } + + // convert string + elseif (is_string($value)) { + $array[$key] = trim(getid3_lib::iconv_fallback($encoding, $this->encoding, $value)); + } + } + } + + + public function HandleAllTags() { + + // key name => array (tag name, character encoding) + static $tags; + if (empty($tags)) { + $tags = array( + 'asf' => array('asf' , 'UTF-16LE'), + 'midi' => array('midi' , 'ISO-8859-1'), + 'nsv' => array('nsv' , 'ISO-8859-1'), + 'ogg' => array('vorbiscomment' , 'UTF-8'), + 'png' => array('png' , 'UTF-8'), + 'tiff' => array('tiff' , 'ISO-8859-1'), + 'quicktime' => array('quicktime' , 'UTF-8'), + 'real' => array('real' , 'ISO-8859-1'), + 'vqf' => array('vqf' , 'ISO-8859-1'), + 'zip' => array('zip' , 'ISO-8859-1'), + 'riff' => array('riff' , 'ISO-8859-1'), + 'lyrics3' => array('lyrics3' , 'ISO-8859-1'), + 'id3v1' => array('id3v1' , $this->encoding_id3v1), + 'id3v2' => array('id3v2' , 'UTF-8'), // not according to the specs (every frame can have a different encoding), but getID3() force-converts all encodings to UTF-8 + 'ape' => array('ape' , 'UTF-8'), + 'cue' => array('cue' , 'ISO-8859-1'), + 'matroska' => array('matroska' , 'UTF-8'), + 'flac' => array('vorbiscomment' , 'UTF-8'), + 'divxtag' => array('divx' , 'ISO-8859-1'), + ); + } + + // loop through comments array + foreach ($tags as $comment_name => $tagname_encoding_array) { + list($tag_name, $encoding) = $tagname_encoding_array; + + // fill in default encoding type if not already present + if (isset($this->info[$comment_name]) && !isset($this->info[$comment_name]['encoding'])) { + $this->info[$comment_name]['encoding'] = $encoding; + } + + // copy comments if key name set + if (!empty($this->info[$comment_name]['comments'])) { + foreach ($this->info[$comment_name]['comments'] as $tag_key => $valuearray) { + foreach ($valuearray as $key => $value) { + if (is_string($value)) { + $value = trim($value, " \r\n\t"); // do not trim nulls from $value!! Unicode characters will get mangled if trailing nulls are removed! + } + if ($value) { + $this->info['tags'][trim($tag_name)][trim($tag_key)][] = $value; + } + } + if ($tag_key == 'picture') { + unset($this->info[$comment_name]['comments'][$tag_key]); + } + } + + if (!isset($this->info['tags'][$tag_name])) { + // comments are set but contain nothing but empty strings, so skip + continue; + } + + if ($this->option_tags_html) { + foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) { + foreach ($valuearray as $key => $value) { + if (is_string($value)) { + //$this->info['tags_html'][$tag_name][$tag_key][$key] = getid3_lib::MultiByteCharString2HTML($value, $encoding); + $this->info['tags_html'][$tag_name][$tag_key][$key] = str_replace('�', '', trim(getid3_lib::MultiByteCharString2HTML($value, $encoding))); + } else { + $this->info['tags_html'][$tag_name][$tag_key][$key] = $value; + } + } + } + } + + $this->CharConvert($this->info['tags'][$tag_name], $encoding); // only copy gets converted! + } + + } + + // pictures can take up a lot of space, and we don't need multiple copies of them + // let there be a single copy in [comments][picture], and not elsewhere + if (!empty($this->info['tags'])) { + $unset_keys = array('tags', 'tags_html'); + foreach ($this->info['tags'] as $tagtype => $tagarray) { + foreach ($tagarray as $tagname => $tagdata) { + if ($tagname == 'picture') { + foreach ($tagdata as $key => $tagarray) { + $this->info['comments']['picture'][] = $tagarray; + if (isset($tagarray['data']) && isset($tagarray['image_mime'])) { + if (isset($this->info['tags'][$tagtype][$tagname][$key])) { + unset($this->info['tags'][$tagtype][$tagname][$key]); + } + if (isset($this->info['tags_html'][$tagtype][$tagname][$key])) { + unset($this->info['tags_html'][$tagtype][$tagname][$key]); + } + } + } + } + } + foreach ($unset_keys as $unset_key) { + // remove possible empty keys from (e.g. [tags][id3v2][picture]) + if (empty($this->info[$unset_key][$tagtype]['picture'])) { + unset($this->info[$unset_key][$tagtype]['picture']); + } + if (empty($this->info[$unset_key][$tagtype])) { + unset($this->info[$unset_key][$tagtype]); + } + if (empty($this->info[$unset_key])) { + unset($this->info[$unset_key]); + } + } + // remove duplicate copy of picture data from (e.g. [id3v2][comments][picture]) + if (isset($this->info[$tagtype]['comments']['picture'])) { + unset($this->info[$tagtype]['comments']['picture']); + } + if (empty($this->info[$tagtype]['comments'])) { + unset($this->info[$tagtype]['comments']); + } + if (empty($this->info[$tagtype])) { + unset($this->info[$tagtype]); + } + } + } + return true; + } + + + public function getHashdata($algorithm) { + switch ($algorithm) { + case 'md5': + case 'sha1': + break; + + default: + return $this->error('bad algorithm "'.$algorithm.'" in getHashdata()'); + break; + } + + if (!empty($this->info['fileformat']) && !empty($this->info['dataformat']) && ($this->info['fileformat'] == 'ogg') && ($this->info['audio']['dataformat'] == 'vorbis')) { + + // We cannot get an identical md5_data value for Ogg files where the comments + // span more than 1 Ogg page (compared to the same audio data with smaller + // comments) using the normal getID3() method of MD5'ing the data between the + // end of the comments and the end of the file (minus any trailing tags), + // because the page sequence numbers of the pages that the audio data is on + // do not match. Under normal circumstances, where comments are smaller than + // the nominal 4-8kB page size, then this is not a problem, but if there are + // very large comments, the only way around it is to strip off the comment + // tags with vorbiscomment and MD5 that file. + // This procedure must be applied to ALL Ogg files, not just the ones with + // comments larger than 1 page, because the below method simply MD5's the + // whole file with the comments stripped, not just the portion after the + // comments block (which is the standard getID3() method. + + // The above-mentioned problem of comments spanning multiple pages and changing + // page sequence numbers likely happens for OggSpeex and OggFLAC as well, but + // currently vorbiscomment only works on OggVorbis files. + + if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { + + $this->warning('Failed making system call to vorbiscomment.exe - '.$algorithm.'_data is incorrect - error returned: PHP running in Safe Mode (backtick operator not available)'); + $this->info[$algorithm.'_data'] = false; + + } else { + + // Prevent user from aborting script + $old_abort = ignore_user_abort(true); + + // Create empty file + $empty = tempnam(GETID3_TEMP_DIR, 'getID3'); + touch($empty); + + // Use vorbiscomment to make temp file without comments + $temp = tempnam(GETID3_TEMP_DIR, 'getID3'); + $file = $this->info['filenamepath']; + + if (GETID3_OS_ISWINDOWS) { + + if (file_exists(GETID3_HELPERAPPSDIR.'vorbiscomment.exe')) { + + $commandline = '"'.GETID3_HELPERAPPSDIR.'vorbiscomment.exe" -w -c "'.$empty.'" "'.$file.'" "'.$temp.'"'; + $VorbisCommentError = `$commandline`; + + } else { + + $VorbisCommentError = 'vorbiscomment.exe not found in '.GETID3_HELPERAPPSDIR; + + } + + } else { + + $commandline = 'vorbiscomment -w -c "'.$empty.'" "'.$file.'" "'.$temp.'" 2>&1'; + $commandline = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg($file).' '.escapeshellarg($temp).' 2>&1'; + $VorbisCommentError = `$commandline`; + + } + + if (!empty($VorbisCommentError)) { + + $this->info['warning'][] = 'Failed making system call to vorbiscomment(.exe) - '.$algorithm.'_data will be incorrect. If vorbiscomment is unavailable, please download from http://www.vorbis.com/download.psp and put in the getID3() directory. Error returned: '.$VorbisCommentError; + $this->info[$algorithm.'_data'] = false; + + } else { + + // Get hash of newly created file + switch ($algorithm) { + case 'md5': + $this->info[$algorithm.'_data'] = md5_file($temp); + break; + + case 'sha1': + $this->info[$algorithm.'_data'] = sha1_file($temp); + break; + } + } + + // Clean up + unlink($empty); + unlink($temp); + + // Reset abort setting + ignore_user_abort($old_abort); + + } + + } else { + + if (!empty($this->info['avdataoffset']) || (isset($this->info['avdataend']) && ($this->info['avdataend'] < $this->info['filesize']))) { + + // get hash from part of file + $this->info[$algorithm.'_data'] = getid3_lib::hash_data($this->info['filenamepath'], $this->info['avdataoffset'], $this->info['avdataend'], $algorithm); + + } else { + + // get hash from whole file + switch ($algorithm) { + case 'md5': + $this->info[$algorithm.'_data'] = md5_file($this->info['filenamepath']); + break; + + case 'sha1': + $this->info[$algorithm.'_data'] = sha1_file($this->info['filenamepath']); + break; + } + } + + } + return true; + } + + + public function ChannelsBitratePlaytimeCalculations() { + + // set channelmode on audio + if (!empty($this->info['audio']['channelmode']) || !isset($this->info['audio']['channels'])) { + // ignore + } elseif ($this->info['audio']['channels'] == 1) { + $this->info['audio']['channelmode'] = 'mono'; + } elseif ($this->info['audio']['channels'] == 2) { + $this->info['audio']['channelmode'] = 'stereo'; + } + + // Calculate combined bitrate - audio + video + $CombinedBitrate = 0; + $CombinedBitrate += (isset($this->info['audio']['bitrate']) ? $this->info['audio']['bitrate'] : 0); + $CombinedBitrate += (isset($this->info['video']['bitrate']) ? $this->info['video']['bitrate'] : 0); + if (($CombinedBitrate > 0) && empty($this->info['bitrate'])) { + $this->info['bitrate'] = $CombinedBitrate; + } + //if ((isset($this->info['video']) && !isset($this->info['video']['bitrate'])) || (isset($this->info['audio']) && !isset($this->info['audio']['bitrate']))) { + // // for example, VBR MPEG video files cannot determine video bitrate: + // // should not set overall bitrate and playtime from audio bitrate only + // unset($this->info['bitrate']); + //} + + // video bitrate undetermined, but calculable + if (isset($this->info['video']['dataformat']) && $this->info['video']['dataformat'] && (!isset($this->info['video']['bitrate']) || ($this->info['video']['bitrate'] == 0))) { + // if video bitrate not set + if (isset($this->info['audio']['bitrate']) && ($this->info['audio']['bitrate'] > 0) && ($this->info['audio']['bitrate'] == $this->info['bitrate'])) { + // AND if audio bitrate is set to same as overall bitrate + if (isset($this->info['playtime_seconds']) && ($this->info['playtime_seconds'] > 0)) { + // AND if playtime is set + if (isset($this->info['avdataend']) && isset($this->info['avdataoffset'])) { + // AND if AV data offset start/end is known + // THEN we can calculate the video bitrate + $this->info['bitrate'] = round((($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds']); + $this->info['video']['bitrate'] = $this->info['bitrate'] - $this->info['audio']['bitrate']; + } + } + } + } + + if ((!isset($this->info['playtime_seconds']) || ($this->info['playtime_seconds'] <= 0)) && !empty($this->info['bitrate'])) { + $this->info['playtime_seconds'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['bitrate']; + } + + if (!isset($this->info['bitrate']) && !empty($this->info['playtime_seconds'])) { + $this->info['bitrate'] = (($this->info['avdataend'] - $this->info['avdataoffset']) * 8) / $this->info['playtime_seconds']; + } + if (isset($this->info['bitrate']) && empty($this->info['audio']['bitrate']) && empty($this->info['video']['bitrate'])) { + if (isset($this->info['audio']['dataformat']) && empty($this->info['video']['resolution_x'])) { + // audio only + $this->info['audio']['bitrate'] = $this->info['bitrate']; + } elseif (isset($this->info['video']['resolution_x']) && empty($this->info['audio']['dataformat'])) { + // video only + $this->info['video']['bitrate'] = $this->info['bitrate']; + } + } + + // Set playtime string + if (!empty($this->info['playtime_seconds']) && empty($this->info['playtime_string'])) { + $this->info['playtime_string'] = getid3_lib::PlaytimeString($this->info['playtime_seconds']); + } + } + + + public function CalculateCompressionRatioVideo() { + if (empty($this->info['video'])) { + return false; + } + if (empty($this->info['video']['resolution_x']) || empty($this->info['video']['resolution_y'])) { + return false; + } + if (empty($this->info['video']['bits_per_sample'])) { + return false; + } + + switch ($this->info['video']['dataformat']) { + case 'bmp': + case 'gif': + case 'jpeg': + case 'jpg': + case 'png': + case 'tiff': + $FrameRate = 1; + $PlaytimeSeconds = 1; + $BitrateCompressed = $this->info['filesize'] * 8; + break; + + default: + if (!empty($this->info['video']['frame_rate'])) { + $FrameRate = $this->info['video']['frame_rate']; + } else { + return false; + } + if (!empty($this->info['playtime_seconds'])) { + $PlaytimeSeconds = $this->info['playtime_seconds']; + } else { + return false; + } + if (!empty($this->info['video']['bitrate'])) { + $BitrateCompressed = $this->info['video']['bitrate']; + } else { + return false; + } + break; + } + $BitrateUncompressed = $this->info['video']['resolution_x'] * $this->info['video']['resolution_y'] * $this->info['video']['bits_per_sample'] * $FrameRate; + + $this->info['video']['compression_ratio'] = $BitrateCompressed / $BitrateUncompressed; + return true; + } + + + public function CalculateCompressionRatioAudio() { + if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate']) || !is_numeric($this->info['audio']['sample_rate'])) { + return false; + } + $this->info['audio']['compression_ratio'] = $this->info['audio']['bitrate'] / ($this->info['audio']['channels'] * $this->info['audio']['sample_rate'] * (!empty($this->info['audio']['bits_per_sample']) ? $this->info['audio']['bits_per_sample'] : 16)); + + if (!empty($this->info['audio']['streams'])) { + foreach ($this->info['audio']['streams'] as $streamnumber => $streamdata) { + if (!empty($streamdata['bitrate']) && !empty($streamdata['channels']) && !empty($streamdata['sample_rate'])) { + $this->info['audio']['streams'][$streamnumber]['compression_ratio'] = $streamdata['bitrate'] / ($streamdata['channels'] * $streamdata['sample_rate'] * (!empty($streamdata['bits_per_sample']) ? $streamdata['bits_per_sample'] : 16)); + } + } + } + return true; + } + + + public function CalculateReplayGain() { + if (isset($this->info['replay_gain'])) { + if (!isset($this->info['replay_gain']['reference_volume'])) { + $this->info['replay_gain']['reference_volume'] = (double) 89.0; + } + if (isset($this->info['replay_gain']['track']['adjustment'])) { + $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment']; + } + if (isset($this->info['replay_gain']['album']['adjustment'])) { + $this->info['replay_gain']['album']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['album']['adjustment']; + } + + if (isset($this->info['replay_gain']['track']['peak'])) { + $this->info['replay_gain']['track']['max_noclip_gain'] = 0 - getid3_lib::RGADamplitude2dB($this->info['replay_gain']['track']['peak']); + } + if (isset($this->info['replay_gain']['album']['peak'])) { + $this->info['replay_gain']['album']['max_noclip_gain'] = 0 - getid3_lib::RGADamplitude2dB($this->info['replay_gain']['album']['peak']); + } + } + return true; + } + + public function ProcessAudioStreams() { + if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) { + if (!isset($this->info['audio']['streams'])) { + foreach ($this->info['audio'] as $key => $value) { + if ($key != 'streams') { + $this->info['audio']['streams'][0][$key] = $value; + } + } + } + } + return true; + } + + public function getid3_tempnam() { + return tempnam($this->tempdir, 'gI3'); + } + + public function include_module($name) { + //if (!file_exists($this->include_path.'module.'.$name.'.php')) { + if (!file_exists(GETID3_INCLUDEPATH.'module.'.$name.'.php')) { + throw new getid3_exception('Required module.'.$name.'.php is missing.'); + } + include_once(GETID3_INCLUDEPATH.'module.'.$name.'.php'); + return true; + } + +} + + +abstract class getid3_handler +{ + protected $getid3; // pointer + + protected $data_string_flag = false; // analyzing filepointer or string + protected $data_string = ''; // string to analyze + protected $data_string_position = 0; // seek position in string + protected $data_string_length = 0; // string length + + private $dependency_to = null; + + + public function __construct(getID3 $getid3, $call_module=null) { + $this->getid3 = $getid3; + + if ($call_module) { + $this->dependency_to = str_replace('getid3_', '', $call_module); + } + } + + + // Analyze from file pointer + abstract public function Analyze(); + + + // Analyze from string instead + public function AnalyzeString($string) { + // Enter string mode + $this->setStringMode($string); + + // Save info + $saved_avdataoffset = $this->getid3->info['avdataoffset']; + $saved_avdataend = $this->getid3->info['avdataend']; + $saved_filesize = (isset($this->getid3->info['filesize']) ? $this->getid3->info['filesize'] : null); // may be not set if called as dependency without openfile() call + + // Reset some info + $this->getid3->info['avdataoffset'] = 0; + $this->getid3->info['avdataend'] = $this->getid3->info['filesize'] = $this->data_string_length; + + // Analyze + $this->Analyze(); + + // Restore some info + $this->getid3->info['avdataoffset'] = $saved_avdataoffset; + $this->getid3->info['avdataend'] = $saved_avdataend; + $this->getid3->info['filesize'] = $saved_filesize; + + // Exit string mode + $this->data_string_flag = false; + } + + public function setStringMode($string) { + $this->data_string_flag = true; + $this->data_string = $string; + $this->data_string_length = strlen($string); + } + + protected function ftell() { + if ($this->data_string_flag) { + return $this->data_string_position; + } + return ftell($this->getid3->fp); + } + + protected function fread($bytes) { + if ($this->data_string_flag) { + $this->data_string_position += $bytes; + return substr($this->data_string, $this->data_string_position - $bytes, $bytes); + } + $pos = $this->ftell() + $bytes; + if (!getid3_lib::intValueSupported($pos)) { + throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') because beyond PHP filesystem limit', 10); + } + return fread($this->getid3->fp, $bytes); + } + + protected function fseek($bytes, $whence=SEEK_SET) { + if ($this->data_string_flag) { + switch ($whence) { + case SEEK_SET: + $this->data_string_position = $bytes; + break; + + case SEEK_CUR: + $this->data_string_position += $bytes; + break; + + case SEEK_END: + $this->data_string_position = $this->data_string_length + $bytes; + break; + } + return 0; + } else { + $pos = $bytes; + if ($whence == SEEK_CUR) { + $pos = $this->ftell() + $bytes; + } elseif ($whence == SEEK_END) { + $pos = $this->info['filesize'] + $bytes; + } + if (!getid3_lib::intValueSupported($pos)) { + throw new getid3_exception('cannot fseek('.$pos.') because beyond PHP filesystem limit', 10); + } + } + return fseek($this->getid3->fp, $bytes, $whence); + } + + protected function feof() { + if ($this->data_string_flag) { + return $this->data_string_position >= $this->data_string_length; + } + return feof($this->getid3->fp); + } + + final protected function isDependencyFor($module) { + return $this->dependency_to == $module; + } + + protected function error($text) + { + $this->getid3->info['error'][] = $text; + + return false; + } + + protected function warning($text) + { + return $this->getid3->warning($text); + } + + protected function notice($text) + { + // does nothing for now + } + + public function saveAttachment($name, $offset, $length, $image_mime=null) { + try { + + // do not extract at all + if ($this->getid3->option_save_attachments === getID3::ATTACHMENTS_NONE) { + + $attachment = null; // do not set any + + // extract to return array + } elseif ($this->getid3->option_save_attachments === getID3::ATTACHMENTS_INLINE) { + + $this->fseek($offset); + $attachment = $this->fread($length); // get whole data in one pass, till it is anyway stored in memory + if ($attachment === false || strlen($attachment) != $length) { + throw new Exception('failed to read attachment data'); + } + + // assume directory path is given + } else { + + // set up destination path + $dir = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->getid3->option_save_attachments), DIRECTORY_SEPARATOR); + if (!is_dir($dir) || !is_writable($dir)) { // check supplied directory + throw new Exception('supplied path ('.$dir.') does not exist, or is not writable'); + } + $dest = $dir.DIRECTORY_SEPARATOR.$name.($image_mime ? '.'.getid3_lib::ImageExtFromMime($image_mime) : ''); + + // create dest file + if (($fp_dest = fopen($dest, 'wb')) == false) { + throw new Exception('failed to create file '.$dest); + } + + // copy data + $this->fseek($offset); + $buffersize = ($this->data_string_flag ? $length : $this->getid3->fread_buffer_size()); + $bytesleft = $length; + while ($bytesleft > 0) { + if (($buffer = $this->fread(min($buffersize, $bytesleft))) === false || ($byteswritten = fwrite($fp_dest, $buffer)) === false || ($byteswritten === 0)) { + throw new Exception($buffer === false ? 'not enough data to read' : 'failed to write to destination file, may be not enough disk space'); + } + $bytesleft -= $byteswritten; + } + + fclose($fp_dest); + $attachment = $dest; + + } + + } catch (Exception $e) { + + // close and remove dest file if created + if (isset($fp_dest) && is_resource($fp_dest)) { + fclose($fp_dest); + unlink($dest); + } + + // do not set any is case of error + $attachment = null; + $this->warning('Failed to extract attachment '.$name.': '.$e->getMessage()); + + } + + // seek to the end of attachment + $this->fseek($offset + $length); + + return $attachment; + } + +} + + +class getid3_exception extends Exception +{ + public $message; +} diff --git a/extensions/TimedMediaHandler/libs/getid3/license.txt b/extensions/TimedMediaHandler/libs/getid3/license.txt new file mode 100644 index 00000000..f349faab --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/license.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey 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) <year> <name of author> + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License.
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio-video.matroska.php b/extensions/TimedMediaHandler/libs/getid3/module.audio-video.matroska.php new file mode 100644 index 00000000..3c1921fb --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio-video.matroska.php @@ -0,0 +1,1771 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio-video.matriska.php // +// module for analyzing Matroska containers // +// dependencies: NONE // +// /// +///////////////////////////////////////////////////////////////// + + +define('EBML_ID_CHAPTERS', 0x0043A770); // [10][43][A7][70] -- A system to define basic menus and partition data. For more detailed information, look at the Chapters Explanation. +define('EBML_ID_SEEKHEAD', 0x014D9B74); // [11][4D][9B][74] -- Contains the position of other level 1 elements. +define('EBML_ID_TAGS', 0x0254C367); // [12][54][C3][67] -- Element containing elements specific to Tracks/Chapters. A list of valid tags can be found <http://www.matroska.org/technical/specs/tagging/index.html>. +define('EBML_ID_INFO', 0x0549A966); // [15][49][A9][66] -- Contains miscellaneous general information and statistics on the file. +define('EBML_ID_TRACKS', 0x0654AE6B); // [16][54][AE][6B] -- A top-level block of information with many tracks described. +define('EBML_ID_SEGMENT', 0x08538067); // [18][53][80][67] -- This element contains all other top-level (level 1) elements. Typically a Matroska file is composed of 1 segment. +define('EBML_ID_ATTACHMENTS', 0x0941A469); // [19][41][A4][69] -- Contain attached files. +define('EBML_ID_EBML', 0x0A45DFA3); // [1A][45][DF][A3] -- Set the EBML characteristics of the data to follow. Each EBML document has to start with this. +define('EBML_ID_CUES', 0x0C53BB6B); // [1C][53][BB][6B] -- A top-level element to speed seeking access. All entries are local to the segment. +define('EBML_ID_CLUSTER', 0x0F43B675); // [1F][43][B6][75] -- The lower level element containing the (monolithic) Block structure. +define('EBML_ID_LANGUAGE', 0x02B59C); // [22][B5][9C] -- Specifies the language of the track in the Matroska languages form. +define('EBML_ID_TRACKTIMECODESCALE', 0x03314F); // [23][31][4F] -- The scale to apply on this track to work at normal speed in relation with other tracks (mostly used to adjust video speed when the audio length differs). +define('EBML_ID_DEFAULTDURATION', 0x03E383); // [23][E3][83] -- Number of nanoseconds (i.e. not scaled) per frame. +define('EBML_ID_CODECNAME', 0x058688); // [25][86][88] -- A human-readable string specifying the codec. +define('EBML_ID_CODECDOWNLOADURL', 0x06B240); // [26][B2][40] -- A URL to download about the codec used. +define('EBML_ID_TIMECODESCALE', 0x0AD7B1); // [2A][D7][B1] -- Timecode scale in nanoseconds (1.000.000 means all timecodes in the segment are expressed in milliseconds). +define('EBML_ID_COLOURSPACE', 0x0EB524); // [2E][B5][24] -- Same value as in AVI (32 bits). +define('EBML_ID_GAMMAVALUE', 0x0FB523); // [2F][B5][23] -- Gamma Value. +define('EBML_ID_CODECSETTINGS', 0x1A9697); // [3A][96][97] -- A string describing the encoding setting used. +define('EBML_ID_CODECINFOURL', 0x1B4040); // [3B][40][40] -- A URL to find information about the codec used. +define('EBML_ID_PREVFILENAME', 0x1C83AB); // [3C][83][AB] -- An escaped filename corresponding to the previous segment. +define('EBML_ID_PREVUID', 0x1CB923); // [3C][B9][23] -- A unique ID to identify the previous chained segment (128 bits). +define('EBML_ID_NEXTFILENAME', 0x1E83BB); // [3E][83][BB] -- An escaped filename corresponding to the next segment. +define('EBML_ID_NEXTUID', 0x1EB923); // [3E][B9][23] -- A unique ID to identify the next chained segment (128 bits). +define('EBML_ID_CONTENTCOMPALGO', 0x0254); // [42][54] -- The compression algorithm used. Algorithms that have been specified so far are: +define('EBML_ID_CONTENTCOMPSETTINGS', 0x0255); // [42][55] -- Settings that might be needed by the decompressor. For Header Stripping (ContentCompAlgo=3), the bytes that were removed from the beggining of each frames of the track. +define('EBML_ID_DOCTYPE', 0x0282); // [42][82] -- A string that describes the type of document that follows this EBML header ('matroska' in our case). +define('EBML_ID_DOCTYPEREADVERSION', 0x0285); // [42][85] -- The minimum DocType version an interpreter has to support to read this file. +define('EBML_ID_EBMLVERSION', 0x0286); // [42][86] -- The version of EBML parser used to create the file. +define('EBML_ID_DOCTYPEVERSION', 0x0287); // [42][87] -- The version of DocType interpreter used to create the file. +define('EBML_ID_EBMLMAXIDLENGTH', 0x02F2); // [42][F2] -- The maximum length of the IDs you'll find in this file (4 or less in Matroska). +define('EBML_ID_EBMLMAXSIZELENGTH', 0x02F3); // [42][F3] -- The maximum length of the sizes you'll find in this file (8 or less in Matroska). This does not override the element size indicated at the beginning of an element. Elements that have an indicated size which is larger than what is allowed by EBMLMaxSizeLength shall be considered invalid. +define('EBML_ID_EBMLREADVERSION', 0x02F7); // [42][F7] -- The minimum EBML version a parser has to support to read this file. +define('EBML_ID_CHAPLANGUAGE', 0x037C); // [43][7C] -- The languages corresponding to the string, in the bibliographic ISO-639-2 form. +define('EBML_ID_CHAPCOUNTRY', 0x037E); // [43][7E] -- The countries corresponding to the string, same 2 octets as in Internet domains. +define('EBML_ID_SEGMENTFAMILY', 0x0444); // [44][44] -- A randomly generated unique ID that all segments related to each other must use (128 bits). +define('EBML_ID_DATEUTC', 0x0461); // [44][61] -- Date of the origin of timecode (value 0), i.e. production date. +define('EBML_ID_TAGLANGUAGE', 0x047A); // [44][7A] -- Specifies the language of the tag specified, in the Matroska languages form. +define('EBML_ID_TAGDEFAULT', 0x0484); // [44][84] -- Indication to know if this is the default/original language to use for the given tag. +define('EBML_ID_TAGBINARY', 0x0485); // [44][85] -- The values of the Tag if it is binary. Note that this cannot be used in the same SimpleTag as TagString. +define('EBML_ID_TAGSTRING', 0x0487); // [44][87] -- The value of the Tag. +define('EBML_ID_DURATION', 0x0489); // [44][89] -- Duration of the segment (based on TimecodeScale). +define('EBML_ID_CHAPPROCESSPRIVATE', 0x050D); // [45][0D] -- Some optional data attached to the ChapProcessCodecID information. For ChapProcessCodecID = 1, it is the "DVD level" equivalent. +define('EBML_ID_CHAPTERFLAGENABLED', 0x0598); // [45][98] -- Specify wether the chapter is enabled. It can be enabled/disabled by a Control Track. When disabled, the movie should skip all the content between the TimeStart and TimeEnd of this chapter. +define('EBML_ID_TAGNAME', 0x05A3); // [45][A3] -- The name of the Tag that is going to be stored. +define('EBML_ID_EDITIONENTRY', 0x05B9); // [45][B9] -- Contains all information about a segment edition. +define('EBML_ID_EDITIONUID', 0x05BC); // [45][BC] -- A unique ID to identify the edition. It's useful for tagging an edition. +define('EBML_ID_EDITIONFLAGHIDDEN', 0x05BD); // [45][BD] -- If an edition is hidden (1), it should not be available to the user interface (but still to Control Tracks). +define('EBML_ID_EDITIONFLAGDEFAULT', 0x05DB); // [45][DB] -- If a flag is set (1) the edition should be used as the default one. +define('EBML_ID_EDITIONFLAGORDERED', 0x05DD); // [45][DD] -- Specify if the chapters can be defined multiple times and the order to play them is enforced. +define('EBML_ID_FILEDATA', 0x065C); // [46][5C] -- The data of the file. +define('EBML_ID_FILEMIMETYPE', 0x0660); // [46][60] -- MIME type of the file. +define('EBML_ID_FILENAME', 0x066E); // [46][6E] -- Filename of the attached file. +define('EBML_ID_FILEREFERRAL', 0x0675); // [46][75] -- A binary value that a track/codec can refer to when the attachment is needed. +define('EBML_ID_FILEDESCRIPTION', 0x067E); // [46][7E] -- A human-friendly name for the attached file. +define('EBML_ID_FILEUID', 0x06AE); // [46][AE] -- Unique ID representing the file, as random as possible. +define('EBML_ID_CONTENTENCALGO', 0x07E1); // [47][E1] -- The encryption algorithm used. The value '0' means that the contents have not been encrypted but only signed. Predefined values: +define('EBML_ID_CONTENTENCKEYID', 0x07E2); // [47][E2] -- For public key algorithms this is the ID of the public key the the data was encrypted with. +define('EBML_ID_CONTENTSIGNATURE', 0x07E3); // [47][E3] -- A cryptographic signature of the contents. +define('EBML_ID_CONTENTSIGKEYID', 0x07E4); // [47][E4] -- This is the ID of the private key the data was signed with. +define('EBML_ID_CONTENTSIGALGO', 0x07E5); // [47][E5] -- The algorithm used for the signature. A value of '0' means that the contents have not been signed but only encrypted. Predefined values: +define('EBML_ID_CONTENTSIGHASHALGO', 0x07E6); // [47][E6] -- The hash algorithm used for the signature. A value of '0' means that the contents have not been signed but only encrypted. Predefined values: +define('EBML_ID_MUXINGAPP', 0x0D80); // [4D][80] -- Muxing application or library ("libmatroska-0.4.3"). +define('EBML_ID_SEEK', 0x0DBB); // [4D][BB] -- Contains a single seek entry to an EBML element. +define('EBML_ID_CONTENTENCODINGORDER', 0x1031); // [50][31] -- Tells when this modification was used during encoding/muxing starting with 0 and counting upwards. The decoder/demuxer has to start with the highest order number it finds and work its way down. This value has to be unique over all ContentEncodingOrder elements in the segment. +define('EBML_ID_CONTENTENCODINGSCOPE', 0x1032); // [50][32] -- A bit field that describes which elements have been modified in this way. Values (big endian) can be OR'ed. Possible values: +define('EBML_ID_CONTENTENCODINGTYPE', 0x1033); // [50][33] -- A value describing what kind of transformation has been done. Possible values: +define('EBML_ID_CONTENTCOMPRESSION', 0x1034); // [50][34] -- Settings describing the compression used. Must be present if the value of ContentEncodingType is 0 and absent otherwise. Each block must be decompressable even if no previous block is available in order not to prevent seeking. +define('EBML_ID_CONTENTENCRYPTION', 0x1035); // [50][35] -- Settings describing the encryption used. Must be present if the value of ContentEncodingType is 1 and absent otherwise. +define('EBML_ID_CUEREFNUMBER', 0x135F); // [53][5F] -- Number of the referenced Block of Track X in the specified Cluster. +define('EBML_ID_NAME', 0x136E); // [53][6E] -- A human-readable track name. +define('EBML_ID_CUEBLOCKNUMBER', 0x1378); // [53][78] -- Number of the Block in the specified Cluster. +define('EBML_ID_TRACKOFFSET', 0x137F); // [53][7F] -- A value to add to the Block's Timecode. This can be used to adjust the playback offset of a track. +define('EBML_ID_SEEKID', 0x13AB); // [53][AB] -- The binary ID corresponding to the element name. +define('EBML_ID_SEEKPOSITION', 0x13AC); // [53][AC] -- The position of the element in the segment in octets (0 = first level 1 element). +define('EBML_ID_STEREOMODE', 0x13B8); // [53][B8] -- Stereo-3D video mode. +define('EBML_ID_OLDSTEREOMODE', 0x13B9); // [53][B9] -- Bogus StereoMode value used in old versions of libmatroska. DO NOT USE. (0: mono, 1: right eye, 2: left eye, 3: both eyes). +define('EBML_ID_PIXELCROPBOTTOM', 0x14AA); // [54][AA] -- The number of video pixels to remove at the bottom of the image (for HDTV content). +define('EBML_ID_DISPLAYWIDTH', 0x14B0); // [54][B0] -- Width of the video frames to display. +define('EBML_ID_DISPLAYUNIT', 0x14B2); // [54][B2] -- Type of the unit for DisplayWidth/Height (0: pixels, 1: centimeters, 2: inches). +define('EBML_ID_ASPECTRATIOTYPE', 0x14B3); // [54][B3] -- Specify the possible modifications to the aspect ratio (0: free resizing, 1: keep aspect ratio, 2: fixed). +define('EBML_ID_DISPLAYHEIGHT', 0x14BA); // [54][BA] -- Height of the video frames to display. +define('EBML_ID_PIXELCROPTOP', 0x14BB); // [54][BB] -- The number of video pixels to remove at the top of the image. +define('EBML_ID_PIXELCROPLEFT', 0x14CC); // [54][CC] -- The number of video pixels to remove on the left of the image. +define('EBML_ID_PIXELCROPRIGHT', 0x14DD); // [54][DD] -- The number of video pixels to remove on the right of the image. +define('EBML_ID_FLAGFORCED', 0x15AA); // [55][AA] -- Set if that track MUST be used during playback. There can be many forced track for a kind (audio, video or subs), the player should select the one which language matches the user preference or the default + forced track. Overlay MAY happen between a forced and non-forced track of the same kind. +define('EBML_ID_MAXBLOCKADDITIONID', 0x15EE); // [55][EE] -- The maximum value of BlockAddID. A value 0 means there is no BlockAdditions for this track. +define('EBML_ID_WRITINGAPP', 0x1741); // [57][41] -- Writing application ("mkvmerge-0.3.3"). +define('EBML_ID_CLUSTERSILENTTRACKS', 0x1854); // [58][54] -- The list of tracks that are not used in that part of the stream. It is useful when using overlay tracks on seeking. Then you should decide what track to use. +define('EBML_ID_CLUSTERSILENTTRACKNUMBER', 0x18D7); // [58][D7] -- One of the track number that are not used from now on in the stream. It could change later if not specified as silent in a further Cluster. +define('EBML_ID_ATTACHEDFILE', 0x21A7); // [61][A7] -- An attached file. +define('EBML_ID_CONTENTENCODING', 0x2240); // [62][40] -- Settings for one content encoding like compression or encryption. +define('EBML_ID_BITDEPTH', 0x2264); // [62][64] -- Bits per sample, mostly used for PCM. +define('EBML_ID_CODECPRIVATE', 0x23A2); // [63][A2] -- Private data only known to the codec. +define('EBML_ID_TARGETS', 0x23C0); // [63][C0] -- Contain all UIDs where the specified meta data apply. It is void to describe everything in the segment. +define('EBML_ID_CHAPTERPHYSICALEQUIV', 0x23C3); // [63][C3] -- Specify the physical equivalent of this ChapterAtom like "DVD" (60) or "SIDE" (50), see complete list of values. +define('EBML_ID_TAGCHAPTERUID', 0x23C4); // [63][C4] -- A unique ID to identify the Chapter(s) the tags belong to. If the value is 0 at this level, the tags apply to all chapters in the Segment. +define('EBML_ID_TAGTRACKUID', 0x23C5); // [63][C5] -- A unique ID to identify the Track(s) the tags belong to. If the value is 0 at this level, the tags apply to all tracks in the Segment. +define('EBML_ID_TAGATTACHMENTUID', 0x23C6); // [63][C6] -- A unique ID to identify the Attachment(s) the tags belong to. If the value is 0 at this level, the tags apply to all the attachments in the Segment. +define('EBML_ID_TAGEDITIONUID', 0x23C9); // [63][C9] -- A unique ID to identify the EditionEntry(s) the tags belong to. If the value is 0 at this level, the tags apply to all editions in the Segment. +define('EBML_ID_TARGETTYPE', 0x23CA); // [63][CA] -- An informational string that can be used to display the logical level of the target like "ALBUM", "TRACK", "MOVIE", "CHAPTER", etc (see TargetType). +define('EBML_ID_TRACKTRANSLATE', 0x2624); // [66][24] -- The track identification for the given Chapter Codec. +define('EBML_ID_TRACKTRANSLATETRACKID', 0x26A5); // [66][A5] -- The binary value used to represent this track in the chapter codec data. The format depends on the ChapProcessCodecID used. +define('EBML_ID_TRACKTRANSLATECODEC', 0x26BF); // [66][BF] -- The chapter codec using this ID (0: Matroska Script, 1: DVD-menu). +define('EBML_ID_TRACKTRANSLATEEDITIONUID', 0x26FC); // [66][FC] -- Specify an edition UID on which this translation applies. When not specified, it means for all editions found in the segment. +define('EBML_ID_SIMPLETAG', 0x27C8); // [67][C8] -- Contains general information about the target. +define('EBML_ID_TARGETTYPEVALUE', 0x28CA); // [68][CA] -- A number to indicate the logical level of the target (see TargetType). +define('EBML_ID_CHAPPROCESSCOMMAND', 0x2911); // [69][11] -- Contains all the commands associated to the Atom. +define('EBML_ID_CHAPPROCESSTIME', 0x2922); // [69][22] -- Defines when the process command should be handled (0: during the whole chapter, 1: before starting playback, 2: after playback of the chapter). +define('EBML_ID_CHAPTERTRANSLATE', 0x2924); // [69][24] -- A tuple of corresponding ID used by chapter codecs to represent this segment. +define('EBML_ID_CHAPPROCESSDATA', 0x2933); // [69][33] -- Contains the command information. The data should be interpreted depending on the ChapProcessCodecID value. For ChapProcessCodecID = 1, the data correspond to the binary DVD cell pre/post commands. +define('EBML_ID_CHAPPROCESS', 0x2944); // [69][44] -- Contains all the commands associated to the Atom. +define('EBML_ID_CHAPPROCESSCODECID', 0x2955); // [69][55] -- Contains the type of the codec used for the processing. A value of 0 means native Matroska processing (to be defined), a value of 1 means the DVD command set is used. More codec IDs can be added later. +define('EBML_ID_CHAPTERTRANSLATEID', 0x29A5); // [69][A5] -- The binary value used to represent this segment in the chapter codec data. The format depends on the ChapProcessCodecID used. +define('EBML_ID_CHAPTERTRANSLATECODEC', 0x29BF); // [69][BF] -- The chapter codec using this ID (0: Matroska Script, 1: DVD-menu). +define('EBML_ID_CHAPTERTRANSLATEEDITIONUID', 0x29FC); // [69][FC] -- Specify an edition UID on which this correspondance applies. When not specified, it means for all editions found in the segment. +define('EBML_ID_CONTENTENCODINGS', 0x2D80); // [6D][80] -- Settings for several content encoding mechanisms like compression or encryption. +define('EBML_ID_MINCACHE', 0x2DE7); // [6D][E7] -- The minimum number of frames a player should be able to cache during playback. If set to 0, the reference pseudo-cache system is not used. +define('EBML_ID_MAXCACHE', 0x2DF8); // [6D][F8] -- The maximum cache size required to store referenced frames in and the current frame. 0 means no cache is needed. +define('EBML_ID_CHAPTERSEGMENTUID', 0x2E67); // [6E][67] -- A segment to play in place of this chapter. Edition ChapterSegmentEditionUID should be used for this segment, otherwise no edition is used. +define('EBML_ID_CHAPTERSEGMENTEDITIONUID', 0x2EBC); // [6E][BC] -- The edition to play from the segment linked in ChapterSegmentUID. +define('EBML_ID_TRACKOVERLAY', 0x2FAB); // [6F][AB] -- Specify that this track is an overlay track for the Track specified (in the u-integer). That means when this track has a gap (see SilentTracks) the overlay track should be used instead. The order of multiple TrackOverlay matters, the first one is the one that should be used. If not found it should be the second, etc. +define('EBML_ID_TAG', 0x3373); // [73][73] -- Element containing elements specific to Tracks/Chapters. +define('EBML_ID_SEGMENTFILENAME', 0x3384); // [73][84] -- A filename corresponding to this segment. +define('EBML_ID_SEGMENTUID', 0x33A4); // [73][A4] -- A randomly generated unique ID to identify the current segment between many others (128 bits). +define('EBML_ID_CHAPTERUID', 0x33C4); // [73][C4] -- A unique ID to identify the Chapter. +define('EBML_ID_TRACKUID', 0x33C5); // [73][C5] -- A unique ID to identify the Track. This should be kept the same when making a direct stream copy of the Track to another file. +define('EBML_ID_ATTACHMENTLINK', 0x3446); // [74][46] -- The UID of an attachment that is used by this codec. +define('EBML_ID_CLUSTERBLOCKADDITIONS', 0x35A1); // [75][A1] -- Contain additional blocks to complete the main one. An EBML parser that has no knowledge of the Block structure could still see and use/skip these data. +define('EBML_ID_CHANNELPOSITIONS', 0x347B); // [7D][7B] -- Table of horizontal angles for each successive channel, see appendix. +define('EBML_ID_OUTPUTSAMPLINGFREQUENCY', 0x38B5); // [78][B5] -- Real output sampling frequency in Hz (used for SBR techniques). +define('EBML_ID_TITLE', 0x3BA9); // [7B][A9] -- General name of the segment. +define('EBML_ID_CHAPTERDISPLAY', 0x00); // [80] -- Contains all possible strings to use for the chapter display. +define('EBML_ID_TRACKTYPE', 0x03); // [83] -- A set of track types coded on 8 bits (1: video, 2: audio, 3: complex, 0x10: logo, 0x11: subtitle, 0x12: buttons, 0x20: control). +define('EBML_ID_CHAPSTRING', 0x05); // [85] -- Contains the string to use as the chapter atom. +define('EBML_ID_CODECID', 0x06); // [86] -- An ID corresponding to the codec, see the codec page for more info. +define('EBML_ID_FLAGDEFAULT', 0x08); // [88] -- Set if that track (audio, video or subs) SHOULD be used if no language found matches the user preference. +define('EBML_ID_CHAPTERTRACKNUMBER', 0x09); // [89] -- UID of the Track to apply this chapter too. In the absense of a control track, choosing this chapter will select the listed Tracks and deselect unlisted tracks. Absense of this element indicates that the Chapter should be applied to any currently used Tracks. +define('EBML_ID_CLUSTERSLICES', 0x0E); // [8E] -- Contains slices description. +define('EBML_ID_CHAPTERTRACK', 0x0F); // [8F] -- List of tracks on which the chapter applies. If this element is not present, all tracks apply +define('EBML_ID_CHAPTERTIMESTART', 0x11); // [91] -- Timecode of the start of Chapter (not scaled). +define('EBML_ID_CHAPTERTIMEEND', 0x12); // [92] -- Timecode of the end of Chapter (timecode excluded, not scaled). +define('EBML_ID_CUEREFTIME', 0x16); // [96] -- Timecode of the referenced Block. +define('EBML_ID_CUEREFCLUSTER', 0x17); // [97] -- Position of the Cluster containing the referenced Block. +define('EBML_ID_CHAPTERFLAGHIDDEN', 0x18); // [98] -- If a chapter is hidden (1), it should not be available to the user interface (but still to Control Tracks). +define('EBML_ID_FLAGINTERLACED', 0x1A); // [9A] -- Set if the video is interlaced. +define('EBML_ID_CLUSTERBLOCKDURATION', 0x1B); // [9B] -- The duration of the Block (based on TimecodeScale). This element is mandatory when DefaultDuration is set for the track. When not written and with no DefaultDuration, the value is assumed to be the difference between the timecode of this Block and the timecode of the next Block in "display" order (not coding order). This element can be useful at the end of a Track (as there is not other Block available), or when there is a break in a track like for subtitle tracks. +define('EBML_ID_FLAGLACING', 0x1C); // [9C] -- Set if the track may contain blocks using lacing. +define('EBML_ID_CHANNELS', 0x1F); // [9F] -- Numbers of channels in the track. +define('EBML_ID_CLUSTERBLOCKGROUP', 0x20); // [A0] -- Basic container of information containing a single Block or BlockVirtual, and information specific to that Block/VirtualBlock. +define('EBML_ID_CLUSTERBLOCK', 0x21); // [A1] -- Block containing the actual data to be rendered and a timecode relative to the Cluster Timecode. +define('EBML_ID_CLUSTERBLOCKVIRTUAL', 0x22); // [A2] -- A Block with no data. It must be stored in the stream at the place the real Block should be in display order. +define('EBML_ID_CLUSTERSIMPLEBLOCK', 0x23); // [A3] -- Similar to Block but without all the extra information, mostly used to reduced overhead when no extra feature is needed. +define('EBML_ID_CLUSTERCODECSTATE', 0x24); // [A4] -- The new codec state to use. Data interpretation is private to the codec. This information should always be referenced by a seek entry. +define('EBML_ID_CLUSTERBLOCKADDITIONAL', 0x25); // [A5] -- Interpreted by the codec as it wishes (using the BlockAddID). +define('EBML_ID_CLUSTERBLOCKMORE', 0x26); // [A6] -- Contain the BlockAdditional and some parameters. +define('EBML_ID_CLUSTERPOSITION', 0x27); // [A7] -- Position of the Cluster in the segment (0 in live broadcast streams). It might help to resynchronise offset on damaged streams. +define('EBML_ID_CODECDECODEALL', 0x2A); // [AA] -- The codec can decode potentially damaged data. +define('EBML_ID_CLUSTERPREVSIZE', 0x2B); // [AB] -- Size of the previous Cluster, in octets. Can be useful for backward playing. +define('EBML_ID_TRACKENTRY', 0x2E); // [AE] -- Describes a track with all elements. +define('EBML_ID_CLUSTERENCRYPTEDBLOCK', 0x2F); // [AF] -- Similar to SimpleBlock but the data inside the Block are Transformed (encrypt and/or signed). +define('EBML_ID_PIXELWIDTH', 0x30); // [B0] -- Width of the encoded video frames in pixels. +define('EBML_ID_CUETIME', 0x33); // [B3] -- Absolute timecode according to the segment time base. +define('EBML_ID_SAMPLINGFREQUENCY', 0x35); // [B5] -- Sampling frequency in Hz. +define('EBML_ID_CHAPTERATOM', 0x36); // [B6] -- Contains the atom information to use as the chapter atom (apply to all tracks). +define('EBML_ID_CUETRACKPOSITIONS', 0x37); // [B7] -- Contain positions for different tracks corresponding to the timecode. +define('EBML_ID_FLAGENABLED', 0x39); // [B9] -- Set if the track is used. +define('EBML_ID_PIXELHEIGHT', 0x3A); // [BA] -- Height of the encoded video frames in pixels. +define('EBML_ID_CUEPOINT', 0x3B); // [BB] -- Contains all information relative to a seek point in the segment. +define('EBML_ID_CRC32', 0x3F); // [BF] -- The CRC is computed on all the data of the Master element it's in, regardless of its position. It's recommended to put the CRC value at the beggining of the Master element for easier reading. All level 1 elements should include a CRC-32. +define('EBML_ID_CLUSTERBLOCKADDITIONID', 0x4B); // [CB] -- The ID of the BlockAdditional element (0 is the main Block). +define('EBML_ID_CLUSTERLACENUMBER', 0x4C); // [CC] -- The reverse number of the frame in the lace (0 is the last frame, 1 is the next to last, etc). While there are a few files in the wild with this element, it is no longer in use and has been deprecated. Being able to interpret this element is not required for playback. +define('EBML_ID_CLUSTERFRAMENUMBER', 0x4D); // [CD] -- The number of the frame to generate from this lace with this delay (allow you to generate many frames from the same Block/Frame). +define('EBML_ID_CLUSTERDELAY', 0x4E); // [CE] -- The (scaled) delay to apply to the element. +define('EBML_ID_CLUSTERDURATION', 0x4F); // [CF] -- The (scaled) duration to apply to the element. +define('EBML_ID_TRACKNUMBER', 0x57); // [D7] -- The track number as used in the Block Header (using more than 127 tracks is not encouraged, though the design allows an unlimited number). +define('EBML_ID_CUEREFERENCE', 0x5B); // [DB] -- The Clusters containing the required referenced Blocks. +define('EBML_ID_VIDEO', 0x60); // [E0] -- Video settings. +define('EBML_ID_AUDIO', 0x61); // [E1] -- Audio settings. +define('EBML_ID_CLUSTERTIMESLICE', 0x68); // [E8] -- Contains extra time information about the data contained in the Block. While there are a few files in the wild with this element, it is no longer in use and has been deprecated. Being able to interpret this element is not required for playback. +define('EBML_ID_CUECODECSTATE', 0x6A); // [EA] -- The position of the Codec State corresponding to this Cue element. 0 means that the data is taken from the initial Track Entry. +define('EBML_ID_CUEREFCODECSTATE', 0x6B); // [EB] -- The position of the Codec State corresponding to this referenced element. 0 means that the data is taken from the initial Track Entry. +define('EBML_ID_VOID', 0x6C); // [EC] -- Used to void damaged data, to avoid unexpected behaviors when using damaged data. The content is discarded. Also used to reserve space in a sub-element for later use. +define('EBML_ID_CLUSTERTIMECODE', 0x67); // [E7] -- Absolute timecode of the cluster (based on TimecodeScale). +define('EBML_ID_CLUSTERBLOCKADDID', 0x6E); // [EE] -- An ID to identify the BlockAdditional level. +define('EBML_ID_CUECLUSTERPOSITION', 0x71); // [F1] -- The position of the Cluster containing the required Block. +define('EBML_ID_CUETRACK', 0x77); // [F7] -- The track for which a position is given. +define('EBML_ID_CLUSTERREFERENCEPRIORITY', 0x7A); // [FA] -- This frame is referenced and has the specified cache priority. In cache only a frame of the same or higher priority can replace this frame. A value of 0 means the frame is not referenced. +define('EBML_ID_CLUSTERREFERENCEBLOCK', 0x7B); // [FB] -- Timecode of another frame used as a reference (ie: B or P frame). The timecode is relative to the block it's attached to. +define('EBML_ID_CLUSTERREFERENCEVIRTUAL', 0x7D); // [FD] -- Relative position of the data that should be in position of the virtual block. + + +/** +* @tutorial http://www.matroska.org/technical/specs/index.html +* +* @todo Rewrite EBML parser to reduce it's size and honor default element values +* @todo After rewrite implement stream size calculation, that will provide additional useful info and enable AAC/FLAC audio bitrate detection +*/ +class getid3_matroska extends getid3_handler +{ + // public options + public static $hide_clusters = true; // if true, do not return information about CLUSTER chunks, since there's a lot of them and they're not usually useful [default: TRUE] + public static $parse_whole_file = false; // true to parse the whole file, not only header [default: FALSE] + + // private parser settings/placeholders + private $EBMLbuffer = ''; + private $EBMLbuffer_offset = 0; + private $EBMLbuffer_length = 0; + private $current_offset = 0; + private $unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID); + + public function Analyze() + { + $info = &$this->getid3->info; + + // parse container + try { + $this->parseEBML($info); + } catch (Exception $e) { + $info['error'][] = 'EBML parser: '.$e->getMessage(); + } + + // calculate playtime + if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) { + foreach ($info['matroska']['info'] as $key => $infoarray) { + if (isset($infoarray['Duration'])) { + // TimecodeScale is how many nanoseconds each Duration unit is + $info['playtime_seconds'] = $infoarray['Duration'] * ((isset($infoarray['TimecodeScale']) ? $infoarray['TimecodeScale'] : 1000000) / 1000000000); + break; + } + } + } + + // extract tags + if (isset($info['matroska']['tags']) && is_array($info['matroska']['tags'])) { + foreach ($info['matroska']['tags'] as $key => $infoarray) { + $this->ExtractCommentsSimpleTag($infoarray); + } + } + + // process tracks + if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) { + foreach ($info['matroska']['tracks']['tracks'] as $key => $trackarray) { + + $track_info = array(); + $track_info['dataformat'] = self::CodecIDtoCommonName($trackarray['CodecID']); + $track_info['default'] = (isset($trackarray['FlagDefault']) ? $trackarray['FlagDefault'] : true); + if (isset($trackarray['Name'])) { $track_info['name'] = $trackarray['Name']; } + + switch ($trackarray['TrackType']) { + + case 1: // Video + $track_info['resolution_x'] = $trackarray['PixelWidth']; + $track_info['resolution_y'] = $trackarray['PixelHeight']; + $track_info['display_unit'] = self::displayUnit(isset($trackarray['DisplayUnit']) ? $trackarray['DisplayUnit'] : 0); + $track_info['display_x'] = (isset($trackarray['DisplayWidth']) ? $trackarray['DisplayWidth'] : $trackarray['PixelWidth']); + $track_info['display_y'] = (isset($trackarray['DisplayHeight']) ? $trackarray['DisplayHeight'] : $trackarray['PixelHeight']); + + if (isset($trackarray['PixelCropBottom'])) { $track_info['crop_bottom'] = $trackarray['PixelCropBottom']; } + if (isset($trackarray['PixelCropTop'])) { $track_info['crop_top'] = $trackarray['PixelCropTop']; } + if (isset($trackarray['PixelCropLeft'])) { $track_info['crop_left'] = $trackarray['PixelCropLeft']; } + if (isset($trackarray['PixelCropRight'])) { $track_info['crop_right'] = $trackarray['PixelCropRight']; } + if (isset($trackarray['DefaultDuration'])) { $track_info['frame_rate'] = round(1000000000 / $trackarray['DefaultDuration'], 3); } + if (isset($trackarray['CodecName'])) { $track_info['codec'] = $trackarray['CodecName']; } + + switch ($trackarray['CodecID']) { + case 'V_MS/VFW/FOURCC': + if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, false)) { + $this->warning('Unable to parse codec private data ['.basename(__FILE__).':'.__LINE__.'] because cannot include "module.audio-video.riff.php"'); + break; + } + $parsed = getid3_riff::ParseBITMAPINFOHEADER($trackarray['CodecPrivate']); + $track_info['codec'] = getid3_riff::fourccLookup($parsed['fourcc']); + $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed; + break; + + /*case 'V_MPEG4/ISO/AVC': + $h264['profile'] = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 1, 1)); + $h264['level'] = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 3, 1)); + $rn = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 4, 1)); + $h264['NALUlength'] = ($rn & 3) + 1; + $rn = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 5, 1)); + $nsps = ($rn & 31); + $offset = 6; + for ($i = 0; $i < $nsps; $i ++) { + $length = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 2)); + $h264['SPS'][] = substr($trackarray['CodecPrivate'], $offset + 2, $length); + $offset += 2 + $length; + } + $npps = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 1)); + $offset += 1; + for ($i = 0; $i < $npps; $i ++) { + $length = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 2)); + $h264['PPS'][] = substr($trackarray['CodecPrivate'], $offset + 2, $length); + $offset += 2 + $length; + } + $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $h264; + break;*/ + } + + $info['video']['streams'][] = $track_info; + break; + + case 2: // Audio + $track_info['sample_rate'] = (isset($trackarray['SamplingFrequency']) ? $trackarray['SamplingFrequency'] : 8000.0); + $track_info['channels'] = (isset($trackarray['Channels']) ? $trackarray['Channels'] : 1); + $track_info['language'] = (isset($trackarray['Language']) ? $trackarray['Language'] : 'eng'); + if (isset($trackarray['BitDepth'])) { $track_info['bits_per_sample'] = $trackarray['BitDepth']; } + if (isset($trackarray['CodecName'])) { $track_info['codec'] = $trackarray['CodecName']; } + + switch ($trackarray['CodecID']) { + case 'A_PCM/INT/LIT': + case 'A_PCM/INT/BIG': + $track_info['bitrate'] = $trackarray['SamplingFrequency'] * $trackarray['Channels'] * $trackarray['BitDepth']; + break; + + case 'A_AC3': + case 'A_DTS': + case 'A_MPEG/L3': + case 'A_MPEG/L2': + case 'A_FLAC': + if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']).'.php', __FILE__, false)) { + $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because cannot include "module.audio.'.$track_info['dataformat'].'.php"'); + break; + } + + if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) { + $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set'); + break; + } + + // create temp instance + $getid3_temp = new getID3(); + if ($track_info['dataformat'] != 'flac') { + $getid3_temp->openfile($this->getid3->filename); + } + $getid3_temp->info['avdataoffset'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset']; + if ($track_info['dataformat'][0] == 'm' || $track_info['dataformat'] == 'flac') { + $getid3_temp->info['avdataend'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'] + $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['length']; + } + + // analyze + $class = 'getid3_'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']); + $header_data_key = $track_info['dataformat'][0] == 'm' ? 'mpeg' : $track_info['dataformat']; + $getid3_audio = new $class($getid3_temp, __CLASS__); + if ($track_info['dataformat'] == 'flac') { + $getid3_audio->AnalyzeString($trackarray['CodecPrivate']); + } + else { + $getid3_audio->Analyze(); + } + if (!empty($getid3_temp->info[$header_data_key])) { + $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info[$header_data_key]; + if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) { + foreach ($getid3_temp->info['audio'] as $key => $value) { + $track_info[$key] = $value; + } + } + } + else { + $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because '.$class.'::Analyze() failed at offset '.$getid3_temp->info['avdataoffset']); + } + + // copy errors and warnings + if (!empty($getid3_temp->info['error'])) { + foreach ($getid3_temp->info['error'] as $newerror) { + $this->warning($class.'() says: ['.$newerror.']'); + } + } + if (!empty($getid3_temp->info['warning'])) { + foreach ($getid3_temp->info['warning'] as $newerror) { + if ($track_info['dataformat'] == 'mp3' && preg_match('/^Probable truncated file: expecting \d+ bytes of audio data, only found \d+ \(short by \d+ bytes\)$/', $newerror)) { + // LAME/Xing header is probably set, but audio data is chunked into Matroska file and near-impossible to verify if audio stream is complete, so ignore useless warning + continue; + } + $this->warning($class.'() says: ['.$newerror.']'); + } + } + unset($getid3_temp, $getid3_audio); + break; + + case 'A_AAC': + case 'A_AAC/MPEG2/LC': + case 'A_AAC/MPEG2/LC/SBR': + case 'A_AAC/MPEG4/LC': + case 'A_AAC/MPEG4/LC/SBR': + $this->warning($trackarray['CodecID'].' audio data contains no header, audio/video bitrates can\'t be calculated'); + break; + + case 'A_VORBIS': + if (!isset($trackarray['CodecPrivate'])) { + $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data not set'); + break; + } + $vorbis_offset = strpos($trackarray['CodecPrivate'], 'vorbis', 1); + if ($vorbis_offset === false) { + $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data does not contain "vorbis" keyword'); + break; + } + $vorbis_offset -= 1; + + if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, false)) { + $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because cannot include "module.audio.ogg.php"'); + break; + } + + // create temp instance + $getid3_temp = new getID3(); + + // analyze + $getid3_ogg = new getid3_ogg($getid3_temp); + $oggpageinfo['page_seqno'] = 0; + $getid3_ogg->ParseVorbisPageHeader($trackarray['CodecPrivate'], $vorbis_offset, $oggpageinfo); + if (!empty($getid3_temp->info['ogg'])) { + $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info['ogg']; + if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) { + foreach ($getid3_temp->info['audio'] as $key => $value) { + $track_info[$key] = $value; + } + } + } + + // copy errors and warnings + if (!empty($getid3_temp->info['error'])) { + foreach ($getid3_temp->info['error'] as $newerror) { + $this->warning('getid3_ogg() says: ['.$newerror.']'); + } + } + if (!empty($getid3_temp->info['warning'])) { + foreach ($getid3_temp->info['warning'] as $newerror) { + $this->warning('getid3_ogg() says: ['.$newerror.']'); + } + } + + if (!empty($getid3_temp->info['ogg']['bitrate_nominal'])) { + $track_info['bitrate'] = $getid3_temp->info['ogg']['bitrate_nominal']; + } + unset($getid3_temp, $getid3_ogg, $oggpageinfo, $vorbis_offset); + break; + + case 'A_MS/ACM': + if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, false)) { + $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because cannot include "module.audio-video.riff.php"'); + break; + } + + $parsed = getid3_riff::parseWAVEFORMATex($trackarray['CodecPrivate']); + foreach ($parsed as $key => $value) { + if ($key != 'raw') { + $track_info[$key] = $value; + } + } + $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed; + break; + + default: + $this->warning('Unhandled audio type "'.(isset($trackarray['CodecID']) ? $trackarray['CodecID'] : '').'"'); + } + + $info['audio']['streams'][] = $track_info; + break; + } + } + + if (!empty($info['video']['streams'])) { + $info['video'] = self::getDefaultStreamInfo($info['video']['streams']); + } + if (!empty($info['audio']['streams'])) { + $info['audio'] = self::getDefaultStreamInfo($info['audio']['streams']); + } + } + + // process attachments + if (isset($info['matroska']['attachments']) && $this->getid3->option_save_attachments !== getID3::ATTACHMENTS_NONE) { + foreach ($info['matroska']['attachments'] as $i => $entry) { + if (strpos($entry['FileMimeType'], 'image/') === 0 && !empty($entry['FileData'])) { + $info['matroska']['comments']['picture'][] = array('data' => $entry['FileData'], 'image_mime' => $entry['FileMimeType'], 'filename' => $entry['FileName']); + } + } + } + + // determine mime type + if (!empty($info['video']['streams'])) { + $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'video/webm' : 'video/x-matroska'); + } elseif (!empty($info['audio']['streams'])) { + $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'audio/webm' : 'audio/x-matroska'); + } elseif (isset($info['mime_type'])) { + unset($info['mime_type']); + } + + return true; + } + + private function parseEBML(&$info) { + // http://www.matroska.org/technical/specs/index.html#EBMLBasics + $this->current_offset = $info['avdataoffset']; + + while ($this->getEBMLelement($top_element, $info['avdataend'])) { + switch ($top_element['id']) { + + case EBML_ID_EBML: + $info['fileformat'] = 'matroska'; + $info['matroska']['header']['offset'] = $top_element['offset']; + $info['matroska']['header']['length'] = $top_element['length']; + + while ($this->getEBMLelement($element_data, $top_element['end'], true)) { + switch ($element_data['id']) { + + case EBML_ID_EBMLVERSION: + case EBML_ID_EBMLREADVERSION: + case EBML_ID_EBMLMAXIDLENGTH: + case EBML_ID_EBMLMAXSIZELENGTH: + case EBML_ID_DOCTYPEVERSION: + case EBML_ID_DOCTYPEREADVERSION: + $element_data['data'] = getid3_lib::BigEndian2Int($element_data['data']); + break; + + case EBML_ID_DOCTYPE: + $element_data['data'] = getid3_lib::trimNullByte($element_data['data']); + $info['matroska']['doctype'] = $element_data['data']; + break; + + case EBML_ID_CRC32: // not useful, ignore + $this->current_offset = $element_data['end']; + unset($element_data); + break; + + default: + $this->unhandledElement('header', __LINE__, $element_data); + } + if (!empty($element_data)) { + unset($element_data['offset'], $element_data['end']); + $info['matroska']['header']['elements'][] = $element_data; + } + } + break; + + case EBML_ID_SEGMENT: + $info['matroska']['segment'][0]['offset'] = $top_element['offset']; + $info['matroska']['segment'][0]['length'] = $top_element['length']; + + while ($this->getEBMLelement($element_data, $top_element['end'])) { + if ($element_data['id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required + $info['matroska']['segments'][] = $element_data; + } + switch ($element_data['id']) { + + case EBML_ID_SEEKHEAD: // Contains the position of other level 1 elements. + + while ($this->getEBMLelement($seek_entry, $element_data['end'])) { + switch ($seek_entry['id']) { + + case EBML_ID_SEEK: // Contains a single seek entry to an EBML element + while ($this->getEBMLelement($sub_seek_entry, $seek_entry['end'], true)) { + + switch ($sub_seek_entry['id']) { + + case EBML_ID_SEEKID: + $seek_entry['target_id'] = self::EBML2Int($sub_seek_entry['data']); + $seek_entry['target_name'] = self::EBMLidName($seek_entry['target_id']); + break; + + case EBML_ID_SEEKPOSITION: + $seek_entry['target_offset'] = $element_data['offset'] + getid3_lib::BigEndian2Int($sub_seek_entry['data']); + break; + + default: + $this->unhandledElement('seekhead.seek', __LINE__, $sub_seek_entry); } + } + + if ($seek_entry['target_id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required + $info['matroska']['seek'][] = $seek_entry; + } + break; + + default: + $this->unhandledElement('seekhead', __LINE__, $seek_entry); + } + } + break; + + case EBML_ID_TRACKS: // A top-level block of information with many tracks described. + $info['matroska']['tracks'] = $element_data; + + while ($this->getEBMLelement($track_entry, $element_data['end'])) { + switch ($track_entry['id']) { + + case EBML_ID_TRACKENTRY: //subelements: Describes a track with all elements. + + while ($this->getEBMLelement($subelement, $track_entry['end'], array(EBML_ID_VIDEO, EBML_ID_AUDIO, EBML_ID_CONTENTENCODINGS, EBML_ID_CODECPRIVATE))) { + switch ($subelement['id']) { + + case EBML_ID_TRACKNUMBER: + case EBML_ID_TRACKUID: + case EBML_ID_TRACKTYPE: + case EBML_ID_MINCACHE: + case EBML_ID_MAXCACHE: + case EBML_ID_MAXBLOCKADDITIONID: + case EBML_ID_DEFAULTDURATION: // nanoseconds per frame + $track_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']); + break; + + case EBML_ID_TRACKTIMECODESCALE: + $track_entry[$subelement['id_name']] = getid3_lib::BigEndian2Float($subelement['data']); + break; + + case EBML_ID_CODECID: + case EBML_ID_LANGUAGE: + case EBML_ID_NAME: + case EBML_ID_CODECNAME: + $track_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']); + break; + + case EBML_ID_CODECPRIVATE: + $track_entry[$subelement['id_name']] = $this->readEBMLelementData($subelement['length'], true); + break; + + case EBML_ID_FLAGENABLED: + case EBML_ID_FLAGDEFAULT: + case EBML_ID_FLAGFORCED: + case EBML_ID_FLAGLACING: + case EBML_ID_CODECDECODEALL: + $track_entry[$subelement['id_name']] = (bool) getid3_lib::BigEndian2Int($subelement['data']); + break; + + case EBML_ID_VIDEO: + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) { + switch ($sub_subelement['id']) { + + case EBML_ID_PIXELWIDTH: + case EBML_ID_PIXELHEIGHT: + case EBML_ID_PIXELCROPBOTTOM: + case EBML_ID_PIXELCROPTOP: + case EBML_ID_PIXELCROPLEFT: + case EBML_ID_PIXELCROPRIGHT: + case EBML_ID_DISPLAYWIDTH: + case EBML_ID_DISPLAYHEIGHT: + case EBML_ID_DISPLAYUNIT: + case EBML_ID_ASPECTRATIOTYPE: + case EBML_ID_STEREOMODE: + case EBML_ID_OLDSTEREOMODE: + $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + case EBML_ID_FLAGINTERLACED: + $track_entry[$sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + case EBML_ID_GAMMAVALUE: + $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Float($sub_subelement['data']); + break; + + case EBML_ID_COLOURSPACE: + $track_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']); + break; + + default: + $this->unhandledElement('track.video', __LINE__, $sub_subelement); + } + } + break; + + case EBML_ID_AUDIO: + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) { + switch ($sub_subelement['id']) { + + case EBML_ID_CHANNELS: + case EBML_ID_BITDEPTH: + $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + case EBML_ID_SAMPLINGFREQUENCY: + case EBML_ID_OUTPUTSAMPLINGFREQUENCY: + $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Float($sub_subelement['data']); + break; + + case EBML_ID_CHANNELPOSITIONS: + $track_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']); + break; + + default: + $this->unhandledElement('track.audio', __LINE__, $sub_subelement); + } + } + break; + + case EBML_ID_CONTENTENCODINGS: + + while ($this->getEBMLelement($sub_subelement, $subelement['end'])) { + switch ($sub_subelement['id']) { + + case EBML_ID_CONTENTENCODING: + + while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], array(EBML_ID_CONTENTCOMPRESSION, EBML_ID_CONTENTENCRYPTION))) { + switch ($sub_sub_subelement['id']) { + + case EBML_ID_CONTENTENCODINGORDER: + case EBML_ID_CONTENTENCODINGSCOPE: + case EBML_ID_CONTENTENCODINGTYPE: + $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']); + break; + + case EBML_ID_CONTENTCOMPRESSION: + + while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) { + switch ($sub_sub_sub_subelement['id']) { + + case EBML_ID_CONTENTCOMPALGO: + $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']); + break; + + case EBML_ID_CONTENTCOMPSETTINGS: + $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; + break; + + default: + $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement); + } + } + break; + + case EBML_ID_CONTENTENCRYPTION: + + while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) { + switch ($sub_sub_sub_subelement['id']) { + + case EBML_ID_CONTENTENCALGO: + case EBML_ID_CONTENTSIGALGO: + case EBML_ID_CONTENTSIGHASHALGO: + $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']); + break; + + case EBML_ID_CONTENTENCKEYID: + case EBML_ID_CONTENTSIGNATURE: + case EBML_ID_CONTENTSIGKEYID: + $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; + break; + + default: + $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement); + } + } + break; + + default: + $this->unhandledElement('track.contentencodings.contentencoding', __LINE__, $sub_sub_subelement); + } + } + break; + + default: + $this->unhandledElement('track.contentencodings', __LINE__, $sub_subelement); + } + } + break; + + default: + $this->unhandledElement('track', __LINE__, $subelement); + } + } + + $info['matroska']['tracks']['tracks'][] = $track_entry; + break; + + default: + $this->unhandledElement('tracks', __LINE__, $track_entry); + } + } + break; + + case EBML_ID_INFO: // Contains miscellaneous general information and statistics on the file. + $info_entry = array(); + + while ($this->getEBMLelement($subelement, $element_data['end'], true)) { + switch ($subelement['id']) { + + case EBML_ID_TIMECODESCALE: + $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']); + break; + + case EBML_ID_DURATION: + $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Float($subelement['data']); + break; + + case EBML_ID_DATEUTC: + $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']); + $info_entry[$subelement['id_name'].'_unix'] = self::EBMLdate2unix($info_entry[$subelement['id_name']]); + break; + + case EBML_ID_SEGMENTUID: + case EBML_ID_PREVUID: + case EBML_ID_NEXTUID: + $info_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']); + break; + + case EBML_ID_SEGMENTFAMILY: + $info_entry[$subelement['id_name']][] = getid3_lib::trimNullByte($subelement['data']); + break; + + case EBML_ID_SEGMENTFILENAME: + case EBML_ID_PREVFILENAME: + case EBML_ID_NEXTFILENAME: + case EBML_ID_TITLE: + case EBML_ID_MUXINGAPP: + case EBML_ID_WRITINGAPP: + $info_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']); + $info['matroska']['comments'][strtolower($subelement['id_name'])][] = $info_entry[$subelement['id_name']]; + break; + + case EBML_ID_CHAPTERTRANSLATE: + $chaptertranslate_entry = array(); + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) { + switch ($sub_subelement['id']) { + + case EBML_ID_CHAPTERTRANSLATEEDITIONUID: + $chaptertranslate_entry[$sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + case EBML_ID_CHAPTERTRANSLATECODEC: + $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + case EBML_ID_CHAPTERTRANSLATEID: + $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']); + break; + + default: + $this->unhandledElement('info.chaptertranslate', __LINE__, $sub_subelement); + } + } + $info_entry[$subelement['id_name']] = $chaptertranslate_entry; + break; + + default: + $this->unhandledElement('info', __LINE__, $subelement); + } + } + $info['matroska']['info'][] = $info_entry; + break; + + case EBML_ID_CUES: // A top-level element to speed seeking access. All entries are local to the segment. Should be mandatory for non "live" streams. + if (self::$hide_clusters) { // do not parse cues if hide clusters is "ON" till they point to clusters anyway + $this->current_offset = $element_data['end']; + break; + } + $cues_entry = array(); + + while ($this->getEBMLelement($subelement, $element_data['end'])) { + switch ($subelement['id']) { + + case EBML_ID_CUEPOINT: + $cuepoint_entry = array(); + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CUETRACKPOSITIONS))) { + switch ($sub_subelement['id']) { + + case EBML_ID_CUETRACKPOSITIONS: + $cuetrackpositions_entry = array(); + + while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) { + switch ($sub_sub_subelement['id']) { + + case EBML_ID_CUETRACK: + case EBML_ID_CUECLUSTERPOSITION: + case EBML_ID_CUEBLOCKNUMBER: + case EBML_ID_CUECODECSTATE: + $cuetrackpositions_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']); + break; + + default: + $this->unhandledElement('cues.cuepoint.cuetrackpositions', __LINE__, $sub_sub_subelement); + } + } + $cuepoint_entry[$sub_subelement['id_name']][] = $cuetrackpositions_entry; + break; + + case EBML_ID_CUETIME: + $cuepoint_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + default: + $this->unhandledElement('cues.cuepoint', __LINE__, $sub_subelement); + } + } + $cues_entry[] = $cuepoint_entry; + break; + + default: + $this->unhandledElement('cues', __LINE__, $subelement); + } + } + $info['matroska']['cues'] = $cues_entry; + break; + + case EBML_ID_TAGS: // Element containing elements specific to Tracks/Chapters. + $tags_entry = array(); + + while ($this->getEBMLelement($subelement, $element_data['end'], false)) { + switch ($subelement['id']) { + + case EBML_ID_TAG: + $tag_entry = array(); + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], false)) { + switch ($sub_subelement['id']) { + + case EBML_ID_TARGETS: + $targets_entry = array(); + + while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) { + switch ($sub_sub_subelement['id']) { + + case EBML_ID_TARGETTYPEVALUE: + $targets_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']); + $targets_entry[strtolower($sub_sub_subelement['id_name']).'_long'] = self::TargetTypeValue($targets_entry[$sub_sub_subelement['id_name']]); + break; + + case EBML_ID_TARGETTYPE: + $targets_entry[$sub_sub_subelement['id_name']] = $sub_sub_subelement['data']; + break; + + case EBML_ID_TAGTRACKUID: + case EBML_ID_TAGEDITIONUID: + case EBML_ID_TAGCHAPTERUID: + case EBML_ID_TAGATTACHMENTUID: + $targets_entry[$sub_sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']); + break; + + default: + $this->unhandledElement('tags.tag.targets', __LINE__, $sub_sub_subelement); + } + } + $tag_entry[$sub_subelement['id_name']] = $targets_entry; + break; + + case EBML_ID_SIMPLETAG: + $tag_entry[$sub_subelement['id_name']][] = $this->HandleEMBLSimpleTag($sub_subelement['end']); + break; + + default: + $this->unhandledElement('tags.tag', __LINE__, $sub_subelement); + } + } + $tags_entry[] = $tag_entry; + break; + + default: + $this->unhandledElement('tags', __LINE__, $subelement); + } + } + $info['matroska']['tags'] = $tags_entry; + break; + + case EBML_ID_ATTACHMENTS: // Contain attached files. + + while ($this->getEBMLelement($subelement, $element_data['end'])) { + switch ($subelement['id']) { + + case EBML_ID_ATTACHEDFILE: + $attachedfile_entry = array(); + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_FILEDATA))) { + switch ($sub_subelement['id']) { + + case EBML_ID_FILEDESCRIPTION: + case EBML_ID_FILENAME: + case EBML_ID_FILEMIMETYPE: + $attachedfile_entry[$sub_subelement['id_name']] = $sub_subelement['data']; + break; + + case EBML_ID_FILEDATA: + $attachedfile_entry['data_offset'] = $this->current_offset; + $attachedfile_entry['data_length'] = $sub_subelement['length']; + + $attachedfile_entry[$sub_subelement['id_name']] = $this->saveAttachment( + $attachedfile_entry['FileName'], + $attachedfile_entry['data_offset'], + $attachedfile_entry['data_length']); + + $this->current_offset = $sub_subelement['end']; + break; + + case EBML_ID_FILEUID: + $attachedfile_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + default: + $this->unhandledElement('attachments.attachedfile', __LINE__, $sub_subelement); + } + } + $info['matroska']['attachments'][] = $attachedfile_entry; + break; + + default: + $this->unhandledElement('attachments', __LINE__, $subelement); + } + } + break; + + case EBML_ID_CHAPTERS: + + while ($this->getEBMLelement($subelement, $element_data['end'])) { + switch ($subelement['id']) { + + case EBML_ID_EDITIONENTRY: + $editionentry_entry = array(); + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CHAPTERATOM))) { + switch ($sub_subelement['id']) { + + case EBML_ID_EDITIONUID: + $editionentry_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + case EBML_ID_EDITIONFLAGHIDDEN: + case EBML_ID_EDITIONFLAGDEFAULT: + case EBML_ID_EDITIONFLAGORDERED: + $editionentry_entry[$sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + case EBML_ID_CHAPTERATOM: + $chapteratom_entry = array(); + + while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], array(EBML_ID_CHAPTERTRACK, EBML_ID_CHAPTERDISPLAY))) { + switch ($sub_sub_subelement['id']) { + + case EBML_ID_CHAPTERSEGMENTUID: + case EBML_ID_CHAPTERSEGMENTEDITIONUID: + $chapteratom_entry[$sub_sub_subelement['id_name']] = $sub_sub_subelement['data']; + break; + + case EBML_ID_CHAPTERFLAGENABLED: + case EBML_ID_CHAPTERFLAGHIDDEN: + $chapteratom_entry[$sub_sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_sub_subelement['data']); + break; + + case EBML_ID_CHAPTERUID: + case EBML_ID_CHAPTERTIMESTART: + case EBML_ID_CHAPTERTIMEEND: + $chapteratom_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']); + break; + + case EBML_ID_CHAPTERTRACK: + $chaptertrack_entry = array(); + + while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) { + switch ($sub_sub_sub_subelement['id']) { + + case EBML_ID_CHAPTERTRACKNUMBER: + $chaptertrack_entry[$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']); + break; + + default: + $this->unhandledElement('chapters.editionentry.chapteratom.chaptertrack', __LINE__, $sub_sub_sub_subelement); + } + } + $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chaptertrack_entry; + break; + + case EBML_ID_CHAPTERDISPLAY: + $chapterdisplay_entry = array(); + + while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) { + switch ($sub_sub_sub_subelement['id']) { + + case EBML_ID_CHAPSTRING: + case EBML_ID_CHAPLANGUAGE: + case EBML_ID_CHAPCOUNTRY: + $chapterdisplay_entry[$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; + break; + + default: + $this->unhandledElement('chapters.editionentry.chapteratom.chapterdisplay', __LINE__, $sub_sub_sub_subelement); + } + } + $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chapterdisplay_entry; + break; + + default: + $this->unhandledElement('chapters.editionentry.chapteratom', __LINE__, $sub_sub_subelement); + } + } + $editionentry_entry[$sub_subelement['id_name']][] = $chapteratom_entry; + break; + + default: + $this->unhandledElement('chapters.editionentry', __LINE__, $sub_subelement); + } + } + $info['matroska']['chapters'][] = $editionentry_entry; + break; + + default: + $this->unhandledElement('chapters', __LINE__, $subelement); + } + } + break; + + case EBML_ID_CLUSTER: // The lower level element containing the (monolithic) Block structure. + $cluster_entry = array(); + + while ($this->getEBMLelement($subelement, $element_data['end'], array(EBML_ID_CLUSTERSILENTTRACKS, EBML_ID_CLUSTERBLOCKGROUP, EBML_ID_CLUSTERSIMPLEBLOCK))) { + switch ($subelement['id']) { + + case EBML_ID_CLUSTERTIMECODE: + case EBML_ID_CLUSTERPOSITION: + case EBML_ID_CLUSTERPREVSIZE: + $cluster_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']); + break; + + case EBML_ID_CLUSTERSILENTTRACKS: + $cluster_silent_tracks = array(); + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) { + switch ($sub_subelement['id']) { + + case EBML_ID_CLUSTERSILENTTRACKNUMBER: + $cluster_silent_tracks[] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + default: + $this->unhandledElement('cluster.silenttracks', __LINE__, $sub_subelement); + } + } + $cluster_entry[$subelement['id_name']][] = $cluster_silent_tracks; + break; + + case EBML_ID_CLUSTERBLOCKGROUP: + $cluster_block_group = array('offset' => $this->current_offset); + + while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CLUSTERBLOCK))) { + switch ($sub_subelement['id']) { + + case EBML_ID_CLUSTERBLOCK: + $cluster_block_group[$sub_subelement['id_name']] = $this->HandleEMBLClusterBlock($sub_subelement, EBML_ID_CLUSTERBLOCK, $info); + break; + + case EBML_ID_CLUSTERREFERENCEPRIORITY: // unsigned-int + case EBML_ID_CLUSTERBLOCKDURATION: // unsigned-int + $cluster_block_group[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); + break; + + case EBML_ID_CLUSTERREFERENCEBLOCK: // signed-int + $cluster_block_group[$sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_subelement['data'], false, true); + break; + + case EBML_ID_CLUSTERCODECSTATE: + $cluster_block_group[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']); + break; + + default: + $this->unhandledElement('clusters.blockgroup', __LINE__, $sub_subelement); + } + } + $cluster_entry[$subelement['id_name']][] = $cluster_block_group; + break; + + case EBML_ID_CLUSTERSIMPLEBLOCK: + $cluster_entry[$subelement['id_name']][] = $this->HandleEMBLClusterBlock($subelement, EBML_ID_CLUSTERSIMPLEBLOCK, $info); + break; + + default: + $this->unhandledElement('cluster', __LINE__, $subelement); + } + $this->current_offset = $subelement['end']; + } + if (!self::$hide_clusters) { + $info['matroska']['cluster'][] = $cluster_entry; + } + + // check to see if all the data we need exists already, if so, break out of the loop + if (!self::$parse_whole_file) { + if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) { + if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) { + if (count($info['matroska']['track_data_offsets']) == count($info['matroska']['tracks']['tracks'])) { + return; + } + } + } + } + break; + + default: + $this->unhandledElement('segment', __LINE__, $element_data); + } + } + break; + + default: + $this->unhandledElement('root', __LINE__, $top_element); + } + } + } + + private function EnsureBufferHasEnoughData($min_data=1024) { + if (($this->current_offset - $this->EBMLbuffer_offset) >= ($this->EBMLbuffer_length - $min_data)) { + $read_bytes = max($min_data, $this->getid3->fread_buffer_size()); + + try { + $this->fseek($this->current_offset); + $this->EBMLbuffer_offset = $this->current_offset; + $this->EBMLbuffer = $this->fread($read_bytes); + $this->EBMLbuffer_length = strlen($this->EBMLbuffer); + } catch (getid3_exception $e) { + $this->warning('EBML parser: '.$e->getMessage()); + return false; + } + + if ($this->EBMLbuffer_length == 0 && $this->feof()) { + return $this->error('EBML parser: ran out of file at offset '.$this->current_offset); + } + } + return true; + } + + private function readEBMLint() { + $actual_offset = $this->current_offset - $this->EBMLbuffer_offset; + + // get length of integer + $first_byte_int = ord($this->EBMLbuffer[$actual_offset]); + if (0x80 & $first_byte_int) { + $length = 1; + } elseif (0x40 & $first_byte_int) { + $length = 2; + } elseif (0x20 & $first_byte_int) { + $length = 3; + } elseif (0x10 & $first_byte_int) { + $length = 4; + } elseif (0x08 & $first_byte_int) { + $length = 5; + } elseif (0x04 & $first_byte_int) { + $length = 6; + } elseif (0x02 & $first_byte_int) { + $length = 7; + } elseif (0x01 & $first_byte_int) { + $length = 8; + } else { + throw new Exception('invalid EBML integer (leading 0x00) at '.$this->current_offset); + } + + // read + $int_value = self::EBML2Int(substr($this->EBMLbuffer, $actual_offset, $length)); + $this->current_offset += $length; + + return $int_value; + } + + private function readEBMLelementData($length, $check_buffer=false) { + if ($check_buffer && !$this->EnsureBufferHasEnoughData($length)) { + return false; + } + $data = substr($this->EBMLbuffer, $this->current_offset - $this->EBMLbuffer_offset, $length); + $this->current_offset += $length; + return $data; + } + + private function getEBMLelement(&$element, $parent_end, $get_data=false) { + if ($this->current_offset >= $parent_end) { + return false; + } + + if (!$this->EnsureBufferHasEnoughData()) { + $this->current_offset = PHP_INT_MAX; // do not exit parser right now, allow to finish current loop to gather maximum information + return false; + } + + $element = array(); + + // set offset + $element['offset'] = $this->current_offset; + + // get ID + $element['id'] = $this->readEBMLint(); + + // get name + $element['id_name'] = self::EBMLidName($element['id']); + + // get length + $element['length'] = $this->readEBMLint(); + + // get end offset + $element['end'] = $this->current_offset + $element['length']; + + // get raw data + $dont_parse = (in_array($element['id'], $this->unuseful_elements) || $element['id_name'] == dechex($element['id'])); + if (($get_data === true || (is_array($get_data) && !in_array($element['id'], $get_data))) && !$dont_parse) { + $element['data'] = $this->readEBMLelementData($element['length'], $element); + } + + return true; + } + + private function unhandledElement($type, $line, $element) { + // warn only about unknown and missed elements, not about unuseful + if (!in_array($element['id'], $this->unuseful_elements)) { + $this->warning('Unhandled '.$type.' element ['.basename(__FILE__).':'.$line.'] ('.$element['id'].'::'.$element['id_name'].' ['.$element['length'].' bytes]) at '.$element['offset']); + } + + // increase offset for unparsed elements + if (!isset($element['data'])) { + $this->current_offset = $element['end']; + } + } + + private function ExtractCommentsSimpleTag($SimpleTagArray) { + if (!empty($SimpleTagArray['SimpleTag'])) { + foreach ($SimpleTagArray['SimpleTag'] as $SimpleTagKey => $SimpleTagData) { + if (!empty($SimpleTagData['TagName']) && !empty($SimpleTagData['TagString'])) { + $this->getid3->info['matroska']['comments'][strtolower($SimpleTagData['TagName'])][] = $SimpleTagData['TagString']; + } + if (!empty($SimpleTagData['SimpleTag'])) { + $this->ExtractCommentsSimpleTag($SimpleTagData); + } + } + } + + return true; + } + + private function HandleEMBLSimpleTag($parent_end) { + $simpletag_entry = array(); + + while ($this->getEBMLelement($element, $parent_end, array(EBML_ID_SIMPLETAG))) { + switch ($element['id']) { + + case EBML_ID_TAGNAME: + case EBML_ID_TAGLANGUAGE: + case EBML_ID_TAGSTRING: + case EBML_ID_TAGBINARY: + $simpletag_entry[$element['id_name']] = $element['data']; + break; + + case EBML_ID_SIMPLETAG: + $simpletag_entry[$element['id_name']][] = $this->HandleEMBLSimpleTag($element['end']); + break; + + case EBML_ID_TAGDEFAULT: + $simpletag_entry[$element['id_name']] = (bool)getid3_lib::BigEndian2Int($element['data']); + break; + + default: + $this->unhandledElement('tag.simpletag', __LINE__, $element); + } + } + + return $simpletag_entry; + } + + private function HandleEMBLClusterBlock($element, $block_type, &$info) { + // http://www.matroska.org/technical/specs/index.html#block_structure + // http://www.matroska.org/technical/specs/index.html#simpleblock_structure + + $block_data = array(); + $block_data['tracknumber'] = $this->readEBMLint(); + $block_data['timecode'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(2), false, true); + $block_data['flags_raw'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1)); + + if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) { + $block_data['flags']['keyframe'] = (($block_data['flags_raw'] & 0x80) >> 7); + //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0x70) >> 4); + } + else { + //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0xF0) >> 4); + } + $block_data['flags']['invisible'] = (bool)(($block_data['flags_raw'] & 0x08) >> 3); + $block_data['flags']['lacing'] = (($block_data['flags_raw'] & 0x06) >> 1); // 00=no lacing; 01=Xiph lacing; 11=EBML lacing; 10=fixed-size lacing + if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) { + $block_data['flags']['discardable'] = (($block_data['flags_raw'] & 0x01)); + } + else { + //$block_data['flags']['reserved2'] = (($block_data['flags_raw'] & 0x01) >> 0); + } + $block_data['flags']['lacing_type'] = self::BlockLacingType($block_data['flags']['lacing']); + + // Lace (when lacing bit is set) + if ($block_data['flags']['lacing'] > 0) { + $block_data['lace_frames'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1)) + 1; // Number of frames in the lace-1 (uint8) + if ($block_data['flags']['lacing'] != 0x02) { + for ($i = 1; $i < $block_data['lace_frames']; $i ++) { // Lace-coded size of each frame of the lace, except for the last one (multiple uint8). *This is not used with Fixed-size lacing as it is calculated automatically from (total size of lace) / (number of frames in lace). + if ($block_data['flags']['lacing'] == 0x03) { // EBML lacing + $block_data['lace_frames_size'][$i] = $this->readEBMLint(); // TODO: read size correctly, calc size for the last frame. For now offsets are deteminded OK with readEBMLint() and that's the most important thing. + } + else { // Xiph lacing + $block_data['lace_frames_size'][$i] = 0; + do { + $size = getid3_lib::BigEndian2Int($this->readEBMLelementData(1)); + $block_data['lace_frames_size'][$i] += $size; + } + while ($size == 255); + } + } + if ($block_data['flags']['lacing'] == 0x01) { // calc size of the last frame only for Xiph lacing, till EBML sizes are now anyway determined incorrectly + $block_data['lace_frames_size'][] = $element['end'] - $this->current_offset - array_sum($block_data['lace_frames_size']); + } + } + } + + if (!isset($info['matroska']['track_data_offsets'][$block_data['tracknumber']])) { + $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['offset'] = $this->current_offset; + $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'] = $element['end'] - $this->current_offset; + //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] = 0; + } + //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] += $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length']; + //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['duration'] = $block_data['timecode'] * ((isset($info['matroska']['info'][0]['TimecodeScale']) ? $info['matroska']['info'][0]['TimecodeScale'] : 1000000) / 1000000000); + + // set offset manually + $this->current_offset = $element['end']; + + return $block_data; + } + + private static function EBML2Int($EBMLstring) { + // http://matroska.org/specs/ + + // Element ID coded with an UTF-8 like system: + // 1xxx xxxx - Class A IDs (2^7 -2 possible values) (base 0x8X) + // 01xx xxxx xxxx xxxx - Class B IDs (2^14-2 possible values) (base 0x4X 0xXX) + // 001x xxxx xxxx xxxx xxxx xxxx - Class C IDs (2^21-2 possible values) (base 0x2X 0xXX 0xXX) + // 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - Class D IDs (2^28-2 possible values) (base 0x1X 0xXX 0xXX 0xXX) + // Values with all x at 0 and 1 are reserved (hence the -2). + + // Data size, in octets, is also coded with an UTF-8 like system : + // 1xxx xxxx - value 0 to 2^7-2 + // 01xx xxxx xxxx xxxx - value 0 to 2^14-2 + // 001x xxxx xxxx xxxx xxxx xxxx - value 0 to 2^21-2 + // 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^28-2 + // 0000 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^35-2 + // 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^42-2 + // 0000 001x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^49-2 + // 0000 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^56-2 + + $first_byte_int = ord($EBMLstring[0]); + if (0x80 & $first_byte_int) { + $EBMLstring[0] = chr($first_byte_int & 0x7F); + } elseif (0x40 & $first_byte_int) { + $EBMLstring[0] = chr($first_byte_int & 0x3F); + } elseif (0x20 & $first_byte_int) { + $EBMLstring[0] = chr($first_byte_int & 0x1F); + } elseif (0x10 & $first_byte_int) { + $EBMLstring[0] = chr($first_byte_int & 0x0F); + } elseif (0x08 & $first_byte_int) { + $EBMLstring[0] = chr($first_byte_int & 0x07); + } elseif (0x04 & $first_byte_int) { + $EBMLstring[0] = chr($first_byte_int & 0x03); + } elseif (0x02 & $first_byte_int) { + $EBMLstring[0] = chr($first_byte_int & 0x01); + } elseif (0x01 & $first_byte_int) { + $EBMLstring[0] = chr($first_byte_int & 0x00); + } + + return getid3_lib::BigEndian2Int($EBMLstring); + } + + private static function EBMLdate2unix($EBMLdatestamp) { + // Date - signed 8 octets integer in nanoseconds with 0 indicating the precise beginning of the millennium (at 2001-01-01T00:00:00,000000000 UTC) + // 978307200 == mktime(0, 0, 0, 1, 1, 2001) == January 1, 2001 12:00:00am UTC + return round(($EBMLdatestamp / 1000000000) + 978307200); + } + + public static function TargetTypeValue($target_type) { + // http://www.matroska.org/technical/specs/tagging/index.html + static $TargetTypeValue = array(); + if (empty($TargetTypeValue)) { + $TargetTypeValue[10] = 'A: ~ V:shot'; // the lowest hierarchy found in music or movies + $TargetTypeValue[20] = 'A:subtrack/part/movement ~ V:scene'; // corresponds to parts of a track for audio (like a movement) + $TargetTypeValue[30] = 'A:track/song ~ V:chapter'; // the common parts of an album or a movie + $TargetTypeValue[40] = 'A:part/session ~ V:part/session'; // when an album or episode has different logical parts + $TargetTypeValue[50] = 'A:album/opera/concert ~ V:movie/episode/concert'; // the most common grouping level of music and video (equals to an episode for TV series) + $TargetTypeValue[60] = 'A:edition/issue/volume/opus ~ V:season/sequel/volume'; // a list of lower levels grouped together + $TargetTypeValue[70] = 'A:collection ~ V:collection'; // the high hierarchy consisting of many different lower items + } + return (isset($TargetTypeValue[$target_type]) ? $TargetTypeValue[$target_type] : $target_type); + } + + public static function BlockLacingType($lacingtype) { + // http://matroska.org/technical/specs/index.html#block_structure + static $BlockLacingType = array(); + if (empty($BlockLacingType)) { + $BlockLacingType[0x00] = 'no lacing'; + $BlockLacingType[0x01] = 'Xiph lacing'; + $BlockLacingType[0x02] = 'fixed-size lacing'; + $BlockLacingType[0x03] = 'EBML lacing'; + } + return (isset($BlockLacingType[$lacingtype]) ? $BlockLacingType[$lacingtype] : $lacingtype); + } + + public static function CodecIDtoCommonName($codecid) { + // http://www.matroska.org/technical/specs/codecid/index.html + static $CodecIDlist = array(); + if (empty($CodecIDlist)) { + $CodecIDlist['A_AAC'] = 'aac'; + $CodecIDlist['A_AAC/MPEG2/LC'] = 'aac'; + $CodecIDlist['A_AC3'] = 'ac3'; + $CodecIDlist['A_DTS'] = 'dts'; + $CodecIDlist['A_FLAC'] = 'flac'; + $CodecIDlist['A_MPEG/L1'] = 'mp1'; + $CodecIDlist['A_MPEG/L2'] = 'mp2'; + $CodecIDlist['A_MPEG/L3'] = 'mp3'; + $CodecIDlist['A_PCM/INT/LIT'] = 'pcm'; // PCM Integer Little Endian + $CodecIDlist['A_PCM/INT/BIG'] = 'pcm'; // PCM Integer Big Endian + $CodecIDlist['A_QUICKTIME/QDMC'] = 'quicktime'; // Quicktime: QDesign Music + $CodecIDlist['A_QUICKTIME/QDM2'] = 'quicktime'; // Quicktime: QDesign Music v2 + $CodecIDlist['A_VORBIS'] = 'vorbis'; + $CodecIDlist['V_MPEG1'] = 'mpeg'; + $CodecIDlist['V_THEORA'] = 'theora'; + $CodecIDlist['V_REAL/RV40'] = 'real'; + $CodecIDlist['V_REAL/RV10'] = 'real'; + $CodecIDlist['V_REAL/RV20'] = 'real'; + $CodecIDlist['V_REAL/RV30'] = 'real'; + $CodecIDlist['V_QUICKTIME'] = 'quicktime'; // Quicktime + $CodecIDlist['V_MPEG4/ISO/AP'] = 'mpeg4'; + $CodecIDlist['V_MPEG4/ISO/ASP'] = 'mpeg4'; + $CodecIDlist['V_MPEG4/ISO/AVC'] = 'h264'; + $CodecIDlist['V_MPEG4/ISO/SP'] = 'mpeg4'; + $CodecIDlist['V_VP8'] = 'vp8'; + $CodecIDlist['V_MS/VFW/FOURCC'] = 'riff'; + $CodecIDlist['A_MS/ACM'] = 'riff'; + } + return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid); + } + + private static function EBMLidName($value) { + static $EBMLidList = array(); + if (empty($EBMLidList)) { + $EBMLidList[EBML_ID_ASPECTRATIOTYPE] = 'AspectRatioType'; + $EBMLidList[EBML_ID_ATTACHEDFILE] = 'AttachedFile'; + $EBMLidList[EBML_ID_ATTACHMENTLINK] = 'AttachmentLink'; + $EBMLidList[EBML_ID_ATTACHMENTS] = 'Attachments'; + $EBMLidList[EBML_ID_AUDIO] = 'Audio'; + $EBMLidList[EBML_ID_BITDEPTH] = 'BitDepth'; + $EBMLidList[EBML_ID_CHANNELPOSITIONS] = 'ChannelPositions'; + $EBMLidList[EBML_ID_CHANNELS] = 'Channels'; + $EBMLidList[EBML_ID_CHAPCOUNTRY] = 'ChapCountry'; + $EBMLidList[EBML_ID_CHAPLANGUAGE] = 'ChapLanguage'; + $EBMLidList[EBML_ID_CHAPPROCESS] = 'ChapProcess'; + $EBMLidList[EBML_ID_CHAPPROCESSCODECID] = 'ChapProcessCodecID'; + $EBMLidList[EBML_ID_CHAPPROCESSCOMMAND] = 'ChapProcessCommand'; + $EBMLidList[EBML_ID_CHAPPROCESSDATA] = 'ChapProcessData'; + $EBMLidList[EBML_ID_CHAPPROCESSPRIVATE] = 'ChapProcessPrivate'; + $EBMLidList[EBML_ID_CHAPPROCESSTIME] = 'ChapProcessTime'; + $EBMLidList[EBML_ID_CHAPSTRING] = 'ChapString'; + $EBMLidList[EBML_ID_CHAPTERATOM] = 'ChapterAtom'; + $EBMLidList[EBML_ID_CHAPTERDISPLAY] = 'ChapterDisplay'; + $EBMLidList[EBML_ID_CHAPTERFLAGENABLED] = 'ChapterFlagEnabled'; + $EBMLidList[EBML_ID_CHAPTERFLAGHIDDEN] = 'ChapterFlagHidden'; + $EBMLidList[EBML_ID_CHAPTERPHYSICALEQUIV] = 'ChapterPhysicalEquiv'; + $EBMLidList[EBML_ID_CHAPTERS] = 'Chapters'; + $EBMLidList[EBML_ID_CHAPTERSEGMENTEDITIONUID] = 'ChapterSegmentEditionUID'; + $EBMLidList[EBML_ID_CHAPTERSEGMENTUID] = 'ChapterSegmentUID'; + $EBMLidList[EBML_ID_CHAPTERTIMEEND] = 'ChapterTimeEnd'; + $EBMLidList[EBML_ID_CHAPTERTIMESTART] = 'ChapterTimeStart'; + $EBMLidList[EBML_ID_CHAPTERTRACK] = 'ChapterTrack'; + $EBMLidList[EBML_ID_CHAPTERTRACKNUMBER] = 'ChapterTrackNumber'; + $EBMLidList[EBML_ID_CHAPTERTRANSLATE] = 'ChapterTranslate'; + $EBMLidList[EBML_ID_CHAPTERTRANSLATECODEC] = 'ChapterTranslateCodec'; + $EBMLidList[EBML_ID_CHAPTERTRANSLATEEDITIONUID] = 'ChapterTranslateEditionUID'; + $EBMLidList[EBML_ID_CHAPTERTRANSLATEID] = 'ChapterTranslateID'; + $EBMLidList[EBML_ID_CHAPTERUID] = 'ChapterUID'; + $EBMLidList[EBML_ID_CLUSTER] = 'Cluster'; + $EBMLidList[EBML_ID_CLUSTERBLOCK] = 'ClusterBlock'; + $EBMLidList[EBML_ID_CLUSTERBLOCKADDID] = 'ClusterBlockAddID'; + $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONAL] = 'ClusterBlockAdditional'; + $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONID] = 'ClusterBlockAdditionID'; + $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONS] = 'ClusterBlockAdditions'; + $EBMLidList[EBML_ID_CLUSTERBLOCKDURATION] = 'ClusterBlockDuration'; + $EBMLidList[EBML_ID_CLUSTERBLOCKGROUP] = 'ClusterBlockGroup'; + $EBMLidList[EBML_ID_CLUSTERBLOCKMORE] = 'ClusterBlockMore'; + $EBMLidList[EBML_ID_CLUSTERBLOCKVIRTUAL] = 'ClusterBlockVirtual'; + $EBMLidList[EBML_ID_CLUSTERCODECSTATE] = 'ClusterCodecState'; + $EBMLidList[EBML_ID_CLUSTERDELAY] = 'ClusterDelay'; + $EBMLidList[EBML_ID_CLUSTERDURATION] = 'ClusterDuration'; + $EBMLidList[EBML_ID_CLUSTERENCRYPTEDBLOCK] = 'ClusterEncryptedBlock'; + $EBMLidList[EBML_ID_CLUSTERFRAMENUMBER] = 'ClusterFrameNumber'; + $EBMLidList[EBML_ID_CLUSTERLACENUMBER] = 'ClusterLaceNumber'; + $EBMLidList[EBML_ID_CLUSTERPOSITION] = 'ClusterPosition'; + $EBMLidList[EBML_ID_CLUSTERPREVSIZE] = 'ClusterPrevSize'; + $EBMLidList[EBML_ID_CLUSTERREFERENCEBLOCK] = 'ClusterReferenceBlock'; + $EBMLidList[EBML_ID_CLUSTERREFERENCEPRIORITY] = 'ClusterReferencePriority'; + $EBMLidList[EBML_ID_CLUSTERREFERENCEVIRTUAL] = 'ClusterReferenceVirtual'; + $EBMLidList[EBML_ID_CLUSTERSILENTTRACKNUMBER] = 'ClusterSilentTrackNumber'; + $EBMLidList[EBML_ID_CLUSTERSILENTTRACKS] = 'ClusterSilentTracks'; + $EBMLidList[EBML_ID_CLUSTERSIMPLEBLOCK] = 'ClusterSimpleBlock'; + $EBMLidList[EBML_ID_CLUSTERTIMECODE] = 'ClusterTimecode'; + $EBMLidList[EBML_ID_CLUSTERTIMESLICE] = 'ClusterTimeSlice'; + $EBMLidList[EBML_ID_CODECDECODEALL] = 'CodecDecodeAll'; + $EBMLidList[EBML_ID_CODECDOWNLOADURL] = 'CodecDownloadURL'; + $EBMLidList[EBML_ID_CODECID] = 'CodecID'; + $EBMLidList[EBML_ID_CODECINFOURL] = 'CodecInfoURL'; + $EBMLidList[EBML_ID_CODECNAME] = 'CodecName'; + $EBMLidList[EBML_ID_CODECPRIVATE] = 'CodecPrivate'; + $EBMLidList[EBML_ID_CODECSETTINGS] = 'CodecSettings'; + $EBMLidList[EBML_ID_COLOURSPACE] = 'ColourSpace'; + $EBMLidList[EBML_ID_CONTENTCOMPALGO] = 'ContentCompAlgo'; + $EBMLidList[EBML_ID_CONTENTCOMPRESSION] = 'ContentCompression'; + $EBMLidList[EBML_ID_CONTENTCOMPSETTINGS] = 'ContentCompSettings'; + $EBMLidList[EBML_ID_CONTENTENCALGO] = 'ContentEncAlgo'; + $EBMLidList[EBML_ID_CONTENTENCKEYID] = 'ContentEncKeyID'; + $EBMLidList[EBML_ID_CONTENTENCODING] = 'ContentEncoding'; + $EBMLidList[EBML_ID_CONTENTENCODINGORDER] = 'ContentEncodingOrder'; + $EBMLidList[EBML_ID_CONTENTENCODINGS] = 'ContentEncodings'; + $EBMLidList[EBML_ID_CONTENTENCODINGSCOPE] = 'ContentEncodingScope'; + $EBMLidList[EBML_ID_CONTENTENCODINGTYPE] = 'ContentEncodingType'; + $EBMLidList[EBML_ID_CONTENTENCRYPTION] = 'ContentEncryption'; + $EBMLidList[EBML_ID_CONTENTSIGALGO] = 'ContentSigAlgo'; + $EBMLidList[EBML_ID_CONTENTSIGHASHALGO] = 'ContentSigHashAlgo'; + $EBMLidList[EBML_ID_CONTENTSIGKEYID] = 'ContentSigKeyID'; + $EBMLidList[EBML_ID_CONTENTSIGNATURE] = 'ContentSignature'; + $EBMLidList[EBML_ID_CRC32] = 'CRC32'; + $EBMLidList[EBML_ID_CUEBLOCKNUMBER] = 'CueBlockNumber'; + $EBMLidList[EBML_ID_CUECLUSTERPOSITION] = 'CueClusterPosition'; + $EBMLidList[EBML_ID_CUECODECSTATE] = 'CueCodecState'; + $EBMLidList[EBML_ID_CUEPOINT] = 'CuePoint'; + $EBMLidList[EBML_ID_CUEREFCLUSTER] = 'CueRefCluster'; + $EBMLidList[EBML_ID_CUEREFCODECSTATE] = 'CueRefCodecState'; + $EBMLidList[EBML_ID_CUEREFERENCE] = 'CueReference'; + $EBMLidList[EBML_ID_CUEREFNUMBER] = 'CueRefNumber'; + $EBMLidList[EBML_ID_CUEREFTIME] = 'CueRefTime'; + $EBMLidList[EBML_ID_CUES] = 'Cues'; + $EBMLidList[EBML_ID_CUETIME] = 'CueTime'; + $EBMLidList[EBML_ID_CUETRACK] = 'CueTrack'; + $EBMLidList[EBML_ID_CUETRACKPOSITIONS] = 'CueTrackPositions'; + $EBMLidList[EBML_ID_DATEUTC] = 'DateUTC'; + $EBMLidList[EBML_ID_DEFAULTDURATION] = 'DefaultDuration'; + $EBMLidList[EBML_ID_DISPLAYHEIGHT] = 'DisplayHeight'; + $EBMLidList[EBML_ID_DISPLAYUNIT] = 'DisplayUnit'; + $EBMLidList[EBML_ID_DISPLAYWIDTH] = 'DisplayWidth'; + $EBMLidList[EBML_ID_DOCTYPE] = 'DocType'; + $EBMLidList[EBML_ID_DOCTYPEREADVERSION] = 'DocTypeReadVersion'; + $EBMLidList[EBML_ID_DOCTYPEVERSION] = 'DocTypeVersion'; + $EBMLidList[EBML_ID_DURATION] = 'Duration'; + $EBMLidList[EBML_ID_EBML] = 'EBML'; + $EBMLidList[EBML_ID_EBMLMAXIDLENGTH] = 'EBMLMaxIDLength'; + $EBMLidList[EBML_ID_EBMLMAXSIZELENGTH] = 'EBMLMaxSizeLength'; + $EBMLidList[EBML_ID_EBMLREADVERSION] = 'EBMLReadVersion'; + $EBMLidList[EBML_ID_EBMLVERSION] = 'EBMLVersion'; + $EBMLidList[EBML_ID_EDITIONENTRY] = 'EditionEntry'; + $EBMLidList[EBML_ID_EDITIONFLAGDEFAULT] = 'EditionFlagDefault'; + $EBMLidList[EBML_ID_EDITIONFLAGHIDDEN] = 'EditionFlagHidden'; + $EBMLidList[EBML_ID_EDITIONFLAGORDERED] = 'EditionFlagOrdered'; + $EBMLidList[EBML_ID_EDITIONUID] = 'EditionUID'; + $EBMLidList[EBML_ID_FILEDATA] = 'FileData'; + $EBMLidList[EBML_ID_FILEDESCRIPTION] = 'FileDescription'; + $EBMLidList[EBML_ID_FILEMIMETYPE] = 'FileMimeType'; + $EBMLidList[EBML_ID_FILENAME] = 'FileName'; + $EBMLidList[EBML_ID_FILEREFERRAL] = 'FileReferral'; + $EBMLidList[EBML_ID_FILEUID] = 'FileUID'; + $EBMLidList[EBML_ID_FLAGDEFAULT] = 'FlagDefault'; + $EBMLidList[EBML_ID_FLAGENABLED] = 'FlagEnabled'; + $EBMLidList[EBML_ID_FLAGFORCED] = 'FlagForced'; + $EBMLidList[EBML_ID_FLAGINTERLACED] = 'FlagInterlaced'; + $EBMLidList[EBML_ID_FLAGLACING] = 'FlagLacing'; + $EBMLidList[EBML_ID_GAMMAVALUE] = 'GammaValue'; + $EBMLidList[EBML_ID_INFO] = 'Info'; + $EBMLidList[EBML_ID_LANGUAGE] = 'Language'; + $EBMLidList[EBML_ID_MAXBLOCKADDITIONID] = 'MaxBlockAdditionID'; + $EBMLidList[EBML_ID_MAXCACHE] = 'MaxCache'; + $EBMLidList[EBML_ID_MINCACHE] = 'MinCache'; + $EBMLidList[EBML_ID_MUXINGAPP] = 'MuxingApp'; + $EBMLidList[EBML_ID_NAME] = 'Name'; + $EBMLidList[EBML_ID_NEXTFILENAME] = 'NextFilename'; + $EBMLidList[EBML_ID_NEXTUID] = 'NextUID'; + $EBMLidList[EBML_ID_OUTPUTSAMPLINGFREQUENCY] = 'OutputSamplingFrequency'; + $EBMLidList[EBML_ID_PIXELCROPBOTTOM] = 'PixelCropBottom'; + $EBMLidList[EBML_ID_PIXELCROPLEFT] = 'PixelCropLeft'; + $EBMLidList[EBML_ID_PIXELCROPRIGHT] = 'PixelCropRight'; + $EBMLidList[EBML_ID_PIXELCROPTOP] = 'PixelCropTop'; + $EBMLidList[EBML_ID_PIXELHEIGHT] = 'PixelHeight'; + $EBMLidList[EBML_ID_PIXELWIDTH] = 'PixelWidth'; + $EBMLidList[EBML_ID_PREVFILENAME] = 'PrevFilename'; + $EBMLidList[EBML_ID_PREVUID] = 'PrevUID'; + $EBMLidList[EBML_ID_SAMPLINGFREQUENCY] = 'SamplingFrequency'; + $EBMLidList[EBML_ID_SEEK] = 'Seek'; + $EBMLidList[EBML_ID_SEEKHEAD] = 'SeekHead'; + $EBMLidList[EBML_ID_SEEKID] = 'SeekID'; + $EBMLidList[EBML_ID_SEEKPOSITION] = 'SeekPosition'; + $EBMLidList[EBML_ID_SEGMENT] = 'Segment'; + $EBMLidList[EBML_ID_SEGMENTFAMILY] = 'SegmentFamily'; + $EBMLidList[EBML_ID_SEGMENTFILENAME] = 'SegmentFilename'; + $EBMLidList[EBML_ID_SEGMENTUID] = 'SegmentUID'; + $EBMLidList[EBML_ID_SIMPLETAG] = 'SimpleTag'; + $EBMLidList[EBML_ID_CLUSTERSLICES] = 'ClusterSlices'; + $EBMLidList[EBML_ID_STEREOMODE] = 'StereoMode'; + $EBMLidList[EBML_ID_OLDSTEREOMODE] = 'OldStereoMode'; + $EBMLidList[EBML_ID_TAG] = 'Tag'; + $EBMLidList[EBML_ID_TAGATTACHMENTUID] = 'TagAttachmentUID'; + $EBMLidList[EBML_ID_TAGBINARY] = 'TagBinary'; + $EBMLidList[EBML_ID_TAGCHAPTERUID] = 'TagChapterUID'; + $EBMLidList[EBML_ID_TAGDEFAULT] = 'TagDefault'; + $EBMLidList[EBML_ID_TAGEDITIONUID] = 'TagEditionUID'; + $EBMLidList[EBML_ID_TAGLANGUAGE] = 'TagLanguage'; + $EBMLidList[EBML_ID_TAGNAME] = 'TagName'; + $EBMLidList[EBML_ID_TAGTRACKUID] = 'TagTrackUID'; + $EBMLidList[EBML_ID_TAGS] = 'Tags'; + $EBMLidList[EBML_ID_TAGSTRING] = 'TagString'; + $EBMLidList[EBML_ID_TARGETS] = 'Targets'; + $EBMLidList[EBML_ID_TARGETTYPE] = 'TargetType'; + $EBMLidList[EBML_ID_TARGETTYPEVALUE] = 'TargetTypeValue'; + $EBMLidList[EBML_ID_TIMECODESCALE] = 'TimecodeScale'; + $EBMLidList[EBML_ID_TITLE] = 'Title'; + $EBMLidList[EBML_ID_TRACKENTRY] = 'TrackEntry'; + $EBMLidList[EBML_ID_TRACKNUMBER] = 'TrackNumber'; + $EBMLidList[EBML_ID_TRACKOFFSET] = 'TrackOffset'; + $EBMLidList[EBML_ID_TRACKOVERLAY] = 'TrackOverlay'; + $EBMLidList[EBML_ID_TRACKS] = 'Tracks'; + $EBMLidList[EBML_ID_TRACKTIMECODESCALE] = 'TrackTimecodeScale'; + $EBMLidList[EBML_ID_TRACKTRANSLATE] = 'TrackTranslate'; + $EBMLidList[EBML_ID_TRACKTRANSLATECODEC] = 'TrackTranslateCodec'; + $EBMLidList[EBML_ID_TRACKTRANSLATEEDITIONUID] = 'TrackTranslateEditionUID'; + $EBMLidList[EBML_ID_TRACKTRANSLATETRACKID] = 'TrackTranslateTrackID'; + $EBMLidList[EBML_ID_TRACKTYPE] = 'TrackType'; + $EBMLidList[EBML_ID_TRACKUID] = 'TrackUID'; + $EBMLidList[EBML_ID_VIDEO] = 'Video'; + $EBMLidList[EBML_ID_VOID] = 'Void'; + $EBMLidList[EBML_ID_WRITINGAPP] = 'WritingApp'; + } + + return (isset($EBMLidList[$value]) ? $EBMLidList[$value] : dechex($value)); + } + + public static function displayUnit($value) { + // http://www.matroska.org/technical/specs/index.html#DisplayUnit + static $units = array( + 0 => 'pixels', + 1 => 'centimeters', + 2 => 'inches', + 3 => 'Display Aspect Ratio'); + + return (isset($units[$value]) ? $units[$value] : 'unknown'); + } + + private static function getDefaultStreamInfo($streams) + { + foreach (array_reverse($streams) as $stream) { + if ($stream['default']) { + break; + } + } + + $unset = array('default', 'name'); + foreach ($unset as $u) { + if (isset($stream[$u])) { + unset($stream[$u]); + } + } + + $info = $stream; + $info['streams'] = $streams; + + return $info; + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio-video.mpeg.php b/extensions/TimedMediaHandler/libs/getid3/module.audio-video.mpeg.php new file mode 100644 index 00000000..999c5d9a --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio-video.mpeg.php @@ -0,0 +1,296 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio-video.mpeg.php // +// module for analyzing MPEG files // +// dependencies: module.audio.mp3.php // +// /// +///////////////////////////////////////////////////////////////// + +getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true); + +define('GETID3_MPEG_VIDEO_PICTURE_START', "\x00\x00\x01\x00"); +define('GETID3_MPEG_VIDEO_USER_DATA_START', "\x00\x00\x01\xB2"); +define('GETID3_MPEG_VIDEO_SEQUENCE_HEADER', "\x00\x00\x01\xB3"); +define('GETID3_MPEG_VIDEO_SEQUENCE_ERROR', "\x00\x00\x01\xB4"); +define('GETID3_MPEG_VIDEO_EXTENSION_START', "\x00\x00\x01\xB5"); +define('GETID3_MPEG_VIDEO_SEQUENCE_END', "\x00\x00\x01\xB7"); +define('GETID3_MPEG_VIDEO_GROUP_START', "\x00\x00\x01\xB8"); +define('GETID3_MPEG_AUDIO_START', "\x00\x00\x01\xC0"); + + +class getid3_mpeg extends getid3_handler +{ + + public function Analyze() { + $info = &$this->getid3->info; + + if ($info['avdataend'] <= $info['avdataoffset']) { + $info['error'][] = '"avdataend" ('.$info['avdataend'].') is unexpectedly less-than-or-equal-to "avdataoffset" ('.$info['avdataoffset'].')'; + return false; + } + $info['fileformat'] = 'mpeg'; + fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); + $MPEGstreamData = fread($this->getid3->fp, min(100000, $info['avdataend'] - $info['avdataoffset'])); + $MPEGstreamDataLength = strlen($MPEGstreamData); + + $foundVideo = true; + $VideoChunkOffset = 0; + while (substr($MPEGstreamData, $VideoChunkOffset++, 4) !== GETID3_MPEG_VIDEO_SEQUENCE_HEADER) { + if ($VideoChunkOffset >= $MPEGstreamDataLength) { + $foundVideo = false; + break; + } + } + if ($foundVideo) { + + // Start code 32 bits + // horizontal frame size 12 bits + // vertical frame size 12 bits + // pixel aspect ratio 4 bits + // frame rate 4 bits + // bitrate 18 bits + // marker bit 1 bit + // VBV buffer size 10 bits + // constrained parameter flag 1 bit + // intra quant. matrix flag 1 bit + // intra quant. matrix values 512 bits (present if matrix flag == 1) + // non-intra quant. matrix flag 1 bit + // non-intra quant. matrix values 512 bits (present if matrix flag == 1) + + $info['video']['dataformat'] = 'mpeg'; + + $VideoChunkOffset += (strlen(GETID3_MPEG_VIDEO_SEQUENCE_HEADER) - 1); + + $FrameSizeDWORD = getid3_lib::BigEndian2Int(substr($MPEGstreamData, $VideoChunkOffset, 3)); + $VideoChunkOffset += 3; + + $AspectRatioFrameRateDWORD = getid3_lib::BigEndian2Int(substr($MPEGstreamData, $VideoChunkOffset, 1)); + $VideoChunkOffset += 1; + + $assortedinformation = getid3_lib::BigEndian2Bin(substr($MPEGstreamData, $VideoChunkOffset, 4)); + $VideoChunkOffset += 4; + + $info['mpeg']['video']['raw']['framesize_horizontal'] = ($FrameSizeDWORD & 0xFFF000) >> 12; // 12 bits for horizontal frame size + $info['mpeg']['video']['raw']['framesize_vertical'] = ($FrameSizeDWORD & 0x000FFF); // 12 bits for vertical frame size + $info['mpeg']['video']['raw']['pixel_aspect_ratio'] = ($AspectRatioFrameRateDWORD & 0xF0) >> 4; + $info['mpeg']['video']['raw']['frame_rate'] = ($AspectRatioFrameRateDWORD & 0x0F); + + $info['mpeg']['video']['framesize_horizontal'] = $info['mpeg']['video']['raw']['framesize_horizontal']; + $info['mpeg']['video']['framesize_vertical'] = $info['mpeg']['video']['raw']['framesize_vertical']; + + $info['mpeg']['video']['pixel_aspect_ratio'] = $this->MPEGvideoAspectRatioLookup($info['mpeg']['video']['raw']['pixel_aspect_ratio']); + $info['mpeg']['video']['pixel_aspect_ratio_text'] = $this->MPEGvideoAspectRatioTextLookup($info['mpeg']['video']['raw']['pixel_aspect_ratio']); + $info['mpeg']['video']['frame_rate'] = $this->MPEGvideoFramerateLookup($info['mpeg']['video']['raw']['frame_rate']); + + $info['mpeg']['video']['raw']['bitrate'] = getid3_lib::Bin2Dec(substr($assortedinformation, 0, 18)); + $info['mpeg']['video']['raw']['marker_bit'] = (bool) getid3_lib::Bin2Dec(substr($assortedinformation, 18, 1)); + $info['mpeg']['video']['raw']['vbv_buffer_size'] = getid3_lib::Bin2Dec(substr($assortedinformation, 19, 10)); + $info['mpeg']['video']['raw']['constrained_param_flag'] = (bool) getid3_lib::Bin2Dec(substr($assortedinformation, 29, 1)); + $info['mpeg']['video']['raw']['intra_quant_flag'] = (bool) getid3_lib::Bin2Dec(substr($assortedinformation, 30, 1)); + if ($info['mpeg']['video']['raw']['intra_quant_flag']) { + + // read 512 bits + $info['mpeg']['video']['raw']['intra_quant'] = getid3_lib::BigEndian2Bin(substr($MPEGstreamData, $VideoChunkOffset, 64)); + $VideoChunkOffset += 64; + + $info['mpeg']['video']['raw']['non_intra_quant_flag'] = (bool) getid3_lib::Bin2Dec(substr($info['mpeg']['video']['raw']['intra_quant'], 511, 1)); + $info['mpeg']['video']['raw']['intra_quant'] = getid3_lib::Bin2Dec(substr($assortedinformation, 31, 1)).substr(getid3_lib::BigEndian2Bin(substr($MPEGstreamData, $VideoChunkOffset, 64)), 0, 511); + + if ($info['mpeg']['video']['raw']['non_intra_quant_flag']) { + $info['mpeg']['video']['raw']['non_intra_quant'] = substr($MPEGstreamData, $VideoChunkOffset, 64); + $VideoChunkOffset += 64; + } + + } else { + + $info['mpeg']['video']['raw']['non_intra_quant_flag'] = (bool) getid3_lib::Bin2Dec(substr($assortedinformation, 31, 1)); + if ($info['mpeg']['video']['raw']['non_intra_quant_flag']) { + $info['mpeg']['video']['raw']['non_intra_quant'] = substr($MPEGstreamData, $VideoChunkOffset, 64); + $VideoChunkOffset += 64; + } + + } + + if ($info['mpeg']['video']['raw']['bitrate'] == 0x3FFFF) { // 18 set bits + + $info['warning'][] = 'This version of getID3() ['.$this->getid3->version().'] cannot determine average bitrate of VBR MPEG video files'; + $info['mpeg']['video']['bitrate_mode'] = 'vbr'; + + } else { + + $info['mpeg']['video']['bitrate'] = $info['mpeg']['video']['raw']['bitrate'] * 400; + $info['mpeg']['video']['bitrate_mode'] = 'cbr'; + $info['video']['bitrate'] = $info['mpeg']['video']['bitrate']; + + } + + $info['video']['resolution_x'] = $info['mpeg']['video']['framesize_horizontal']; + $info['video']['resolution_y'] = $info['mpeg']['video']['framesize_vertical']; + $info['video']['frame_rate'] = $info['mpeg']['video']['frame_rate']; + $info['video']['bitrate_mode'] = $info['mpeg']['video']['bitrate_mode']; + $info['video']['pixel_aspect_ratio'] = $info['mpeg']['video']['pixel_aspect_ratio']; + $info['video']['lossless'] = false; + $info['video']['bits_per_sample'] = 24; + + } else { + + $info['error'][] = 'Could not find start of video block in the first 100,000 bytes (or before end of file) - this might not be an MPEG-video file?'; + + } + + //0x000001B3 begins the sequence_header of every MPEG video stream. + //But in MPEG-2, this header must immediately be followed by an + //extension_start_code (0x000001B5) with a sequence_extension ID (1). + //(This extension contains all the additional MPEG-2 stuff.) + //MPEG-1 doesn't have this extension, so that's a sure way to tell the + //difference between MPEG-1 and MPEG-2 video streams. + + if (substr($MPEGstreamData, $VideoChunkOffset, 4) == GETID3_MPEG_VIDEO_EXTENSION_START) { + $info['video']['codec'] = 'MPEG-2'; + } else { + $info['video']['codec'] = 'MPEG-1'; + } + + + $AudioChunkOffset = 0; + while (true) { + while (substr($MPEGstreamData, $AudioChunkOffset++, 4) !== GETID3_MPEG_AUDIO_START) { + if ($AudioChunkOffset >= $MPEGstreamDataLength) { + break 2; + } + } + + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_temp->info = $info; + $getid3_mp3 = new getid3_mp3($getid3_temp); + for ($i = 0; $i <= 7; $i++) { + // some files have the MPEG-audio header 8 bytes after the end of the $00 $00 $01 $C0 signature, some have it up to 13 bytes (or more?) after + // I have no idea why or what the difference is, so this is a stupid hack. + // If anybody has any better idea of what's going on, please let me know - info@getid3.org + fseek($getid3_temp->fp, ftell($this->getid3->fp), SEEK_SET); + $getid3_temp->info = $info; // only overwrite real data if valid header found + if ($getid3_mp3->decodeMPEGaudioHeader(($AudioChunkOffset + 3) + 8 + $i, $getid3_temp->info, false)) { + $info = $getid3_temp->info; + $info['audio']['bitrate_mode'] = 'cbr'; + $info['audio']['lossless'] = false; + unset($getid3_temp, $getid3_mp3); + break 2; + } + } + unset($getid3_temp, $getid3_mp3); + } + + // Temporary hack to account for interleaving overhead: + if (!empty($info['video']['bitrate']) && !empty($info['audio']['bitrate'])) { + $info['playtime_seconds'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / ($info['video']['bitrate'] + $info['audio']['bitrate']); + + // Interleaved MPEG audio/video files have a certain amount of overhead that varies + // by both video and audio bitrates, and not in any sensible, linear/logarithmic patter + // Use interpolated lookup tables to approximately guess how much is overhead, because + // playtime is calculated as filesize / total-bitrate + $info['playtime_seconds'] *= $this->MPEGsystemNonOverheadPercentage($info['video']['bitrate'], $info['audio']['bitrate']); + + //switch ($info['video']['bitrate']) { + // case('5000000'): + // $multiplier = 0.93292642112380355828048824319889; + // break; + // case('5500000'): + // $multiplier = 0.93582895375200989965359777343219; + // break; + // case('6000000'): + // $multiplier = 0.93796247714820932532911373859139; + // break; + // case('7000000'): + // $multiplier = 0.9413264083635103463010117778776; + // break; + // default: + // $multiplier = 1; + // break; + //} + //$info['playtime_seconds'] *= $multiplier; + //$info['warning'][] = 'Interleaved MPEG audio/video playtime may be inaccurate. With current hack should be within a few seconds of accurate. Report to info@getid3.org if off by more than 10 seconds.'; + if ($info['video']['bitrate'] < 50000) { + $info['warning'][] = 'Interleaved MPEG audio/video playtime may be slightly inaccurate for video bitrates below 100kbps. Except in extreme low-bitrate situations, error should be less than 1%. Report to info@getid3.org if greater than this.'; + } + } + + return true; + } + + + public function MPEGsystemNonOverheadPercentage($VideoBitrate, $AudioBitrate) { + $OverheadPercentage = 0; + + $AudioBitrate = max(min($AudioBitrate / 1000, 384), 32); // limit to range of 32kbps - 384kbps (should be only legal bitrates, but maybe VBR?) + $VideoBitrate = max(min($VideoBitrate / 1000, 10000), 10); // limit to range of 10kbps - 10Mbps (beyond that curves flatten anyways, no big loss) + + + //OMBB[audiobitrate] = array(video-10kbps, video-100kbps, video-1000kbps, video-10000kbps) + $OverheadMultiplierByBitrate[32] = array(0, 0.9676287944368530, 0.9802276264360310, 0.9844916183244460, 0.9852821845179940); + $OverheadMultiplierByBitrate[48] = array(0, 0.9779100089209830, 0.9787770035359320, 0.9846738664076130, 0.9852683013799960); + $OverheadMultiplierByBitrate[56] = array(0, 0.9731249855367600, 0.9776624308938040, 0.9832606361852130, 0.9843922606633340); + $OverheadMultiplierByBitrate[64] = array(0, 0.9755642683275760, 0.9795256705493390, 0.9836573009193170, 0.9851122539404470); + $OverheadMultiplierByBitrate[96] = array(0, 0.9788025247497290, 0.9798553314148700, 0.9822956869792560, 0.9834815119124690); + $OverheadMultiplierByBitrate[128] = array(0, 0.9816940050925480, 0.9821675936072120, 0.9829756927470870, 0.9839763420152050); + $OverheadMultiplierByBitrate[160] = array(0, 0.9825894094561180, 0.9820913399073960, 0.9823907143253970, 0.9832821783651570); + $OverheadMultiplierByBitrate[192] = array(0, 0.9832038474336260, 0.9825731694317960, 0.9821028622712400, 0.9828262076447620); + $OverheadMultiplierByBitrate[224] = array(0, 0.9836516298538770, 0.9824718601823890, 0.9818302180625380, 0.9823735101626480); + $OverheadMultiplierByBitrate[256] = array(0, 0.9845863022094920, 0.9837229411967540, 0.9824521662210830, 0.9828645172100790); + $OverheadMultiplierByBitrate[320] = array(0, 0.9849565280263180, 0.9837683142805110, 0.9822885275960400, 0.9824424382727190); + $OverheadMultiplierByBitrate[384] = array(0, 0.9856094774357600, 0.9844573394432720, 0.9825970399837330, 0.9824673808303890); + + $BitrateToUseMin = 32; + $BitrateToUseMax = 32; + $previousBitrate = 32; + foreach ($OverheadMultiplierByBitrate as $key => $value) { + if ($AudioBitrate >= $previousBitrate) { + $BitrateToUseMin = $previousBitrate; + } + if ($AudioBitrate < $key) { + $BitrateToUseMax = $key; + break; + } + $previousBitrate = $key; + } + $FactorA = ($BitrateToUseMax - $AudioBitrate) / ($BitrateToUseMax - $BitrateToUseMin); + + $VideoBitrateLog10 = log10($VideoBitrate); + $VideoFactorMin1 = $OverheadMultiplierByBitrate[$BitrateToUseMin][floor($VideoBitrateLog10)]; + $VideoFactorMin2 = $OverheadMultiplierByBitrate[$BitrateToUseMax][floor($VideoBitrateLog10)]; + $VideoFactorMax1 = $OverheadMultiplierByBitrate[$BitrateToUseMin][ceil($VideoBitrateLog10)]; + $VideoFactorMax2 = $OverheadMultiplierByBitrate[$BitrateToUseMax][ceil($VideoBitrateLog10)]; + $FactorV = $VideoBitrateLog10 - floor($VideoBitrateLog10); + + $OverheadPercentage = $VideoFactorMin1 * $FactorA * $FactorV; + $OverheadPercentage += $VideoFactorMin2 * (1 - $FactorA) * $FactorV; + $OverheadPercentage += $VideoFactorMax1 * $FactorA * (1 - $FactorV); + $OverheadPercentage += $VideoFactorMax2 * (1 - $FactorA) * (1 - $FactorV); + + return $OverheadPercentage; + } + + + public function MPEGvideoFramerateLookup($rawframerate) { + $MPEGvideoFramerateLookup = array(0, 23.976, 24, 25, 29.97, 30, 50, 59.94, 60); + return (isset($MPEGvideoFramerateLookup[$rawframerate]) ? (float) $MPEGvideoFramerateLookup[$rawframerate] : (float) 0); + } + + public function MPEGvideoAspectRatioLookup($rawaspectratio) { + $MPEGvideoAspectRatioLookup = array(0, 1, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, 0.8935, 0.9157, 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, 1.2015, 0); + return (isset($MPEGvideoAspectRatioLookup[$rawaspectratio]) ? (float) $MPEGvideoAspectRatioLookup[$rawaspectratio] : (float) 0); + } + + public function MPEGvideoAspectRatioTextLookup($rawaspectratio) { + $MPEGvideoAspectRatioTextLookup = array('forbidden', 'square pixels', '0.6735', '16:9, 625 line, PAL', '0.7615', '0.8055', '16:9, 525 line, NTSC', '0.8935', '4:3, 625 line, PAL, CCIR601', '0.9815', '1.0255', '1.0695', '4:3, 525 line, NTSC, CCIR601', '1.1575', '1.2015', 'reserved'); + return (isset($MPEGvideoAspectRatioTextLookup[$rawaspectratio]) ? $MPEGvideoAspectRatioTextLookup[$rawaspectratio] : ''); + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio-video.quicktime.php b/extensions/TimedMediaHandler/libs/getid3/module.audio-video.quicktime.php new file mode 100644 index 00000000..e59d61cc --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio-video.quicktime.php @@ -0,0 +1,2192 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio-video.quicktime.php // +// module for analyzing Quicktime and MP3-in-MP4 files // +// dependencies: module.audio.mp3.php // +// /// +///////////////////////////////////////////////////////////////// + +getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true); + +class getid3_quicktime extends getid3_handler +{ + + public $ReturnAtomData = true; + public $ParseAllPossibleAtoms = false; + + public function Analyze() { + $info = &$this->getid3->info; + + $info['fileformat'] = 'quicktime'; + $info['quicktime']['hinting'] = false; + $info['quicktime']['controller'] = 'standard'; // may be overridden if 'ctyp' atom is present + + fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); + + $offset = 0; + $atomcounter = 0; + + while ($offset < $info['avdataend']) { + if (!getid3_lib::intValueSupported($offset)) { + $info['error'][] = 'Unable to parse atom at offset '.$offset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions'; + break; + } + fseek($this->getid3->fp, $offset, SEEK_SET); + $AtomHeader = fread($this->getid3->fp, 8); + + $atomsize = getid3_lib::BigEndian2Int(substr($AtomHeader, 0, 4)); + $atomname = substr($AtomHeader, 4, 4); + + // 64-bit MOV patch by jlegateŲktnc*com + if ($atomsize == 1) { + $atomsize = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 8)); + } + + $info['quicktime'][$atomname]['name'] = $atomname; + $info['quicktime'][$atomname]['size'] = $atomsize; + $info['quicktime'][$atomname]['offset'] = $offset; + + if (($offset + $atomsize) > $info['avdataend']) { + $info['error'][] = 'Atom at offset '.$offset.' claims to go beyond end-of-file (length: '.$atomsize.' bytes)'; + return false; + } + + if ($atomsize == 0) { + // Furthermore, for historical reasons the list of atoms is optionally + // terminated by a 32-bit integer set to 0. If you are writing a program + // to read user data atoms, you should allow for the terminating 0. + break; + } + switch ($atomname) { + case 'mdat': // Media DATa atom + // 'mdat' contains the actual data for the audio/video + if (($atomsize > 8) && (!isset($info['avdataend_tmp']) || ($info['quicktime'][$atomname]['size'] > ($info['avdataend_tmp'] - $info['avdataoffset'])))) { + + $info['avdataoffset'] = $info['quicktime'][$atomname]['offset'] + 8; + $OldAVDataEnd = $info['avdataend']; + $info['avdataend'] = $info['quicktime'][$atomname]['offset'] + $info['quicktime'][$atomname]['size']; + + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_temp->info['avdataoffset'] = $info['avdataoffset']; + $getid3_temp->info['avdataend'] = $info['avdataend']; + $getid3_mp3 = new getid3_mp3($getid3_temp); + if ($getid3_mp3->MPEGaudioHeaderValid($getid3_mp3->MPEGaudioHeaderDecode(fread($this->getid3->fp, 4)))) { + $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false); + if (!empty($getid3_temp->info['warning'])) { + foreach ($getid3_temp->info['warning'] as $value) { + $info['warning'][] = $value; + } + } + if (!empty($getid3_temp->info['mpeg'])) { + $info['mpeg'] = $getid3_temp->info['mpeg']; + if (isset($info['mpeg']['audio'])) { + $info['audio']['dataformat'] = 'mp3'; + $info['audio']['codec'] = (!empty($info['mpeg']['audio']['encoder']) ? $info['mpeg']['audio']['encoder'] : (!empty($info['mpeg']['audio']['codec']) ? $info['mpeg']['audio']['codec'] : (!empty($info['mpeg']['audio']['LAME']) ? 'LAME' :'mp3'))); + $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate']; + $info['audio']['channels'] = $info['mpeg']['audio']['channels']; + $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate']; + $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']); + $info['bitrate'] = $info['audio']['bitrate']; + } + } + } + unset($getid3_mp3, $getid3_temp); + $info['avdataend'] = $OldAVDataEnd; + unset($OldAVDataEnd); + + } + break; + + case 'free': // FREE space atom + case 'skip': // SKIP atom + case 'wide': // 64-bit expansion placeholder atom + // 'free', 'skip' and 'wide' are just padding, contains no useful data at all + break; + + default: + $atomHierarchy = array(); + $info['quicktime'][$atomname] = $this->QuicktimeParseAtom($atomname, $atomsize, fread($this->getid3->fp, $atomsize), $offset, $atomHierarchy, $this->ParseAllPossibleAtoms); + break; + } + + $offset += $atomsize; + $atomcounter++; + } + + if (!empty($info['avdataend_tmp'])) { + // this value is assigned to a temp value and then erased because + // otherwise any atoms beyond the 'mdat' atom would not get parsed + $info['avdataend'] = $info['avdataend_tmp']; + unset($info['avdataend_tmp']); + } + + if (!isset($info['bitrate']) && isset($info['playtime_seconds'])) { + $info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds']; + } + if (isset($info['bitrate']) && !isset($info['audio']['bitrate']) && !isset($info['quicktime']['video'])) { + $info['audio']['bitrate'] = $info['bitrate']; + } + if (!empty($info['playtime_seconds']) && !isset($info['video']['frame_rate']) && !empty($info['quicktime']['stts_framecount'])) { + foreach ($info['quicktime']['stts_framecount'] as $key => $samples_count) { + $samples_per_second = $samples_count / $info['playtime_seconds']; + if ($samples_per_second > 240) { + // has to be audio samples + } else { + $info['video']['frame_rate'] = $samples_per_second; + break; + } + } + } + if (($info['audio']['dataformat'] == 'mp4') && empty($info['video']['resolution_x'])) { + $info['fileformat'] = 'mp4'; + $info['mime_type'] = 'audio/mp4'; + unset($info['video']['dataformat']); + } + + if (!$this->ReturnAtomData) { + unset($info['quicktime']['moov']); + } + + if (empty($info['audio']['dataformat']) && !empty($info['quicktime']['audio'])) { + $info['audio']['dataformat'] = 'quicktime'; + } + if (empty($info['video']['dataformat']) && !empty($info['quicktime']['video'])) { + $info['video']['dataformat'] = 'quicktime'; + } + + return true; + } + + public function QuicktimeParseAtom($atomname, $atomsize, $atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) { + // http://developer.apple.com/techpubs/quicktime/qtdevdocs/APIREF/INDEX/atomalphaindex.htm + + $info = &$this->getid3->info; + + $atom_parent = array_pop($atomHierarchy); + array_push($atomHierarchy, $atomname); + $atom_structure['hierarchy'] = implode(' ', $atomHierarchy); + $atom_structure['name'] = $atomname; + $atom_structure['size'] = $atomsize; + $atom_structure['offset'] = $baseoffset; +//echo getid3_lib::PrintHexBytes(substr($atom_data, 0, 8)).'<br>'; +//echo getid3_lib::PrintHexBytes(substr($atom_data, 0, 8), false).'<br><br>'; + switch ($atomname) { + case 'moov': // MOVie container atom + case 'trak': // TRAcK container atom + case 'clip': // CLIPping container atom + case 'matt': // track MATTe container atom + case 'edts': // EDiTS container atom + case 'tref': // Track REFerence container atom + case 'mdia': // MeDIA container atom + case 'minf': // Media INFormation container atom + case 'dinf': // Data INFormation container atom + case 'udta': // User DaTA container atom + case 'cmov': // Compressed MOVie container atom + case 'rmra': // Reference Movie Record Atom + case 'rmda': // Reference Movie Descriptor Atom + case 'gmhd': // Generic Media info HeaDer atom (seen on QTVR) + $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); + break; + + case 'ilst': // Item LiST container atom + $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); + + // some "ilst" atoms contain data atoms that have a numeric name, and the data is far more accessible if the returned array is compacted + $allnumericnames = true; + foreach ($atom_structure['subatoms'] as $subatomarray) { + if (!is_integer($subatomarray['name']) || (count($subatomarray['subatoms']) != 1)) { + $allnumericnames = false; + break; + } + } + if ($allnumericnames) { + $newData = array(); + foreach ($atom_structure['subatoms'] as $subatomarray) { + foreach ($subatomarray['subatoms'] as $newData_subatomarray) { + unset($newData_subatomarray['hierarchy'], $newData_subatomarray['name']); + $newData[$subatomarray['name']] = $newData_subatomarray; + break; + } + } + $atom_structure['data'] = $newData; + unset($atom_structure['subatoms']); + } + break; + + case "\x00\x00\x00\x01": + case "\x00\x00\x00\x02": + case "\x00\x00\x00\x03": + case "\x00\x00\x00\x04": + case "\x00\x00\x00\x05": + $atomname = getid3_lib::BigEndian2Int($atomname); + $atom_structure['name'] = $atomname; + $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); + break; + + case 'stbl': // Sample TaBLe container atom + $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); + $isVideo = false; + $framerate = 0; + $framecount = 0; + foreach ($atom_structure['subatoms'] as $key => $value_array) { + if (isset($value_array['sample_description_table'])) { + foreach ($value_array['sample_description_table'] as $key2 => $value_array2) { + if (isset($value_array2['data_format'])) { + switch ($value_array2['data_format']) { + case 'avc1': + case 'mp4v': + // video data + $isVideo = true; + break; + case 'mp4a': + // audio data + break; + } + } + } + } elseif (isset($value_array['time_to_sample_table'])) { + foreach ($value_array['time_to_sample_table'] as $key2 => $value_array2) { + if (isset($value_array2['sample_count']) && isset($value_array2['sample_duration']) && ($value_array2['sample_duration'] > 0)) { + $framerate = round($info['quicktime']['time_scale'] / $value_array2['sample_duration'], 3); + $framecount = $value_array2['sample_count']; + } + } + } + } + if ($isVideo && $framerate) { + $info['quicktime']['video']['frame_rate'] = $framerate; + $info['video']['frame_rate'] = $info['quicktime']['video']['frame_rate']; + } + if ($isVideo && $framecount) { + $info['quicktime']['video']['frame_count'] = $framecount; + } + break; + + + case 'aART': // Album ARTist + case 'catg': // CaTeGory + case 'covr': // COVeR artwork + case 'cpil': // ComPILation + case 'cprt': // CoPyRighT + case 'desc': // DESCription + case 'disk': // DISK number + case 'egid': // Episode Global ID + case 'gnre': // GeNRE + case 'keyw': // KEYWord + case 'ldes': + case 'pcst': // PodCaST + case 'pgap': // GAPless Playback + case 'purd': // PURchase Date + case 'purl': // Podcast URL + case 'rati': + case 'rndu': + case 'rpdu': + case 'rtng': // RaTiNG + case 'stik': + case 'tmpo': // TeMPO (BPM) + case 'trkn': // TRacK Number + case 'tves': // TV EpiSode + case 'tvnn': // TV Network Name + case 'tvsh': // TV SHow Name + case 'tvsn': // TV SeasoN + case 'akID': // iTunes store account type + case 'apID': + case 'atID': + case 'cmID': + case 'cnID': + case 'geID': + case 'plID': + case 'sfID': // iTunes store country + case '©alb': // ALBum + case '©art': // ARTist + case '©ART': + case '©aut': + case '©cmt': // CoMmenT + case '©com': // COMposer + case '©cpy': + case '©day': // content created year + case '©dir': + case '©ed1': + case '©ed2': + case '©ed3': + case '©ed4': + case '©ed5': + case '©ed6': + case '©ed7': + case '©ed8': + case '©ed9': + case '©enc': + case '©fmt': + case '©gen': // GENre + case '©grp': // GRouPing + case '©hst': + case '©inf': + case '©lyr': // LYRics + case '©mak': + case '©mod': + case '©nam': // full NAMe + case '©ope': + case '©PRD': + case '©prd': + case '©prf': + case '©req': + case '©src': + case '©swr': + case '©too': // encoder + case '©trk': // TRacK + case '©url': + case '©wrn': + case '©wrt': // WRiTer + case '----': // itunes specific + if ($atom_parent == 'udta') { + // User data atom handler + $atom_structure['data_length'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2)); + $atom_structure['language_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 2)); + $atom_structure['data'] = substr($atom_data, 4); + + $atom_structure['language'] = $this->QuicktimeLanguageLookup($atom_structure['language_id']); + if (empty($info['comments']['language']) || (!in_array($atom_structure['language'], $info['comments']['language']))) { + $info['comments']['language'][] = $atom_structure['language']; + } + } else { + // Apple item list box atom handler + $atomoffset = 0; + if (substr($atom_data, 2, 2) == "\x10\xB5") { + // not sure what it means, but observed on iPhone4 data. + // Each $atom_data has 2 bytes of datasize, plus 0x10B5, then data + while ($atomoffset < strlen($atom_data)) { + $boxsmallsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset, 2)); + $boxsmalltype = substr($atom_data, $atomoffset + 2, 2); + $boxsmalldata = substr($atom_data, $atomoffset + 4, $boxsmallsize); + switch ($boxsmalltype) { + case "\x10\xB5": + $atom_structure['data'] = $boxsmalldata; + break; + default: + $info['warning'][] = 'Unknown QuickTime smallbox type: "'.getid3_lib::PrintHexBytes($boxsmalltype).'" at offset '.$baseoffset; + $atom_structure['data'] = $atom_data; + break; + } + $atomoffset += (4 + $boxsmallsize); + } + } else { + while ($atomoffset < strlen($atom_data)) { + $boxsize = getid3_lib::BigEndian2Int(substr($atom_data, $atomoffset, 4)); + $boxtype = substr($atom_data, $atomoffset + 4, 4); + $boxdata = substr($atom_data, $atomoffset + 8, $boxsize - 8); + if ($boxsize <= 1) { + $info['warning'][] = 'Invalid QuickTime atom box size "'.$boxsize.'" in atom "'.$atomname.'" at offset: '.($atom_structure['offset'] + $atomoffset); + $atom_structure['data'] = null; + $atomoffset = strlen($atom_data); + break; + } + $atomoffset += $boxsize; + + switch ($boxtype) { + case 'mean': + case 'name': + $atom_structure[$boxtype] = substr($boxdata, 4); + break; + + case 'data': + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($boxdata, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($boxdata, 1, 3)); + switch ($atom_structure['flags_raw']) { + case 0: // data flag + case 21: // tmpo/cpil flag + switch ($atomname) { + case 'cpil': + case 'pcst': + case 'pgap': + $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1)); + break; + + case 'tmpo': + $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 2)); + break; + + case 'disk': + case 'trkn': + $num = getid3_lib::BigEndian2Int(substr($boxdata, 10, 2)); + $num_total = getid3_lib::BigEndian2Int(substr($boxdata, 12, 2)); + $atom_structure['data'] = empty($num) ? '' : $num; + $atom_structure['data'] .= empty($num_total) ? '' : '/'.$num_total; + break; + + case 'gnre': + $GenreID = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4)); + $atom_structure['data'] = getid3_id3v1::LookupGenreName($GenreID - 1); + break; + + case 'rtng': + $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1)); + $atom_structure['data'] = $this->QuicktimeContentRatingLookup($atom_structure[$atomname]); + break; + + case 'stik': + $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1)); + $atom_structure['data'] = $this->QuicktimeSTIKLookup($atom_structure[$atomname]); + break; + + case 'sfID': + $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4)); + $atom_structure['data'] = $this->QuicktimeStoreFrontCodeLookup($atom_structure[$atomname]); + break; + + case 'egid': + case 'purl': + $atom_structure['data'] = substr($boxdata, 8); + break; + + default: + $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4)); + } + break; + + case 1: // text flag + case 13: // image flag + default: + $atom_structure['data'] = substr($boxdata, 8); + break; + + } + break; + + default: + $info['warning'][] = 'Unknown QuickTime box type: "'.getid3_lib::PrintHexBytes($boxtype).'" at offset '.$baseoffset; + $atom_structure['data'] = $atom_data; + + } + } + } + } + $this->CopyToAppropriateCommentsSection($atomname, $atom_structure['data'], $atom_structure['name']); + break; + + + case 'play': // auto-PLAY atom + $atom_structure['autoplay'] = (bool) getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + + $info['quicktime']['autoplay'] = $atom_structure['autoplay']; + break; + + + case 'WLOC': // Window LOCation atom + $atom_structure['location_x'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2)); + $atom_structure['location_y'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 2)); + break; + + + case 'LOOP': // LOOPing atom + case 'SelO': // play SELection Only atom + case 'AllF': // play ALL Frames atom + $atom_structure['data'] = getid3_lib::BigEndian2Int($atom_data); + break; + + + case 'name': // + case 'MCPS': // Media Cleaner PRo + case '@PRM': // adobe PReMiere version + case '@PRQ': // adobe PRemiere Quicktime version + $atom_structure['data'] = $atom_data; + break; + + + case 'cmvd': // Compressed MooV Data atom + // Code by ubergeekŲubergeek*tv based on information from + // http://developer.apple.com/quicktime/icefloe/dispatch012.html + $atom_structure['unCompressedSize'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4)); + + $CompressedFileData = substr($atom_data, 4); + if ($UncompressedHeader = @gzuncompress($CompressedFileData)) { + $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($UncompressedHeader, 0, $atomHierarchy, $ParseAllPossibleAtoms); + } else { + $info['warning'][] = 'Error decompressing compressed MOV atom at offset '.$atom_structure['offset']; + } + break; + + + case 'dcom': // Data COMpression atom + $atom_structure['compression_id'] = $atom_data; + $atom_structure['compression_text'] = $this->QuicktimeDCOMLookup($atom_data); + break; + + + case 'rdrf': // Reference movie Data ReFerence atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); + $atom_structure['flags']['internal_data'] = (bool) ($atom_structure['flags_raw'] & 0x000001); + + $atom_structure['reference_type_name'] = substr($atom_data, 4, 4); + $atom_structure['reference_length'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 4)); + switch ($atom_structure['reference_type_name']) { + case 'url ': + $atom_structure['url'] = $this->NoNullString(substr($atom_data, 12)); + break; + + case 'alis': + $atom_structure['file_alias'] = substr($atom_data, 12); + break; + + case 'rsrc': + $atom_structure['resource_alias'] = substr($atom_data, 12); + break; + + default: + $atom_structure['data'] = substr($atom_data, 12); + break; + } + break; + + + case 'rmqu': // Reference Movie QUality atom + $atom_structure['movie_quality'] = getid3_lib::BigEndian2Int($atom_data); + break; + + + case 'rmcs': // Reference Movie Cpu Speed atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['cpu_speed_rating'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); + break; + + + case 'rmvc': // Reference Movie Version Check atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['gestalt_selector'] = substr($atom_data, 4, 4); + $atom_structure['gestalt_value_mask'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 4)); + $atom_structure['gestalt_value'] = getid3_lib::BigEndian2Int(substr($atom_data, 12, 4)); + $atom_structure['gestalt_check_type'] = getid3_lib::BigEndian2Int(substr($atom_data, 14, 2)); + break; + + + case 'rmcd': // Reference Movie Component check atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['component_type'] = substr($atom_data, 4, 4); + $atom_structure['component_subtype'] = substr($atom_data, 8, 4); + $atom_structure['component_manufacturer'] = substr($atom_data, 12, 4); + $atom_structure['component_flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4)); + $atom_structure['component_flags_mask'] = getid3_lib::BigEndian2Int(substr($atom_data, 20, 4)); + $atom_structure['component_min_version'] = getid3_lib::BigEndian2Int(substr($atom_data, 24, 4)); + break; + + + case 'rmdr': // Reference Movie Data Rate atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['data_rate'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + + $atom_structure['data_rate_bps'] = $atom_structure['data_rate'] * 10; + break; + + + case 'rmla': // Reference Movie Language Atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['language_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); + + $atom_structure['language'] = $this->QuicktimeLanguageLookup($atom_structure['language_id']); + if (empty($info['comments']['language']) || (!in_array($atom_structure['language'], $info['comments']['language']))) { + $info['comments']['language'][] = $atom_structure['language']; + } + break; + + + case 'rmla': // Reference Movie Language Atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['track_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); + break; + + + case 'ptv ': // Print To Video - defines a movie's full screen mode + // http://developer.apple.com/documentation/QuickTime/APIREF/SOURCESIV/at_ptv-_pg.htm + $atom_structure['display_size_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2)); + $atom_structure['reserved_1'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 2)); // hardcoded: 0x0000 + $atom_structure['reserved_2'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); // hardcoded: 0x0000 + $atom_structure['slide_show_flag'] = getid3_lib::BigEndian2Int(substr($atom_data, 6, 1)); + $atom_structure['play_on_open_flag'] = getid3_lib::BigEndian2Int(substr($atom_data, 7, 1)); + + $atom_structure['flags']['play_on_open'] = (bool) $atom_structure['play_on_open_flag']; + $atom_structure['flags']['slide_show'] = (bool) $atom_structure['slide_show_flag']; + + $ptv_lookup[0] = 'normal'; + $ptv_lookup[1] = 'double'; + $ptv_lookup[2] = 'half'; + $ptv_lookup[3] = 'full'; + $ptv_lookup[4] = 'current'; + if (isset($ptv_lookup[$atom_structure['display_size_raw']])) { + $atom_structure['display_size'] = $ptv_lookup[$atom_structure['display_size_raw']]; + } else { + $info['warning'][] = 'unknown "ptv " display constant ('.$atom_structure['display_size_raw'].')'; + } + break; + + + case 'stsd': // Sample Table Sample Description atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $stsdEntriesDataOffset = 8; + for ($i = 0; $i < $atom_structure['number_entries']; $i++) { + $atom_structure['sample_description_table'][$i]['size'] = getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 4)); + $stsdEntriesDataOffset += 4; + $atom_structure['sample_description_table'][$i]['data_format'] = substr($atom_data, $stsdEntriesDataOffset, 4); + $stsdEntriesDataOffset += 4; + $atom_structure['sample_description_table'][$i]['reserved'] = getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 6)); + $stsdEntriesDataOffset += 6; + $atom_structure['sample_description_table'][$i]['reference_index'] = getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 2)); + $stsdEntriesDataOffset += 2; + $atom_structure['sample_description_table'][$i]['data'] = substr($atom_data, $stsdEntriesDataOffset, ($atom_structure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2)); + $stsdEntriesDataOffset += ($atom_structure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2); + + $atom_structure['sample_description_table'][$i]['encoder_version'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 0, 2)); + $atom_structure['sample_description_table'][$i]['encoder_revision'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 2, 2)); + $atom_structure['sample_description_table'][$i]['encoder_vendor'] = substr($atom_structure['sample_description_table'][$i]['data'], 4, 4); + + switch ($atom_structure['sample_description_table'][$i]['encoder_vendor']) { + + case "\x00\x00\x00\x00": + // audio tracks + $atom_structure['sample_description_table'][$i]['audio_channels'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 8, 2)); + $atom_structure['sample_description_table'][$i]['audio_bit_depth'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 10, 2)); + $atom_structure['sample_description_table'][$i]['audio_compression_id'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12, 2)); + $atom_structure['sample_description_table'][$i]['audio_packet_size'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 14, 2)); + $atom_structure['sample_description_table'][$i]['audio_sample_rate'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 16, 4)); + + // video tracks + // http://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap3/qtff3.html + $atom_structure['sample_description_table'][$i]['temporal_quality'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 8, 4)); + $atom_structure['sample_description_table'][$i]['spatial_quality'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12, 4)); + $atom_structure['sample_description_table'][$i]['width'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 16, 2)); + $atom_structure['sample_description_table'][$i]['height'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 18, 2)); + $atom_structure['sample_description_table'][$i]['resolution_x'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 24, 4)); + $atom_structure['sample_description_table'][$i]['resolution_y'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 28, 4)); + $atom_structure['sample_description_table'][$i]['data_size'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 32, 4)); + $atom_structure['sample_description_table'][$i]['frame_count'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 36, 2)); + $atom_structure['sample_description_table'][$i]['compressor_name'] = substr($atom_structure['sample_description_table'][$i]['data'], 38, 4); + $atom_structure['sample_description_table'][$i]['pixel_depth'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 42, 2)); + $atom_structure['sample_description_table'][$i]['color_table_id'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 44, 2)); + + switch ($atom_structure['sample_description_table'][$i]['data_format']) { + case '2vuY':
+ case 'avc1':
+ case 'cvid':
+ case 'dvc ':
+ case 'dvcp':
+ case 'gif ':
+ case 'h263':
+ case 'jpeg':
+ case 'kpcd':
+ case 'mjpa':
+ case 'mjpb':
+ case 'mp4v':
+ case 'png ':
+ case 'raw ':
+ case 'rle ':
+ case 'rpza':
+ case 'smc ':
+ case 'SVQ1':
+ case 'SVQ3':
+ case 'tiff':
+ case 'v210':
+ case 'v216':
+ case 'v308':
+ case 'v408':
+ case 'v410':
+ case 'yuv2':
+ $info['fileformat'] = 'mp4'; + $info['video']['fourcc'] = $atom_structure['sample_description_table'][$i]['data_format']; +// http://www.getid3.org/phpBB3/viewtopic.php?t=1550 +//if ((!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($atom_structure['sample_description_table'][$i]['width'])) && (empty($info['video']['resolution_x']) || empty($info['video']['resolution_y']) || (number_format($info['video']['resolution_x'], 6) != number_format(round($info['video']['resolution_x']), 6)) || (number_format($info['video']['resolution_y'], 6) != number_format(round($info['video']['resolution_y']), 6)))) { // ugly check for floating point numbers +if (!empty($atom_structure['sample_description_table'][$i]['width']) && !empty($atom_structure['sample_description_table'][$i]['height'])) { + // assume that values stored here are more important than values stored in [tkhd] atom + $info['video']['resolution_x'] = $atom_structure['sample_description_table'][$i]['width']; + $info['video']['resolution_y'] = $atom_structure['sample_description_table'][$i]['height']; + $info['quicktime']['video']['resolution_x'] = $info['video']['resolution_x']; + $info['quicktime']['video']['resolution_y'] = $info['video']['resolution_y']; +} + break; + + case 'qtvr': + $info['video']['dataformat'] = 'quicktimevr'; + break; + + case 'mp4a': + default: + $info['quicktime']['audio']['codec'] = $this->QuicktimeAudioCodecLookup($atom_structure['sample_description_table'][$i]['data_format']); + $info['quicktime']['audio']['sample_rate'] = $atom_structure['sample_description_table'][$i]['audio_sample_rate']; + $info['quicktime']['audio']['channels'] = $atom_structure['sample_description_table'][$i]['audio_channels']; + $info['quicktime']['audio']['bit_depth'] = $atom_structure['sample_description_table'][$i]['audio_bit_depth']; + $info['audio']['codec'] = $info['quicktime']['audio']['codec']; + $info['audio']['sample_rate'] = $info['quicktime']['audio']['sample_rate']; + $info['audio']['channels'] = $info['quicktime']['audio']['channels']; + $info['audio']['bits_per_sample'] = $info['quicktime']['audio']['bit_depth']; + switch ($atom_structure['sample_description_table'][$i]['data_format']) { + case 'raw ': // PCM + case 'alac': // Apple Lossless Audio Codec + $info['audio']['lossless'] = true; + break; + default: + $info['audio']['lossless'] = false; + break; + } + break; + } + break; + + default: + switch ($atom_structure['sample_description_table'][$i]['data_format']) { + case 'mp4s': + $info['fileformat'] = 'mp4'; + break; + + default: + // video atom + $atom_structure['sample_description_table'][$i]['video_temporal_quality'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 8, 4)); + $atom_structure['sample_description_table'][$i]['video_spatial_quality'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12, 4)); + $atom_structure['sample_description_table'][$i]['video_frame_width'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 16, 2)); + $atom_structure['sample_description_table'][$i]['video_frame_height'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 18, 2)); + $atom_structure['sample_description_table'][$i]['video_resolution_x'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 20, 4)); + $atom_structure['sample_description_table'][$i]['video_resolution_y'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 24, 4)); + $atom_structure['sample_description_table'][$i]['video_data_size'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 28, 4)); + $atom_structure['sample_description_table'][$i]['video_frame_count'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 32, 2)); + $atom_structure['sample_description_table'][$i]['video_encoder_name_len'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 34, 1)); + $atom_structure['sample_description_table'][$i]['video_encoder_name'] = substr($atom_structure['sample_description_table'][$i]['data'], 35, $atom_structure['sample_description_table'][$i]['video_encoder_name_len']); + $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 66, 2)); + $atom_structure['sample_description_table'][$i]['video_color_table_id'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 68, 2)); + + $atom_structure['sample_description_table'][$i]['video_pixel_color_type'] = (($atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color'); + $atom_structure['sample_description_table'][$i]['video_pixel_color_name'] = $this->QuicktimeColorNameLookup($atom_structure['sample_description_table'][$i]['video_pixel_color_depth']); + + if ($atom_structure['sample_description_table'][$i]['video_pixel_color_name'] != 'invalid') { + $info['quicktime']['video']['codec_fourcc'] = $atom_structure['sample_description_table'][$i]['data_format']; + $info['quicktime']['video']['codec_fourcc_lookup'] = $this->QuicktimeVideoCodecLookup($atom_structure['sample_description_table'][$i]['data_format']); + $info['quicktime']['video']['codec'] = (($atom_structure['sample_description_table'][$i]['video_encoder_name_len'] > 0) ? $atom_structure['sample_description_table'][$i]['video_encoder_name'] : $atom_structure['sample_description_table'][$i]['data_format']); + $info['quicktime']['video']['color_depth'] = $atom_structure['sample_description_table'][$i]['video_pixel_color_depth']; + $info['quicktime']['video']['color_depth_name'] = $atom_structure['sample_description_table'][$i]['video_pixel_color_name']; + + $info['video']['codec'] = $info['quicktime']['video']['codec']; + $info['video']['bits_per_sample'] = $info['quicktime']['video']['color_depth']; + } + $info['video']['lossless'] = false; + $info['video']['pixel_aspect_ratio'] = (float) 1; + break; + } + break; + } + switch (strtolower($atom_structure['sample_description_table'][$i]['data_format'])) { + case 'mp4a': + $info['audio']['dataformat'] = 'mp4'; + $info['quicktime']['audio']['codec'] = 'mp4'; + break; + + case '3ivx': + case '3iv1': + case '3iv2': + $info['video']['dataformat'] = '3ivx'; + break; + + case 'xvid': + $info['video']['dataformat'] = 'xvid'; + break; + + case 'mp4v': + $info['video']['dataformat'] = 'mpeg4'; + break; + + case 'divx': + case 'div1': + case 'div2': + case 'div3': + case 'div4': + case 'div5': + case 'div6': + $info['video']['dataformat'] = 'divx'; + break; + + default: + // do nothing + break; + } + unset($atom_structure['sample_description_table'][$i]['data']); + } + break; + + + case 'stts': // Sample Table Time-to-Sample atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $sttsEntriesDataOffset = 8; + //$FrameRateCalculatorArray = array(); + $frames_count = 0; + for ($i = 0; $i < $atom_structure['number_entries']; $i++) { + $atom_structure['time_to_sample_table'][$i]['sample_count'] = getid3_lib::BigEndian2Int(substr($atom_data, $sttsEntriesDataOffset, 4)); + $sttsEntriesDataOffset += 4; + $atom_structure['time_to_sample_table'][$i]['sample_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, $sttsEntriesDataOffset, 4)); + $sttsEntriesDataOffset += 4; + + $frames_count += $atom_structure['time_to_sample_table'][$i]['sample_count']; + + // THIS SECTION REPLACED WITH CODE IN "stbl" ATOM + //if (!empty($info['quicktime']['time_scale']) && ($atom_structure['time_to_sample_table'][$i]['sample_duration'] > 0)) { + // $stts_new_framerate = $info['quicktime']['time_scale'] / $atom_structure['time_to_sample_table'][$i]['sample_duration']; + // if ($stts_new_framerate <= 60) { + // // some atoms have durations of "1" giving a very large framerate, which probably is not right + // $info['video']['frame_rate'] = max($info['video']['frame_rate'], $stts_new_framerate); + // } + //} + // + //$FrameRateCalculatorArray[($info['quicktime']['time_scale'] / $atom_structure['time_to_sample_table'][$i]['sample_duration'])] += $atom_structure['time_to_sample_table'][$i]['sample_count']; + } + $info['quicktime']['stts_framecount'][] = $frames_count; + //$sttsFramesTotal = 0; + //$sttsSecondsTotal = 0; + //foreach ($FrameRateCalculatorArray as $frames_per_second => $frame_count) { + // if (($frames_per_second > 60) || ($frames_per_second < 1)) { + // // not video FPS information, probably audio information + // $sttsFramesTotal = 0; + // $sttsSecondsTotal = 0; + // break; + // } + // $sttsFramesTotal += $frame_count; + // $sttsSecondsTotal += $frame_count / $frames_per_second; + //} + //if (($sttsFramesTotal > 0) && ($sttsSecondsTotal > 0)) { + // if (($sttsFramesTotal / $sttsSecondsTotal) > $info['video']['frame_rate']) { + // $info['video']['frame_rate'] = $sttsFramesTotal / $sttsSecondsTotal; + // } + //} + break; + + + case 'stss': // Sample Table Sync Sample (key frames) atom + if ($ParseAllPossibleAtoms) { + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $stssEntriesDataOffset = 8; + for ($i = 0; $i < $atom_structure['number_entries']; $i++) { + $atom_structure['time_to_sample_table'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $stssEntriesDataOffset, 4)); + $stssEntriesDataOffset += 4; + } + } + break; + + + case 'stsc': // Sample Table Sample-to-Chunk atom + if ($ParseAllPossibleAtoms) { + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $stscEntriesDataOffset = 8; + for ($i = 0; $i < $atom_structure['number_entries']; $i++) { + $atom_structure['sample_to_chunk_table'][$i]['first_chunk'] = getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4)); + $stscEntriesDataOffset += 4; + $atom_structure['sample_to_chunk_table'][$i]['samples_per_chunk'] = getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4)); + $stscEntriesDataOffset += 4; + $atom_structure['sample_to_chunk_table'][$i]['sample_description'] = getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4)); + $stscEntriesDataOffset += 4; + } + } + break; + + + case 'stsz': // Sample Table SiZe atom + if ($ParseAllPossibleAtoms) { + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['sample_size'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 4)); + $stszEntriesDataOffset = 12; + if ($atom_structure['sample_size'] == 0) { + for ($i = 0; $i < $atom_structure['number_entries']; $i++) { + $atom_structure['sample_size_table'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $stszEntriesDataOffset, 4)); + $stszEntriesDataOffset += 4; + } + } + } + break; + + + case 'stco': // Sample Table Chunk Offset atom + if ($ParseAllPossibleAtoms) { + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $stcoEntriesDataOffset = 8; + for ($i = 0; $i < $atom_structure['number_entries']; $i++) { + $atom_structure['chunk_offset_table'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $stcoEntriesDataOffset, 4)); + $stcoEntriesDataOffset += 4; + } + } + break; + + + case 'co64': // Chunk Offset 64-bit (version of "stco" that supports > 2GB files) + if ($ParseAllPossibleAtoms) { + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $stcoEntriesDataOffset = 8; + for ($i = 0; $i < $atom_structure['number_entries']; $i++) { + $atom_structure['chunk_offset_table'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $stcoEntriesDataOffset, 8)); + $stcoEntriesDataOffset += 8; + } + } + break; + + + case 'dref': // Data REFerence atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $drefDataOffset = 8; + for ($i = 0; $i < $atom_structure['number_entries']; $i++) { + $atom_structure['data_references'][$i]['size'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 4)); + $drefDataOffset += 4; + $atom_structure['data_references'][$i]['type'] = substr($atom_data, $drefDataOffset, 4); + $drefDataOffset += 4; + $atom_structure['data_references'][$i]['version'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 1)); + $drefDataOffset += 1; + $atom_structure['data_references'][$i]['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 3)); // hardcoded: 0x0000 + $drefDataOffset += 3; + $atom_structure['data_references'][$i]['data'] = substr($atom_data, $drefDataOffset, ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3)); + $drefDataOffset += ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3); + + $atom_structure['data_references'][$i]['flags']['self_reference'] = (bool) ($atom_structure['data_references'][$i]['flags_raw'] & 0x001); + } + break; + + + case 'gmin': // base Media INformation atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['graphics_mode'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); + $atom_structure['opcolor_red'] = getid3_lib::BigEndian2Int(substr($atom_data, 6, 2)); + $atom_structure['opcolor_green'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 2)); + $atom_structure['opcolor_blue'] = getid3_lib::BigEndian2Int(substr($atom_data, 10, 2)); + $atom_structure['balance'] = getid3_lib::BigEndian2Int(substr($atom_data, 12, 2)); + $atom_structure['reserved'] = getid3_lib::BigEndian2Int(substr($atom_data, 14, 2)); + break; + + + case 'smhd': // Sound Media information HeaDer atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['balance'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); + $atom_structure['reserved'] = getid3_lib::BigEndian2Int(substr($atom_data, 6, 2)); + break; + + + case 'vmhd': // Video Media information HeaDer atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); + $atom_structure['graphics_mode'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); + $atom_structure['opcolor_red'] = getid3_lib::BigEndian2Int(substr($atom_data, 6, 2)); + $atom_structure['opcolor_green'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 2)); + $atom_structure['opcolor_blue'] = getid3_lib::BigEndian2Int(substr($atom_data, 10, 2)); + + $atom_structure['flags']['no_lean_ahead'] = (bool) ($atom_structure['flags_raw'] & 0x001); + break; + + + case 'hdlr': // HanDLeR reference atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['component_type'] = substr($atom_data, 4, 4); + $atom_structure['component_subtype'] = substr($atom_data, 8, 4); + $atom_structure['component_manufacturer'] = substr($atom_data, 12, 4); + $atom_structure['component_flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4)); + $atom_structure['component_flags_mask'] = getid3_lib::BigEndian2Int(substr($atom_data, 20, 4)); + $atom_structure['component_name'] = $this->Pascal2String(substr($atom_data, 24)); + + if (($atom_structure['component_subtype'] == 'STpn') && ($atom_structure['component_manufacturer'] == 'zzzz')) { + $info['video']['dataformat'] = 'quicktimevr'; + } + break; + + + case 'mdhd': // MeDia HeaDer atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['creation_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $atom_structure['modify_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 4)); + $atom_structure['time_scale'] = getid3_lib::BigEndian2Int(substr($atom_data, 12, 4)); + $atom_structure['duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4)); + $atom_structure['language_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 20, 2)); + $atom_structure['quality'] = getid3_lib::BigEndian2Int(substr($atom_data, 22, 2)); + + if ($atom_structure['time_scale'] == 0) { + $info['error'][] = 'Corrupt Quicktime file: mdhd.time_scale == zero'; + return false; + } + $info['quicktime']['time_scale'] = (isset($info['quicktime']['time_scale']) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']); + + $atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']); + $atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']); + $atom_structure['playtime_seconds'] = $atom_structure['duration'] / $atom_structure['time_scale']; + $atom_structure['language'] = $this->QuicktimeLanguageLookup($atom_structure['language_id']); + if (empty($info['comments']['language']) || (!in_array($atom_structure['language'], $info['comments']['language']))) { + $info['comments']['language'][] = $atom_structure['language']; + } + break; + + + case 'pnot': // Preview atom + $atom_structure['modification_date'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4)); // "standard Macintosh format" + $atom_structure['version_number'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); // hardcoded: 0x00 + $atom_structure['atom_type'] = substr($atom_data, 6, 4); // usually: 'PICT' + $atom_structure['atom_index'] = getid3_lib::BigEndian2Int(substr($atom_data, 10, 2)); // usually: 0x01 + + $atom_structure['modification_date_unix'] = getid3_lib::DateMac2Unix($atom_structure['modification_date']); + break; + + + case 'crgn': // Clipping ReGioN atom + $atom_structure['region_size'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2)); // The Region size, Region boundary box, + $atom_structure['boundary_box'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 8)); // and Clipping region data fields + $atom_structure['clipping_data'] = substr($atom_data, 10); // constitute a QuickDraw region. + break; + + + case 'load': // track LOAD settings atom + $atom_structure['preload_start_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4)); + $atom_structure['preload_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $atom_structure['preload_flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 4)); + $atom_structure['default_hints_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 12, 4)); + + $atom_structure['default_hints']['double_buffer'] = (bool) ($atom_structure['default_hints_raw'] & 0x0020); + $atom_structure['default_hints']['high_quality'] = (bool) ($atom_structure['default_hints_raw'] & 0x0100); + break; + + + case 'tmcd': // TiMe CoDe atom + case 'chap': // CHAPter list atom + case 'sync': // SYNChronization atom + case 'scpt': // tranSCriPT atom + case 'ssrc': // non-primary SouRCe atom + for ($i = 0; $i < (strlen($atom_data) % 4); $i++) { + $atom_structure['track_id'][$i] = getid3_lib::BigEndian2Int(substr($atom_data, $i * 4, 4)); + } + break; + + + case 'elst': // Edit LiST atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + for ($i = 0; $i < $atom_structure['number_entries']; $i++ ) { + $atom_structure['edit_list'][$i]['track_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($i * 12) + 0, 4)); + $atom_structure['edit_list'][$i]['media_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($i * 12) + 4, 4)); + $atom_structure['edit_list'][$i]['media_rate'] = getid3_lib::FixedPoint16_16(substr($atom_data, 8 + ($i * 12) + 8, 4)); + } + break; + + + case 'kmat': // compressed MATte atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 + $atom_structure['matte_data_raw'] = substr($atom_data, 4); + break; + + + case 'ctab': // Color TABle atom + $atom_structure['color_table_seed'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4)); // hardcoded: 0x00000000 + $atom_structure['color_table_flags'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); // hardcoded: 0x8000 + $atom_structure['color_table_size'] = getid3_lib::BigEndian2Int(substr($atom_data, 6, 2)) + 1; + for ($colortableentry = 0; $colortableentry < $atom_structure['color_table_size']; $colortableentry++) { + $atom_structure['color_table'][$colortableentry]['alpha'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 0, 2)); + $atom_structure['color_table'][$colortableentry]['red'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 2, 2)); + $atom_structure['color_table'][$colortableentry]['green'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 4, 2)); + $atom_structure['color_table'][$colortableentry]['blue'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 6, 2)); + } + break; + + + case 'mvhd': // MoVie HeaDer atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); + $atom_structure['creation_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $atom_structure['modify_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 4)); + $atom_structure['time_scale'] = getid3_lib::BigEndian2Int(substr($atom_data, 12, 4)); + $atom_structure['duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4)); + $atom_structure['preferred_rate'] = getid3_lib::FixedPoint16_16(substr($atom_data, 20, 4)); + $atom_structure['preferred_volume'] = getid3_lib::FixedPoint8_8(substr($atom_data, 24, 2)); + $atom_structure['reserved'] = substr($atom_data, 26, 10); + $atom_structure['matrix_a'] = getid3_lib::FixedPoint16_16(substr($atom_data, 36, 4)); + $atom_structure['matrix_b'] = getid3_lib::FixedPoint16_16(substr($atom_data, 40, 4)); + $atom_structure['matrix_u'] = getid3_lib::FixedPoint2_30(substr($atom_data, 44, 4)); + $atom_structure['matrix_c'] = getid3_lib::FixedPoint16_16(substr($atom_data, 48, 4)); + $atom_structure['matrix_d'] = getid3_lib::FixedPoint16_16(substr($atom_data, 52, 4)); + $atom_structure['matrix_v'] = getid3_lib::FixedPoint2_30(substr($atom_data, 56, 4)); + $atom_structure['matrix_x'] = getid3_lib::FixedPoint16_16(substr($atom_data, 60, 4)); + $atom_structure['matrix_y'] = getid3_lib::FixedPoint16_16(substr($atom_data, 64, 4)); + $atom_structure['matrix_w'] = getid3_lib::FixedPoint2_30(substr($atom_data, 68, 4)); + $atom_structure['preview_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 72, 4)); + $atom_structure['preview_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 76, 4)); + $atom_structure['poster_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 80, 4)); + $atom_structure['selection_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 84, 4)); + $atom_structure['selection_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 88, 4)); + $atom_structure['current_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 92, 4)); + $atom_structure['next_track_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 96, 4)); + + if ($atom_structure['time_scale'] == 0) { + $info['error'][] = 'Corrupt Quicktime file: mvhd.time_scale == zero'; + return false; + } + $atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']); + $atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']); + $info['quicktime']['time_scale'] = (isset($info['quicktime']['time_scale']) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']); + $info['quicktime']['display_scale'] = $atom_structure['matrix_a']; + $info['playtime_seconds'] = $atom_structure['duration'] / $atom_structure['time_scale']; + break; + + + case 'tkhd': // TracK HeaDer atom + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); + $atom_structure['creation_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $atom_structure['modify_time'] = getid3_lib::BigEndian2Int(substr($atom_data, 8, 4)); + $atom_structure['trackid'] = getid3_lib::BigEndian2Int(substr($atom_data, 12, 4)); + $atom_structure['reserved1'] = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4)); + $atom_structure['duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 20, 4)); + $atom_structure['reserved2'] = getid3_lib::BigEndian2Int(substr($atom_data, 24, 8)); + $atom_structure['layer'] = getid3_lib::BigEndian2Int(substr($atom_data, 32, 2)); + $atom_structure['alternate_group'] = getid3_lib::BigEndian2Int(substr($atom_data, 34, 2)); + $atom_structure['volume'] = getid3_lib::FixedPoint8_8(substr($atom_data, 36, 2)); + $atom_structure['reserved3'] = getid3_lib::BigEndian2Int(substr($atom_data, 38, 2)); +// http://developer.apple.com/library/mac/#documentation/QuickTime/RM/MovieBasics/MTEditing/K-Chapter/11MatrixFunctions.html +// http://developer.apple.com/library/mac/#documentation/QuickTime/qtff/QTFFChap4/qtff4.html#//apple_ref/doc/uid/TP40000939-CH206-18737 + $atom_structure['matrix_a'] = getid3_lib::FixedPoint16_16(substr($atom_data, 40, 4)); + $atom_structure['matrix_b'] = getid3_lib::FixedPoint16_16(substr($atom_data, 44, 4)); + $atom_structure['matrix_u'] = getid3_lib::FixedPoint2_30(substr($atom_data, 48, 4)); + $atom_structure['matrix_c'] = getid3_lib::FixedPoint16_16(substr($atom_data, 52, 4)); + $atom_structure['matrix_d'] = getid3_lib::FixedPoint16_16(substr($atom_data, 56, 4)); + $atom_structure['matrix_v'] = getid3_lib::FixedPoint2_30(substr($atom_data, 60, 4)); + $atom_structure['matrix_x'] = getid3_lib::FixedPoint16_16(substr($atom_data, 64, 4)); + $atom_structure['matrix_y'] = getid3_lib::FixedPoint16_16(substr($atom_data, 68, 4)); + $atom_structure['matrix_w'] = getid3_lib::FixedPoint2_30(substr($atom_data, 72, 4)); + $atom_structure['width'] = getid3_lib::FixedPoint16_16(substr($atom_data, 76, 4)); + $atom_structure['height'] = getid3_lib::FixedPoint16_16(substr($atom_data, 80, 4)); + $atom_structure['flags']['enabled'] = (bool) ($atom_structure['flags_raw'] & 0x0001); + $atom_structure['flags']['in_movie'] = (bool) ($atom_structure['flags_raw'] & 0x0002); + $atom_structure['flags']['in_preview'] = (bool) ($atom_structure['flags_raw'] & 0x0004); + $atom_structure['flags']['in_poster'] = (bool) ($atom_structure['flags_raw'] & 0x0008); + $atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']); + $atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']); + + if ($atom_structure['flags']['enabled'] == 1) { + if (!isset($info['video']['resolution_x']) || !isset($info['video']['resolution_y'])) { + $info['video']['resolution_x'] = $atom_structure['width']; + $info['video']['resolution_y'] = $atom_structure['height']; + } + $info['video']['resolution_x'] = max($info['video']['resolution_x'], $atom_structure['width']); + $info['video']['resolution_y'] = max($info['video']['resolution_y'], $atom_structure['height']); + $info['quicktime']['video']['resolution_x'] = $info['video']['resolution_x']; + $info['quicktime']['video']['resolution_y'] = $info['video']['resolution_y']; + } else { + // see: http://www.getid3.org/phpBB3/viewtopic.php?t=1295 + //if (isset($info['video']['resolution_x'])) { unset($info['video']['resolution_x']); } + //if (isset($info['video']['resolution_y'])) { unset($info['video']['resolution_y']); } + //if (isset($info['quicktime']['video'])) { unset($info['quicktime']['video']); } + } + break; + + + case 'iods': // Initial Object DeScriptor atom + // http://www.koders.com/c/fid1FAB3E762903DC482D8A246D4A4BF9F28E049594.aspx?s=windows.h + // http://libquicktime.sourcearchive.com/documentation/1.0.2plus-pdebian/iods_8c-source.html + $offset = 0; + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1)); + $offset += 1; + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 3)); + $offset += 3; + $atom_structure['mp4_iod_tag'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1)); + $offset += 1; + $atom_structure['length'] = $this->quicktime_read_mp4_descr_length($atom_data, $offset); + //$offset already adjusted by quicktime_read_mp4_descr_length() + $atom_structure['object_descriptor_id'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2)); + $offset += 2; + $atom_structure['od_profile_level'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1)); + $offset += 1; + $atom_structure['scene_profile_level'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1)); + $offset += 1; + $atom_structure['audio_profile_id'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1)); + $offset += 1; + $atom_structure['video_profile_id'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1)); + $offset += 1; + $atom_structure['graphics_profile_level'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1)); + $offset += 1; + + $atom_structure['num_iods_tracks'] = ($atom_structure['length'] - 7) / 6; // 6 bytes would only be right if all tracks use 1-byte length fields + for ($i = 0; $i < $atom_structure['num_iods_tracks']; $i++) { + $atom_structure['track'][$i]['ES_ID_IncTag'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 1)); + $offset += 1; + $atom_structure['track'][$i]['length'] = $this->quicktime_read_mp4_descr_length($atom_data, $offset); + //$offset already adjusted by quicktime_read_mp4_descr_length() + $atom_structure['track'][$i]['track_id'] = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 4)); + $offset += 4; + } + + $atom_structure['audio_profile_name'] = $this->QuicktimeIODSaudioProfileName($atom_structure['audio_profile_id']); + $atom_structure['video_profile_name'] = $this->QuicktimeIODSvideoProfileName($atom_structure['video_profile_id']); + break; + + case 'ftyp': // FileTYPe (?) atom (for MP4 it seems) + $atom_structure['signature'] = substr($atom_data, 0, 4); + $atom_structure['unknown_1'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); + $atom_structure['fourcc'] = substr($atom_data, 8, 4); + break; + + case 'mdat': // Media DATa atom + case 'free': // FREE space atom + case 'skip': // SKIP atom + case 'wide': // 64-bit expansion placeholder atom + // 'mdat' data is too big to deal with, contains no useful metadata + // 'free', 'skip' and 'wide' are just padding, contains no useful data at all + + // When writing QuickTime files, it is sometimes necessary to update an atom's size. + // It is impossible to update a 32-bit atom to a 64-bit atom since the 32-bit atom + // is only 8 bytes in size, and the 64-bit atom requires 16 bytes. Therefore, QuickTime + // puts an 8-byte placeholder atom before any atoms it may have to update the size of. + // In this way, if the atom needs to be converted from a 32-bit to a 64-bit atom, the + // placeholder atom can be overwritten to obtain the necessary 8 extra bytes. + // The placeholder atom has a type of kWideAtomPlaceholderType ( 'wide' ). + break; + + + case 'nsav': // NoSAVe atom + // http://developer.apple.com/technotes/tn/tn2038.html + $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4)); + break; + + case 'ctyp': // Controller TYPe atom (seen on QTVR) + // http://homepages.slingshot.co.nz/~helmboy/quicktime/formats/qtm-layout.txt + // some controller names are: + // 0x00 + 'std' for linear movie + // 'none' for no controls + $atom_structure['ctyp'] = substr($atom_data, 0, 4); + $info['quicktime']['controller'] = $atom_structure['ctyp']; + switch ($atom_structure['ctyp']) { + case 'qtvr': + $info['video']['dataformat'] = 'quicktimevr'; + break; + } + break; + + case 'pano': // PANOrama track (seen on QTVR) + $atom_structure['pano'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4)); + break; + + case 'hint': // HINT track + case 'hinf': // + case 'hinv': // + case 'hnti': // + $info['quicktime']['hinting'] = true; + break; + + case 'imgt': // IMaGe Track reference (kQTVRImageTrackRefType) (seen on QTVR) + for ($i = 0; $i < ($atom_structure['size'] - 8); $i += 4) { + $atom_structure['imgt'][] = getid3_lib::BigEndian2Int(substr($atom_data, $i, 4)); + } + break; + + + // Observed-but-not-handled atom types are just listed here to prevent warnings being generated + case 'FXTC': // Something to do with Adobe After Effects (?) + case 'PrmA': + case 'code': + case 'FIEL': // this is NOT "fiel" (Field Ordering) as describe here: http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/chapter_4_section_2.html + case 'tapt': // TrackApertureModeDimensionsAID - http://developer.apple.com/documentation/QuickTime/Reference/QT7-1_Update_Reference/Constants/Constants.html + // tapt seems to be used to compute the video size [http://www.getid3.org/phpBB3/viewtopic.php?t=838] + // * http://lists.apple.com/archives/quicktime-api/2006/Aug/msg00014.html + // * http://handbrake.fr/irclogs/handbrake-dev/handbrake-dev20080128_pg2.html + case 'ctts':// STCompositionOffsetAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html + case 'cslg':// STCompositionShiftLeastGreatestAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html + case 'sdtp':// STSampleDependencyAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html + case 'stps':// STPartialSyncSampleAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html + //$atom_structure['data'] = $atom_data; + break; + + case '©xyz': // GPS latitude+longitude+altitude + $atom_structure['data'] = $atom_data; + if (preg_match('#([\\+\\-][0-9\\.]+)([\\+\\-][0-9\\.]+)([\\+\\-][0-9\\.]+)?/$#i', $atom_data, $matches)) { + @list($all, $latitude, $longitude, $altitude) = $matches; + $info['quicktime']['comments']['gps_latitude'][] = floatval($latitude); + $info['quicktime']['comments']['gps_longitude'][] = floatval($longitude); + if (!empty($altitude)) { + $info['quicktime']['comments']['gps_altitude'][] = floatval($altitude); + } + } else { + $info['warning'][] = 'QuickTime atom "©xyz" data does not match expected data pattern at offset '.$baseoffset.'. Please report as getID3() bug.'; + } + break; + + case 'NCDT': + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html + // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100 + $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 4, $atomHierarchy, $ParseAllPossibleAtoms); + break; + case 'NCTH': // Nikon Camera THumbnail image + case 'NCVW': // Nikon Camera preVieW image + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html + if (preg_match('/^\xFF\xD8\xFF/', $atom_data)) { + $atom_structure['data'] = $atom_data; + $atom_structure['image_mime'] = 'image/jpeg'; + $atom_structure['description'] = (($atomname == 'NCTH') ? 'Nikon Camera Thumbnail Image' : (($atomname == 'NCVW') ? 'Nikon Camera Preview Image' : 'Nikon preview image')); + $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_data, 'description'=>$atom_structure['description']); + } + break; + case 'NCHD': // MakerNoteVersion + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html + $atom_structure['data'] = $atom_data; + break; + case 'NCTG': // NikonTags + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG + $atom_structure['data'] = $this->QuicktimeParseNikonNCTG($atom_data); + break; + case 'NCDB': // NikonTags + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html + $atom_structure['data'] = $atom_data; + break; + + case "\x00\x00\x00\x00": + case 'meta': // METAdata atom + // some kind of metacontainer, may contain a big data dump such as: + // mdta keys mdtacom.apple.quicktime.make (mdtacom.apple.quicktime.creationdate ,mdtacom.apple.quicktime.location.ISO6709 $mdtacom.apple.quicktime.software !mdtacom.apple.quicktime.model ilst data DEApple 0 (data DE2011-05-11T17:54:04+0200 2 *data DE+52.4936+013.3897+040.247/ data DE4.3.1 data DEiPhone 4 + // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt + + $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1)); + $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); + $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); + //$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms); + break; + + case 'data': // metaDATA atom + // seems to be 2 bytes language code (ASCII), 2 bytes unknown (set to 0x10B5 in sample I have), remainder is useful data + $atom_structure['language'] = substr($atom_data, 4 + 0, 2); + $atom_structure['unknown'] = getid3_lib::BigEndian2Int(substr($atom_data, 4 + 2, 2)); + $atom_structure['data'] = substr($atom_data, 4 + 4); + break; + + default: + $info['warning'][] = 'Unknown QuickTime atom type: "'.$atomname.'" ('.trim(getid3_lib::PrintHexBytes($atomname)).') at offset '.$baseoffset; + $atom_structure['data'] = $atom_data; + break; + } + array_pop($atomHierarchy); + return $atom_structure; + } + + public function QuicktimeParseContainerAtom($atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) { +//echo 'QuicktimeParseContainerAtom('.substr($atom_data, 4, 4).') @ '.$baseoffset.'<br><br>'; + $atom_structure = false; + $subatomoffset = 0; + $subatomcounter = 0; + if ((strlen($atom_data) == 4) && (getid3_lib::BigEndian2Int($atom_data) == 0x00000000)) { + return false; + } + while ($subatomoffset < strlen($atom_data)) { + $subatomsize = getid3_lib::BigEndian2Int(substr($atom_data, $subatomoffset + 0, 4)); + $subatomname = substr($atom_data, $subatomoffset + 4, 4); + $subatomdata = substr($atom_data, $subatomoffset + 8, $subatomsize - 8); + if ($subatomsize == 0) { + // Furthermore, for historical reasons the list of atoms is optionally + // terminated by a 32-bit integer set to 0. If you are writing a program + // to read user data atoms, you should allow for the terminating 0. + return $atom_structure; + } + + $atom_structure[$subatomcounter] = $this->QuicktimeParseAtom($subatomname, $subatomsize, $subatomdata, $baseoffset + $subatomoffset, $atomHierarchy, $ParseAllPossibleAtoms); + + $subatomoffset += $subatomsize; + $subatomcounter++; + } + return $atom_structure; + } + + + public function quicktime_read_mp4_descr_length($data, &$offset) { + // http://libquicktime.sourcearchive.com/documentation/2:1.0.2plus-pdebian-2build1/esds_8c-source.html + $num_bytes = 0; + $length = 0; + do { + $b = ord(substr($data, $offset++, 1)); + $length = ($length << 7) | ($b & 0x7F); + } while (($b & 0x80) && ($num_bytes++ < 4)); + return $length; + } + + + public function QuicktimeLanguageLookup($languageid) { + static $QuicktimeLanguageLookup = array(); + if (empty($QuicktimeLanguageLookup)) { + $QuicktimeLanguageLookup[0] = 'English'; + $QuicktimeLanguageLookup[1] = 'French'; + $QuicktimeLanguageLookup[2] = 'German'; + $QuicktimeLanguageLookup[3] = 'Italian'; + $QuicktimeLanguageLookup[4] = 'Dutch'; + $QuicktimeLanguageLookup[5] = 'Swedish'; + $QuicktimeLanguageLookup[6] = 'Spanish'; + $QuicktimeLanguageLookup[7] = 'Danish'; + $QuicktimeLanguageLookup[8] = 'Portuguese'; + $QuicktimeLanguageLookup[9] = 'Norwegian'; + $QuicktimeLanguageLookup[10] = 'Hebrew'; + $QuicktimeLanguageLookup[11] = 'Japanese'; + $QuicktimeLanguageLookup[12] = 'Arabic'; + $QuicktimeLanguageLookup[13] = 'Finnish'; + $QuicktimeLanguageLookup[14] = 'Greek'; + $QuicktimeLanguageLookup[15] = 'Icelandic'; + $QuicktimeLanguageLookup[16] = 'Maltese'; + $QuicktimeLanguageLookup[17] = 'Turkish'; + $QuicktimeLanguageLookup[18] = 'Croatian'; + $QuicktimeLanguageLookup[19] = 'Chinese (Traditional)'; + $QuicktimeLanguageLookup[20] = 'Urdu'; + $QuicktimeLanguageLookup[21] = 'Hindi'; + $QuicktimeLanguageLookup[22] = 'Thai'; + $QuicktimeLanguageLookup[23] = 'Korean'; + $QuicktimeLanguageLookup[24] = 'Lithuanian'; + $QuicktimeLanguageLookup[25] = 'Polish'; + $QuicktimeLanguageLookup[26] = 'Hungarian'; + $QuicktimeLanguageLookup[27] = 'Estonian'; + $QuicktimeLanguageLookup[28] = 'Lettish'; + $QuicktimeLanguageLookup[28] = 'Latvian'; + $QuicktimeLanguageLookup[29] = 'Saamisk'; + $QuicktimeLanguageLookup[29] = 'Lappish'; + $QuicktimeLanguageLookup[30] = 'Faeroese'; + $QuicktimeLanguageLookup[31] = 'Farsi'; + $QuicktimeLanguageLookup[31] = 'Persian'; + $QuicktimeLanguageLookup[32] = 'Russian'; + $QuicktimeLanguageLookup[33] = 'Chinese (Simplified)'; + $QuicktimeLanguageLookup[34] = 'Flemish'; + $QuicktimeLanguageLookup[35] = 'Irish'; + $QuicktimeLanguageLookup[36] = 'Albanian'; + $QuicktimeLanguageLookup[37] = 'Romanian'; + $QuicktimeLanguageLookup[38] = 'Czech'; + $QuicktimeLanguageLookup[39] = 'Slovak'; + $QuicktimeLanguageLookup[40] = 'Slovenian'; + $QuicktimeLanguageLookup[41] = 'Yiddish'; + $QuicktimeLanguageLookup[42] = 'Serbian'; + $QuicktimeLanguageLookup[43] = 'Macedonian'; + $QuicktimeLanguageLookup[44] = 'Bulgarian'; + $QuicktimeLanguageLookup[45] = 'Ukrainian'; + $QuicktimeLanguageLookup[46] = 'Byelorussian'; + $QuicktimeLanguageLookup[47] = 'Uzbek'; + $QuicktimeLanguageLookup[48] = 'Kazakh'; + $QuicktimeLanguageLookup[49] = 'Azerbaijani'; + $QuicktimeLanguageLookup[50] = 'AzerbaijanAr'; + $QuicktimeLanguageLookup[51] = 'Armenian'; + $QuicktimeLanguageLookup[52] = 'Georgian'; + $QuicktimeLanguageLookup[53] = 'Moldavian'; + $QuicktimeLanguageLookup[54] = 'Kirghiz'; + $QuicktimeLanguageLookup[55] = 'Tajiki'; + $QuicktimeLanguageLookup[56] = 'Turkmen'; + $QuicktimeLanguageLookup[57] = 'Mongolian'; + $QuicktimeLanguageLookup[58] = 'MongolianCyr'; + $QuicktimeLanguageLookup[59] = 'Pashto'; + $QuicktimeLanguageLookup[60] = 'Kurdish'; + $QuicktimeLanguageLookup[61] = 'Kashmiri'; + $QuicktimeLanguageLookup[62] = 'Sindhi'; + $QuicktimeLanguageLookup[63] = 'Tibetan'; + $QuicktimeLanguageLookup[64] = 'Nepali'; + $QuicktimeLanguageLookup[65] = 'Sanskrit'; + $QuicktimeLanguageLookup[66] = 'Marathi'; + $QuicktimeLanguageLookup[67] = 'Bengali'; + $QuicktimeLanguageLookup[68] = 'Assamese'; + $QuicktimeLanguageLookup[69] = 'Gujarati'; + $QuicktimeLanguageLookup[70] = 'Punjabi'; + $QuicktimeLanguageLookup[71] = 'Oriya'; + $QuicktimeLanguageLookup[72] = 'Malayalam'; + $QuicktimeLanguageLookup[73] = 'Kannada'; + $QuicktimeLanguageLookup[74] = 'Tamil'; + $QuicktimeLanguageLookup[75] = 'Telugu'; + $QuicktimeLanguageLookup[76] = 'Sinhalese'; + $QuicktimeLanguageLookup[77] = 'Burmese'; + $QuicktimeLanguageLookup[78] = 'Khmer'; + $QuicktimeLanguageLookup[79] = 'Lao'; + $QuicktimeLanguageLookup[80] = 'Vietnamese'; + $QuicktimeLanguageLookup[81] = 'Indonesian'; + $QuicktimeLanguageLookup[82] = 'Tagalog'; + $QuicktimeLanguageLookup[83] = 'MalayRoman'; + $QuicktimeLanguageLookup[84] = 'MalayArabic'; + $QuicktimeLanguageLookup[85] = 'Amharic'; + $QuicktimeLanguageLookup[86] = 'Tigrinya'; + $QuicktimeLanguageLookup[87] = 'Galla'; + $QuicktimeLanguageLookup[87] = 'Oromo'; + $QuicktimeLanguageLookup[88] = 'Somali'; + $QuicktimeLanguageLookup[89] = 'Swahili'; + $QuicktimeLanguageLookup[90] = 'Ruanda'; + $QuicktimeLanguageLookup[91] = 'Rundi'; + $QuicktimeLanguageLookup[92] = 'Chewa'; + $QuicktimeLanguageLookup[93] = 'Malagasy'; + $QuicktimeLanguageLookup[94] = 'Esperanto'; + $QuicktimeLanguageLookup[128] = 'Welsh'; + $QuicktimeLanguageLookup[129] = 'Basque'; + $QuicktimeLanguageLookup[130] = 'Catalan'; + $QuicktimeLanguageLookup[131] = 'Latin'; + $QuicktimeLanguageLookup[132] = 'Quechua'; + $QuicktimeLanguageLookup[133] = 'Guarani'; + $QuicktimeLanguageLookup[134] = 'Aymara'; + $QuicktimeLanguageLookup[135] = 'Tatar'; + $QuicktimeLanguageLookup[136] = 'Uighur'; + $QuicktimeLanguageLookup[137] = 'Dzongkha'; + $QuicktimeLanguageLookup[138] = 'JavaneseRom'; + } + return (isset($QuicktimeLanguageLookup[$languageid]) ? $QuicktimeLanguageLookup[$languageid] : 'invalid'); + } + + public function QuicktimeVideoCodecLookup($codecid) { + static $QuicktimeVideoCodecLookup = array(); + if (empty($QuicktimeVideoCodecLookup)) { + $QuicktimeVideoCodecLookup['.SGI'] = 'SGI'; + $QuicktimeVideoCodecLookup['3IV1'] = '3ivx MPEG-4 v1'; + $QuicktimeVideoCodecLookup['3IV2'] = '3ivx MPEG-4 v2'; + $QuicktimeVideoCodecLookup['3IVX'] = '3ivx MPEG-4'; + $QuicktimeVideoCodecLookup['8BPS'] = 'Planar RGB'; + $QuicktimeVideoCodecLookup['avc1'] = 'H.264/MPEG-4 AVC'; + $QuicktimeVideoCodecLookup['avr '] = 'AVR-JPEG'; + $QuicktimeVideoCodecLookup['b16g'] = '16Gray'; + $QuicktimeVideoCodecLookup['b32a'] = '32AlphaGray'; + $QuicktimeVideoCodecLookup['b48r'] = '48RGB'; + $QuicktimeVideoCodecLookup['b64a'] = '64ARGB'; + $QuicktimeVideoCodecLookup['base'] = 'Base'; + $QuicktimeVideoCodecLookup['clou'] = 'Cloud'; + $QuicktimeVideoCodecLookup['cmyk'] = 'CMYK'; + $QuicktimeVideoCodecLookup['cvid'] = 'Cinepak'; + $QuicktimeVideoCodecLookup['dmb1'] = 'OpenDML JPEG'; + $QuicktimeVideoCodecLookup['dvc '] = 'DVC-NTSC'; + $QuicktimeVideoCodecLookup['dvcp'] = 'DVC-PAL'; + $QuicktimeVideoCodecLookup['dvpn'] = 'DVCPro-NTSC'; + $QuicktimeVideoCodecLookup['dvpp'] = 'DVCPro-PAL'; + $QuicktimeVideoCodecLookup['fire'] = 'Fire'; + $QuicktimeVideoCodecLookup['flic'] = 'FLC'; + $QuicktimeVideoCodecLookup['gif '] = 'GIF'; + $QuicktimeVideoCodecLookup['h261'] = 'H261'; + $QuicktimeVideoCodecLookup['h263'] = 'H263'; + $QuicktimeVideoCodecLookup['IV41'] = 'Indeo4'; + $QuicktimeVideoCodecLookup['jpeg'] = 'JPEG'; + $QuicktimeVideoCodecLookup['kpcd'] = 'PhotoCD'; + $QuicktimeVideoCodecLookup['mjpa'] = 'Motion JPEG-A'; + $QuicktimeVideoCodecLookup['mjpb'] = 'Motion JPEG-B'; + $QuicktimeVideoCodecLookup['msvc'] = 'Microsoft Video1'; + $QuicktimeVideoCodecLookup['myuv'] = 'MPEG YUV420'; + $QuicktimeVideoCodecLookup['path'] = 'Vector'; + $QuicktimeVideoCodecLookup['png '] = 'PNG'; + $QuicktimeVideoCodecLookup['PNTG'] = 'MacPaint'; + $QuicktimeVideoCodecLookup['qdgx'] = 'QuickDrawGX'; + $QuicktimeVideoCodecLookup['qdrw'] = 'QuickDraw'; + $QuicktimeVideoCodecLookup['raw '] = 'RAW'; + $QuicktimeVideoCodecLookup['ripl'] = 'WaterRipple'; + $QuicktimeVideoCodecLookup['rpza'] = 'Video'; + $QuicktimeVideoCodecLookup['smc '] = 'Graphics'; + $QuicktimeVideoCodecLookup['SVQ1'] = 'Sorenson Video 1'; + $QuicktimeVideoCodecLookup['SVQ1'] = 'Sorenson Video 3'; + $QuicktimeVideoCodecLookup['syv9'] = 'Sorenson YUV9'; + $QuicktimeVideoCodecLookup['tga '] = 'Targa'; + $QuicktimeVideoCodecLookup['tiff'] = 'TIFF'; + $QuicktimeVideoCodecLookup['WRAW'] = 'Windows RAW'; + $QuicktimeVideoCodecLookup['WRLE'] = 'BMP'; + $QuicktimeVideoCodecLookup['y420'] = 'YUV420'; + $QuicktimeVideoCodecLookup['yuv2'] = 'ComponentVideo'; + $QuicktimeVideoCodecLookup['yuvs'] = 'ComponentVideoUnsigned'; + $QuicktimeVideoCodecLookup['yuvu'] = 'ComponentVideoSigned'; + } + return (isset($QuicktimeVideoCodecLookup[$codecid]) ? $QuicktimeVideoCodecLookup[$codecid] : ''); + } + + public function QuicktimeAudioCodecLookup($codecid) { + static $QuicktimeAudioCodecLookup = array(); + if (empty($QuicktimeAudioCodecLookup)) { + $QuicktimeAudioCodecLookup['.mp3'] = 'Fraunhofer MPEG Layer-III alias'; + $QuicktimeAudioCodecLookup['aac '] = 'ISO/IEC 14496-3 AAC'; + $QuicktimeAudioCodecLookup['agsm'] = 'Apple GSM 10:1'; + $QuicktimeAudioCodecLookup['alac'] = 'Apple Lossless Audio Codec'; + $QuicktimeAudioCodecLookup['alaw'] = 'A-law 2:1'; + $QuicktimeAudioCodecLookup['conv'] = 'Sample Format'; + $QuicktimeAudioCodecLookup['dvca'] = 'DV'; + $QuicktimeAudioCodecLookup['dvi '] = 'DV 4:1'; + $QuicktimeAudioCodecLookup['eqal'] = 'Frequency Equalizer'; + $QuicktimeAudioCodecLookup['fl32'] = '32-bit Floating Point'; + $QuicktimeAudioCodecLookup['fl64'] = '64-bit Floating Point'; + $QuicktimeAudioCodecLookup['ima4'] = 'Interactive Multimedia Association 4:1'; + $QuicktimeAudioCodecLookup['in24'] = '24-bit Integer'; + $QuicktimeAudioCodecLookup['in32'] = '32-bit Integer'; + $QuicktimeAudioCodecLookup['lpc '] = 'LPC 23:1'; + $QuicktimeAudioCodecLookup['MAC3'] = 'Macintosh Audio Compression/Expansion (MACE) 3:1'; + $QuicktimeAudioCodecLookup['MAC6'] = 'Macintosh Audio Compression/Expansion (MACE) 6:1'; + $QuicktimeAudioCodecLookup['mixb'] = '8-bit Mixer'; + $QuicktimeAudioCodecLookup['mixw'] = '16-bit Mixer'; + $QuicktimeAudioCodecLookup['mp4a'] = 'ISO/IEC 14496-3 AAC'; + $QuicktimeAudioCodecLookup['MS'."\x00\x02"] = 'Microsoft ADPCM'; + $QuicktimeAudioCodecLookup['MS'."\x00\x11"] = 'DV IMA'; + $QuicktimeAudioCodecLookup['MS'."\x00\x55"] = 'Fraunhofer MPEG Layer III'; + $QuicktimeAudioCodecLookup['NONE'] = 'No Encoding'; + $QuicktimeAudioCodecLookup['Qclp'] = 'Qualcomm PureVoice'; + $QuicktimeAudioCodecLookup['QDM2'] = 'QDesign Music 2'; + $QuicktimeAudioCodecLookup['QDMC'] = 'QDesign Music 1'; + $QuicktimeAudioCodecLookup['ratb'] = '8-bit Rate'; + $QuicktimeAudioCodecLookup['ratw'] = '16-bit Rate'; + $QuicktimeAudioCodecLookup['raw '] = 'raw PCM'; + $QuicktimeAudioCodecLookup['sour'] = 'Sound Source'; + $QuicktimeAudioCodecLookup['sowt'] = 'signed/two\'s complement (Little Endian)'; + $QuicktimeAudioCodecLookup['str1'] = 'Iomega MPEG layer II'; + $QuicktimeAudioCodecLookup['str2'] = 'Iomega MPEG *layer II'; + $QuicktimeAudioCodecLookup['str3'] = 'Iomega MPEG **layer II'; + $QuicktimeAudioCodecLookup['str4'] = 'Iomega MPEG ***layer II'; + $QuicktimeAudioCodecLookup['twos'] = 'signed/two\'s complement (Big Endian)'; + $QuicktimeAudioCodecLookup['ulaw'] = 'mu-law 2:1'; + } + return (isset($QuicktimeAudioCodecLookup[$codecid]) ? $QuicktimeAudioCodecLookup[$codecid] : ''); + } + + public function QuicktimeDCOMLookup($compressionid) { + static $QuicktimeDCOMLookup = array(); + if (empty($QuicktimeDCOMLookup)) { + $QuicktimeDCOMLookup['zlib'] = 'ZLib Deflate'; + $QuicktimeDCOMLookup['adec'] = 'Apple Compression'; + } + return (isset($QuicktimeDCOMLookup[$compressionid]) ? $QuicktimeDCOMLookup[$compressionid] : ''); + } + + public function QuicktimeColorNameLookup($colordepthid) { + static $QuicktimeColorNameLookup = array(); + if (empty($QuicktimeColorNameLookup)) { + $QuicktimeColorNameLookup[1] = '2-color (monochrome)'; + $QuicktimeColorNameLookup[2] = '4-color'; + $QuicktimeColorNameLookup[4] = '16-color'; + $QuicktimeColorNameLookup[8] = '256-color'; + $QuicktimeColorNameLookup[16] = 'thousands (16-bit color)'; + $QuicktimeColorNameLookup[24] = 'millions (24-bit color)'; + $QuicktimeColorNameLookup[32] = 'millions+ (32-bit color)'; + $QuicktimeColorNameLookup[33] = 'black & white'; + $QuicktimeColorNameLookup[34] = '4-gray'; + $QuicktimeColorNameLookup[36] = '16-gray'; + $QuicktimeColorNameLookup[40] = '256-gray'; + } + return (isset($QuicktimeColorNameLookup[$colordepthid]) ? $QuicktimeColorNameLookup[$colordepthid] : 'invalid'); + } + + public function QuicktimeSTIKLookup($stik) { + static $QuicktimeSTIKLookup = array(); + if (empty($QuicktimeSTIKLookup)) { + $QuicktimeSTIKLookup[0] = 'Movie'; + $QuicktimeSTIKLookup[1] = 'Normal'; + $QuicktimeSTIKLookup[2] = 'Audiobook'; + $QuicktimeSTIKLookup[5] = 'Whacked Bookmark'; + $QuicktimeSTIKLookup[6] = 'Music Video'; + $QuicktimeSTIKLookup[9] = 'Short Film'; + $QuicktimeSTIKLookup[10] = 'TV Show'; + $QuicktimeSTIKLookup[11] = 'Booklet'; + $QuicktimeSTIKLookup[14] = 'Ringtone'; + $QuicktimeSTIKLookup[21] = 'Podcast'; + } + return (isset($QuicktimeSTIKLookup[$stik]) ? $QuicktimeSTIKLookup[$stik] : 'invalid'); + } + + public function QuicktimeIODSaudioProfileName($audio_profile_id) { + static $QuicktimeIODSaudioProfileNameLookup = array(); + if (empty($QuicktimeIODSaudioProfileNameLookup)) { + $QuicktimeIODSaudioProfileNameLookup = array( + 0x00 => 'ISO Reserved (0x00)', + 0x01 => 'Main Audio Profile @ Level 1', + 0x02 => 'Main Audio Profile @ Level 2', + 0x03 => 'Main Audio Profile @ Level 3', + 0x04 => 'Main Audio Profile @ Level 4', + 0x05 => 'Scalable Audio Profile @ Level 1', + 0x06 => 'Scalable Audio Profile @ Level 2', + 0x07 => 'Scalable Audio Profile @ Level 3', + 0x08 => 'Scalable Audio Profile @ Level 4', + 0x09 => 'Speech Audio Profile @ Level 1', + 0x0A => 'Speech Audio Profile @ Level 2', + 0x0B => 'Synthetic Audio Profile @ Level 1', + 0x0C => 'Synthetic Audio Profile @ Level 2', + 0x0D => 'Synthetic Audio Profile @ Level 3', + 0x0E => 'High Quality Audio Profile @ Level 1', + 0x0F => 'High Quality Audio Profile @ Level 2', + 0x10 => 'High Quality Audio Profile @ Level 3', + 0x11 => 'High Quality Audio Profile @ Level 4', + 0x12 => 'High Quality Audio Profile @ Level 5', + 0x13 => 'High Quality Audio Profile @ Level 6', + 0x14 => 'High Quality Audio Profile @ Level 7', + 0x15 => 'High Quality Audio Profile @ Level 8', + 0x16 => 'Low Delay Audio Profile @ Level 1', + 0x17 => 'Low Delay Audio Profile @ Level 2', + 0x18 => 'Low Delay Audio Profile @ Level 3', + 0x19 => 'Low Delay Audio Profile @ Level 4', + 0x1A => 'Low Delay Audio Profile @ Level 5', + 0x1B => 'Low Delay Audio Profile @ Level 6', + 0x1C => 'Low Delay Audio Profile @ Level 7', + 0x1D => 'Low Delay Audio Profile @ Level 8', + 0x1E => 'Natural Audio Profile @ Level 1', + 0x1F => 'Natural Audio Profile @ Level 2', + 0x20 => 'Natural Audio Profile @ Level 3', + 0x21 => 'Natural Audio Profile @ Level 4', + 0x22 => 'Mobile Audio Internetworking Profile @ Level 1', + 0x23 => 'Mobile Audio Internetworking Profile @ Level 2', + 0x24 => 'Mobile Audio Internetworking Profile @ Level 3', + 0x25 => 'Mobile Audio Internetworking Profile @ Level 4', + 0x26 => 'Mobile Audio Internetworking Profile @ Level 5', + 0x27 => 'Mobile Audio Internetworking Profile @ Level 6', + 0x28 => 'AAC Profile @ Level 1', + 0x29 => 'AAC Profile @ Level 2', + 0x2A => 'AAC Profile @ Level 4', + 0x2B => 'AAC Profile @ Level 5', + 0x2C => 'High Efficiency AAC Profile @ Level 2', + 0x2D => 'High Efficiency AAC Profile @ Level 3', + 0x2E => 'High Efficiency AAC Profile @ Level 4', + 0x2F => 'High Efficiency AAC Profile @ Level 5', + 0xFE => 'Not part of MPEG-4 audio profiles', + 0xFF => 'No audio capability required', + ); + } + return (isset($QuicktimeIODSaudioProfileNameLookup[$audio_profile_id]) ? $QuicktimeIODSaudioProfileNameLookup[$audio_profile_id] : 'ISO Reserved / User Private'); + } + + + public function QuicktimeIODSvideoProfileName($video_profile_id) { + static $QuicktimeIODSvideoProfileNameLookup = array(); + if (empty($QuicktimeIODSvideoProfileNameLookup)) { + $QuicktimeIODSvideoProfileNameLookup = array( + 0x00 => 'Reserved (0x00) Profile', + 0x01 => 'Simple Profile @ Level 1', + 0x02 => 'Simple Profile @ Level 2', + 0x03 => 'Simple Profile @ Level 3', + 0x08 => 'Simple Profile @ Level 0', + 0x10 => 'Simple Scalable Profile @ Level 0', + 0x11 => 'Simple Scalable Profile @ Level 1', + 0x12 => 'Simple Scalable Profile @ Level 2', + 0x15 => 'AVC/H264 Profile', + 0x21 => 'Core Profile @ Level 1', + 0x22 => 'Core Profile @ Level 2', + 0x32 => 'Main Profile @ Level 2', + 0x33 => 'Main Profile @ Level 3', + 0x34 => 'Main Profile @ Level 4', + 0x42 => 'N-bit Profile @ Level 2', + 0x51 => 'Scalable Texture Profile @ Level 1', + 0x61 => 'Simple Face Animation Profile @ Level 1', + 0x62 => 'Simple Face Animation Profile @ Level 2', + 0x63 => 'Simple FBA Profile @ Level 1', + 0x64 => 'Simple FBA Profile @ Level 2', + 0x71 => 'Basic Animated Texture Profile @ Level 1', + 0x72 => 'Basic Animated Texture Profile @ Level 2', + 0x81 => 'Hybrid Profile @ Level 1', + 0x82 => 'Hybrid Profile @ Level 2', + 0x91 => 'Advanced Real Time Simple Profile @ Level 1', + 0x92 => 'Advanced Real Time Simple Profile @ Level 2', + 0x93 => 'Advanced Real Time Simple Profile @ Level 3', + 0x94 => 'Advanced Real Time Simple Profile @ Level 4', + 0xA1 => 'Core Scalable Profile @ Level1', + 0xA2 => 'Core Scalable Profile @ Level2', + 0xA3 => 'Core Scalable Profile @ Level3', + 0xB1 => 'Advanced Coding Efficiency Profile @ Level 1', + 0xB2 => 'Advanced Coding Efficiency Profile @ Level 2', + 0xB3 => 'Advanced Coding Efficiency Profile @ Level 3', + 0xB4 => 'Advanced Coding Efficiency Profile @ Level 4', + 0xC1 => 'Advanced Core Profile @ Level 1', + 0xC2 => 'Advanced Core Profile @ Level 2', + 0xD1 => 'Advanced Scalable Texture @ Level1', + 0xD2 => 'Advanced Scalable Texture @ Level2', + 0xE1 => 'Simple Studio Profile @ Level 1', + 0xE2 => 'Simple Studio Profile @ Level 2', + 0xE3 => 'Simple Studio Profile @ Level 3', + 0xE4 => 'Simple Studio Profile @ Level 4', + 0xE5 => 'Core Studio Profile @ Level 1', + 0xE6 => 'Core Studio Profile @ Level 2', + 0xE7 => 'Core Studio Profile @ Level 3', + 0xE8 => 'Core Studio Profile @ Level 4', + 0xF0 => 'Advanced Simple Profile @ Level 0', + 0xF1 => 'Advanced Simple Profile @ Level 1', + 0xF2 => 'Advanced Simple Profile @ Level 2', + 0xF3 => 'Advanced Simple Profile @ Level 3', + 0xF4 => 'Advanced Simple Profile @ Level 4', + 0xF5 => 'Advanced Simple Profile @ Level 5', + 0xF7 => 'Advanced Simple Profile @ Level 3b', + 0xF8 => 'Fine Granularity Scalable Profile @ Level 0', + 0xF9 => 'Fine Granularity Scalable Profile @ Level 1', + 0xFA => 'Fine Granularity Scalable Profile @ Level 2', + 0xFB => 'Fine Granularity Scalable Profile @ Level 3', + 0xFC => 'Fine Granularity Scalable Profile @ Level 4', + 0xFD => 'Fine Granularity Scalable Profile @ Level 5', + 0xFE => 'Not part of MPEG-4 Visual profiles', + 0xFF => 'No visual capability required', + ); + } + return (isset($QuicktimeIODSvideoProfileNameLookup[$video_profile_id]) ? $QuicktimeIODSvideoProfileNameLookup[$video_profile_id] : 'ISO Reserved Profile'); + } + + + public function QuicktimeContentRatingLookup($rtng) { + static $QuicktimeContentRatingLookup = array(); + if (empty($QuicktimeContentRatingLookup)) { + $QuicktimeContentRatingLookup[0] = 'None'; + $QuicktimeContentRatingLookup[2] = 'Clean'; + $QuicktimeContentRatingLookup[4] = 'Explicit'; + } + return (isset($QuicktimeContentRatingLookup[$rtng]) ? $QuicktimeContentRatingLookup[$rtng] : 'invalid'); + } + + public function QuicktimeStoreAccountTypeLookup($akid) { + static $QuicktimeStoreAccountTypeLookup = array(); + if (empty($QuicktimeStoreAccountTypeLookup)) { + $QuicktimeStoreAccountTypeLookup[0] = 'iTunes'; + $QuicktimeStoreAccountTypeLookup[1] = 'AOL'; + } + return (isset($QuicktimeStoreAccountTypeLookup[$akid]) ? $QuicktimeStoreAccountTypeLookup[$akid] : 'invalid'); + } + + public function QuicktimeStoreFrontCodeLookup($sfid) { + static $QuicktimeStoreFrontCodeLookup = array(); + if (empty($QuicktimeStoreFrontCodeLookup)) { + $QuicktimeStoreFrontCodeLookup[143460] = 'Australia'; + $QuicktimeStoreFrontCodeLookup[143445] = 'Austria'; + $QuicktimeStoreFrontCodeLookup[143446] = 'Belgium'; + $QuicktimeStoreFrontCodeLookup[143455] = 'Canada'; + $QuicktimeStoreFrontCodeLookup[143458] = 'Denmark'; + $QuicktimeStoreFrontCodeLookup[143447] = 'Finland'; + $QuicktimeStoreFrontCodeLookup[143442] = 'France'; + $QuicktimeStoreFrontCodeLookup[143443] = 'Germany'; + $QuicktimeStoreFrontCodeLookup[143448] = 'Greece'; + $QuicktimeStoreFrontCodeLookup[143449] = 'Ireland'; + $QuicktimeStoreFrontCodeLookup[143450] = 'Italy'; + $QuicktimeStoreFrontCodeLookup[143462] = 'Japan'; + $QuicktimeStoreFrontCodeLookup[143451] = 'Luxembourg'; + $QuicktimeStoreFrontCodeLookup[143452] = 'Netherlands'; + $QuicktimeStoreFrontCodeLookup[143461] = 'New Zealand'; + $QuicktimeStoreFrontCodeLookup[143457] = 'Norway'; + $QuicktimeStoreFrontCodeLookup[143453] = 'Portugal'; + $QuicktimeStoreFrontCodeLookup[143454] = 'Spain'; + $QuicktimeStoreFrontCodeLookup[143456] = 'Sweden'; + $QuicktimeStoreFrontCodeLookup[143459] = 'Switzerland'; + $QuicktimeStoreFrontCodeLookup[143444] = 'United Kingdom'; + $QuicktimeStoreFrontCodeLookup[143441] = 'United States'; + } + return (isset($QuicktimeStoreFrontCodeLookup[$sfid]) ? $QuicktimeStoreFrontCodeLookup[$sfid] : 'invalid'); + } + + public function QuicktimeParseNikonNCTG($atom_data) { + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG + // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100 + // Data is stored as records of: + // * 4 bytes record type + // * 2 bytes size of data field type: + // 0x0001 = flag (size field *= 1-byte) + // 0x0002 = char (size field *= 1-byte) + // 0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB + // 0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD + // 0x0005 = float (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together + // 0x0007 = bytes (size field *= 1-byte), values are stored as ?????? + // 0x0008 = ????? (size field *= 2-byte), values are stored as ?????? + // * 2 bytes data size field + // * ? bytes data (string data may be null-padded; datestamp fields are in the format "2011:05:25 20:24:15") + // all integers are stored BigEndian + + $NCTGtagName = array( + 0x00000001 => 'Make', + 0x00000002 => 'Model', + 0x00000003 => 'Software', + 0x00000011 => 'CreateDate', + 0x00000012 => 'DateTimeOriginal', + 0x00000013 => 'FrameCount', + 0x00000016 => 'FrameRate', + 0x00000022 => 'FrameWidth', + 0x00000023 => 'FrameHeight', + 0x00000032 => 'AudioChannels', + 0x00000033 => 'AudioBitsPerSample', + 0x00000034 => 'AudioSampleRate', + 0x02000001 => 'MakerNoteVersion', + 0x02000005 => 'WhiteBalance', + 0x0200000b => 'WhiteBalanceFineTune', + 0x0200001e => 'ColorSpace', + 0x02000023 => 'PictureControlData', + 0x02000024 => 'WorldTime', + 0x02000032 => 'UnknownInfo', + 0x02000083 => 'LensType', + 0x02000084 => 'Lens', + ); + + $offset = 0; + $datalength = strlen($atom_data); + $parsed = array(); + while ($offset < $datalength) { +//echo getid3_lib::PrintHexBytes(substr($atom_data, $offset, 4)).'<br>'; + $record_type = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 4)); $offset += 4; + $data_size_type = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2)); $offset += 2; + $data_size = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2)); $offset += 2; + switch ($data_size_type) { + case 0x0001: // 0x0001 = flag (size field *= 1-byte) + $data = getid3_lib::BigEndian2Int(substr($atom_data, $offset, $data_size * 1)); + $offset += ($data_size * 1); + break; + case 0x0002: // 0x0002 = char (size field *= 1-byte) + $data = substr($atom_data, $offset, $data_size * 1); + $offset += ($data_size * 1); + $data = rtrim($data, "\x00"); + break; + case 0x0003: // 0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB + $data = ''; + for ($i = $data_size - 1; $i >= 0; $i--) { + $data .= substr($atom_data, $offset + ($i * 2), 2); + } + $data = getid3_lib::BigEndian2Int($data); + $offset += ($data_size * 2); + break; + case 0x0004: // 0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD + $data = ''; + for ($i = $data_size - 1; $i >= 0; $i--) { + $data .= substr($atom_data, $offset + ($i * 4), 4); + } + $data = getid3_lib::BigEndian2Int($data); + $offset += ($data_size * 4); + break; + case 0x0005: // 0x0005 = float (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together + $data = array(); + for ($i = 0; $i < $data_size; $i++) { + $numerator = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 0, 4)); + $denomninator = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 4, 4)); + if ($denomninator == 0) { + $data[$i] = false; + } else { + $data[$i] = (double) $numerator / $denomninator; + } + } + $offset += (8 * $data_size); + if (count($data) == 1) { + $data = $data[0]; + } + break; + case 0x0007: // 0x0007 = bytes (size field *= 1-byte), values are stored as ?????? + $data = substr($atom_data, $offset, $data_size * 1); + $offset += ($data_size * 1); + break; + case 0x0008: // 0x0008 = ????? (size field *= 2-byte), values are stored as ?????? + $data = substr($atom_data, $offset, $data_size * 2); + $offset += ($data_size * 2); + break; + default: +echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br>'; + break 2; + } + + switch ($record_type) { + case 0x00000011: // CreateDate + case 0x00000012: // DateTimeOriginal + $data = strtotime($data); + break; + case 0x0200001e: // ColorSpace + switch ($data) { + case 1: + $data = 'sRGB'; + break; + case 2: + $data = 'Adobe RGB'; + break; + } + break; + case 0x02000023: // PictureControlData + $PictureControlAdjust = array(0=>'default', 1=>'quick', 2=>'full'); + $FilterEffect = array(0x80=>'off', 0x81=>'yellow', 0x82=>'orange', 0x83=>'red', 0x84=>'green', 0xff=>'n/a'); + $ToningEffect = array(0x80=>'b&w', 0x81=>'sepia', 0x82=>'cyanotype', 0x83=>'red', 0x84=>'yellow', 0x85=>'green', 0x86=>'blue-green', 0x87=>'blue', 0x88=>'purple-blue', 0x89=>'red-purple', 0xff=>'n/a'); + $data = array( + 'PictureControlVersion' => substr($data, 0, 4), + 'PictureControlName' => rtrim(substr($data, 4, 20), "\x00"), + 'PictureControlBase' => rtrim(substr($data, 24, 20), "\x00"), + //'?' => substr($data, 44, 4), + 'PictureControlAdjust' => $PictureControlAdjust[ord(substr($data, 48, 1))], + 'PictureControlQuickAdjust' => ord(substr($data, 49, 1)), + 'Sharpness' => ord(substr($data, 50, 1)), + 'Contrast' => ord(substr($data, 51, 1)), + 'Brightness' => ord(substr($data, 52, 1)), + 'Saturation' => ord(substr($data, 53, 1)), + 'HueAdjustment' => ord(substr($data, 54, 1)), + 'FilterEffect' => $FilterEffect[ord(substr($data, 55, 1))], + 'ToningEffect' => $ToningEffect[ord(substr($data, 56, 1))], + 'ToningSaturation' => ord(substr($data, 57, 1)), + ); + break; + case 0x02000024: // WorldTime + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#WorldTime + // timezone is stored as offset from GMT in minutes + $timezone = getid3_lib::BigEndian2Int(substr($data, 0, 2)); + if ($timezone & 0x8000) { + $timezone = 0 - (0x10000 - $timezone); + } + $timezone /= 60; + + $dst = (bool) getid3_lib::BigEndian2Int(substr($data, 2, 1)); + switch (getid3_lib::BigEndian2Int(substr($data, 3, 1))) { + case 2: + $datedisplayformat = 'D/M/Y'; break; + case 1: + $datedisplayformat = 'M/D/Y'; break; + case 0: + default: + $datedisplayformat = 'Y/M/D'; break; + } + + $data = array('timezone'=>floatval($timezone), 'dst'=>$dst, 'display'=>$datedisplayformat); + break; + case 0x02000083: // LensType + $data = array( + //'_' => $data, + 'mf' => (bool) ($data & 0x01), + 'd' => (bool) ($data & 0x02), + 'g' => (bool) ($data & 0x04), + 'vr' => (bool) ($data & 0x08), + ); + break; + } + $tag_name = (isset($NCTGtagName[$record_type]) ? $NCTGtagName[$record_type] : '0x'.str_pad(dechex($record_type), 8, '0', STR_PAD_LEFT)); + $parsed[$tag_name] = $data; + } + return $parsed; + } + + + public function CopyToAppropriateCommentsSection($keyname, $data, $boxname='') { + static $handyatomtranslatorarray = array(); + if (empty($handyatomtranslatorarray)) { + $handyatomtranslatorarray['©cpy'] = 'copyright'; + $handyatomtranslatorarray['©day'] = 'creation_date'; // iTunes 4.0 + $handyatomtranslatorarray['©dir'] = 'director'; + $handyatomtranslatorarray['©ed1'] = 'edit1'; + $handyatomtranslatorarray['©ed2'] = 'edit2'; + $handyatomtranslatorarray['©ed3'] = 'edit3'; + $handyatomtranslatorarray['©ed4'] = 'edit4'; + $handyatomtranslatorarray['©ed5'] = 'edit5'; + $handyatomtranslatorarray['©ed6'] = 'edit6'; + $handyatomtranslatorarray['©ed7'] = 'edit7'; + $handyatomtranslatorarray['©ed8'] = 'edit8'; + $handyatomtranslatorarray['©ed9'] = 'edit9'; + $handyatomtranslatorarray['©fmt'] = 'format'; + $handyatomtranslatorarray['©inf'] = 'information'; + $handyatomtranslatorarray['©prd'] = 'producer'; + $handyatomtranslatorarray['©prf'] = 'performers'; + $handyatomtranslatorarray['©req'] = 'system_requirements'; + $handyatomtranslatorarray['©src'] = 'source_credit'; + $handyatomtranslatorarray['©wrt'] = 'writer'; + + // http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt + $handyatomtranslatorarray['©nam'] = 'title'; // iTunes 4.0 + $handyatomtranslatorarray['©cmt'] = 'comment'; // iTunes 4.0 + $handyatomtranslatorarray['©wrn'] = 'warning'; + $handyatomtranslatorarray['©hst'] = 'host_computer'; + $handyatomtranslatorarray['©mak'] = 'make'; + $handyatomtranslatorarray['©mod'] = 'model'; + $handyatomtranslatorarray['©PRD'] = 'product'; + $handyatomtranslatorarray['©swr'] = 'software'; + $handyatomtranslatorarray['©aut'] = 'author'; + $handyatomtranslatorarray['©ART'] = 'artist'; + $handyatomtranslatorarray['©trk'] = 'track'; + $handyatomtranslatorarray['©alb'] = 'album'; // iTunes 4.0 + $handyatomtranslatorarray['©com'] = 'comment'; + $handyatomtranslatorarray['©gen'] = 'genre'; // iTunes 4.0 + $handyatomtranslatorarray['©ope'] = 'composer'; + $handyatomtranslatorarray['©url'] = 'url'; + $handyatomtranslatorarray['©enc'] = 'encoder'; + + // http://atomicparsley.sourceforge.net/mpeg-4files.html + $handyatomtranslatorarray['©art'] = 'artist'; // iTunes 4.0 + $handyatomtranslatorarray['aART'] = 'album_artist'; + $handyatomtranslatorarray['trkn'] = 'track_number'; // iTunes 4.0 + $handyatomtranslatorarray['disk'] = 'disc_number'; // iTunes 4.0 + $handyatomtranslatorarray['gnre'] = 'genre'; // iTunes 4.0 + $handyatomtranslatorarray['©too'] = 'encoder'; // iTunes 4.0 + $handyatomtranslatorarray['tmpo'] = 'bpm'; // iTunes 4.0 + $handyatomtranslatorarray['cprt'] = 'copyright'; // iTunes 4.0? + $handyatomtranslatorarray['cpil'] = 'compilation'; // iTunes 4.0 + $handyatomtranslatorarray['covr'] = 'picture'; // iTunes 4.0 + $handyatomtranslatorarray['rtng'] = 'rating'; // iTunes 4.0 + $handyatomtranslatorarray['©grp'] = 'grouping'; // iTunes 4.2 + $handyatomtranslatorarray['stik'] = 'stik'; // iTunes 4.9 + $handyatomtranslatorarray['pcst'] = 'podcast'; // iTunes 4.9 + $handyatomtranslatorarray['catg'] = 'category'; // iTunes 4.9 + $handyatomtranslatorarray['keyw'] = 'keyword'; // iTunes 4.9 + $handyatomtranslatorarray['purl'] = 'podcast_url'; // iTunes 4.9 + $handyatomtranslatorarray['egid'] = 'episode_guid'; // iTunes 4.9 + $handyatomtranslatorarray['desc'] = 'description'; // iTunes 5.0 + $handyatomtranslatorarray['©lyr'] = 'lyrics'; // iTunes 5.0 + $handyatomtranslatorarray['tvnn'] = 'tv_network_name'; // iTunes 6.0 + $handyatomtranslatorarray['tvsh'] = 'tv_show_name'; // iTunes 6.0 + $handyatomtranslatorarray['tvsn'] = 'tv_season'; // iTunes 6.0 + $handyatomtranslatorarray['tves'] = 'tv_episode'; // iTunes 6.0 + $handyatomtranslatorarray['purd'] = 'purchase_date'; // iTunes 6.0.2 + $handyatomtranslatorarray['pgap'] = 'gapless_playback'; // iTunes 7.0 + + // http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt + + + + // boxnames: + /* + $handyatomtranslatorarray['iTunSMPB'] = 'iTunSMPB'; + $handyatomtranslatorarray['iTunNORM'] = 'iTunNORM'; + $handyatomtranslatorarray['Encoding Params'] = 'Encoding Params'; + $handyatomtranslatorarray['replaygain_track_gain'] = 'replaygain_track_gain'; + $handyatomtranslatorarray['replaygain_track_peak'] = 'replaygain_track_peak'; + $handyatomtranslatorarray['replaygain_track_minmax'] = 'replaygain_track_minmax'; + $handyatomtranslatorarray['MusicIP PUID'] = 'MusicIP PUID'; + $handyatomtranslatorarray['MusicBrainz Artist Id'] = 'MusicBrainz Artist Id'; + $handyatomtranslatorarray['MusicBrainz Album Id'] = 'MusicBrainz Album Id'; + $handyatomtranslatorarray['MusicBrainz Album Artist Id'] = 'MusicBrainz Album Artist Id'; + $handyatomtranslatorarray['MusicBrainz Track Id'] = 'MusicBrainz Track Id'; + $handyatomtranslatorarray['MusicBrainz Disc Id'] = 'MusicBrainz Disc Id'; + + // http://age.hobba.nl/audio/tag_frame_reference.html + $handyatomtranslatorarray['PLAY_COUNTER'] = 'play_counter'; // Foobar2000 - http://www.getid3.org/phpBB3/viewtopic.php?t=1355 + $handyatomtranslatorarray['MEDIATYPE'] = 'mediatype'; // Foobar2000 - http://www.getid3.org/phpBB3/viewtopic.php?t=1355 + */ + } + $info = &$this->getid3->info; + $comment_key = ''; + if ($boxname && ($boxname != $keyname)) { + $comment_key = (isset($handyatomtranslatorarray[$boxname]) ? $handyatomtranslatorarray[$boxname] : $boxname); + } elseif (isset($handyatomtranslatorarray[$keyname])) { + $comment_key = $handyatomtranslatorarray[$keyname]; + } + if ($comment_key) { + if ($comment_key == 'picture') { + if (!is_array($data)) { + $image_mime = ''; + if (preg_match('#^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A#', $data)) { + $image_mime = 'image/png'; + } elseif (preg_match('#^\xFF\xD8\xFF#', $data)) { + $image_mime = 'image/jpeg'; + } elseif (preg_match('#^GIF#', $data)) { + $image_mime = 'image/gif'; + } elseif (preg_match('#^BM#', $data)) { + $image_mime = 'image/bmp'; + } + $data = array('data'=>$data, 'image_mime'=>$image_mime); + } + } + $info['quicktime']['comments'][$comment_key][] = $data; + } + return true; + } + + public function NoNullString($nullterminatedstring) { + // remove the single null terminator on null terminated strings + if (substr($nullterminatedstring, strlen($nullterminatedstring) - 1, 1) === "\x00") { + return substr($nullterminatedstring, 0, strlen($nullterminatedstring) - 1); + } + return $nullterminatedstring; + } + + public function Pascal2String($pascalstring) { + // Pascal strings have 1 unsigned byte at the beginning saying how many chars (1-255) are in the string + return substr($pascalstring, 1); + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio-video.riff.php b/extensions/TimedMediaHandler/libs/getid3/module.audio-video.riff.php new file mode 100644 index 00000000..5ac5d1cd --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio-video.riff.php @@ -0,0 +1,2435 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio-video.riff.php // +// module for analyzing RIFF files // +// multiple formats supported by this module: // +// Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX // +// dependencies: module.audio.mp3.php // +// module.audio.ac3.php // +// module.audio.dts.php // +// /// +///////////////////////////////////////////////////////////////// + +/** +* @todo Parse AC-3/DTS audio inside WAVE correctly +* @todo Rewrite RIFF parser totally +*/ + +getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true); +getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, true); +getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.dts.php', __FILE__, true); + +class getid3_riff extends getid3_handler +{ + + public function Analyze() { + $info = &$this->getid3->info; + + // initialize these values to an empty array, otherwise they default to NULL + // and you can't append array values to a NULL value + $info['riff'] = array('raw'=>array()); + + // Shortcuts + $thisfile_riff = &$info['riff']; + $thisfile_riff_raw = &$thisfile_riff['raw']; + $thisfile_audio = &$info['audio']; + $thisfile_video = &$info['video']; + $thisfile_audio_dataformat = &$thisfile_audio['dataformat']; + $thisfile_riff_audio = &$thisfile_riff['audio']; + $thisfile_riff_video = &$thisfile_riff['video']; + + $Original['avdataoffset'] = $info['avdataoffset']; + $Original['avdataend'] = $info['avdataend']; + + $this->fseek($info['avdataoffset']); + $RIFFheader = $this->fread(12); + $offset = $this->ftell(); + $RIFFtype = substr($RIFFheader, 0, 4); + $RIFFsize = substr($RIFFheader, 4, 4); + $RIFFsubtype = substr($RIFFheader, 8, 4); + + switch ($RIFFtype) { + + case 'FORM': // AIFF, AIFC + $info['fileformat'] = 'aiff'; + $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize); + $thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4)); + break; + + case 'RIFF': // AVI, WAV, etc + case 'SDSS': // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com) + case 'RMP3': // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s + $info['fileformat'] = 'riff'; + $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize); + if ($RIFFsubtype == 'RMP3') { + // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s + $RIFFsubtype = 'WAVE'; + } + $thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4)); + if (($info['avdataend'] - $info['filesize']) == 1) { + // LiteWave appears to incorrectly *not* pad actual output file + // to nearest WORD boundary so may appear to be short by one + // byte, in which case - skip warning + $info['avdataend'] = $info['filesize']; + } + + $nextRIFFoffset = $Original['avdataoffset'] + 8 + $thisfile_riff['header_size']; // 8 = "RIFF" + 32-bit offset + while ($nextRIFFoffset < min($info['filesize'], $info['avdataend'])) { + try { + $this->fseek($nextRIFFoffset); + } catch (getid3_exception $e) { + if ($e->getCode() == 10) { + //$this->warning('RIFF parser: '.$e->getMessage()); + $this->error('AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime may be wrong'); + $this->warning('[avdataend] value may be incorrect, multiple AVIX chunks may be present'); + break; + } else { + throw $e; + } + } + $nextRIFFheader = $this->fread(12); + if ($nextRIFFoffset == ($info['avdataend'] - 1)) { + if (substr($nextRIFFheader, 0, 1) == "\x00") { + // RIFF padded to WORD boundary, we're actually already at the end + break; + } + } + $nextRIFFheaderID = substr($nextRIFFheader, 0, 4); + $nextRIFFsize = $this->EitherEndian2Int(substr($nextRIFFheader, 4, 4)); + $nextRIFFtype = substr($nextRIFFheader, 8, 4); + $chunkdata = array(); + $chunkdata['offset'] = $nextRIFFoffset + 8; + $chunkdata['size'] = $nextRIFFsize; + $nextRIFFoffset = $chunkdata['offset'] + $chunkdata['size']; + + switch ($nextRIFFheaderID) { + + case 'RIFF': + $chunkdata['chunks'] = $this->ParseRIFF($chunkdata['offset'] + 4, $nextRIFFoffset); + + if (!isset($thisfile_riff[$nextRIFFtype])) { + $thisfile_riff[$nextRIFFtype] = array(); + } + $thisfile_riff[$nextRIFFtype][] = $chunkdata; + break; + + case 'JUNK': + // ignore + $thisfile_riff[$nextRIFFheaderID][] = $chunkdata; + break; + + case 'IDVX': + $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunkdata['size'])); + break; + + default: + if ($info['filesize'] == ($chunkdata['offset'] - 8 + 128)) { + $DIVXTAG = $nextRIFFheader.$this->fread(128 - 12); + if (substr($DIVXTAG, -7) == 'DIVXTAG') { + // DIVXTAG is supposed to be inside an IDVX chunk in a LIST chunk, but some bad encoders just slap it on the end of a file + $this->warning('Found wrongly-structured DIVXTAG at offset '.($this->ftell() - 128).', parsing anyway'); + $info['divxtag']['comments'] = self::ParseDIVXTAG($DIVXTAG); + break 2; + } + } + $this->warning('Expecting "RIFF|JUNK|IDVX" at '.$nextRIFFoffset.', found "'.$nextRIFFheaderID.'" ('.getid3_lib::PrintHexBytes($nextRIFFheaderID).') - skipping rest of file'); + break 2; + + } + + } + if ($RIFFsubtype == 'WAVE') { + $thisfile_riff_WAVE = &$thisfile_riff['WAVE']; + } + break; + + default: + $this->error('Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead'); + unset($info['fileformat']); + return false; + } + + $streamindex = 0; + switch ($RIFFsubtype) { + case 'WAVE': + if (empty($thisfile_audio['bitrate_mode'])) { + $thisfile_audio['bitrate_mode'] = 'cbr'; + } + if (empty($thisfile_audio_dataformat)) { + $thisfile_audio_dataformat = 'wav'; + } + + if (isset($thisfile_riff_WAVE['data'][0]['offset'])) { + $info['avdataoffset'] = $thisfile_riff_WAVE['data'][0]['offset'] + 8; + $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff_WAVE['data'][0]['size']; + } + if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) { + + $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']); + $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag']; + if (!isset($thisfile_riff_audio[$streamindex]['bitrate']) || ($thisfile_riff_audio[$streamindex]['bitrate'] == 0)) { + $info['error'][] = 'Corrupt RIFF file: bitrate_audio == zero'; + return false; + } + $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw']; + unset($thisfile_riff_audio[$streamindex]['raw']); + $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex]; + + $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]); + if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') { + $info['warning'][] = 'Audio codec = '.$thisfile_audio['codec']; + } + $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate']; + + if (empty($info['playtime_seconds'])) { // may already be set (e.g. DTS-WAV) + $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']); + } + + $thisfile_audio['lossless'] = false; + if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) { + switch ($thisfile_riff_raw['fmt ']['wFormatTag']) { + + case 0x0001: // PCM + $thisfile_audio['lossless'] = true; + break; + + case 0x2000: // AC-3 + $thisfile_audio_dataformat = 'ac3'; + break; + + default: + // do nothing + break; + + } + } + $thisfile_audio['streams'][$streamindex]['wformattag'] = $thisfile_audio['wformattag']; + $thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode']; + $thisfile_audio['streams'][$streamindex]['lossless'] = $thisfile_audio['lossless']; + $thisfile_audio['streams'][$streamindex]['dataformat'] = $thisfile_audio_dataformat; + } + + if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) { + + // shortcuts + $rgadData = &$thisfile_riff_WAVE['rgad'][0]['data']; + $thisfile_riff_raw['rgad'] = array('track'=>array(), 'album'=>array()); + $thisfile_riff_raw_rgad = &$thisfile_riff_raw['rgad']; + $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track']; + $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album']; + + $thisfile_riff_raw_rgad['fPeakAmplitude'] = getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4)); + $thisfile_riff_raw_rgad['nRadioRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 4, 2)); + $thisfile_riff_raw_rgad['nAudiophileRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 6, 2)); + + $nRadioRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT); + $nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT); + $thisfile_riff_raw_rgad_track['name'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3)); + $thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3)); + $thisfile_riff_raw_rgad_track['signbit'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1)); + $thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9)); + $thisfile_riff_raw_rgad_album['name'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3)); + $thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3)); + $thisfile_riff_raw_rgad_album['signbit'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1)); + $thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9)); + + $thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude']; + if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) { + $thisfile_riff['rgad']['track']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']); + $thisfile_riff['rgad']['track']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']); + $thisfile_riff['rgad']['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']); + } + if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) { + $thisfile_riff['rgad']['album']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']); + $thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']); + $thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']); + } + } + + if (isset($thisfile_riff_WAVE['fact'][0]['data'])) { + $thisfile_riff_raw['fact']['NumberOfSamples'] = $this->EitherEndian2Int(substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4)); + + // This should be a good way of calculating exact playtime, + // but some sample files have had incorrect number of samples, + // so cannot use this method + + // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) { + // $info['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec']; + // } + } + if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) { + $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8); + } + + if (isset($thisfile_riff_WAVE['bext'][0]['data'])) { + // shortcut + $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0]; + + $thisfile_riff_WAVE_bext_0['title'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 0, 256)); + $thisfile_riff_WAVE_bext_0['author'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 256, 32)); + $thisfile_riff_WAVE_bext_0['reference'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 288, 32)); + $thisfile_riff_WAVE_bext_0['origin_date'] = substr($thisfile_riff_WAVE_bext_0['data'], 320, 10); + $thisfile_riff_WAVE_bext_0['origin_time'] = substr($thisfile_riff_WAVE_bext_0['data'], 330, 8); + $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338, 8)); + $thisfile_riff_WAVE_bext_0['bwf_version'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346, 1)); + $thisfile_riff_WAVE_bext_0['reserved'] = substr($thisfile_riff_WAVE_bext_0['data'], 347, 254); + $thisfile_riff_WAVE_bext_0['coding_history'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601))); + if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) { + if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) { + list($dummy, $bext_timestamp['year'], $bext_timestamp['month'], $bext_timestamp['day']) = $matches_bext_date; + list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time; + $thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']); + } else { + $info['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid'; + } + } else { + $info['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid'; + } + $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author']; + $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_bext_0['title']; + } + + if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) { + // shortcut + $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0]; + + $thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2)); + $thisfile_riff_WAVE_MEXT_0['flags']['homogenous'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001); + if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) { + $thisfile_riff_WAVE_MEXT_0['flags']['padding'] = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true; + $thisfile_riff_WAVE_MEXT_0['flags']['22_or_44'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004); + $thisfile_riff_WAVE_MEXT_0['flags']['free_format'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008); + + $thisfile_riff_WAVE_MEXT_0['nominal_frame_size'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2)); + } + $thisfile_riff_WAVE_MEXT_0['anciliary_data_length'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2)); + $thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2)); + $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001); + $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002); + $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004); + } + + if (isset($thisfile_riff_WAVE['cart'][0]['data'])) { + // shortcut + $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0]; + + $thisfile_riff_WAVE_cart_0['version'] = substr($thisfile_riff_WAVE_cart_0['data'], 0, 4); + $thisfile_riff_WAVE_cart_0['title'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 4, 64)); + $thisfile_riff_WAVE_cart_0['artist'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 68, 64)); + $thisfile_riff_WAVE_cart_0['cut_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 132, 64)); + $thisfile_riff_WAVE_cart_0['client_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 196, 64)); + $thisfile_riff_WAVE_cart_0['category'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 260, 64)); + $thisfile_riff_WAVE_cart_0['classification'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 324, 64)); + $thisfile_riff_WAVE_cart_0['out_cue'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 388, 64)); + $thisfile_riff_WAVE_cart_0['start_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 452, 10)); + $thisfile_riff_WAVE_cart_0['start_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 462, 8)); + $thisfile_riff_WAVE_cart_0['end_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 470, 10)); + $thisfile_riff_WAVE_cart_0['end_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 480, 8)); + $thisfile_riff_WAVE_cart_0['producer_app_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 488, 64)); + $thisfile_riff_WAVE_cart_0['producer_app_version'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 552, 64)); + $thisfile_riff_WAVE_cart_0['user_defined_text'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 616, 64)); + $thisfile_riff_WAVE_cart_0['zero_db_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 680, 4), true); + for ($i = 0; $i < 8; $i++) { + $thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] = substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4); + $thisfile_riff_WAVE_cart_0['post_time'][$i]['timer_value'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8) + 4, 4)); + } + $thisfile_riff_WAVE_cart_0['url'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 748, 1024)); + $thisfile_riff_WAVE_cart_0['tag_text'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772))); + + $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist']; + $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_cart_0['title']; + } + + if (isset($thisfile_riff_WAVE['SNDM'][0]['data'])) { + // SoundMiner metadata + + // shortcuts + $thisfile_riff_WAVE_SNDM_0 = &$thisfile_riff_WAVE['SNDM'][0]; + $thisfile_riff_WAVE_SNDM_0_data = &$thisfile_riff_WAVE_SNDM_0['data']; + $SNDM_startoffset = 0; + $SNDM_endoffset = $thisfile_riff_WAVE_SNDM_0['size']; + + while ($SNDM_startoffset < $SNDM_endoffset) { + $SNDM_thisTagOffset = 0; + $SNDM_thisTagSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4)); + $SNDM_thisTagOffset += 4; + $SNDM_thisTagKey = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4); + $SNDM_thisTagOffset += 4; + $SNDM_thisTagDataSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2)); + $SNDM_thisTagOffset += 2; + $SNDM_thisTagDataFlags = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2)); + $SNDM_thisTagOffset += 2; + $SNDM_thisTagDataText = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, $SNDM_thisTagDataSize); + $SNDM_thisTagOffset += $SNDM_thisTagDataSize; + + if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) { + $info['warning'][] = 'RIFF.WAVE.SNDM.data contains tag not expected length (expected: '.$SNDM_thisTagSize.', found: '.(4 + 4 + 2 + 2 + $SNDM_thisTagDataSize).') at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')'; + break; + } elseif ($SNDM_thisTagSize <= 0) { + $info['warning'][] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')'; + break; + } + $SNDM_startoffset += $SNDM_thisTagSize; + + $thisfile_riff_WAVE_SNDM_0['parsed_raw'][$SNDM_thisTagKey] = $SNDM_thisTagDataText; + if ($parsedkey = self::waveSNDMtagLookup($SNDM_thisTagKey)) { + $thisfile_riff_WAVE_SNDM_0['parsed'][$parsedkey] = $SNDM_thisTagDataText; + } else { + $info['warning'][] = 'RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')'; + } + } + + $tagmapping = array( + 'tracktitle'=>'title', + 'category' =>'genre', + 'cdtitle' =>'album', + 'tracktitle'=>'title', + ); + foreach ($tagmapping as $fromkey => $tokey) { + if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) { + $thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey]; + } + } + } + + if (isset($thisfile_riff_WAVE['iXML'][0]['data'])) { + // requires functions simplexml_load_string and get_object_vars + if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE['iXML'][0]['data'])) { + $thisfile_riff_WAVE['iXML'][0]['parsed'] = $parsedXML; + if (isset($parsedXML['SPEED']['MASTER_SPEED'])) { + @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['MASTER_SPEED']); + $thisfile_riff_WAVE['iXML'][0]['master_speed'] = $numerator / ($denominator ? $denominator : 1000); + } + if (isset($parsedXML['SPEED']['TIMECODE_RATE'])) { + @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['TIMECODE_RATE']); + $thisfile_riff_WAVE['iXML'][0]['timecode_rate'] = $numerator / ($denominator ? $denominator : 1000); + } + if (isset($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO']) && !empty($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) && !empty($thisfile_riff_WAVE['iXML'][0]['timecode_rate'])) { + $samples_since_midnight = floatval(ltrim($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI'].$parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'], '0')); + $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] = $samples_since_midnight / $parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']; + $h = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] / 3600); + $m = floor(($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600)) / 60); + $s = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60)); + $f = ($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60) - $s) * $thisfile_riff_WAVE['iXML'][0]['timecode_rate']; + $thisfile_riff_WAVE['iXML'][0]['timecode_string'] = sprintf('%02d:%02d:%02d:%05.2f', $h, $m, $s, $f); + $thisfile_riff_WAVE['iXML'][0]['timecode_string_round'] = sprintf('%02d:%02d:%02d:%02d', $h, $m, $s, round($f)); + } + unset($parsedXML); + } + } + + + + if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) { + $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate']; + $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']); + } + + if (!empty($info['wavpack'])) { + $thisfile_audio_dataformat = 'wavpack'; + $thisfile_audio['bitrate_mode'] = 'vbr'; + $thisfile_audio['encoder'] = 'WavPack v'.$info['wavpack']['version']; + + // Reset to the way it was - RIFF parsing will have messed this up + $info['avdataend'] = $Original['avdataend']; + $thisfile_audio['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds']; + + $this->fseek($info['avdataoffset'] - 44); + $RIFFdata = $this->fread(44); + $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 4, 4)) + 8; + $OrignalRIFFdataSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44; + + if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) { + $info['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize); + $this->fseek($info['avdataend']); + $RIFFdata .= $this->fread($OrignalRIFFheaderSize - $OrignalRIFFdataSize); + } + + // move the data chunk after all other chunks (if any) + // so that the RIFF parser doesn't see EOF when trying + // to skip over the data chunk + $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8); + $getid3_riff = new getid3_riff($this->getid3); + $getid3_riff->ParseRIFFdata($RIFFdata); + unset($getid3_riff); + } + + if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) { + switch ($thisfile_riff_raw['fmt ']['wFormatTag']) { + case 0x0001: // PCM + if (!empty($info['ac3'])) { + // Dolby Digital WAV files masquerade as PCM-WAV, but they're not + $thisfile_audio['wformattag'] = 0x2000; + $thisfile_audio['codec'] = self::wFormatTagLookup($thisfile_audio['wformattag']); + $thisfile_audio['lossless'] = false; + $thisfile_audio['bitrate'] = $info['ac3']['bitrate']; + $thisfile_audio['sample_rate'] = $info['ac3']['sample_rate']; + } + if (!empty($info['dts'])) { + // Dolby DTS files masquerade as PCM-WAV, but they're not + $thisfile_audio['wformattag'] = 0x2001; + $thisfile_audio['codec'] = self::wFormatTagLookup($thisfile_audio['wformattag']); + $thisfile_audio['lossless'] = false; + $thisfile_audio['bitrate'] = $info['dts']['bitrate']; + $thisfile_audio['sample_rate'] = $info['dts']['sample_rate']; + } + break; + case 0x08AE: // ClearJump LiteWave + $thisfile_audio['bitrate_mode'] = 'vbr'; + $thisfile_audio_dataformat = 'litewave'; + + //typedef struct tagSLwFormat { + // WORD m_wCompFormat; // low byte defines compression method, high byte is compression flags + // DWORD m_dwScale; // scale factor for lossy compression + // DWORD m_dwBlockSize; // number of samples in encoded blocks + // WORD m_wQuality; // alias for the scale factor + // WORD m_wMarkDistance; // distance between marks in bytes + // WORD m_wReserved; + // + // //following paramters are ignored if CF_FILESRC is not set + // DWORD m_dwOrgSize; // original file size in bytes + // WORD m_bFactExists; // indicates if 'fact' chunk exists in the original file + // DWORD m_dwRiffChunkSize; // riff chunk size in the original file + // + // PCMWAVEFORMAT m_OrgWf; // original wave format + // }SLwFormat, *PSLwFormat; + + // shortcut + $thisfile_riff['litewave']['raw'] = array(); + $riff_litewave = &$thisfile_riff['litewave']; + $riff_litewave_raw = &$riff_litewave['raw']; + + $flags = array( + 'compression_method' => 1, + 'compression_flags' => 1, + 'm_dwScale' => 4, + 'm_dwBlockSize' => 4, + 'm_wQuality' => 2, + 'm_wMarkDistance' => 2, + 'm_wReserved' => 2, + 'm_dwOrgSize' => 4, + 'm_bFactExists' => 2, + 'm_dwRiffChunkSize' => 4, + ); + $litewave_offset = 18; + foreach ($flags as $flag => $length) { + $riff_litewave_raw[$flag] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], $litewave_offset, $length)); + $litewave_offset += $length; + } + + //$riff_litewave['quality_factor'] = intval(round((2000 - $riff_litewave_raw['m_dwScale']) / 20)); + $riff_litewave['quality_factor'] = $riff_litewave_raw['m_wQuality']; + + $riff_litewave['flags']['raw_source'] = ($riff_litewave_raw['compression_flags'] & 0x01) ? false : true; + $riff_litewave['flags']['vbr_blocksize'] = ($riff_litewave_raw['compression_flags'] & 0x02) ? false : true; + $riff_litewave['flags']['seekpoints'] = (bool) ($riff_litewave_raw['compression_flags'] & 0x04); + + $thisfile_audio['lossless'] = (($riff_litewave_raw['m_wQuality'] == 100) ? true : false); + $thisfile_audio['encoder_options'] = '-q'.$riff_litewave['quality_factor']; + break; + + default: + break; + } + } + if ($info['avdataend'] > $info['filesize']) { + switch (!empty($thisfile_audio_dataformat) ? $thisfile_audio_dataformat : '') { + case 'wavpack': // WavPack + case 'lpac': // LPAC + case 'ofr': // OptimFROG + case 'ofs': // OptimFROG DualStream + // lossless compressed audio formats that keep original RIFF headers - skip warning + break; + + case 'litewave': + if (($info['avdataend'] - $info['filesize']) == 1) { + // LiteWave appears to incorrectly *not* pad actual output file + // to nearest WORD boundary so may appear to be short by one + // byte, in which case - skip warning + } else { + // Short by more than one byte, throw warning + $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)'; + $info['avdataend'] = $info['filesize']; + } + break; + + default: + if ((($info['avdataend'] - $info['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($info['filesize'] - $info['avdataoffset']) % 2) == 1)) { + // output file appears to be incorrectly *not* padded to nearest WORD boundary + // Output less severe warning + $info['warning'][] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)'; + $info['avdataend'] = $info['filesize']; + } else { + // Short by more than one byte, throw warning + $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)'; + $info['avdataend'] = $info['filesize']; + } + break; + } + } + if (!empty($info['mpeg']['audio']['LAME']['audio_bytes'])) { + if ((($info['avdataend'] - $info['avdataoffset']) - $info['mpeg']['audio']['LAME']['audio_bytes']) == 1) { + $info['avdataend']--; + $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored'; + } + } + if (isset($thisfile_audio_dataformat) && ($thisfile_audio_dataformat == 'ac3')) { + unset($thisfile_audio['bits_per_sample']); + if (!empty($info['ac3']['bitrate']) && ($info['ac3']['bitrate'] != $thisfile_audio['bitrate'])) { + $thisfile_audio['bitrate'] = $info['ac3']['bitrate']; + } + } + break; + + case 'AVI ': + $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably + $thisfile_video['dataformat'] = 'avi'; + $info['mime_type'] = 'video/avi'; + + if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) { + $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8; + if (isset($thisfile_riff['AVIX'])) { + $info['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size']; + } else { + $info['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size']; + } + if ($info['avdataend'] > $info['filesize']) { + $info['warning'][] = 'Probably truncated file - expecting '.($info['avdataend'] - $info['avdataoffset']).' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($info['avdataend'] - $info['filesize']).' bytes)'; + $info['avdataend'] = $info['filesize']; + } + } + + if (isset($thisfile_riff['AVI ']['hdrl']['strl']['indx'])) { + //$bIndexType = array( + // 0x00 => 'AVI_INDEX_OF_INDEXES', + // 0x01 => 'AVI_INDEX_OF_CHUNKS', + // 0x80 => 'AVI_INDEX_IS_DATA', + //); + //$bIndexSubtype = array( + // 0x01 => array( + // 0x01 => 'AVI_INDEX_2FIELD', + // ), + //); + foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) { + $ahsisd = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data']; + + $thisfile_riff_raw['indx'][$streamnumber]['wLongsPerEntry'] = $this->EitherEndian2Int(substr($ahsisd, 0, 2)); + $thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType'] = $this->EitherEndian2Int(substr($ahsisd, 2, 1)); + $thisfile_riff_raw['indx'][$streamnumber]['bIndexType'] = $this->EitherEndian2Int(substr($ahsisd, 3, 1)); + $thisfile_riff_raw['indx'][$streamnumber]['nEntriesInUse'] = $this->EitherEndian2Int(substr($ahsisd, 4, 4)); + $thisfile_riff_raw['indx'][$streamnumber]['dwChunkId'] = substr($ahsisd, 8, 4); + $thisfile_riff_raw['indx'][$streamnumber]['dwReserved'] = $this->EitherEndian2Int(substr($ahsisd, 12, 4)); + + //$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name'] = $bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']]; + //$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = $bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']]; + + unset($ahsisd); + } + } + if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) { + $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data']; + + // shortcut + $thisfile_riff_raw['avih'] = array(); + $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih']; + + $thisfile_riff_raw_avih['dwMicroSecPerFrame'] = $this->EitherEndian2Int(substr($avihData, 0, 4)); // frame display rate (or 0L) + if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) { + $info['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero'; + return false; + } + + $flags = array( + 'dwMaxBytesPerSec', // max. transfer rate + 'dwPaddingGranularity', // pad to multiples of this size; normally 2K. + 'dwFlags', // the ever-present flags + 'dwTotalFrames', // # frames in file + 'dwInitialFrames', // + 'dwStreams', // + 'dwSuggestedBufferSize', // + 'dwWidth', // + 'dwHeight', // + 'dwScale', // + 'dwRate', // + 'dwStart', // + 'dwLength', // + ); + $avih_offset = 4; + foreach ($flags as $flag) { + $thisfile_riff_raw_avih[$flag] = $this->EitherEndian2Int(substr($avihData, $avih_offset, 4)); + $avih_offset += 4; + } + + $flags = array( + 'hasindex' => 0x00000010, + 'mustuseindex' => 0x00000020, + 'interleaved' => 0x00000100, + 'trustcktype' => 0x00000800, + 'capturedfile' => 0x00010000, + 'copyrighted' => 0x00020010, + ); + foreach ($flags as $flag => $value) { + $thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value); + } + + // shortcut + $thisfile_riff_video[$streamindex] = array(); + $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex]; + + if ($thisfile_riff_raw_avih['dwWidth'] > 0) { + $thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth']; + $thisfile_video['resolution_x'] = $thisfile_riff_video_current['frame_width']; + } + if ($thisfile_riff_raw_avih['dwHeight'] > 0) { + $thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight']; + $thisfile_video['resolution_y'] = $thisfile_riff_video_current['frame_height']; + } + if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) { + $thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames']; + $thisfile_video['total_frames'] = $thisfile_riff_video_current['total_frames']; + } + + $thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3); + $thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate']; + } + if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) { + if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) { + for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) { + if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) { + $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data']; + $strhfccType = substr($strhData, 0, 4); + + if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) { + $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data']; + + // shortcut + $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex]; + + switch ($strhfccType) { + case 'auds': + $thisfile_audio['bitrate_mode'] = 'cbr'; + $thisfile_audio_dataformat = 'wav'; + if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) { + $streamindex = count($thisfile_riff_audio); + } + + $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($strfData); + $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag']; + + // shortcut + $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex]; + $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex]; + + if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) { + unset($thisfile_audio_streams_currentstream['bits_per_sample']); + } + $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag']; + unset($thisfile_audio_streams_currentstream['raw']); + + // shortcut + $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw']; + + unset($thisfile_riff_audio[$streamindex]['raw']); + $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]); + + $thisfile_audio['lossless'] = false; + switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) { + case 0x0001: // PCM + $thisfile_audio_dataformat = 'wav'; + $thisfile_audio['lossless'] = true; + break; + + case 0x0050: // MPEG Layer 2 or Layer 1 + $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2 + break; + + case 0x0055: // MPEG Layer 3 + $thisfile_audio_dataformat = 'mp3'; + break; + + case 0x00FF: // AAC + $thisfile_audio_dataformat = 'aac'; + break; + + case 0x0161: // Windows Media v7 / v8 / v9 + case 0x0162: // Windows Media Professional v9 + case 0x0163: // Windows Media Lossess v9 + $thisfile_audio_dataformat = 'wma'; + break; + + case 0x2000: // AC-3 + $thisfile_audio_dataformat = 'ac3'; + break; + + case 0x2001: // DTS + $thisfile_audio_dataformat = 'dts'; + break; + + default: + $thisfile_audio_dataformat = 'wav'; + break; + } + $thisfile_audio_streams_currentstream['dataformat'] = $thisfile_audio_dataformat; + $thisfile_audio_streams_currentstream['lossless'] = $thisfile_audio['lossless']; + $thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode']; + break; + + + case 'iavs': + case 'vids': + // shortcut + $thisfile_riff_raw['strh'][$i] = array(); + $thisfile_riff_raw_strh_current = &$thisfile_riff_raw['strh'][$i]; + + $thisfile_riff_raw_strh_current['fccType'] = substr($strhData, 0, 4); // same as $strhfccType; + $thisfile_riff_raw_strh_current['fccHandler'] = substr($strhData, 4, 4); + $thisfile_riff_raw_strh_current['dwFlags'] = $this->EitherEndian2Int(substr($strhData, 8, 4)); // Contains AVITF_* flags + $thisfile_riff_raw_strh_current['wPriority'] = $this->EitherEndian2Int(substr($strhData, 12, 2)); + $thisfile_riff_raw_strh_current['wLanguage'] = $this->EitherEndian2Int(substr($strhData, 14, 2)); + $thisfile_riff_raw_strh_current['dwInitialFrames'] = $this->EitherEndian2Int(substr($strhData, 16, 4)); + $thisfile_riff_raw_strh_current['dwScale'] = $this->EitherEndian2Int(substr($strhData, 20, 4)); + $thisfile_riff_raw_strh_current['dwRate'] = $this->EitherEndian2Int(substr($strhData, 24, 4)); + $thisfile_riff_raw_strh_current['dwStart'] = $this->EitherEndian2Int(substr($strhData, 28, 4)); + $thisfile_riff_raw_strh_current['dwLength'] = $this->EitherEndian2Int(substr($strhData, 32, 4)); + $thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = $this->EitherEndian2Int(substr($strhData, 36, 4)); + $thisfile_riff_raw_strh_current['dwQuality'] = $this->EitherEndian2Int(substr($strhData, 40, 4)); + $thisfile_riff_raw_strh_current['dwSampleSize'] = $this->EitherEndian2Int(substr($strhData, 44, 4)); + $thisfile_riff_raw_strh_current['rcFrame'] = $this->EitherEndian2Int(substr($strhData, 48, 4)); + + $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strh_current['fccHandler']); + $thisfile_video['fourcc'] = $thisfile_riff_raw_strh_current['fccHandler']; + if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) { + $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']); + $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']; + } + $thisfile_video['codec'] = $thisfile_riff_video_current['codec']; + $thisfile_video['pixel_aspect_ratio'] = (float) 1; + switch ($thisfile_riff_raw_strh_current['fccHandler']) { + case 'HFYU': // Huffman Lossless Codec + case 'IRAW': // Intel YUV Uncompressed + case 'YUY2': // Uncompressed YUV 4:2:2 + $thisfile_video['lossless'] = true; + break; + + default: + $thisfile_video['lossless'] = false; + break; + } + + switch ($strhfccType) { + case 'vids': + $thisfile_riff_raw_strf_strhfccType_streamindex = self::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($info['fileformat'] == 'riff')); + $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount']; + + if ($thisfile_riff_video_current['codec'] == 'DV') { + $thisfile_riff_video_current['dv_type'] = 2; + } + break; + + case 'iavs': + $thisfile_riff_video_current['dv_type'] = 1; + break; + } + break; + + default: + $info['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"'; + break; + + } + } + } + + if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) { + + $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']; + if (self::fourccLookup($thisfile_video['fourcc'])) { + $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_video['fourcc']); + $thisfile_video['codec'] = $thisfile_riff_video_current['codec']; + } + + switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) { + case 'HFYU': // Huffman Lossless Codec + case 'IRAW': // Intel YUV Uncompressed + case 'YUY2': // Uncompressed YUV 4:2:2 + $thisfile_video['lossless'] = true; + //$thisfile_video['bits_per_sample'] = 24; + break; + + default: + $thisfile_video['lossless'] = false; + //$thisfile_video['bits_per_sample'] = 24; + break; + } + + } + } + } + } + break; + + case 'CDDA': + $thisfile_audio['bitrate_mode'] = 'cbr'; + $thisfile_audio_dataformat = 'cda'; + $thisfile_audio['lossless'] = true; + unset($info['mime_type']); + + $info['avdataoffset'] = 44; + + if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) { + // shortcut + $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0]; + + $thisfile_riff_CDDA_fmt_0['unknown1'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 0, 2)); + $thisfile_riff_CDDA_fmt_0['track_num'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 2, 2)); + $thisfile_riff_CDDA_fmt_0['disc_id'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 4, 4)); + $thisfile_riff_CDDA_fmt_0['start_offset_frame'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 8, 4)); + $thisfile_riff_CDDA_fmt_0['playtime_frames'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4)); + $thisfile_riff_CDDA_fmt_0['unknown6'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4)); + $thisfile_riff_CDDA_fmt_0['unknown7'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4)); + + $thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75; + $thisfile_riff_CDDA_fmt_0['playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75; + $info['comments']['track'] = $thisfile_riff_CDDA_fmt_0['track_num']; + $info['playtime_seconds'] = $thisfile_riff_CDDA_fmt_0['playtime_seconds']; + + // hardcoded data for CD-audio + $thisfile_audio['sample_rate'] = 44100; + $thisfile_audio['channels'] = 2; + $thisfile_audio['bits_per_sample'] = 16; + $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample']; + $thisfile_audio['bitrate_mode'] = 'cbr'; + } + break; + + + case 'AIFF': + case 'AIFC': + $thisfile_audio['bitrate_mode'] = 'cbr'; + $thisfile_audio_dataformat = 'aiff'; + $thisfile_audio['lossless'] = true; + $info['mime_type'] = 'audio/x-aiff'; + + if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) { + $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8; + $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size']; + if ($info['avdataend'] > $info['filesize']) { + if (($info['avdataend'] == ($info['filesize'] + 1)) && (($info['filesize'] % 2) == 1)) { + // structures rounded to 2-byte boundary, but dumb encoders + // forget to pad end of file to make this actually work + } else { + $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found'; + } + $info['avdataend'] = $info['filesize']; + } + } + + if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) { + + // shortcut + $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data']; + + $thisfile_riff_audio['channels'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 0, 2), true); + $thisfile_riff_audio['total_samples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 2, 4), false); + $thisfile_riff_audio['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 6, 2), true); + $thisfile_riff_audio['sample_rate'] = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 8, 10)); + + if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) { + $thisfile_riff_audio['codec_fourcc'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18, 4); + $CodecNameSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22, 1), false); + $thisfile_riff_audio['codec_name'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23, $CodecNameSize); + switch ($thisfile_riff_audio['codec_name']) { + case 'NONE': + $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)'; + $thisfile_audio['lossless'] = true; + break; + + case '': + switch ($thisfile_riff_audio['codec_fourcc']) { + // http://developer.apple.com/qa/snd/snd07.html + case 'sowt': + $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM'; + $thisfile_audio['lossless'] = true; + break; + + case 'twos': + $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM'; + $thisfile_audio['lossless'] = true; + break; + + default: + break; + } + break; + + default: + $thisfile_audio['codec'] = $thisfile_riff_audio['codec_name']; + $thisfile_audio['lossless'] = false; + break; + } + } + + $thisfile_audio['channels'] = $thisfile_riff_audio['channels']; + if ($thisfile_riff_audio['bits_per_sample'] > 0) { + $thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample']; + } + $thisfile_audio['sample_rate'] = $thisfile_riff_audio['sample_rate']; + if ($thisfile_audio['sample_rate'] == 0) { + $info['error'][] = 'Corrupted AIFF file: sample_rate == zero'; + return false; + } + $info['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate']; + } + + if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) { + $offset = 0; + $CommentCount = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false); + $offset += 2; + for ($i = 0; $i < $CommentCount; $i++) { + $info['comments_raw'][$i]['timestamp'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false); + $offset += 4; + $info['comments_raw'][$i]['marker_id'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true); + $offset += 2; + $CommentLength = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false); + $offset += 2; + $info['comments_raw'][$i]['comment'] = substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength); + $offset += $CommentLength; + + $info['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($info['comments_raw'][$i]['timestamp']); + $thisfile_riff['comments']['comment'][] = $info['comments_raw'][$i]['comment']; + } + } + + $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment'); + foreach ($CommentsChunkNames as $key => $value) { + if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) { + $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data']; + } + } +/* + if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) { + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_id3v2 = new getid3_id3v2($getid3_temp); + $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8; + if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) { + $info['id3v2'] = $getid3_temp->info['id3v2']; + } + unset($getid3_temp, $getid3_id3v2); + } +*/ + break; + + case '8SVX': + $thisfile_audio['bitrate_mode'] = 'cbr'; + $thisfile_audio_dataformat = '8svx'; + $thisfile_audio['bits_per_sample'] = 8; + $thisfile_audio['channels'] = 1; // overridden below, if need be + $info['mime_type'] = 'audio/x-aiff'; + + if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) { + $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8; + $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size']; + if ($info['avdataend'] > $info['filesize']) { + $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found'; + } + } + + if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) { + // shortcut + $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0]; + + $thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 0, 4)); + $thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 4, 4)); + $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 8, 4)); + $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2)); + $thisfile_riff_RIFFsubtype_VHDR_0['ctOctave'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1)); + $thisfile_riff_RIFFsubtype_VHDR_0['sCompression'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1)); + $thisfile_riff_RIFFsubtype_VHDR_0['Volume'] = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4)); + + $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec']; + + switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) { + case 0: + $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)'; + $thisfile_audio['lossless'] = true; + $ActualBitsPerSample = 8; + break; + + case 1: + $thisfile_audio['codec'] = 'Fibonacci-delta encoding'; + $thisfile_audio['lossless'] = false; + $ActualBitsPerSample = 4; + break; + + default: + $info['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"'; + break; + } + } + + if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) { + $ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4)); + switch ($ChannelsIndex) { + case 6: // Stereo + $thisfile_audio['channels'] = 2; + break; + + case 2: // Left channel only + case 4: // Right channel only + $thisfile_audio['channels'] = 1; + break; + + default: + $info['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"'; + break; + } + + } + + $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment'); + foreach ($CommentsChunkNames as $key => $value) { + if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) { + $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data']; + } + } + + $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels']; + if (!empty($thisfile_audio['bitrate'])) { + $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) / ($thisfile_audio['bitrate'] / 8); + } + break; + + + case 'CDXA': + $info['mime_type'] = 'video/mpeg'; + if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) { + if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) { + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_mpeg = new getid3_mpeg($getid3_temp); + $getid3_mpeg->Analyze(); + if (empty($getid3_temp->info['error'])) { + $info['audio'] = $getid3_temp->info['audio']; + $info['video'] = $getid3_temp->info['video']; + $info['mpeg'] = $getid3_temp->info['mpeg']; + $info['warning'] = $getid3_temp->info['warning']; + } + unset($getid3_temp, $getid3_mpeg); + } + } + break; + + + default: + $info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead'; + unset($info['fileformat']); + break; + } + + switch ($RIFFsubtype) { + case 'WAVE': + case 'AIFF': + case 'AIFC': + $ID3v2_key_good = 'id3 '; + $ID3v2_keys_bad = array('ID3 ', 'tag '); + foreach ($ID3v2_keys_bad as $ID3v2_key_bad) { + if (isset($thisfile_riff[$RIFFsubtype][$ID3v2_key_bad]) && !array_key_exists($ID3v2_key_good, $thisfile_riff[$RIFFsubtype])) { + $thisfile_riff[$RIFFsubtype][$ID3v2_key_good] = $thisfile_riff[$RIFFsubtype][$ID3v2_key_bad]; + $info['warning'][] = 'mapping "'.$ID3v2_key_bad.'" chunk to "'.$ID3v2_key_good.'"'; + } + } + + if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) { + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_id3v2 = new getid3_id3v2($getid3_temp); + $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8; + if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) { + $info['id3v2'] = $getid3_temp->info['id3v2']; + } + unset($getid3_temp, $getid3_id3v2); + } + break; + } + + if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) { + $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4)); + } + if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) { + self::parseComments($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']); + } + if (isset($thisfile_riff['AVI ']['INFO']) && is_array($thisfile_riff['AVI ']['INFO'])) { + self::parseComments($thisfile_riff['AVI ']['INFO'], $thisfile_riff['comments']); + } + + if (empty($thisfile_audio['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version'])) { + $thisfile_audio['encoder'] = $info['mpeg']['audio']['LAME']['short_version']; + } + + if (!isset($info['playtime_seconds'])) { + $info['playtime_seconds'] = 0; + } + if (isset($thisfile_riff_raw['strh'][0]['dwLength']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) { + // needed for >2GB AVIs where 'avih' chunk only lists number of frames in that chunk, not entire movie + $info['playtime_seconds'] = $thisfile_riff_raw['strh'][0]['dwLength'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000); + } elseif (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) { + $info['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000); + } + + if ($info['playtime_seconds'] > 0) { + if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) { + + if (!isset($info['bitrate'])) { + $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8); + } + + } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) { + + if (!isset($thisfile_audio['bitrate'])) { + $thisfile_audio['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8); + } + + } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) { + + if (!isset($thisfile_video['bitrate'])) { + $thisfile_video['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8); + } + + } + } + + + if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($info['playtime_seconds'] > 0)) { + + $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8); + $thisfile_audio['bitrate'] = 0; + $thisfile_video['bitrate'] = $info['bitrate']; + foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) { + $thisfile_video['bitrate'] -= $audioinfoarray['bitrate']; + $thisfile_audio['bitrate'] += $audioinfoarray['bitrate']; + } + if ($thisfile_video['bitrate'] <= 0) { + unset($thisfile_video['bitrate']); + } + if ($thisfile_audio['bitrate'] <= 0) { + unset($thisfile_audio['bitrate']); + } + } + + if (isset($info['mpeg']['audio'])) { + $thisfile_audio_dataformat = 'mp'.$info['mpeg']['audio']['layer']; + $thisfile_audio['sample_rate'] = $info['mpeg']['audio']['sample_rate']; + $thisfile_audio['channels'] = $info['mpeg']['audio']['channels']; + $thisfile_audio['bitrate'] = $info['mpeg']['audio']['bitrate']; + $thisfile_audio['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']); + if (!empty($info['mpeg']['audio']['codec'])) { + $thisfile_audio['codec'] = $info['mpeg']['audio']['codec'].' '.$thisfile_audio['codec']; + } + if (!empty($thisfile_audio['streams'])) { + foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) { + if ($streamdata['dataformat'] == $thisfile_audio_dataformat) { + $thisfile_audio['streams'][$streamnumber]['sample_rate'] = $thisfile_audio['sample_rate']; + $thisfile_audio['streams'][$streamnumber]['channels'] = $thisfile_audio['channels']; + $thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate']; + $thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode']; + $thisfile_audio['streams'][$streamnumber]['codec'] = $thisfile_audio['codec']; + } + } + } + $getid3_mp3 = new getid3_mp3($this->getid3); + $thisfile_audio['encoder_options'] = $getid3_mp3->GuessEncoderOptions(); + unset($getid3_mp3); + } + + + if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) { + switch ($thisfile_audio_dataformat) { + case 'ac3': + // ignore bits_per_sample + break; + + default: + $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample']; + break; + } + } + + + if (empty($thisfile_riff_raw)) { + unset($thisfile_riff['raw']); + } + if (empty($thisfile_riff_audio)) { + unset($thisfile_riff['audio']); + } + if (empty($thisfile_riff_video)) { + unset($thisfile_riff['video']); + } + + return true; + } + + public function ParseRIFF($startoffset, $maxoffset) { + $info = &$this->getid3->info; + + $RIFFchunk = false; + $FoundAllChunksWeNeed = false; + + try { + $this->fseek($startoffset); + $maxoffset = min($maxoffset, $info['avdataend']); + while ($this->ftell() < $maxoffset) { + $chunknamesize = $this->fread(8); + //$chunkname = substr($chunknamesize, 0, 4); + $chunkname = str_replace("\x00", '_', substr($chunknamesize, 0, 4)); // note: chunk names of 4 null bytes do appear to be legal (has been observed inside INFO and PRMI chunks, for example), but makes traversing array keys more difficult + $chunksize = $this->EitherEndian2Int(substr($chunknamesize, 4, 4)); + //if (strlen(trim($chunkname, "\x00")) < 4) { + if (strlen($chunkname) < 4) { + $this->error('Expecting chunk name at offset '.($this->ftell() - 8).' but found nothing. Aborting RIFF parsing.'); + break; + } + if (($chunksize == 0) && ($chunkname != 'JUNK')) { + $this->warning('Chunk ('.$chunkname.') size at offset '.($this->ftell() - 4).' is zero. Aborting RIFF parsing.'); + break; + } + if (($chunksize % 2) != 0) { + // all structures are packed on word boundaries + $chunksize++; + } + + switch ($chunkname) { + case 'LIST': + $listname = $this->fread(4); + if (preg_match('#^(movi|rec )$#i', $listname)) { + $RIFFchunk[$listname]['offset'] = $this->ftell() - 4; + $RIFFchunk[$listname]['size'] = $chunksize; + + if (!$FoundAllChunksWeNeed) { + $WhereWeWere = $this->ftell(); + $AudioChunkHeader = $this->fread(12); + $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2); + $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2); + $AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4)); + + if ($AudioChunkStreamType == 'wb') { + $FirstFourBytes = substr($AudioChunkHeader, 8, 4); + if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) { + // MP3 + if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) { + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_temp->info['avdataoffset'] = $this->ftell() - 4; + $getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize; + $getid3_mp3 = new getid3_mp3($getid3_temp); + $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false); + if (isset($getid3_temp->info['mpeg']['audio'])) { + $info['mpeg']['audio'] = $getid3_temp->info['mpeg']['audio']; + $info['audio'] = $getid3_temp->info['audio']; + $info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer']; + $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate']; + $info['audio']['channels'] = $info['mpeg']['audio']['channels']; + $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate']; + $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']); + //$info['bitrate'] = $info['audio']['bitrate']; + } + unset($getid3_temp, $getid3_mp3); + } + + } elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) { + + // AC3 + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_temp->info['avdataoffset'] = $this->ftell() - 4; + $getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize; + $getid3_ac3 = new getid3_ac3($getid3_temp); + $getid3_ac3->Analyze(); + if (empty($getid3_temp->info['error'])) { + $info['audio'] = $getid3_temp->info['audio']; + $info['ac3'] = $getid3_temp->info['ac3']; + if (!empty($getid3_temp->info['warning'])) { + foreach ($getid3_temp->info['warning'] as $key => $value) { + $info['warning'][] = $value; + } + } + } + unset($getid3_temp, $getid3_ac3); + } + } + $FoundAllChunksWeNeed = true; + $this->fseek($WhereWeWere); + } + $this->fseek($chunksize - 4, SEEK_CUR); + + } else { + + if (!isset($RIFFchunk[$listname])) { + $RIFFchunk[$listname] = array(); + } + $LISTchunkParent = $listname; + $LISTchunkMaxOffset = $this->ftell() - 4 + $chunksize; + if ($parsedChunk = $this->ParseRIFF($this->ftell(), $LISTchunkMaxOffset)) { + $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk); + } + + } + break; + + default: + if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) { + $this->fseek($chunksize, SEEK_CUR); + break; + } + $thisindex = 0; + if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) { + $thisindex = count($RIFFchunk[$chunkname]); + } + $RIFFchunk[$chunkname][$thisindex]['offset'] = $this->ftell() - 8; + $RIFFchunk[$chunkname][$thisindex]['size'] = $chunksize; + switch ($chunkname) { + case 'data': + $info['avdataoffset'] = $this->ftell(); + $info['avdataend'] = $info['avdataoffset'] + $chunksize; + + $testData = $this->fread(36); + if ($testData === '') { + break; + } + if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) { + + // Probably is MP3 data + if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) { + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_temp->info['avdataoffset'] = $info['avdataoffset']; + $getid3_temp->info['avdataend'] = $info['avdataend']; + $getid3_mp3 = new getid3_mp3($getid3_temp); + $getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false); + if (empty($getid3_temp->info['error'])) { + $info['audio'] = $getid3_temp->info['audio']; + $info['mpeg'] = $getid3_temp->info['mpeg']; + } + unset($getid3_temp, $getid3_mp3); + } + + } elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) { + + // This is probably AC-3 data + $getid3_temp = new getID3(); + if ($isRegularAC3) { + $getid3_temp->openfile($this->getid3->filename); + $getid3_temp->info['avdataoffset'] = $info['avdataoffset']; + $getid3_temp->info['avdataend'] = $info['avdataend']; + } + $getid3_ac3 = new getid3_ac3($getid3_temp); + if ($isRegularAC3) { + $getid3_ac3->Analyze(); + } else { + // Dolby Digital WAV + // AC-3 content, but not encoded in same format as normal AC-3 file + // For one thing, byte order is swapped + $ac3_data = ''; + for ($i = 0; $i < 28; $i += 2) { + $ac3_data .= substr($testData, 8 + $i + 1, 1); + $ac3_data .= substr($testData, 8 + $i + 0, 1); + } + $getid3_ac3->AnalyzeString($ac3_data); + } + + if (empty($getid3_temp->info['error'])) { + $info['audio'] = $getid3_temp->info['audio']; + $info['ac3'] = $getid3_temp->info['ac3']; + if (!empty($getid3_temp->info['warning'])) { + foreach ($getid3_temp->info['warning'] as $newerror) { + $this->warning('getid3_ac3() says: ['.$newerror.']'); + } + } + } + unset($getid3_temp, $getid3_ac3); + + } elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) { + + // This is probably DTS data + $getid3_temp = new getID3(); + $getid3_temp->openfile($this->getid3->filename); + $getid3_temp->info['avdataoffset'] = $info['avdataoffset']; + $getid3_dts = new getid3_dts($getid3_temp); + $getid3_dts->Analyze(); + if (empty($getid3_temp->info['error'])) { + $info['audio'] = $getid3_temp->info['audio']; + $info['dts'] = $getid3_temp->info['dts']; + $info['playtime_seconds'] = $getid3_temp->info['playtime_seconds']; // may not match RIFF calculations since DTS-WAV often used 14/16 bit-word packing + if (!empty($getid3_temp->info['warning'])) { + foreach ($getid3_temp->info['warning'] as $newerror) { + $this->warning('getid3_dts() says: ['.$newerror.']'); + } + } + } + + unset($getid3_temp, $getid3_dts); + + } elseif (substr($testData, 0, 4) == 'wvpk') { + + // This is WavPack data + $info['wavpack']['offset'] = $info['avdataoffset']; + $info['wavpack']['size'] = getid3_lib::LittleEndian2Int(substr($testData, 4, 4)); + $this->parseWavPackHeader(substr($testData, 8, 28)); + + } else { + // This is some other kind of data (quite possibly just PCM) + // do nothing special, just skip it + } + $nextoffset = $info['avdataend']; + $this->fseek($nextoffset); + break; + + case 'iXML': + case 'bext': + case 'cart': + case 'fmt ': + case 'strh': + case 'strf': + case 'indx': + case 'MEXT': + case 'DISP': + // always read data in + case 'JUNK': + // should be: never read data in + // but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc) + if ($chunksize < 1048576) { + if ($chunksize > 0) { + $RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize); + if ($chunkname == 'JUNK') { + if (preg_match('#^([\\x20-\\x7F]+)#', $RIFFchunk[$chunkname][$thisindex]['data'], $matches)) { + // only keep text characters [chr(32)-chr(127)] + $info['riff']['comments']['junk'][] = trim($matches[1]); + } + // but if nothing there, ignore + // remove the key in either case + unset($RIFFchunk[$chunkname][$thisindex]['data']); + } + } + } else { + $this->warning('Chunk "'.$chunkname.'" at offset '.$this->ftell().' is unexpectedly larger than 1MB (claims to be '.number_format($chunksize).' bytes), skipping data'); + $this->fseek($chunksize, SEEK_CUR); + } + break; + + //case 'IDVX': + // $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize)); + // break; + + default: + if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) { + $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset']; + $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size']; + unset($RIFFchunk[$chunkname][$thisindex]['offset']); + unset($RIFFchunk[$chunkname][$thisindex]['size']); + if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) { + unset($RIFFchunk[$chunkname][$thisindex]); + } + if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) { + unset($RIFFchunk[$chunkname]); + } + $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = $this->fread($chunksize); + } elseif ($chunksize < 2048) { + // only read data in if smaller than 2kB + $RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize); + } else { + $this->fseek($chunksize, SEEK_CUR); + } + break; + } + break; + } + } + + } catch (getid3_exception $e) { + if ($e->getCode() == 10) { + $this->warning('RIFF parser: '.$e->getMessage()); + } else { + throw $e; + } + } + + return $RIFFchunk; + } + + public function ParseRIFFdata(&$RIFFdata) { + $info = &$this->getid3->info; + if ($RIFFdata) { + $tempfile = tempnam(GETID3_TEMP_DIR, 'getID3'); + $fp_temp = fopen($tempfile, 'wb'); + $RIFFdataLength = strlen($RIFFdata); + $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4); + for ($i = 0; $i < 4; $i++) { + $RIFFdata[($i + 4)] = $NewLengthString[$i]; + } + fwrite($fp_temp, $RIFFdata); + fclose($fp_temp); + + $getid3_temp = new getID3(); + $getid3_temp->openfile($tempfile); + $getid3_temp->info['filesize'] = $RIFFdataLength; + $getid3_temp->info['filenamepath'] = $info['filenamepath']; + $getid3_temp->info['tags'] = $info['tags']; + $getid3_temp->info['warning'] = $info['warning']; + $getid3_temp->info['error'] = $info['error']; + $getid3_temp->info['comments'] = $info['comments']; + $getid3_temp->info['audio'] = (isset($info['audio']) ? $info['audio'] : array()); + $getid3_temp->info['video'] = (isset($info['video']) ? $info['video'] : array()); + $getid3_riff = new getid3_riff($getid3_temp); + $getid3_riff->Analyze(); + + $info['riff'] = $getid3_temp->info['riff']; + $info['warning'] = $getid3_temp->info['warning']; + $info['error'] = $getid3_temp->info['error']; + $info['tags'] = $getid3_temp->info['tags']; + $info['comments'] = $getid3_temp->info['comments']; + unset($getid3_riff, $getid3_temp); + unlink($tempfile); + } + return false; + } + + public static function parseComments(&$RIFFinfoArray, &$CommentsTargetArray) { + $RIFFinfoKeyLookup = array( + 'IARL'=>'archivallocation', + 'IART'=>'artist', + 'ICDS'=>'costumedesigner', + 'ICMS'=>'commissionedby', + 'ICMT'=>'comment', + 'ICNT'=>'country', + 'ICOP'=>'copyright', + 'ICRD'=>'creationdate', + 'IDIM'=>'dimensions', + 'IDIT'=>'digitizationdate', + 'IDPI'=>'resolution', + 'IDST'=>'distributor', + 'IEDT'=>'editor', + 'IENG'=>'engineers', + 'IFRM'=>'accountofparts', + 'IGNR'=>'genre', + 'IKEY'=>'keywords', + 'ILGT'=>'lightness', + 'ILNG'=>'language', + 'IMED'=>'orignalmedium', + 'IMUS'=>'composer', + 'INAM'=>'title', + 'IPDS'=>'productiondesigner', + 'IPLT'=>'palette', + 'IPRD'=>'product', + 'IPRO'=>'producer', + 'IPRT'=>'part', + 'IRTD'=>'rating', + 'ISBJ'=>'subject', + 'ISFT'=>'software', + 'ISGN'=>'secondarygenre', + 'ISHP'=>'sharpness', + 'ISRC'=>'sourcesupplier', + 'ISRF'=>'digitizationsource', + 'ISTD'=>'productionstudio', + 'ISTR'=>'starring', + 'ITCH'=>'encoded_by', + 'IWEB'=>'url', + 'IWRI'=>'writer', + '____'=>'comment', + ); + foreach ($RIFFinfoKeyLookup as $key => $value) { + if (isset($RIFFinfoArray[$key])) { + foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) { + if (trim($commentdata['data']) != '') { + if (isset($CommentsTargetArray[$value])) { + $CommentsTargetArray[$value][] = trim($commentdata['data']); + } else { + $CommentsTargetArray[$value] = array(trim($commentdata['data'])); + } + } + } + } + } + return true; + } + + public static function parseWAVEFORMATex($WaveFormatExData) { + // shortcut + $WaveFormatEx['raw'] = array(); + $WaveFormatEx_raw = &$WaveFormatEx['raw']; + + $WaveFormatEx_raw['wFormatTag'] = substr($WaveFormatExData, 0, 2); + $WaveFormatEx_raw['nChannels'] = substr($WaveFormatExData, 2, 2); + $WaveFormatEx_raw['nSamplesPerSec'] = substr($WaveFormatExData, 4, 4); + $WaveFormatEx_raw['nAvgBytesPerSec'] = substr($WaveFormatExData, 8, 4); + $WaveFormatEx_raw['nBlockAlign'] = substr($WaveFormatExData, 12, 2); + $WaveFormatEx_raw['wBitsPerSample'] = substr($WaveFormatExData, 14, 2); + if (strlen($WaveFormatExData) > 16) { + $WaveFormatEx_raw['cbSize'] = substr($WaveFormatExData, 16, 2); + } + $WaveFormatEx_raw = array_map('getid3_lib::LittleEndian2Int', $WaveFormatEx_raw); + + $WaveFormatEx['codec'] = self::wFormatTagLookup($WaveFormatEx_raw['wFormatTag']); + $WaveFormatEx['channels'] = $WaveFormatEx_raw['nChannels']; + $WaveFormatEx['sample_rate'] = $WaveFormatEx_raw['nSamplesPerSec']; + $WaveFormatEx['bitrate'] = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8; + $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample']; + + return $WaveFormatEx; + } + + public function parseWavPackHeader($WavPackChunkData) { + // typedef struct { + // char ckID [4]; + // long ckSize; + // short version; + // short bits; // added for version 2.00 + // short flags, shift; // added for version 3.00 + // long total_samples, crc, crc2; + // char extension [4], extra_bc, extras [3]; + // } WavpackHeader; + + // shortcut + $info = &$this->getid3->info; + $info['wavpack'] = array(); + $thisfile_wavpack = &$info['wavpack']; + + $thisfile_wavpack['version'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 0, 2)); + if ($thisfile_wavpack['version'] >= 2) { + $thisfile_wavpack['bits'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 2, 2)); + } + if ($thisfile_wavpack['version'] >= 3) { + $thisfile_wavpack['flags_raw'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 4, 2)); + $thisfile_wavpack['shift'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 6, 2)); + $thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 8, 4)); + $thisfile_wavpack['crc1'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4)); + $thisfile_wavpack['crc2'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4)); + $thisfile_wavpack['extension'] = substr($WavPackChunkData, 20, 4); + $thisfile_wavpack['extra_bc'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1)); + for ($i = 0; $i <= 2; $i++) { + $thisfile_wavpack['extras'][] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1)); + } + + // shortcut + $thisfile_wavpack['flags'] = array(); + $thisfile_wavpack_flags = &$thisfile_wavpack['flags']; + + $thisfile_wavpack_flags['mono'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001); + $thisfile_wavpack_flags['fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002); + $thisfile_wavpack_flags['raw_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004); + $thisfile_wavpack_flags['calc_noise'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008); + $thisfile_wavpack_flags['high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010); + $thisfile_wavpack_flags['3_byte_samples'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020); + $thisfile_wavpack_flags['over_20_bits'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040); + $thisfile_wavpack_flags['use_wvc'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080); + $thisfile_wavpack_flags['noiseshaping'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100); + $thisfile_wavpack_flags['very_fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200); + $thisfile_wavpack_flags['new_high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400); + $thisfile_wavpack_flags['cancel_extreme'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800); + $thisfile_wavpack_flags['cross_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000); + $thisfile_wavpack_flags['new_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000); + $thisfile_wavpack_flags['joint_stereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000); + $thisfile_wavpack_flags['extra_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000); + $thisfile_wavpack_flags['override_noiseshape'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000); + $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000); + $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000); + $thisfile_wavpack_flags['create_exe'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000); + } + + return true; + } + + public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) { + + $parsed['biSize'] = substr($BITMAPINFOHEADER, 0, 4); // number of bytes required by the BITMAPINFOHEADER structure + $parsed['biWidth'] = substr($BITMAPINFOHEADER, 4, 4); // width of the bitmap in pixels + $parsed['biHeight'] = substr($BITMAPINFOHEADER, 8, 4); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner + $parsed['biPlanes'] = substr($BITMAPINFOHEADER, 12, 2); // number of color planes on the target device. In most cases this value must be set to 1 + $parsed['biBitCount'] = substr($BITMAPINFOHEADER, 14, 2); // Specifies the number of bits per pixels + $parsed['biSizeImage'] = substr($BITMAPINFOHEADER, 20, 4); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures) + $parsed['biXPelsPerMeter'] = substr($BITMAPINFOHEADER, 24, 4); // horizontal resolution, in pixels per metre, of the target device + $parsed['biYPelsPerMeter'] = substr($BITMAPINFOHEADER, 28, 4); // vertical resolution, in pixels per metre, of the target device + $parsed['biClrUsed'] = substr($BITMAPINFOHEADER, 32, 4); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression + $parsed['biClrImportant'] = substr($BITMAPINFOHEADER, 36, 4); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important + $parsed = array_map('getid3_lib::'.($littleEndian ? 'Little' : 'Big').'Endian2Int', $parsed); + + $parsed['fourcc'] = substr($BITMAPINFOHEADER, 16, 4); // compression identifier + + return $parsed; + } + + public static function ParseDIVXTAG($DIVXTAG, $raw=false) { + // structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/ + // source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip + // 'Byte Layout: '1111111111111111 + // '32 for Movie - 1 '1111111111111111 + // '28 for Author - 6 '6666666666666666 + // '4 for year - 2 '6666666666662222 + // '3 for genre - 3 '7777777777777777 + // '48 for Comments - 7 '7777777777777777 + // '1 for Rating - 4 '7777777777777777 + // '5 for Future Additions - 0 '333400000DIVXTAG + // '128 bytes total + + static $DIVXTAGgenre = array( + 0 => 'Action', + 1 => 'Action/Adventure', + 2 => 'Adventure', + 3 => 'Adult', + 4 => 'Anime', + 5 => 'Cartoon', + 6 => 'Claymation', + 7 => 'Comedy', + 8 => 'Commercial', + 9 => 'Documentary', + 10 => 'Drama', + 11 => 'Home Video', + 12 => 'Horror', + 13 => 'Infomercial', + 14 => 'Interactive', + 15 => 'Mystery', + 16 => 'Music Video', + 17 => 'Other', + 18 => 'Religion', + 19 => 'Sci Fi', + 20 => 'Thriller', + 21 => 'Western', + ), + $DIVXTAGrating = array( + 0 => 'Unrated', + 1 => 'G', + 2 => 'PG', + 3 => 'PG-13', + 4 => 'R', + 5 => 'NC-17', + ); + + $parsed['title'] = trim(substr($DIVXTAG, 0, 32)); + $parsed['artist'] = trim(substr($DIVXTAG, 32, 28)); + $parsed['year'] = intval(trim(substr($DIVXTAG, 60, 4))); + $parsed['comment'] = trim(substr($DIVXTAG, 64, 48)); + $parsed['genre_id'] = intval(trim(substr($DIVXTAG, 112, 3))); + $parsed['rating_id'] = ord(substr($DIVXTAG, 115, 1)); + //$parsed['padding'] = substr($DIVXTAG, 116, 5); // 5-byte null + //$parsed['magic'] = substr($DIVXTAG, 121, 7); // "DIVXTAG" + + $parsed['genre'] = (isset($DIVXTAGgenre[$parsed['genre_id']]) ? $DIVXTAGgenre[$parsed['genre_id']] : $parsed['genre_id']); + $parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']); + + if (!$raw) { + unset($parsed['genre_id'], $parsed['rating_id']); + foreach ($parsed as $key => $value) { + if (!$value === '') { + unset($parsed['key']); + } + } + } + + foreach ($parsed as $tag => $value) { + $parsed[$tag] = array($value); + } + + return $parsed; + } + + public static function waveSNDMtagLookup($tagshortname) { + $begin = __LINE__; + + /** This is not a comment! + + \A9kwd keywords + \A9BPM bpm + \A9trt tracktitle + \A9des description + \A9gen category + \A9fin featuredinstrument + \A9LID longid + \A9bex bwdescription + \A9pub publisher + \A9cdt cdtitle + \A9alb library + \A9com composer + + */ + + return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm'); + } + + public static function wFormatTagLookup($wFormatTag) { + + $begin = __LINE__; + + /** This is not a comment! + + 0x0000 Microsoft Unknown Wave Format + 0x0001 Pulse Code Modulation (PCM) + 0x0002 Microsoft ADPCM + 0x0003 IEEE Float + 0x0004 Compaq Computer VSELP + 0x0005 IBM CVSD + 0x0006 Microsoft A-Law + 0x0007 Microsoft mu-Law + 0x0008 Microsoft DTS + 0x0010 OKI ADPCM + 0x0011 Intel DVI/IMA ADPCM + 0x0012 Videologic MediaSpace ADPCM + 0x0013 Sierra Semiconductor ADPCM + 0x0014 Antex Electronics G.723 ADPCM + 0x0015 DSP Solutions DigiSTD + 0x0016 DSP Solutions DigiFIX + 0x0017 Dialogic OKI ADPCM + 0x0018 MediaVision ADPCM + 0x0019 Hewlett-Packard CU + 0x0020 Yamaha ADPCM + 0x0021 Speech Compression Sonarc + 0x0022 DSP Group TrueSpeech + 0x0023 Echo Speech EchoSC1 + 0x0024 Audiofile AF36 + 0x0025 Audio Processing Technology APTX + 0x0026 AudioFile AF10 + 0x0027 Prosody 1612 + 0x0028 LRC + 0x0030 Dolby AC2 + 0x0031 Microsoft GSM 6.10 + 0x0032 MSNAudio + 0x0033 Antex Electronics ADPCME + 0x0034 Control Resources VQLPC + 0x0035 DSP Solutions DigiREAL + 0x0036 DSP Solutions DigiADPCM + 0x0037 Control Resources CR10 + 0x0038 Natural MicroSystems VBXADPCM + 0x0039 Crystal Semiconductor IMA ADPCM + 0x003A EchoSC3 + 0x003B Rockwell ADPCM + 0x003C Rockwell Digit LK + 0x003D Xebec + 0x0040 Antex Electronics G.721 ADPCM + 0x0041 G.728 CELP + 0x0042 MSG723 + 0x0050 MPEG Layer-2 or Layer-1 + 0x0052 RT24 + 0x0053 PAC + 0x0055 MPEG Layer-3 + 0x0059 Lucent G.723 + 0x0060 Cirrus + 0x0061 ESPCM + 0x0062 Voxware + 0x0063 Canopus Atrac + 0x0064 G.726 ADPCM + 0x0065 G.722 ADPCM + 0x0066 DSAT + 0x0067 DSAT Display + 0x0069 Voxware Byte Aligned + 0x0070 Voxware AC8 + 0x0071 Voxware AC10 + 0x0072 Voxware AC16 + 0x0073 Voxware AC20 + 0x0074 Voxware MetaVoice + 0x0075 Voxware MetaSound + 0x0076 Voxware RT29HW + 0x0077 Voxware VR12 + 0x0078 Voxware VR18 + 0x0079 Voxware TQ40 + 0x0080 Softsound + 0x0081 Voxware TQ60 + 0x0082 MSRT24 + 0x0083 G.729A + 0x0084 MVI MV12 + 0x0085 DF G.726 + 0x0086 DF GSM610 + 0x0088 ISIAudio + 0x0089 Onlive + 0x0091 SBC24 + 0x0092 Dolby AC3 SPDIF + 0x0093 MediaSonic G.723 + 0x0094 Aculab PLC Prosody 8kbps + 0x0097 ZyXEL ADPCM + 0x0098 Philips LPCBB + 0x0099 Packed + 0x00FF AAC + 0x0100 Rhetorex ADPCM + 0x0101 IBM mu-law + 0x0102 IBM A-law + 0x0103 IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM) + 0x0111 Vivo G.723 + 0x0112 Vivo Siren + 0x0123 Digital G.723 + 0x0125 Sanyo LD ADPCM + 0x0130 Sipro Lab Telecom ACELP NET + 0x0131 Sipro Lab Telecom ACELP 4800 + 0x0132 Sipro Lab Telecom ACELP 8V3 + 0x0133 Sipro Lab Telecom G.729 + 0x0134 Sipro Lab Telecom G.729A + 0x0135 Sipro Lab Telecom Kelvin + 0x0140 Windows Media Video V8 + 0x0150 Qualcomm PureVoice + 0x0151 Qualcomm HalfRate + 0x0155 Ring Zero Systems TUB GSM + 0x0160 Microsoft Audio 1 + 0x0161 Windows Media Audio V7 / V8 / V9 + 0x0162 Windows Media Audio Professional V9 + 0x0163 Windows Media Audio Lossless V9 + 0x0200 Creative Labs ADPCM + 0x0202 Creative Labs Fastspeech8 + 0x0203 Creative Labs Fastspeech10 + 0x0210 UHER Informatic GmbH ADPCM + 0x0220 Quarterdeck + 0x0230 I-link Worldwide VC + 0x0240 Aureal RAW Sport + 0x0250 Interactive Products HSX + 0x0251 Interactive Products RPELP + 0x0260 Consistent Software CS2 + 0x0270 Sony SCX + 0x0300 Fujitsu FM Towns Snd + 0x0400 BTV Digital + 0x0401 Intel Music Coder + 0x0450 QDesign Music + 0x0680 VME VMPCM + 0x0681 AT&T Labs TPC + 0x08AE ClearJump LiteWave + 0x1000 Olivetti GSM + 0x1001 Olivetti ADPCM + 0x1002 Olivetti CELP + 0x1003 Olivetti SBC + 0x1004 Olivetti OPR + 0x1100 Lernout & Hauspie Codec (0x1100) + 0x1101 Lernout & Hauspie CELP Codec (0x1101) + 0x1102 Lernout & Hauspie SBC Codec (0x1102) + 0x1103 Lernout & Hauspie SBC Codec (0x1103) + 0x1104 Lernout & Hauspie SBC Codec (0x1104) + 0x1400 Norris + 0x1401 AT&T ISIAudio + 0x1500 Soundspace Music Compression + 0x181C VoxWare RT24 Speech + 0x1FC4 NCT Soft ALF2CD (www.nctsoft.com) + 0x2000 Dolby AC3 + 0x2001 Dolby DTS + 0x2002 WAVE_FORMAT_14_4 + 0x2003 WAVE_FORMAT_28_8 + 0x2004 WAVE_FORMAT_COOK + 0x2005 WAVE_FORMAT_DNET + 0x674F Ogg Vorbis 1 + 0x6750 Ogg Vorbis 2 + 0x6751 Ogg Vorbis 3 + 0x676F Ogg Vorbis 1+ + 0x6770 Ogg Vorbis 2+ + 0x6771 Ogg Vorbis 3+ + 0x7A21 GSM-AMR (CBR, no SID) + 0x7A22 GSM-AMR (VBR, including SID) + 0xFFFE WAVE_FORMAT_EXTENSIBLE + 0xFFFF WAVE_FORMAT_DEVELOPMENT + + */ + + return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag'); + } + + public static function fourccLookup($fourcc) { + + $begin = __LINE__; + + /** This is not a comment! + + swot http://developer.apple.com/qa/snd/snd07.html + ____ No Codec (____) + _BIT BI_BITFIELDS (Raw RGB) + _JPG JPEG compressed + _PNG PNG compressed W3C/ISO/IEC (RFC-2083) + _RAW Full Frames (Uncompressed) + _RGB Raw RGB Bitmap + _RL4 RLE 4bpp RGB + _RL8 RLE 8bpp RGB + 3IV1 3ivx MPEG-4 v1 + 3IV2 3ivx MPEG-4 v2 + 3IVX 3ivx MPEG-4 + AASC Autodesk Animator + ABYR Kensington ?ABYR? + AEMI Array Microsystems VideoONE MPEG1-I Capture + AFLC Autodesk Animator FLC + AFLI Autodesk Animator FLI + AMPG Array Microsystems VideoONE MPEG + ANIM Intel RDX (ANIM) + AP41 AngelPotion Definitive + ASV1 Asus Video v1 + ASV2 Asus Video v2 + ASVX Asus Video 2.0 (audio) + AUR2 AuraVision Aura 2 Codec - YUV 4:2:2 + AURA AuraVision Aura 1 Codec - YUV 4:1:1 + AVDJ Independent JPEG Group\'s codec (AVDJ) + AVRN Independent JPEG Group\'s codec (AVRN) + AYUV 4:4:4 YUV (AYUV) + AZPR Quicktime Apple Video (AZPR) + BGR Raw RGB32 + BLZ0 Blizzard DivX MPEG-4 + BTVC Conexant Composite Video + BINK RAD Game Tools Bink Video + BT20 Conexant Prosumer Video + BTCV Conexant Composite Video Codec + BW10 Data Translation Broadway MPEG Capture + CC12 Intel YUV12 + CDVC Canopus DV + CFCC Digital Processing Systems DPS Perception + CGDI Microsoft Office 97 Camcorder Video + CHAM Winnov Caviara Champagne + CJPG Creative WebCam JPEG + CLJR Cirrus Logic YUV 4:1:1 + CMYK Common Data Format in Printing (Colorgraph) + CPLA Weitek 4:2:0 YUV Planar + CRAM Microsoft Video 1 (CRAM) + cvid Radius Cinepak + CVID Radius Cinepak + CWLT Microsoft Color WLT DIB + CYUV Creative Labs YUV + CYUY ATI YUV + D261 H.261 + D263 H.263 + DIB Device Independent Bitmap + DIV1 FFmpeg OpenDivX + DIV2 Microsoft MPEG-4 v1/v2 + DIV3 DivX ;-) MPEG-4 v3.x Low-Motion + DIV4 DivX ;-) MPEG-4 v3.x Fast-Motion + DIV5 DivX MPEG-4 v5.x + DIV6 DivX ;-) (MS MPEG-4 v3.x) + DIVX DivX MPEG-4 v4 (OpenDivX / Project Mayo) + divx DivX MPEG-4 + DMB1 Matrox Rainbow Runner hardware MJPEG + DMB2 Paradigm MJPEG + DSVD ?DSVD? + DUCK Duck TrueMotion 1.0 + DPS0 DPS/Leitch Reality Motion JPEG + DPSC DPS/Leitch PAR Motion JPEG + DV25 Matrox DVCPRO codec + DV50 Matrox DVCPRO50 codec + DVC IEC 61834 and SMPTE 314M (DVC/DV Video) + DVCP IEC 61834 and SMPTE 314M (DVC/DV Video) + DVHD IEC Standard DV 1125 lines @ 30fps / 1250 lines @ 25fps + DVMA Darim Vision DVMPEG (dummy for MPEG compressor) (www.darvision.com) + DVSL IEC Standard DV compressed in SD (SDL) + DVAN ?DVAN? + DVE2 InSoft DVE-2 Videoconferencing + dvsd IEC 61834 and SMPTE 314M DVC/DV Video + DVSD IEC 61834 and SMPTE 314M DVC/DV Video + DVX1 Lucent DVX1000SP Video Decoder + DVX2 Lucent DVX2000S Video Decoder + DVX3 Lucent DVX3000S Video Decoder + DX50 DivX v5 + DXT1 Microsoft DirectX Compressed Texture (DXT1) + DXT2 Microsoft DirectX Compressed Texture (DXT2) + DXT3 Microsoft DirectX Compressed Texture (DXT3) + DXT4 Microsoft DirectX Compressed Texture (DXT4) + DXT5 Microsoft DirectX Compressed Texture (DXT5) + DXTC Microsoft DirectX Compressed Texture (DXTC) + DXTn Microsoft DirectX Compressed Texture (DXTn) + EM2V Etymonix MPEG-2 I-frame (www.etymonix.com) + EKQ0 Elsa ?EKQ0? + ELK0 Elsa ?ELK0? + ESCP Eidos Escape + ETV1 eTreppid Video ETV1 + ETV2 eTreppid Video ETV2 + ETVC eTreppid Video ETVC + FLIC Autodesk FLI/FLC Animation + FLV1 Sorenson Spark + FLV4 On2 TrueMotion VP6 + FRWT Darim Vision Forward Motion JPEG (www.darvision.com) + FRWU Darim Vision Forward Uncompressed (www.darvision.com) + FLJP D-Vision Field Encoded Motion JPEG + FPS1 FRAPS v1 + FRWA SoftLab-Nsk Forward Motion JPEG w/ alpha channel + FRWD SoftLab-Nsk Forward Motion JPEG + FVF1 Iterated Systems Fractal Video Frame + GLZW Motion LZW (gabest@freemail.hu) + GPEG Motion JPEG (gabest@freemail.hu) + GWLT Microsoft Greyscale WLT DIB + H260 Intel ITU H.260 Videoconferencing + H261 Intel ITU H.261 Videoconferencing + H262 Intel ITU H.262 Videoconferencing + H263 Intel ITU H.263 Videoconferencing + H264 Intel ITU H.264 Videoconferencing + H265 Intel ITU H.265 Videoconferencing + H266 Intel ITU H.266 Videoconferencing + H267 Intel ITU H.267 Videoconferencing + H268 Intel ITU H.268 Videoconferencing + H269 Intel ITU H.269 Videoconferencing + HFYU Huffman Lossless Codec + HMCR Rendition Motion Compensation Format (HMCR) + HMRR Rendition Motion Compensation Format (HMRR) + I263 FFmpeg I263 decoder + IF09 Indeo YVU9 ("YVU9 with additional delta-frame info after the U plane") + IUYV Interlaced version of UYVY (www.leadtools.com) + IY41 Interlaced version of Y41P (www.leadtools.com) + IYU1 12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec IEEE standard + IYU2 24 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec IEEE standard + IYUV Planar YUV format (8-bpp Y plane, followed by 8-bpp 2\D72 U and V planes) + i263 Intel ITU H.263 Videoconferencing (i263) + I420 Intel Indeo 4 + IAN Intel Indeo 4 (RDX) + ICLB InSoft CellB Videoconferencing + IGOR Power DVD + IJPG Intergraph JPEG + ILVC Intel Layered Video + ILVR ITU-T H.263+ + IPDV I-O Data Device Giga AVI DV Codec + IR21 Intel Indeo 2.1 + IRAW Intel YUV Uncompressed + IV30 Intel Indeo 3.0 + IV31 Intel Indeo 3.1 + IV32 Ligos Indeo 3.2 + IV33 Ligos Indeo 3.3 + IV34 Ligos Indeo 3.4 + IV35 Ligos Indeo 3.5 + IV36 Ligos Indeo 3.6 + IV37 Ligos Indeo 3.7 + IV38 Ligos Indeo 3.8 + IV39 Ligos Indeo 3.9 + IV40 Ligos Indeo Interactive 4.0 + IV41 Ligos Indeo Interactive 4.1 + IV42 Ligos Indeo Interactive 4.2 + IV43 Ligos Indeo Interactive 4.3 + IV44 Ligos Indeo Interactive 4.4 + IV45 Ligos Indeo Interactive 4.5 + IV46 Ligos Indeo Interactive 4.6 + IV47 Ligos Indeo Interactive 4.7 + IV48 Ligos Indeo Interactive 4.8 + IV49 Ligos Indeo Interactive 4.9 + IV50 Ligos Indeo Interactive 5.0 + JBYR Kensington ?JBYR? + JPEG Still Image JPEG DIB + JPGL Pegasus Lossless Motion JPEG + KMVC Team17 Software Karl Morton\'s Video Codec + LSVM Vianet Lighting Strike Vmail (Streaming) (www.vianet.com) + LEAD LEAD Video Codec + Ljpg LEAD MJPEG Codec + MDVD Alex MicroDVD Video (hacked MS MPEG-4) (www.tiasoft.de) + MJPA Morgan Motion JPEG (MJPA) (www.morgan-multimedia.com) + MJPB Morgan Motion JPEG (MJPB) (www.morgan-multimedia.com) + MMES Matrox MPEG-2 I-frame + MP2v Microsoft S-Mpeg 4 version 1 (MP2v) + MP42 Microsoft S-Mpeg 4 version 2 (MP42) + MP43 Microsoft S-Mpeg 4 version 3 (MP43) + MP4S Microsoft S-Mpeg 4 version 3 (MP4S) + MP4V FFmpeg MPEG-4 + MPG1 FFmpeg MPEG 1/2 + MPG2 FFmpeg MPEG 1/2 + MPG3 FFmpeg DivX ;-) (MS MPEG-4 v3) + MPG4 Microsoft MPEG-4 + MPGI Sigma Designs MPEG + MPNG PNG images decoder + MSS1 Microsoft Windows Screen Video + MSZH LCL (Lossless Codec Library) (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm) + M261 Microsoft H.261 + M263 Microsoft H.263 + M4S2 Microsoft Fully Compliant MPEG-4 v2 simple profile (M4S2) + m4s2 Microsoft Fully Compliant MPEG-4 v2 simple profile (m4s2) + MC12 ATI Motion Compensation Format (MC12) + MCAM ATI Motion Compensation Format (MCAM) + MJ2C Morgan Multimedia Motion JPEG2000 + mJPG IBM Motion JPEG w/ Huffman Tables + MJPG Microsoft Motion JPEG DIB + MP42 Microsoft MPEG-4 (low-motion) + MP43 Microsoft MPEG-4 (fast-motion) + MP4S Microsoft MPEG-4 (MP4S) + mp4s Microsoft MPEG-4 (mp4s) + MPEG Chromatic Research MPEG-1 Video I-Frame + MPG4 Microsoft MPEG-4 Video High Speed Compressor + MPGI Sigma Designs MPEG + MRCA FAST Multimedia Martin Regen Codec + MRLE Microsoft Run Length Encoding + MSVC Microsoft Video 1 + MTX1 Matrox ?MTX1? + MTX2 Matrox ?MTX2? + MTX3 Matrox ?MTX3? + MTX4 Matrox ?MTX4? + MTX5 Matrox ?MTX5? + MTX6 Matrox ?MTX6? + MTX7 Matrox ?MTX7? + MTX8 Matrox ?MTX8? + MTX9 Matrox ?MTX9? + MV12 Motion Pixels Codec (old) + MWV1 Aware Motion Wavelets + nAVI SMR Codec (hack of Microsoft MPEG-4) (IRC #shadowrealm) + NT00 NewTek LightWave HDTV YUV w/ Alpha (www.newtek.com) + NUV1 NuppelVideo + NTN1 Nogatech Video Compression 1 + NVS0 nVidia GeForce Texture (NVS0) + NVS1 nVidia GeForce Texture (NVS1) + NVS2 nVidia GeForce Texture (NVS2) + NVS3 nVidia GeForce Texture (NVS3) + NVS4 nVidia GeForce Texture (NVS4) + NVS5 nVidia GeForce Texture (NVS5) + NVT0 nVidia GeForce Texture (NVT0) + NVT1 nVidia GeForce Texture (NVT1) + NVT2 nVidia GeForce Texture (NVT2) + NVT3 nVidia GeForce Texture (NVT3) + NVT4 nVidia GeForce Texture (NVT4) + NVT5 nVidia GeForce Texture (NVT5) + PIXL MiroXL, Pinnacle PCTV + PDVC I-O Data Device Digital Video Capture DV codec + PGVV Radius Video Vision + PHMO IBM Photomotion + PIM1 MPEG Realtime (Pinnacle Cards) + PIM2 Pegasus Imaging ?PIM2? + PIMJ Pegasus Imaging Lossless JPEG + PVEZ Horizons Technology PowerEZ + PVMM PacketVideo Corporation MPEG-4 + PVW2 Pegasus Imaging Wavelet Compression + Q1.0 Q-Team\'s QPEG 1.0 (www.q-team.de) + Q1.1 Q-Team\'s QPEG 1.1 (www.q-team.de) + QPEG Q-Team QPEG 1.0 + qpeq Q-Team QPEG 1.1 + RGB Raw BGR32 + RGBA Raw RGB w/ Alpha + RMP4 REALmagic MPEG-4 (unauthorized XVID copy) (www.sigmadesigns.com) + ROQV Id RoQ File Video Decoder + RPZA Quicktime Apple Video (RPZA) + RUD0 Rududu video codec (http://rududu.ifrance.com/rududu/) + RV10 RealVideo 1.0 (aka RealVideo 5.0) + RV13 RealVideo 1.0 (RV13) + RV20 RealVideo G2 + RV30 RealVideo 8 + RV40 RealVideo 9 + RGBT Raw RGB w/ Transparency + RLE Microsoft Run Length Encoder + RLE4 Run Length Encoded (4bpp, 16-color) + RLE8 Run Length Encoded (8bpp, 256-color) + RT21 Intel Indeo RealTime Video 2.1 + rv20 RealVideo G2 + rv30 RealVideo 8 + RVX Intel RDX (RVX ) + SMC Apple Graphics (SMC ) + SP54 Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2 + SPIG Radius Spigot + SVQ3 Sorenson Video 3 (Apple Quicktime 5) + s422 Tekram VideoCap C210 YUV 4:2:2 + SDCC Sun Communication Digital Camera Codec + SFMC CrystalNet Surface Fitting Method + SMSC Radius SMSC + SMSD Radius SMSD + smsv WorldConnect Wavelet Video + SPIG Radius Spigot + SPLC Splash Studios ACM Audio Codec (www.splashstudios.net) + SQZ2 Microsoft VXTreme Video Codec V2 + STVA ST Microelectronics CMOS Imager Data (Bayer) + STVB ST Microelectronics CMOS Imager Data (Nudged Bayer) + STVC ST Microelectronics CMOS Imager Data (Bunched) + STVX ST Microelectronics CMOS Imager Data (Extended CODEC Data Format) + STVY ST Microelectronics CMOS Imager Data (Extended CODEC Data Format with Correction Data) + SV10 Sorenson Video R1 + SVQ1 Sorenson Video + T420 Toshiba YUV 4:2:0 + TM2A Duck TrueMotion Archiver 2.0 (www.duck.com) + TVJP Pinnacle/Truevision Targa 2000 board (TVJP) + TVMJ Pinnacle/Truevision Targa 2000 board (TVMJ) + TY0N Tecomac Low-Bit Rate Codec (www.tecomac.com) + TY2C Trident Decompression Driver + TLMS TeraLogic Motion Intraframe Codec (TLMS) + TLST TeraLogic Motion Intraframe Codec (TLST) + TM20 Duck TrueMotion 2.0 + TM2X Duck TrueMotion 2X + TMIC TeraLogic Motion Intraframe Codec (TMIC) + TMOT Horizons Technology TrueMotion S + tmot Horizons TrueMotion Video Compression + TR20 Duck TrueMotion RealTime 2.0 + TSCC TechSmith Screen Capture Codec + TV10 Tecomac Low-Bit Rate Codec + TY2N Trident ?TY2N? + U263 UB Video H.263/H.263+/H.263++ Decoder + UMP4 UB Video MPEG 4 (www.ubvideo.com) + UYNV Nvidia UYVY packed 4:2:2 + UYVP Evans & Sutherland YCbCr 4:2:2 extended precision + UCOD eMajix.com ClearVideo + ULTI IBM Ultimotion + UYVY UYVY packed 4:2:2 + V261 Lucent VX2000S + VIFP VFAPI Reader Codec (www.yks.ne.jp/~hori/) + VIV1 FFmpeg H263+ decoder + VIV2 Vivo H.263 + VQC2 Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf) + VTLP Alaris VideoGramPiX + VYU9 ATI YUV (VYU9) + VYUY ATI YUV (VYUY) + V261 Lucent VX2000S + V422 Vitec Multimedia 24-bit YUV 4:2:2 Format + V655 Vitec Multimedia 16-bit YUV 4:2:2 Format + VCR1 ATI Video Codec 1 + VCR2 ATI Video Codec 2 + VCR3 ATI VCR 3.0 + VCR4 ATI VCR 4.0 + VCR5 ATI VCR 5.0 + VCR6 ATI VCR 6.0 + VCR7 ATI VCR 7.0 + VCR8 ATI VCR 8.0 + VCR9 ATI VCR 9.0 + VDCT Vitec Multimedia Video Maker Pro DIB + VDOM VDOnet VDOWave + VDOW VDOnet VDOLive (H.263) + VDTZ Darim Vison VideoTizer YUV + VGPX Alaris VideoGramPiX + VIDS Vitec Multimedia YUV 4:2:2 CCIR 601 for V422 + VIVO Vivo H.263 v2.00 + vivo Vivo H.263 + VIXL Miro/Pinnacle Video XL + VLV1 VideoLogic/PURE Digital Videologic Capture + VP30 On2 VP3.0 + VP31 On2 VP3.1 + VP6F On2 TrueMotion VP6 + VX1K Lucent VX1000S Video Codec + VX2K Lucent VX2000S Video Codec + VXSP Lucent VX1000SP Video Codec + WBVC Winbond W9960 + WHAM Microsoft Video 1 (WHAM) + WINX Winnov Software Compression + WJPG AverMedia Winbond JPEG + WMV1 Windows Media Video V7 + WMV2 Windows Media Video V8 + WMV3 Windows Media Video V9 + WNV1 Winnov Hardware Compression + XYZP Extended PAL format XYZ palette (www.riff.org) + x263 Xirlink H.263 + XLV0 NetXL Video Decoder + XMPG Xing MPEG (I-Frame only) + XVID XviD MPEG-4 (www.xvid.org) + XXAN ?XXAN? + YU92 Intel YUV (YU92) + YUNV Nvidia Uncompressed YUV 4:2:2 + YUVP Extended PAL format YUV palette (www.riff.org) + Y211 YUV 2:1:1 Packed + Y411 YUV 4:1:1 Packed + Y41B Weitek YUV 4:1:1 Planar + Y41P Brooktree PC1 YUV 4:1:1 Packed + Y41T Brooktree PC1 YUV 4:1:1 with transparency + Y42B Weitek YUV 4:2:2 Planar + Y42T Brooktree UYUV 4:2:2 with transparency + Y422 ADS Technologies Copy of UYVY used in Pyro WebCam firewire camera + Y800 Simple, single Y plane for monochrome images + Y8 Grayscale video + YC12 Intel YUV 12 codec + YUV8 Winnov Caviar YUV8 + YUV9 Intel YUV9 + YUY2 Uncompressed YUV 4:2:2 + YUYV Canopus YUV + YV12 YVU12 Planar + YVU9 Intel YVU9 Planar (8-bpp Y plane, followed by 8-bpp 4x4 U and V planes) + YVYU YVYU 4:2:2 Packed + ZLIB Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm) + ZPEG Metheus Video Zipper + + */ + + return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc'); + } + + private function EitherEndian2Int($byteword, $signed=false) { + if ($this->getid3->info['fileformat'] == 'riff') { + return getid3_lib::LittleEndian2Int($byteword, $signed); + } + return getid3_lib::BigEndian2Int($byteword, false, $signed); + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio.ac3.php b/extensions/TimedMediaHandler/libs/getid3/module.audio.ac3.php new file mode 100644 index 00000000..9834feb5 --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio.ac3.php @@ -0,0 +1,473 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio.ac3.php // +// module for analyzing AC-3 (aka Dolby Digital) audio files // +// dependencies: NONE // +// /// +///////////////////////////////////////////////////////////////// + + +class getid3_ac3 extends getid3_handler +{ + private $AC3header = array(); + private $BSIoffset = 0; + + const syncword = "\x0B\x77"; + + public function Analyze() { + $info = &$this->getid3->info; + + ///AH + $info['ac3']['raw']['bsi'] = array(); + $thisfile_ac3 = &$info['ac3']; + $thisfile_ac3_raw = &$thisfile_ac3['raw']; + $thisfile_ac3_raw_bsi = &$thisfile_ac3_raw['bsi']; + + + // http://www.atsc.org/standards/a_52a.pdf + + $info['fileformat'] = 'ac3'; + + // An AC-3 serial coded audio bit stream is made up of a sequence of synchronization frames + // Each synchronization frame contains 6 coded audio blocks (AB), each of which represent 256 + // new audio samples per channel. A synchronization information (SI) header at the beginning + // of each frame contains information needed to acquire and maintain synchronization. A + // bit stream information (BSI) header follows SI, and contains parameters describing the coded + // audio service. The coded audio blocks may be followed by an auxiliary data (Aux) field. At the + // end of each frame is an error check field that includes a CRC word for error detection. An + // additional CRC word is located in the SI header, the use of which, by a decoder, is optional. + // + // syncinfo() | bsi() | AB0 | AB1 | AB2 | AB3 | AB4 | AB5 | Aux | CRC + + // syncinfo() { + // syncword 16 + // crc1 16 + // fscod 2 + // frmsizecod 6 + // } /* end of syncinfo */ + + $this->fseek($info['avdataoffset']); + $this->AC3header['syncinfo'] = $this->fread(5); + + if (strpos($this->AC3header['syncinfo'], self::syncword) === 0) { + $thisfile_ac3_raw['synchinfo']['synchword'] = self::syncword; + $offset = 2; + } else { + if (!$this->isDependencyFor('matroska')) { + unset($info['fileformat'], $info['ac3']); + return $this->error('Expecting "'.getid3_lib::PrintHexBytes(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes(substr($this->AC3header['syncinfo'], 0, 2)).'"'); + } + $offset = 0; + $this->fseek(-2, SEEK_CUR); + } + + $info['audio']['dataformat'] = 'ac3'; + $info['audio']['bitrate_mode'] = 'cbr'; + $info['audio']['lossless'] = false; + + $thisfile_ac3_raw['synchinfo']['crc1'] = getid3_lib::LittleEndian2Int(substr($this->AC3header['syncinfo'], $offset, 2)); + $ac3_synchinfo_fscod_frmsizecod = getid3_lib::LittleEndian2Int(substr($this->AC3header['syncinfo'], ($offset + 2), 1)); + $thisfile_ac3_raw['synchinfo']['fscod'] = ($ac3_synchinfo_fscod_frmsizecod & 0xC0) >> 6; + $thisfile_ac3_raw['synchinfo']['frmsizecod'] = ($ac3_synchinfo_fscod_frmsizecod & 0x3F); + + $thisfile_ac3['sample_rate'] = self::sampleRateCodeLookup($thisfile_ac3_raw['synchinfo']['fscod']); + if ($thisfile_ac3_raw['synchinfo']['fscod'] <= 3) { + $info['audio']['sample_rate'] = $thisfile_ac3['sample_rate']; + } + + $thisfile_ac3['frame_length'] = self::frameSizeLookup($thisfile_ac3_raw['synchinfo']['frmsizecod'], $thisfile_ac3_raw['synchinfo']['fscod']); + $thisfile_ac3['bitrate'] = self::bitrateLookup($thisfile_ac3_raw['synchinfo']['frmsizecod']); + $info['audio']['bitrate'] = $thisfile_ac3['bitrate']; + + $this->AC3header['bsi'] = getid3_lib::BigEndian2Bin($this->fread(15)); + $ac3_bsi_offset = 0; + + $thisfile_ac3_raw_bsi['bsid'] = $this->readHeaderBSI(5); + if ($thisfile_ac3_raw_bsi['bsid'] > 8) { + // Decoders which can decode version 8 will thus be able to decode version numbers less than 8. + // If this standard is extended by the addition of additional elements or features, a value of bsid greater than 8 will be used. + // Decoders built to this version of the standard will not be able to decode versions with bsid greater than 8. + $this->error('Bit stream identification is version '.$thisfile_ac3_raw_bsi['bsid'].', but getID3() only understands up to version 8'); + unset($info['ac3']); + return false; + } + + $thisfile_ac3_raw_bsi['bsmod'] = $this->readHeaderBSI(3); + $thisfile_ac3_raw_bsi['acmod'] = $this->readHeaderBSI(3); + + $thisfile_ac3['service_type'] = self::serviceTypeLookup($thisfile_ac3_raw_bsi['bsmod'], $thisfile_ac3_raw_bsi['acmod']); + $ac3_coding_mode = self::audioCodingModeLookup($thisfile_ac3_raw_bsi['acmod']); + foreach($ac3_coding_mode as $key => $value) { + $thisfile_ac3[$key] = $value; + } + switch ($thisfile_ac3_raw_bsi['acmod']) { + case 0: + case 1: + $info['audio']['channelmode'] = 'mono'; + break; + case 3: + case 4: + $info['audio']['channelmode'] = 'stereo'; + break; + default: + $info['audio']['channelmode'] = 'surround'; + break; + } + $info['audio']['channels'] = $thisfile_ac3['num_channels']; + + if ($thisfile_ac3_raw_bsi['acmod'] & 0x01) { + // If the lsb of acmod is a 1, center channel is in use and cmixlev follows in the bit stream. + $thisfile_ac3_raw_bsi['cmixlev'] = $this->readHeaderBSI(2); + $thisfile_ac3['center_mix_level'] = self::centerMixLevelLookup($thisfile_ac3_raw_bsi['cmixlev']); + } + + if ($thisfile_ac3_raw_bsi['acmod'] & 0x04) { + // If the msb of acmod is a 1, surround channels are in use and surmixlev follows in the bit stream. + $thisfile_ac3_raw_bsi['surmixlev'] = $this->readHeaderBSI(2); + $thisfile_ac3['surround_mix_level'] = self::surroundMixLevelLookup($thisfile_ac3_raw_bsi['surmixlev']); + } + + if ($thisfile_ac3_raw_bsi['acmod'] == 0x02) { + // When operating in the two channel mode, this 2-bit code indicates whether or not the program has been encoded in Dolby Surround. + $thisfile_ac3_raw_bsi['dsurmod'] = $this->readHeaderBSI(2); + $thisfile_ac3['dolby_surround_mode'] = self::dolbySurroundModeLookup($thisfile_ac3_raw_bsi['dsurmod']); + } + + $thisfile_ac3_raw_bsi['lfeon'] = (bool) $this->readHeaderBSI(1); + $thisfile_ac3['lfe_enabled'] = $thisfile_ac3_raw_bsi['lfeon']; + if ($thisfile_ac3_raw_bsi['lfeon']) { + //$info['audio']['channels']++; + $info['audio']['channels'] .= '.1'; + } + + $thisfile_ac3['channels_enabled'] = self::channelsEnabledLookup($thisfile_ac3_raw_bsi['acmod'], $thisfile_ac3_raw_bsi['lfeon']); + + // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31. + // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent. + $thisfile_ac3_raw_bsi['dialnorm'] = $this->readHeaderBSI(5); + $thisfile_ac3['dialogue_normalization'] = '-'.$thisfile_ac3_raw_bsi['dialnorm'].'dB'; + + $thisfile_ac3_raw_bsi['compre_flag'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['compre_flag']) { + $thisfile_ac3_raw_bsi['compr'] = $this->readHeaderBSI(8); + $thisfile_ac3['heavy_compression'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr']); + } + + $thisfile_ac3_raw_bsi['langcode_flag'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['langcode_flag']) { + $thisfile_ac3_raw_bsi['langcod'] = $this->readHeaderBSI(8); + } + + $thisfile_ac3_raw_bsi['audprodie'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['audprodie']) { + $thisfile_ac3_raw_bsi['mixlevel'] = $this->readHeaderBSI(5); + $thisfile_ac3_raw_bsi['roomtyp'] = $this->readHeaderBSI(2); + + $thisfile_ac3['mixing_level'] = (80 + $thisfile_ac3_raw_bsi['mixlevel']).'dB'; + $thisfile_ac3['room_type'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp']); + } + + if ($thisfile_ac3_raw_bsi['acmod'] == 0x00) { + // If acmod is 0, then two completely independent program channels (dual mono) + // are encoded into the bit stream, and are referenced as Ch1, Ch2. In this case, + // a number of additional items are present in BSI or audblk to fully describe Ch2. + + // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31. + // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent. + $thisfile_ac3_raw_bsi['dialnorm2'] = $this->readHeaderBSI(5); + $thisfile_ac3['dialogue_normalization2'] = '-'.$thisfile_ac3_raw_bsi['dialnorm2'].'dB'; + + $thisfile_ac3_raw_bsi['compre_flag2'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['compre_flag2']) { + $thisfile_ac3_raw_bsi['compr2'] = $this->readHeaderBSI(8); + $thisfile_ac3['heavy_compression2'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr2']); + } + + $thisfile_ac3_raw_bsi['langcode_flag2'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['langcode_flag2']) { + $thisfile_ac3_raw_bsi['langcod2'] = $this->readHeaderBSI(8); + } + + $thisfile_ac3_raw_bsi['audprodie2'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['audprodie2']) { + $thisfile_ac3_raw_bsi['mixlevel2'] = $this->readHeaderBSI(5); + $thisfile_ac3_raw_bsi['roomtyp2'] = $this->readHeaderBSI(2); + + $thisfile_ac3['mixing_level2'] = (80 + $thisfile_ac3_raw_bsi['mixlevel2']).'dB'; + $thisfile_ac3['room_type2'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp2']); + } + + } + + $thisfile_ac3_raw_bsi['copyright'] = (bool) $this->readHeaderBSI(1); + + $thisfile_ac3_raw_bsi['original'] = (bool) $this->readHeaderBSI(1); + + $thisfile_ac3_raw_bsi['timecode1_flag'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['timecode1_flag']) { + $thisfile_ac3_raw_bsi['timecode1'] = $this->readHeaderBSI(14); + } + + $thisfile_ac3_raw_bsi['timecode2_flag'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['timecode2_flag']) { + $thisfile_ac3_raw_bsi['timecode2'] = $this->readHeaderBSI(14); + } + + $thisfile_ac3_raw_bsi['addbsi_flag'] = (bool) $this->readHeaderBSI(1); + if ($thisfile_ac3_raw_bsi['addbsi_flag']) { + $thisfile_ac3_raw_bsi['addbsi_length'] = $this->readHeaderBSI(6); + + $this->AC3header['bsi'] .= getid3_lib::BigEndian2Bin($this->fread($thisfile_ac3_raw_bsi['addbsi_length'])); + + $thisfile_ac3_raw_bsi['addbsi_data'] = substr($this->AC3header['bsi'], $this->BSIoffset, $thisfile_ac3_raw_bsi['addbsi_length'] * 8); + $this->BSIoffset += $thisfile_ac3_raw_bsi['addbsi_length'] * 8; + } + + return true; + } + + private function readHeaderBSI($length) { + $data = substr($this->AC3header['bsi'], $this->BSIoffset, $length); + $this->BSIoffset += $length; + + return bindec($data); + } + + public static function sampleRateCodeLookup($fscod) { + static $sampleRateCodeLookup = array( + 0 => 48000, + 1 => 44100, + 2 => 32000, + 3 => 'reserved' // If the reserved code is indicated, the decoder should not attempt to decode audio and should mute. + ); + return (isset($sampleRateCodeLookup[$fscod]) ? $sampleRateCodeLookup[$fscod] : false); + } + + public static function serviceTypeLookup($bsmod, $acmod) { + static $serviceTypeLookup = array(); + if (empty($serviceTypeLookup)) { + for ($i = 0; $i <= 7; $i++) { + $serviceTypeLookup[0][$i] = 'main audio service: complete main (CM)'; + $serviceTypeLookup[1][$i] = 'main audio service: music and effects (ME)'; + $serviceTypeLookup[2][$i] = 'associated service: visually impaired (VI)'; + $serviceTypeLookup[3][$i] = 'associated service: hearing impaired (HI)'; + $serviceTypeLookup[4][$i] = 'associated service: dialogue (D)'; + $serviceTypeLookup[5][$i] = 'associated service: commentary (C)'; + $serviceTypeLookup[6][$i] = 'associated service: emergency (E)'; + } + + $serviceTypeLookup[7][1] = 'associated service: voice over (VO)'; + for ($i = 2; $i <= 7; $i++) { + $serviceTypeLookup[7][$i] = 'main audio service: karaoke'; + } + } + return (isset($serviceTypeLookup[$bsmod][$acmod]) ? $serviceTypeLookup[$bsmod][$acmod] : false); + } + + public static function audioCodingModeLookup($acmod) { + // array(channel configuration, # channels (not incl LFE), channel order) + static $audioCodingModeLookup = array ( + 0 => array('channel_config'=>'1+1', 'num_channels'=>2, 'channel_order'=>'Ch1,Ch2'), + 1 => array('channel_config'=>'1/0', 'num_channels'=>1, 'channel_order'=>'C'), + 2 => array('channel_config'=>'2/0', 'num_channels'=>2, 'channel_order'=>'L,R'), + 3 => array('channel_config'=>'3/0', 'num_channels'=>3, 'channel_order'=>'L,C,R'), + 4 => array('channel_config'=>'2/1', 'num_channels'=>3, 'channel_order'=>'L,R,S'), + 5 => array('channel_config'=>'3/1', 'num_channels'=>4, 'channel_order'=>'L,C,R,S'), + 6 => array('channel_config'=>'2/2', 'num_channels'=>4, 'channel_order'=>'L,R,SL,SR'), + 7 => array('channel_config'=>'3/2', 'num_channels'=>5, 'channel_order'=>'L,C,R,SL,SR'), + ); + return (isset($audioCodingModeLookup[$acmod]) ? $audioCodingModeLookup[$acmod] : false); + } + + public static function centerMixLevelLookup($cmixlev) { + static $centerMixLevelLookup; + if (empty($centerMixLevelLookup)) { + $centerMixLevelLookup = array( + 0 => pow(2, -3.0 / 6), // 0.707 (-3.0 dB) + 1 => pow(2, -4.5 / 6), // 0.595 (-4.5 dB) + 2 => pow(2, -6.0 / 6), // 0.500 (-6.0 dB) + 3 => 'reserved' + ); + } + return (isset($centerMixLevelLookup[$cmixlev]) ? $centerMixLevelLookup[$cmixlev] : false); + } + + public static function surroundMixLevelLookup($surmixlev) { + static $surroundMixLevelLookup; + if (empty($surroundMixLevelLookup)) { + $surroundMixLevelLookup = array( + 0 => pow(2, -3.0 / 6), + 1 => pow(2, -6.0 / 6), + 2 => 0, + 3 => 'reserved' + ); + } + return (isset($surroundMixLevelLookup[$surmixlev]) ? $surroundMixLevelLookup[$surmixlev] : false); + } + + public static function dolbySurroundModeLookup($dsurmod) { + static $dolbySurroundModeLookup = array( + 0 => 'not indicated', + 1 => 'Not Dolby Surround encoded', + 2 => 'Dolby Surround encoded', + 3 => 'reserved' + ); + return (isset($dolbySurroundModeLookup[$dsurmod]) ? $dolbySurroundModeLookup[$dsurmod] : false); + } + + public static function channelsEnabledLookup($acmod, $lfeon) { + $lookup = array( + 'ch1'=>(bool) ($acmod == 0), + 'ch2'=>(bool) ($acmod == 0), + 'left'=>(bool) ($acmod > 1), + 'right'=>(bool) ($acmod > 1), + 'center'=>(bool) ($acmod & 0x01), + 'surround_mono'=>false, + 'surround_left'=>false, + 'surround_right'=>false, + 'lfe'=>$lfeon); + switch ($acmod) { + case 4: + case 5: + $lookup['surround_mono'] = true; + break; + case 6: + case 7: + $lookup['surround_left'] = true; + $lookup['surround_right'] = true; + break; + } + return $lookup; + } + + public static function heavyCompression($compre) { + // The first four bits indicate gain changes in 6.02dB increments which can be + // implemented with an arithmetic shift operation. The following four bits + // indicate linear gain changes, and require a 5-bit multiply. + // We will represent the two 4-bit fields of compr as follows: + // X0 X1 X2 X3 . Y4 Y5 Y6 Y7 + // The meaning of the X values is most simply described by considering X to represent a 4-bit + // signed integer with values from -8 to +7. The gain indicated by X is then (X + 1) * 6.02 dB. The + // following table shows this in detail. + + // Meaning of 4 msb of compr + // 7 +48.16 dB + // 6 +42.14 dB + // 5 +36.12 dB + // 4 +30.10 dB + // 3 +24.08 dB + // 2 +18.06 dB + // 1 +12.04 dB + // 0 +6.02 dB + // -1 0 dB + // -2 -6.02 dB + // -3 -12.04 dB + // -4 -18.06 dB + // -5 -24.08 dB + // -6 -30.10 dB + // -7 -36.12 dB + // -8 -42.14 dB + + $fourbit = str_pad(decbin(($compre & 0xF0) >> 4), 4, '0', STR_PAD_LEFT); + if ($fourbit{0} == '1') { + $log_gain = -8 + bindec(substr($fourbit, 1)); + } else { + $log_gain = bindec(substr($fourbit, 1)); + } + $log_gain = ($log_gain + 1) * getid3_lib::RGADamplitude2dB(2); + + // The value of Y is a linear representation of a gain change of up to -6 dB. Y is considered to + // be an unsigned fractional integer, with a leading value of 1, or: 0.1 Y4 Y5 Y6 Y7 (base 2). Y can + // represent values between 0.111112 (or 31/32) and 0.100002 (or 1/2). Thus, Y can represent gain + // changes from -0.28 dB to -6.02 dB. + + $lin_gain = (16 + ($compre & 0x0F)) / 32; + + // The combination of X and Y values allows compr to indicate gain changes from + // 48.16 - 0.28 = +47.89 dB, to + // -42.14 - 6.02 = -48.16 dB. + + return $log_gain - $lin_gain; + } + + public static function roomTypeLookup($roomtyp) { + static $roomTypeLookup = array( + 0 => 'not indicated', + 1 => 'large room, X curve monitor', + 2 => 'small room, flat monitor', + 3 => 'reserved' + ); + return (isset($roomTypeLookup[$roomtyp]) ? $roomTypeLookup[$roomtyp] : false); + } + + public static function frameSizeLookup($frmsizecod, $fscod) { + $padding = (bool) ($frmsizecod % 2); + $framesizeid = floor($frmsizecod / 2); + + static $frameSizeLookup = array(); + if (empty($frameSizeLookup)) { + $frameSizeLookup = array ( + 0 => array(128, 138, 192), + 1 => array(40, 160, 174, 240), + 2 => array(48, 192, 208, 288), + 3 => array(56, 224, 242, 336), + 4 => array(64, 256, 278, 384), + 5 => array(80, 320, 348, 480), + 6 => array(96, 384, 416, 576), + 7 => array(112, 448, 486, 672), + 8 => array(128, 512, 556, 768), + 9 => array(160, 640, 696, 960), + 10 => array(192, 768, 834, 1152), + 11 => array(224, 896, 974, 1344), + 12 => array(256, 1024, 1114, 1536), + 13 => array(320, 1280, 1392, 1920), + 14 => array(384, 1536, 1670, 2304), + 15 => array(448, 1792, 1950, 2688), + 16 => array(512, 2048, 2228, 3072), + 17 => array(576, 2304, 2506, 3456), + 18 => array(640, 2560, 2786, 3840) + ); + } + if (($fscod == 1) && $padding) { + // frame lengths are padded by 1 word (16 bits) at 44100 + $frameSizeLookup[$frmsizecod] += 2; + } + return (isset($frameSizeLookup[$framesizeid][$fscod]) ? $frameSizeLookup[$framesizeid][$fscod] : false); + } + + public static function bitrateLookup($frmsizecod) { + $framesizeid = floor($frmsizecod / 2); + + static $bitrateLookup = array( + 0 => 32000, + 1 => 40000, + 2 => 48000, + 3 => 56000, + 4 => 64000, + 5 => 80000, + 6 => 96000, + 7 => 112000, + 8 => 128000, + 9 => 160000, + 10 => 192000, + 11 => 224000, + 12 => 256000, + 13 => 320000, + 14 => 384000, + 15 => 448000, + 16 => 512000, + 17 => 576000, + 18 => 640000 + ); + return (isset($bitrateLookup[$framesizeid]) ? $bitrateLookup[$framesizeid] : false); + } + + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio.dts.php b/extensions/TimedMediaHandler/libs/getid3/module.audio.dts.php new file mode 100644 index 00000000..1c6b36f9 --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio.dts.php @@ -0,0 +1,291 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio.dts.php // +// module for analyzing DTS Audio files // +// dependencies: NONE // +// // +///////////////////////////////////////////////////////////////// + + +/** +* @tutorial http://wiki.multimedia.cx/index.php?title=DTS +*/ + +class getid3_dts extends getid3_handler +{ + /** + * Default DTS syncword used in native .cpt or .dts formats + */ + const syncword = "\x7F\xFE\x80\x01"; + + private $readBinDataOffset = 0; + + /** + * Possible syncwords indicating bitstream encoding + */ + public static $syncwords = array( + 0 => "\x7F\xFE\x80\x01", // raw big-endian + 1 => "\xFE\x7F\x01\x80", // raw little-endian + 2 => "\x1F\xFF\xE8\x00", // 14-bit big-endian + 3 => "\xFF\x1F\x00\xE8"); // 14-bit little-endian + + public function Analyze() { + $info = &$this->getid3->info; + $info['fileformat'] = 'dts'; + + $this->fseek($info['avdataoffset']); + $DTSheader = $this->fread(20); // we only need 2 words magic + 6 words frame header, but these words may be normal 16-bit words OR 14-bit words with 2 highest bits set to zero, so 8 words can be either 8*16/8 = 16 bytes OR 8*16*(16/14)/8 = 18.3 bytes + + // check syncword + $sync = substr($DTSheader, 0, 4); + if (($encoding = array_search($sync, self::$syncwords)) !== false) { + + $info['dts']['raw']['magic'] = $sync; + $this->readBinDataOffset = 32; + + } elseif ($this->isDependencyFor('matroska')) { + + // Matroska contains DTS without syncword encoded as raw big-endian format + $encoding = 0; + $this->readBinDataOffset = 0; + + } else { + + unset($info['fileformat']); + return $this->error('Expecting "'.implode('| ', array_map('getid3_lib::PrintHexBytes', self::$syncwords)).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($sync).'"'); + + } + + // decode header + $fhBS = ''; + for ($word_offset = 0; $word_offset <= strlen($DTSheader); $word_offset += 2) { + switch ($encoding) { + case 0: // raw big-endian + $fhBS .= getid3_lib::BigEndian2Bin( substr($DTSheader, $word_offset, 2) ); + break; + case 1: // raw little-endian + $fhBS .= getid3_lib::BigEndian2Bin(strrev(substr($DTSheader, $word_offset, 2))); + break; + case 2: // 14-bit big-endian + $fhBS .= substr(getid3_lib::BigEndian2Bin( substr($DTSheader, $word_offset, 2) ), 2, 14); + break; + case 3: // 14-bit little-endian + $fhBS .= substr(getid3_lib::BigEndian2Bin(strrev(substr($DTSheader, $word_offset, 2))), 2, 14); + break; + } + } + + $info['dts']['raw']['frame_type'] = $this->readBinData($fhBS, 1); + $info['dts']['raw']['deficit_samples'] = $this->readBinData($fhBS, 5); + $info['dts']['flags']['crc_present'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['raw']['pcm_sample_blocks'] = $this->readBinData($fhBS, 7); + $info['dts']['raw']['frame_byte_size'] = $this->readBinData($fhBS, 14); + $info['dts']['raw']['channel_arrangement'] = $this->readBinData($fhBS, 6); + $info['dts']['raw']['sample_frequency'] = $this->readBinData($fhBS, 4); + $info['dts']['raw']['bitrate'] = $this->readBinData($fhBS, 5); + $info['dts']['flags']['embedded_downmix'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['flags']['dynamicrange'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['flags']['timestamp'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['flags']['auxdata'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['flags']['hdcd'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['raw']['extension_audio'] = $this->readBinData($fhBS, 3); + $info['dts']['flags']['extended_coding'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['flags']['audio_sync_insertion'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['raw']['lfe_effects'] = $this->readBinData($fhBS, 2); + $info['dts']['flags']['predictor_history'] = (bool) $this->readBinData($fhBS, 1); + if ($info['dts']['flags']['crc_present']) { + $info['dts']['raw']['crc16'] = $this->readBinData($fhBS, 16); + } + $info['dts']['flags']['mri_perfect_reconst'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['raw']['encoder_soft_version'] = $this->readBinData($fhBS, 4); + $info['dts']['raw']['copy_history'] = $this->readBinData($fhBS, 2); + $info['dts']['raw']['bits_per_sample'] = $this->readBinData($fhBS, 2); + $info['dts']['flags']['surround_es'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['flags']['front_sum_diff'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['flags']['surround_sum_diff'] = (bool) $this->readBinData($fhBS, 1); + $info['dts']['raw']['dialog_normalization'] = $this->readBinData($fhBS, 4); + + + $info['dts']['bitrate'] = self::bitrateLookup($info['dts']['raw']['bitrate']); + $info['dts']['bits_per_sample'] = self::bitPerSampleLookup($info['dts']['raw']['bits_per_sample']); + $info['dts']['sample_rate'] = self::sampleRateLookup($info['dts']['raw']['sample_frequency']); + $info['dts']['dialog_normalization'] = self::dialogNormalization($info['dts']['raw']['dialog_normalization'], $info['dts']['raw']['encoder_soft_version']); + $info['dts']['flags']['lossless'] = (($info['dts']['raw']['bitrate'] == 31) ? true : false); + $info['dts']['bitrate_mode'] = (($info['dts']['raw']['bitrate'] == 30) ? 'vbr' : 'cbr'); + $info['dts']['channels'] = self::numChannelsLookup($info['dts']['raw']['channel_arrangement']); + $info['dts']['channel_arrangement'] = self::channelArrangementLookup($info['dts']['raw']['channel_arrangement']); + + $info['audio']['dataformat'] = 'dts'; + $info['audio']['lossless'] = $info['dts']['flags']['lossless']; + $info['audio']['bitrate_mode'] = $info['dts']['bitrate_mode']; + $info['audio']['bits_per_sample'] = $info['dts']['bits_per_sample']; + $info['audio']['sample_rate'] = $info['dts']['sample_rate']; + $info['audio']['channels'] = $info['dts']['channels']; + $info['audio']['bitrate'] = $info['dts']['bitrate']; + if (isset($info['avdataend']) && !empty($info['dts']['bitrate']) && is_numeric($info['dts']['bitrate'])) { + $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) / ($info['dts']['bitrate'] / 8); + if (($encoding == 2) || ($encoding == 3)) { + // 14-bit data packed into 16-bit words, so the playtime is wrong because only (14/16) of the bytes in the data portion of the file are used at the specified bitrate + $info['playtime_seconds'] *= (14 / 16); + } + } + return true; + } + + private function readBinData($bin, $length) { + $data = substr($bin, $this->readBinDataOffset, $length); + $this->readBinDataOffset += $length; + + return bindec($data); + } + + public static function bitrateLookup($index) { + static $lookup = array( + 0 => 32000, + 1 => 56000, + 2 => 64000, + 3 => 96000, + 4 => 112000, + 5 => 128000, + 6 => 192000, + 7 => 224000, + 8 => 256000, + 9 => 320000, + 10 => 384000, + 11 => 448000, + 12 => 512000, + 13 => 576000, + 14 => 640000, + 15 => 768000, + 16 => 960000, + 17 => 1024000, + 18 => 1152000, + 19 => 1280000, + 20 => 1344000, + 21 => 1408000, + 22 => 1411200, + 23 => 1472000, + 24 => 1536000, + 25 => 1920000, + 26 => 2048000, + 27 => 3072000, + 28 => 3840000, + 29 => 'open', + 30 => 'variable', + 31 => 'lossless', + ); + return (isset($lookup[$index]) ? $lookup[$index] : false); + } + + public static function sampleRateLookup($index) { + static $lookup = array( + 0 => 'invalid', + 1 => 8000, + 2 => 16000, + 3 => 32000, + 4 => 'invalid', + 5 => 'invalid', + 6 => 11025, + 7 => 22050, + 8 => 44100, + 9 => 'invalid', + 10 => 'invalid', + 11 => 12000, + 12 => 24000, + 13 => 48000, + 14 => 'invalid', + 15 => 'invalid', + ); + return (isset($lookup[$index]) ? $lookup[$index] : false); + } + + public static function bitPerSampleLookup($index) { + static $lookup = array( + 0 => 16, + 1 => 20, + 2 => 24, + 3 => 24, + ); + return (isset($lookup[$index]) ? $lookup[$index] : false); + } + + public static function numChannelsLookup($index) { + switch ($index) { + case 0: + return 1; + break; + case 1: + case 2: + case 3: + case 4: + return 2; + break; + case 5: + case 6: + return 3; + break; + case 7: + case 8: + return 4; + break; + case 9: + return 5; + break; + case 10: + case 11: + case 12: + return 6; + break; + case 13: + return 7; + break; + case 14: + case 15: + return 8; + break; + } + return false; + } + + public static function channelArrangementLookup($index) { + static $lookup = array( + 0 => 'A', + 1 => 'A + B (dual mono)', + 2 => 'L + R (stereo)', + 3 => '(L+R) + (L-R) (sum-difference)', + 4 => 'LT + RT (left and right total)', + 5 => 'C + L + R', + 6 => 'L + R + S', + 7 => 'C + L + R + S', + 8 => 'L + R + SL + SR', + 9 => 'C + L + R + SL + SR', + 10 => 'CL + CR + L + R + SL + SR', + 11 => 'C + L + R+ LR + RR + OV', + 12 => 'CF + CR + LF + RF + LR + RR', + 13 => 'CL + C + CR + L + R + SL + SR', + 14 => 'CL + CR + L + R + SL1 + SL2 + SR1 + SR2', + 15 => 'CL + C+ CR + L + R + SL + S + SR', + ); + return (isset($lookup[$index]) ? $lookup[$index] : 'user-defined'); + } + + public static function dialogNormalization($index, $version) { + switch ($version) { + case 7: + return 0 - $index; + break; + case 6: + return 0 - 16 - $index; + break; + } + return false; + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio.flac.php b/extensions/TimedMediaHandler/libs/getid3/module.audio.flac.php new file mode 100644 index 00000000..6b9598c7 --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio.flac.php @@ -0,0 +1,442 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio.flac.php // +// module for analyzing FLAC and OggFLAC audio files // +// dependencies: module.audio.ogg.php // +// /// +///////////////////////////////////////////////////////////////// + + +getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, true); + +/** +* @tutorial http://flac.sourceforge.net/format.html +*/ +class getid3_flac extends getid3_handler +{ + const syncword = 'fLaC'; + + public function Analyze() { + $info = &$this->getid3->info; + + $this->fseek($info['avdataoffset']); + $StreamMarker = $this->fread(4); + if ($StreamMarker != self::syncword) { + return $this->error('Expecting "'.getid3_lib::PrintHexBytes(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($StreamMarker).'"'); + } + $info['fileformat'] = 'flac'; + $info['audio']['dataformat'] = 'flac'; + $info['audio']['bitrate_mode'] = 'vbr'; + $info['audio']['lossless'] = true; + + // parse flac container + return $this->parseMETAdata(); + } + + public function parseMETAdata() { + $info = &$this->getid3->info; + do { + $BlockOffset = $this->ftell(); + $BlockHeader = $this->fread(4); + $LBFBT = getid3_lib::BigEndian2Int(substr($BlockHeader, 0, 1)); + $LastBlockFlag = (bool) ($LBFBT & 0x80); + $BlockType = ($LBFBT & 0x7F); + $BlockLength = getid3_lib::BigEndian2Int(substr($BlockHeader, 1, 3)); + $BlockTypeText = self::metaBlockTypeLookup($BlockType); + + if (($BlockOffset + 4 + $BlockLength) > $info['avdataend']) { + $this->error('METADATA_BLOCK_HEADER.BLOCK_TYPE ('.$BlockTypeText.') at offset '.$BlockOffset.' extends beyond end of file'); + break; + } + if ($BlockLength < 1) { + $this->error('METADATA_BLOCK_HEADER.BLOCK_LENGTH ('.$BlockLength.') at offset '.$BlockOffset.' is invalid'); + break; + } + + $info['flac'][$BlockTypeText]['raw'] = array(); + $BlockTypeText_raw = &$info['flac'][$BlockTypeText]['raw']; + + $BlockTypeText_raw['offset'] = $BlockOffset; + $BlockTypeText_raw['last_meta_block'] = $LastBlockFlag; + $BlockTypeText_raw['block_type'] = $BlockType; + $BlockTypeText_raw['block_type_text'] = $BlockTypeText; + $BlockTypeText_raw['block_length'] = $BlockLength; + if ($BlockTypeText_raw['block_type'] != 0x06) { // do not read attachment data automatically + $BlockTypeText_raw['block_data'] = $this->fread($BlockLength); + } + + switch ($BlockTypeText) { + case 'STREAMINFO': // 0x00 + if (!$this->parseSTREAMINFO($BlockTypeText_raw['block_data'])) { + return false; + } + break; + + case 'PADDING': // 0x01 + unset($info['flac']['PADDING']); // ignore + break; + + case 'APPLICATION': // 0x02 + if (!$this->parseAPPLICATION($BlockTypeText_raw['block_data'])) { + return false; + } + break; + + case 'SEEKTABLE': // 0x03 + if (!$this->parseSEEKTABLE($BlockTypeText_raw['block_data'])) { + return false; + } + break; + + case 'VORBIS_COMMENT': // 0x04 + if (!$this->parseVORBIS_COMMENT($BlockTypeText_raw['block_data'])) { + return false; + } + break; + + case 'CUESHEET': // 0x05 + if (!$this->parseCUESHEET($BlockTypeText_raw['block_data'])) { + return false; + } + break; + + case 'PICTURE': // 0x06 + if (!$this->parsePICTURE()) { + return false; + } + break; + + default: + $this->warning('Unhandled METADATA_BLOCK_HEADER.BLOCK_TYPE ('.$BlockType.') at offset '.$BlockOffset); + } + + unset($info['flac'][$BlockTypeText]['raw']); + $info['avdataoffset'] = $this->ftell(); + } + while ($LastBlockFlag === false); + + // handle tags + if (!empty($info['flac']['VORBIS_COMMENT']['comments'])) { + $info['flac']['comments'] = $info['flac']['VORBIS_COMMENT']['comments']; + } + if (!empty($info['flac']['VORBIS_COMMENT']['vendor'])) { + $info['audio']['encoder'] = str_replace('reference ', '', $info['flac']['VORBIS_COMMENT']['vendor']); + } + + // copy attachments to 'comments' array if nesesary + if (isset($info['flac']['PICTURE']) && ($this->getid3->option_save_attachments !== getID3::ATTACHMENTS_NONE)) { + foreach ($info['flac']['PICTURE'] as $entry) { + if (!empty($entry['data'])) { + $info['flac']['comments']['picture'][] = array('image_mime'=>$entry['image_mime'], 'data'=>$entry['data']); + } + } + } + + if (isset($info['flac']['STREAMINFO'])) { + if (!$this->isDependencyFor('matroska')) { + $info['flac']['compressed_audio_bytes'] = $info['avdataend'] - $info['avdataoffset']; + } + $info['flac']['uncompressed_audio_bytes'] = $info['flac']['STREAMINFO']['samples_stream'] * $info['flac']['STREAMINFO']['channels'] * ($info['flac']['STREAMINFO']['bits_per_sample'] / 8); + if ($info['flac']['uncompressed_audio_bytes'] == 0) { + return $this->error('Corrupt FLAC file: uncompressed_audio_bytes == zero'); + } + if (!empty($info['flac']['compressed_audio_bytes'])) { + $info['flac']['compression_ratio'] = $info['flac']['compressed_audio_bytes'] / $info['flac']['uncompressed_audio_bytes']; + } + } + + // set md5_data_source - built into flac 0.5+ + if (isset($info['flac']['STREAMINFO']['audio_signature'])) { + + if ($info['flac']['STREAMINFO']['audio_signature'] === str_repeat("\x00", 16)) { + $this->warning('FLAC STREAMINFO.audio_signature is null (known issue with libOggFLAC)'); + } + else { + $info['md5_data_source'] = ''; + $md5 = $info['flac']['STREAMINFO']['audio_signature']; + for ($i = 0; $i < strlen($md5); $i++) { + $info['md5_data_source'] .= str_pad(dechex(ord($md5[$i])), 2, '00', STR_PAD_LEFT); + } + if (!preg_match('/^[0-9a-f]{32}$/', $info['md5_data_source'])) { + unset($info['md5_data_source']); + } + } + } + + if (isset($info['flac']['STREAMINFO']['bits_per_sample'])) { + $info['audio']['bits_per_sample'] = $info['flac']['STREAMINFO']['bits_per_sample']; + if ($info['audio']['bits_per_sample'] == 8) { + // special case + // must invert sign bit on all data bytes before MD5'ing to match FLAC's calculated value + // MD5sum calculates on unsigned bytes, but FLAC calculated MD5 on 8-bit audio data as signed + $this->warning('FLAC calculates MD5 data strangely on 8-bit audio, so the stored md5_data_source value will not match the decoded WAV file'); + } + } + + return true; + } + + private function parseSTREAMINFO($BlockData) { + $info = &$this->getid3->info; + + $info['flac']['STREAMINFO'] = array(); + $streaminfo = &$info['flac']['STREAMINFO']; + + $streaminfo['min_block_size'] = getid3_lib::BigEndian2Int(substr($BlockData, 0, 2)); + $streaminfo['max_block_size'] = getid3_lib::BigEndian2Int(substr($BlockData, 2, 2)); + $streaminfo['min_frame_size'] = getid3_lib::BigEndian2Int(substr($BlockData, 4, 3)); + $streaminfo['max_frame_size'] = getid3_lib::BigEndian2Int(substr($BlockData, 7, 3)); + + $SRCSBSS = getid3_lib::BigEndian2Bin(substr($BlockData, 10, 8)); + $streaminfo['sample_rate'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 0, 20)); + $streaminfo['channels'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 20, 3)) + 1; + $streaminfo['bits_per_sample'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 23, 5)) + 1; + $streaminfo['samples_stream'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 28, 36)); + + $streaminfo['audio_signature'] = substr($BlockData, 18, 16); + + if (!empty($streaminfo['sample_rate'])) { + + $info['audio']['bitrate_mode'] = 'vbr'; + $info['audio']['sample_rate'] = $streaminfo['sample_rate']; + $info['audio']['channels'] = $streaminfo['channels']; + $info['audio']['bits_per_sample'] = $streaminfo['bits_per_sample']; + $info['playtime_seconds'] = $streaminfo['samples_stream'] / $streaminfo['sample_rate']; + if ($info['playtime_seconds'] > 0) { + if (!$this->isDependencyFor('matroska')) { + $info['audio']['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds']; + } + else { + $this->warning('Cannot determine audio bitrate because total stream size is unknown'); + } + } + + } else { + return $this->error('Corrupt METAdata block: STREAMINFO'); + } + + return true; + } + + private function parseAPPLICATION($BlockData) { + $info = &$this->getid3->info; + + $ApplicationID = getid3_lib::BigEndian2Int(substr($BlockData, 0, 4)); + $info['flac']['APPLICATION'][$ApplicationID]['name'] = self::applicationIDLookup($ApplicationID); + $info['flac']['APPLICATION'][$ApplicationID]['data'] = substr($BlockData, 4); + + return true; + } + + private function parseSEEKTABLE($BlockData) { + $info = &$this->getid3->info; + + $offset = 0; + $BlockLength = strlen($BlockData); + $placeholderpattern = str_repeat("\xFF", 8); + while ($offset < $BlockLength) { + $SampleNumberString = substr($BlockData, $offset, 8); + $offset += 8; + if ($SampleNumberString == $placeholderpattern) { + + // placeholder point + getid3_lib::safe_inc($info['flac']['SEEKTABLE']['placeholders'], 1); + $offset += 10; + + } else { + + $SampleNumber = getid3_lib::BigEndian2Int($SampleNumberString); + $info['flac']['SEEKTABLE'][$SampleNumber]['offset'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8)); + $offset += 8; + $info['flac']['SEEKTABLE'][$SampleNumber]['samples'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 2)); + $offset += 2; + + } + } + + return true; + } + + private function parseVORBIS_COMMENT($BlockData) { + $info = &$this->getid3->info; + + $getid3_ogg = new getid3_ogg($this->getid3); + if ($this->isDependencyFor('matroska')) { + $getid3_ogg->setStringMode($this->data_string); + } + $getid3_ogg->ParseVorbisComments(); + if (isset($info['ogg'])) { + unset($info['ogg']['comments_raw']); + $info['flac']['VORBIS_COMMENT'] = $info['ogg']; + unset($info['ogg']); + } + + unset($getid3_ogg); + + return true; + } + + private function parseCUESHEET($BlockData) { + $info = &$this->getid3->info; + $offset = 0; + $info['flac']['CUESHEET']['media_catalog_number'] = trim(substr($BlockData, $offset, 128), "\0"); + $offset += 128; + $info['flac']['CUESHEET']['lead_in_samples'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8)); + $offset += 8; + $info['flac']['CUESHEET']['flags']['is_cd'] = (bool) (getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1)) & 0x80); + $offset += 1; + + $offset += 258; // reserved + + $info['flac']['CUESHEET']['number_tracks'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1)); + $offset += 1; + + for ($track = 0; $track < $info['flac']['CUESHEET']['number_tracks']; $track++) { + $TrackSampleOffset = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8)); + $offset += 8; + $TrackNumber = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1)); + $offset += 1; + + $info['flac']['CUESHEET']['tracks'][$TrackNumber]['sample_offset'] = $TrackSampleOffset; + + $info['flac']['CUESHEET']['tracks'][$TrackNumber]['isrc'] = substr($BlockData, $offset, 12); + $offset += 12; + + $TrackFlagsRaw = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1)); + $offset += 1; + $info['flac']['CUESHEET']['tracks'][$TrackNumber]['flags']['is_audio'] = (bool) ($TrackFlagsRaw & 0x80); + $info['flac']['CUESHEET']['tracks'][$TrackNumber]['flags']['pre_emphasis'] = (bool) ($TrackFlagsRaw & 0x40); + + $offset += 13; // reserved + + $info['flac']['CUESHEET']['tracks'][$TrackNumber]['index_points'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1)); + $offset += 1; + + for ($index = 0; $index < $info['flac']['CUESHEET']['tracks'][$TrackNumber]['index_points']; $index++) { + $IndexSampleOffset = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8)); + $offset += 8; + $IndexNumber = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1)); + $offset += 1; + + $offset += 3; // reserved + + $info['flac']['CUESHEET']['tracks'][$TrackNumber]['indexes'][$IndexNumber] = $IndexSampleOffset; + } + } + + return true; + } + + /** + * Parse METADATA_BLOCK_PICTURE flac structure and extract attachment + * External usage: audio.ogg + */ + public function parsePICTURE() { + $info = &$this->getid3->info; + + $picture['typeid'] = getid3_lib::BigEndian2Int($this->fread(4)); + $picture['type'] = self::pictureTypeLookup($picture['typeid']); + $picture['image_mime'] = $this->fread(getid3_lib::BigEndian2Int($this->fread(4))); + $descr_length = getid3_lib::BigEndian2Int($this->fread(4)); + if ($descr_length) { + $picture['description'] = $this->fread($descr_length); + } + $picture['width'] = getid3_lib::BigEndian2Int($this->fread(4)); + $picture['height'] = getid3_lib::BigEndian2Int($this->fread(4)); + $picture['color_depth'] = getid3_lib::BigEndian2Int($this->fread(4)); + $picture['colors_indexed'] = getid3_lib::BigEndian2Int($this->fread(4)); + $data_length = getid3_lib::BigEndian2Int($this->fread(4)); + + if ($picture['image_mime'] == '-->') { + $picture['data'] = $this->fread($data_length); + } else { + $picture['data'] = $this->saveAttachment( + str_replace('/', '_', $picture['type']).'_'.$this->ftell(), + $this->ftell(), + $data_length, + $picture['image_mime']); + } + + $info['flac']['PICTURE'][] = $picture; + + return true; + } + + public static function metaBlockTypeLookup($blocktype) { + static $lookup = array( + 0 => 'STREAMINFO', + 1 => 'PADDING', + 2 => 'APPLICATION', + 3 => 'SEEKTABLE', + 4 => 'VORBIS_COMMENT', + 5 => 'CUESHEET', + 6 => 'PICTURE', + ); + return (isset($lookup[$blocktype]) ? $lookup[$blocktype] : 'reserved'); + } + + public static function applicationIDLookup($applicationid) { + // http://flac.sourceforge.net/id.html + static $lookup = array( + 0x41544348 => 'FlacFile', // "ATCH" + 0x42534F4C => 'beSolo', // "BSOL" + 0x42554753 => 'Bugs Player', // "BUGS" + 0x43756573 => 'GoldWave cue points (specification)', // "Cues" + 0x46696361 => 'CUE Splitter', // "Fica" + 0x46746F6C => 'flac-tools', // "Ftol" + 0x4D4F5442 => 'MOTB MetaCzar', // "MOTB" + 0x4D505345 => 'MP3 Stream Editor', // "MPSE" + 0x4D754D4C => 'MusicML: Music Metadata Language', // "MuML" + 0x52494646 => 'Sound Devices RIFF chunk storage', // "RIFF" + 0x5346464C => 'Sound Font FLAC', // "SFFL" + 0x534F4E59 => 'Sony Creative Software', // "SONY" + 0x5351455A => 'flacsqueeze', // "SQEZ" + 0x54745776 => 'TwistedWave', // "TtWv" + 0x55495453 => 'UITS Embedding tools', // "UITS" + 0x61696666 => 'FLAC AIFF chunk storage', // "aiff" + 0x696D6167 => 'flac-image application for storing arbitrary files in APPLICATION metadata blocks', // "imag" + 0x7065656D => 'Parseable Embedded Extensible Metadata (specification)', // "peem" + 0x71667374 => 'QFLAC Studio', // "qfst" + 0x72696666 => 'FLAC RIFF chunk storage', // "riff" + 0x74756E65 => 'TagTuner', // "tune" + 0x78626174 => 'XBAT', // "xbat" + 0x786D6364 => 'xmcd', // "xmcd" + ); + return (isset($lookup[$applicationid]) ? $lookup[$applicationid] : 'reserved'); + } + + public static function pictureTypeLookup($type_id) { + static $lookup = array ( + 0 => 'Other', + 1 => '32x32 pixels \'file icon\' (PNG only)', + 2 => 'Other file icon', + 3 => 'Cover (front)', + 4 => 'Cover (back)', + 5 => 'Leaflet page', + 6 => 'Media (e.g. label side of CD)', + 7 => 'Lead artist/lead performer/soloist', + 8 => 'Artist/performer', + 9 => 'Conductor', + 10 => 'Band/Orchestra', + 11 => 'Composer', + 12 => 'Lyricist/text writer', + 13 => 'Recording Location', + 14 => 'During recording', + 15 => 'During performance', + 16 => 'Movie/video screen capture', + 17 => 'A bright coloured fish', + 18 => 'Illustration', + 19 => 'Band/artist logotype', + 20 => 'Publisher/Studio logotype', + ); + return (isset($lookup[$type_id]) ? $lookup[$type_id] : 'reserved'); + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio.mp3.php b/extensions/TimedMediaHandler/libs/getid3/module.audio.mp3.php new file mode 100644 index 00000000..e6ffea94 --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio.mp3.php @@ -0,0 +1,2009 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio.mp3.php // +// module for analyzing MP3 files // +// dependencies: NONE // +// /// +///////////////////////////////////////////////////////////////// + + +// number of frames to scan to determine if MPEG-audio sequence is valid +// Lower this number to 5-20 for faster scanning +// Increase this number to 50+ for most accurate detection of valid VBR/CBR +// mpeg-audio streams +define('GETID3_MP3_VALID_CHECK_FRAMES', 35); + + +class getid3_mp3 extends getid3_handler +{ + + public $allow_bruteforce = false; // forces getID3() to scan the file byte-by-byte and log all the valid audio frame headers - extremely slow, unrecommended, but may provide data from otherwise-unusuable files + + public function Analyze() { + $info = &$this->getid3->info; + + $initialOffset = $info['avdataoffset']; + + if (!$this->getOnlyMPEGaudioInfo($info['avdataoffset'])) { + if ($this->allow_bruteforce) { + $info['error'][] = 'Rescanning file in BruteForce mode'; + $this->getOnlyMPEGaudioInfoBruteForce($this->getid3->fp, $info); + } + } + + + if (isset($info['mpeg']['audio']['bitrate_mode'])) { + $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']); + } + + if (((isset($info['id3v2']['headerlength']) && ($info['avdataoffset'] > $info['id3v2']['headerlength'])) || (!isset($info['id3v2']) && ($info['avdataoffset'] > 0) && ($info['avdataoffset'] != $initialOffset)))) { + + $synchoffsetwarning = 'Unknown data before synch '; + if (isset($info['id3v2']['headerlength'])) { + $synchoffsetwarning .= '(ID3v2 header ends at '.$info['id3v2']['headerlength'].', then '.($info['avdataoffset'] - $info['id3v2']['headerlength']).' bytes garbage, '; + } elseif ($initialOffset > 0) { + $synchoffsetwarning .= '(should be at '.$initialOffset.', '; + } else { + $synchoffsetwarning .= '(should be at beginning of file, '; + } + $synchoffsetwarning .= 'synch detected at '.$info['avdataoffset'].')'; + if (isset($info['audio']['bitrate_mode']) && ($info['audio']['bitrate_mode'] == 'cbr')) { + + if (!empty($info['id3v2']['headerlength']) && (($info['avdataoffset'] - $info['id3v2']['headerlength']) == $info['mpeg']['audio']['framelength'])) { + + $synchoffsetwarning .= '. This is a known problem with some versions of LAME (3.90-3.92) DLL in CBR mode.'; + $info['audio']['codec'] = 'LAME'; + $CurrentDataLAMEversionString = 'LAME3.'; + + } elseif (empty($info['id3v2']['headerlength']) && ($info['avdataoffset'] == $info['mpeg']['audio']['framelength'])) { + + $synchoffsetwarning .= '. This is a known problem with some versions of LAME (3.90 - 3.92) DLL in CBR mode.'; + $info['audio']['codec'] = 'LAME'; + $CurrentDataLAMEversionString = 'LAME3.'; + + } + + } + $info['warning'][] = $synchoffsetwarning; + + } + + if (isset($info['mpeg']['audio']['LAME'])) { + $info['audio']['codec'] = 'LAME'; + if (!empty($info['mpeg']['audio']['LAME']['long_version'])) { + $info['audio']['encoder'] = rtrim($info['mpeg']['audio']['LAME']['long_version'], "\x00"); + } elseif (!empty($info['mpeg']['audio']['LAME']['short_version'])) { + $info['audio']['encoder'] = rtrim($info['mpeg']['audio']['LAME']['short_version'], "\x00"); + } + } + + $CurrentDataLAMEversionString = (!empty($CurrentDataLAMEversionString) ? $CurrentDataLAMEversionString : (isset($info['audio']['encoder']) ? $info['audio']['encoder'] : '')); + if (!empty($CurrentDataLAMEversionString) && (substr($CurrentDataLAMEversionString, 0, 6) == 'LAME3.') && !preg_match('[0-9\)]', substr($CurrentDataLAMEversionString, -1))) { + // a version number of LAME that does not end with a number like "LAME3.92" + // or with a closing parenthesis like "LAME3.88 (alpha)" + // or a version of LAME with the LAMEtag-not-filled-in-DLL-mode bug (3.90-3.92) + + // not sure what the actual last frame length will be, but will be less than or equal to 1441 + $PossiblyLongerLAMEversion_FrameLength = 1441; + + // Not sure what version of LAME this is - look in padding of last frame for longer version string + $PossibleLAMEversionStringOffset = $info['avdataend'] - $PossiblyLongerLAMEversion_FrameLength; + fseek($this->getid3->fp, $PossibleLAMEversionStringOffset); + $PossiblyLongerLAMEversion_Data = fread($this->getid3->fp, $PossiblyLongerLAMEversion_FrameLength); + switch (substr($CurrentDataLAMEversionString, -1)) { + case 'a': + case 'b': + // "LAME3.94a" will have a longer version string of "LAME3.94 (alpha)" for example + // need to trim off "a" to match longer string + $CurrentDataLAMEversionString = substr($CurrentDataLAMEversionString, 0, -1); + break; + } + if (($PossiblyLongerLAMEversion_String = strstr($PossiblyLongerLAMEversion_Data, $CurrentDataLAMEversionString)) !== false) { + if (substr($PossiblyLongerLAMEversion_String, 0, strlen($CurrentDataLAMEversionString)) == $CurrentDataLAMEversionString) { + $PossiblyLongerLAMEversion_NewString = substr($PossiblyLongerLAMEversion_String, 0, strspn($PossiblyLongerLAMEversion_String, 'LAME0123456789., (abcdefghijklmnopqrstuvwxyzJFSOND)')); //"LAME3.90.3" "LAME3.87 (beta 1, Sep 27 2000)" "LAME3.88 (beta)" + if (empty($info['audio']['encoder']) || (strlen($PossiblyLongerLAMEversion_NewString) > strlen($info['audio']['encoder']))) { + $info['audio']['encoder'] = $PossiblyLongerLAMEversion_NewString; + } + } + } + } + if (!empty($info['audio']['encoder'])) { + $info['audio']['encoder'] = rtrim($info['audio']['encoder'], "\x00 "); + } + + switch (isset($info['mpeg']['audio']['layer']) ? $info['mpeg']['audio']['layer'] : '') { + case 1: + case 2: + $info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer']; + break; + } + if (isset($info['fileformat']) && ($info['fileformat'] == 'mp3')) { + switch ($info['audio']['dataformat']) { + case 'mp1': + case 'mp2': + case 'mp3': + $info['fileformat'] = $info['audio']['dataformat']; + break; + + default: + $info['warning'][] = 'Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$info['audio']['dataformat'].'"'; + break; + } + } + + if (empty($info['fileformat'])) { + unset($info['fileformat']); + unset($info['audio']['bitrate_mode']); + unset($info['avdataoffset']); + unset($info['avdataend']); + return false; + } + + $info['mime_type'] = 'audio/mpeg'; + $info['audio']['lossless'] = false; + + // Calculate playtime + if (!isset($info['playtime_seconds']) && isset($info['audio']['bitrate']) && ($info['audio']['bitrate'] > 0)) { + $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['audio']['bitrate']; + } + + $info['audio']['encoder_options'] = $this->GuessEncoderOptions(); + + return true; + } + + + public function GuessEncoderOptions() { + // shortcuts + $info = &$this->getid3->info; + if (!empty($info['mpeg']['audio'])) { + $thisfile_mpeg_audio = &$info['mpeg']['audio']; + if (!empty($thisfile_mpeg_audio['LAME'])) { + $thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME']; + } + } + + $encoder_options = ''; + static $NamedPresetBitrates = array(16, 24, 40, 56, 112, 128, 160, 192, 256); + + if (isset($thisfile_mpeg_audio['VBR_method']) && ($thisfile_mpeg_audio['VBR_method'] == 'Fraunhofer') && !empty($thisfile_mpeg_audio['VBR_quality'])) { + + $encoder_options = 'VBR q'.$thisfile_mpeg_audio['VBR_quality']; + + } elseif (!empty($thisfile_mpeg_audio_lame['preset_used']) && (!in_array($thisfile_mpeg_audio_lame['preset_used_id'], $NamedPresetBitrates))) { + + $encoder_options = $thisfile_mpeg_audio_lame['preset_used']; + + } elseif (!empty($thisfile_mpeg_audio_lame['vbr_quality'])) { + + static $KnownEncoderValues = array(); + if (empty($KnownEncoderValues)) { + + //$KnownEncoderValues[abrbitrate_minbitrate][vbr_quality][raw_vbr_method][raw_noise_shaping][raw_stereo_mode][ath_type][lowpass_frequency] = 'preset name'; + $KnownEncoderValues[0xFF][58][1][1][3][2][20500] = '--alt-preset insane'; // 3.90, 3.90.1, 3.92 + $KnownEncoderValues[0xFF][58][1][1][3][2][20600] = '--alt-preset insane'; // 3.90.2, 3.90.3, 3.91 + $KnownEncoderValues[0xFF][57][1][1][3][4][20500] = '--alt-preset insane'; // 3.94, 3.95 + $KnownEncoderValues['**'][78][3][2][3][2][19500] = '--alt-preset extreme'; // 3.90, 3.90.1, 3.92 + $KnownEncoderValues['**'][78][3][2][3][2][19600] = '--alt-preset extreme'; // 3.90.2, 3.91 + $KnownEncoderValues['**'][78][3][1][3][2][19600] = '--alt-preset extreme'; // 3.90.3 + $KnownEncoderValues['**'][78][4][2][3][2][19500] = '--alt-preset fast extreme'; // 3.90, 3.90.1, 3.92 + $KnownEncoderValues['**'][78][4][2][3][2][19600] = '--alt-preset fast extreme'; // 3.90.2, 3.90.3, 3.91 + $KnownEncoderValues['**'][78][3][2][3][4][19000] = '--alt-preset standard'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92 + $KnownEncoderValues['**'][78][3][1][3][4][19000] = '--alt-preset standard'; // 3.90.3 + $KnownEncoderValues['**'][78][4][2][3][4][19000] = '--alt-preset fast standard'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92 + $KnownEncoderValues['**'][78][4][1][3][4][19000] = '--alt-preset fast standard'; // 3.90.3 + $KnownEncoderValues['**'][88][4][1][3][3][19500] = '--r3mix'; // 3.90, 3.90.1, 3.92 + $KnownEncoderValues['**'][88][4][1][3][3][19600] = '--r3mix'; // 3.90.2, 3.90.3, 3.91 + $KnownEncoderValues['**'][67][4][1][3][4][18000] = '--r3mix'; // 3.94, 3.95 + $KnownEncoderValues['**'][68][3][2][3][4][18000] = '--alt-preset medium'; // 3.90.3 + $KnownEncoderValues['**'][68][4][2][3][4][18000] = '--alt-preset fast medium'; // 3.90.3 + + $KnownEncoderValues[0xFF][99][1][1][1][2][0] = '--preset studio'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92 + $KnownEncoderValues[0xFF][58][2][1][3][2][20600] = '--preset studio'; // 3.90.3, 3.93.1 + $KnownEncoderValues[0xFF][58][2][1][3][2][20500] = '--preset studio'; // 3.93 + $KnownEncoderValues[0xFF][57][2][1][3][4][20500] = '--preset studio'; // 3.94, 3.95 + $KnownEncoderValues[0xC0][88][1][1][1][2][0] = '--preset cd'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92 + $KnownEncoderValues[0xC0][58][2][2][3][2][19600] = '--preset cd'; // 3.90.3, 3.93.1 + $KnownEncoderValues[0xC0][58][2][2][3][2][19500] = '--preset cd'; // 3.93 + $KnownEncoderValues[0xC0][57][2][1][3][4][19500] = '--preset cd'; // 3.94, 3.95 + $KnownEncoderValues[0xA0][78][1][1][3][2][18000] = '--preset hifi'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92 + $KnownEncoderValues[0xA0][58][2][2][3][2][18000] = '--preset hifi'; // 3.90.3, 3.93, 3.93.1 + $KnownEncoderValues[0xA0][57][2][1][3][4][18000] = '--preset hifi'; // 3.94, 3.95 + $KnownEncoderValues[0x80][67][1][1][3][2][18000] = '--preset tape'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92 + $KnownEncoderValues[0x80][67][1][1][3][2][15000] = '--preset radio'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92 + $KnownEncoderValues[0x70][67][1][1][3][2][15000] = '--preset fm'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92 + $KnownEncoderValues[0x70][58][2][2][3][2][16000] = '--preset tape/radio/fm'; // 3.90.3, 3.93, 3.93.1 + $KnownEncoderValues[0x70][57][2][1][3][4][16000] = '--preset tape/radio/fm'; // 3.94, 3.95 + $KnownEncoderValues[0x38][58][2][2][0][2][10000] = '--preset voice'; // 3.90.3, 3.93, 3.93.1 + $KnownEncoderValues[0x38][57][2][1][0][4][15000] = '--preset voice'; // 3.94, 3.95 + $KnownEncoderValues[0x38][57][2][1][0][4][16000] = '--preset voice'; // 3.94a14 + $KnownEncoderValues[0x28][65][1][1][0][2][7500] = '--preset mw-us'; // 3.90, 3.90.1, 3.92 + $KnownEncoderValues[0x28][65][1][1][0][2][7600] = '--preset mw-us'; // 3.90.2, 3.91 + $KnownEncoderValues[0x28][58][2][2][0][2][7000] = '--preset mw-us'; // 3.90.3, 3.93, 3.93.1 + $KnownEncoderValues[0x28][57][2][1][0][4][10500] = '--preset mw-us'; // 3.94, 3.95 + $KnownEncoderValues[0x28][57][2][1][0][4][11200] = '--preset mw-us'; // 3.94a14 + $KnownEncoderValues[0x28][57][2][1][0][4][8800] = '--preset mw-us'; // 3.94a15 + $KnownEncoderValues[0x18][58][2][2][0][2][4000] = '--preset phon+/lw/mw-eu/sw'; // 3.90.3, 3.93.1 + $KnownEncoderValues[0x18][58][2][2][0][2][3900] = '--preset phon+/lw/mw-eu/sw'; // 3.93 + $KnownEncoderValues[0x18][57][2][1][0][4][5900] = '--preset phon+/lw/mw-eu/sw'; // 3.94, 3.95 + $KnownEncoderValues[0x18][57][2][1][0][4][6200] = '--preset phon+/lw/mw-eu/sw'; // 3.94a14 + $KnownEncoderValues[0x18][57][2][1][0][4][3200] = '--preset phon+/lw/mw-eu/sw'; // 3.94a15 + $KnownEncoderValues[0x10][58][2][2][0][2][3800] = '--preset phone'; // 3.90.3, 3.93.1 + $KnownEncoderValues[0x10][58][2][2][0][2][3700] = '--preset phone'; // 3.93 + $KnownEncoderValues[0x10][57][2][1][0][4][5600] = '--preset phone'; // 3.94, 3.95 + } + + if (isset($KnownEncoderValues[$thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate']][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']])) { + + $encoder_options = $KnownEncoderValues[$thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate']][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']]; + + } elseif (isset($KnownEncoderValues['**'][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']])) { + + $encoder_options = $KnownEncoderValues['**'][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']]; + + } elseif ($info['audio']['bitrate_mode'] == 'vbr') { + + // http://gabriel.mp3-tech.org/mp3infotag.html + // int Quality = (100 - 10 * gfp->VBR_q - gfp->quality)h + + + $LAME_V_value = 10 - ceil($thisfile_mpeg_audio_lame['vbr_quality'] / 10); + $LAME_q_value = 100 - $thisfile_mpeg_audio_lame['vbr_quality'] - ($LAME_V_value * 10); + $encoder_options = '-V'.$LAME_V_value.' -q'.$LAME_q_value; + + } elseif ($info['audio']['bitrate_mode'] == 'cbr') { + + $encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000); + + } else { + + $encoder_options = strtoupper($info['audio']['bitrate_mode']); + + } + + } elseif (!empty($thisfile_mpeg_audio_lame['bitrate_abr'])) { + + $encoder_options = 'ABR'.$thisfile_mpeg_audio_lame['bitrate_abr']; + + } elseif (!empty($info['audio']['bitrate'])) { + + if ($info['audio']['bitrate_mode'] == 'cbr') { + $encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000); + } else { + $encoder_options = strtoupper($info['audio']['bitrate_mode']); + } + + } + if (!empty($thisfile_mpeg_audio_lame['bitrate_min'])) { + $encoder_options .= ' -b'.$thisfile_mpeg_audio_lame['bitrate_min']; + } + + if (!empty($thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']) || !empty($thisfile_mpeg_audio_lame['encoding_flags']['nogap_next'])) { + $encoder_options .= ' --nogap'; + } + + if (!empty($thisfile_mpeg_audio_lame['lowpass_frequency'])) { + $ExplodedOptions = explode(' ', $encoder_options, 4); + if ($ExplodedOptions[0] == '--r3mix') { + $ExplodedOptions[1] = 'r3mix'; + } + switch ($ExplodedOptions[0]) { + case '--preset': + case '--alt-preset': + case '--r3mix': + if ($ExplodedOptions[1] == 'fast') { + $ExplodedOptions[1] .= ' '.$ExplodedOptions[2]; + } + switch ($ExplodedOptions[1]) { + case 'portable': + case 'medium': + case 'standard': + case 'extreme': + case 'insane': + case 'fast portable': + case 'fast medium': + case 'fast standard': + case 'fast extreme': + case 'fast insane': + case 'r3mix': + static $ExpectedLowpass = array( + 'insane|20500' => 20500, + 'insane|20600' => 20600, // 3.90.2, 3.90.3, 3.91 + 'medium|18000' => 18000, + 'fast medium|18000' => 18000, + 'extreme|19500' => 19500, // 3.90, 3.90.1, 3.92, 3.95 + 'extreme|19600' => 19600, // 3.90.2, 3.90.3, 3.91, 3.93.1 + 'fast extreme|19500' => 19500, // 3.90, 3.90.1, 3.92, 3.95 + 'fast extreme|19600' => 19600, // 3.90.2, 3.90.3, 3.91, 3.93.1 + 'standard|19000' => 19000, + 'fast standard|19000' => 19000, + 'r3mix|19500' => 19500, // 3.90, 3.90.1, 3.92 + 'r3mix|19600' => 19600, // 3.90.2, 3.90.3, 3.91 + 'r3mix|18000' => 18000, // 3.94, 3.95 + ); + if (!isset($ExpectedLowpass[$ExplodedOptions[1].'|'.$thisfile_mpeg_audio_lame['lowpass_frequency']]) && ($thisfile_mpeg_audio_lame['lowpass_frequency'] < 22050) && (round($thisfile_mpeg_audio_lame['lowpass_frequency'] / 1000) < round($thisfile_mpeg_audio['sample_rate'] / 2000))) { + $encoder_options .= ' --lowpass '.$thisfile_mpeg_audio_lame['lowpass_frequency']; + } + break; + + default: + break; + } + break; + } + } + + if (isset($thisfile_mpeg_audio_lame['raw']['source_sample_freq'])) { + if (($thisfile_mpeg_audio['sample_rate'] == 44100) && ($thisfile_mpeg_audio_lame['raw']['source_sample_freq'] != 1)) { + $encoder_options .= ' --resample 44100'; + } elseif (($thisfile_mpeg_audio['sample_rate'] == 48000) && ($thisfile_mpeg_audio_lame['raw']['source_sample_freq'] != 2)) { + $encoder_options .= ' --resample 48000'; + } elseif ($thisfile_mpeg_audio['sample_rate'] < 44100) { + switch ($thisfile_mpeg_audio_lame['raw']['source_sample_freq']) { + case 0: // <= 32000 + // may or may not be same as source frequency - ignore + break; + case 1: // 44100 + case 2: // 48000 + case 3: // 48000+ + $ExplodedOptions = explode(' ', $encoder_options, 4); + switch ($ExplodedOptions[0]) { + case '--preset': + case '--alt-preset': + switch ($ExplodedOptions[1]) { + case 'fast': + case 'portable': + case 'medium': + case 'standard': + case 'extreme': + case 'insane': + $encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate']; + break; + + default: + static $ExpectedResampledRate = array( + 'phon+/lw/mw-eu/sw|16000' => 16000, + 'mw-us|24000' => 24000, // 3.95 + 'mw-us|32000' => 32000, // 3.93 + 'mw-us|16000' => 16000, // 3.92 + 'phone|16000' => 16000, + 'phone|11025' => 11025, // 3.94a15 + 'radio|32000' => 32000, // 3.94a15 + 'fm/radio|32000' => 32000, // 3.92 + 'fm|32000' => 32000, // 3.90 + 'voice|32000' => 32000); + if (!isset($ExpectedResampledRate[$ExplodedOptions[1].'|'.$thisfile_mpeg_audio['sample_rate']])) { + $encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate']; + } + break; + } + break; + + case '--r3mix': + default: + $encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate']; + break; + } + break; + } + } + } + if (empty($encoder_options) && !empty($info['audio']['bitrate']) && !empty($info['audio']['bitrate_mode'])) { + //$encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000); + $encoder_options = strtoupper($info['audio']['bitrate_mode']); + } + + return $encoder_options; + } + + + public function decodeMPEGaudioHeader($offset, &$info, $recursivesearch=true, $ScanAsCBR=false, $FastMPEGheaderScan=false) { + static $MPEGaudioVersionLookup; + static $MPEGaudioLayerLookup; + static $MPEGaudioBitrateLookup; + static $MPEGaudioFrequencyLookup; + static $MPEGaudioChannelModeLookup; + static $MPEGaudioModeExtensionLookup; + static $MPEGaudioEmphasisLookup; + if (empty($MPEGaudioVersionLookup)) { + $MPEGaudioVersionLookup = self::MPEGaudioVersionArray(); + $MPEGaudioLayerLookup = self::MPEGaudioLayerArray(); + $MPEGaudioBitrateLookup = self::MPEGaudioBitrateArray(); + $MPEGaudioFrequencyLookup = self::MPEGaudioFrequencyArray(); + $MPEGaudioChannelModeLookup = self::MPEGaudioChannelModeArray(); + $MPEGaudioModeExtensionLookup = self::MPEGaudioModeExtensionArray(); + $MPEGaudioEmphasisLookup = self::MPEGaudioEmphasisArray(); + } + + if (fseek($this->getid3->fp, $offset, SEEK_SET) != 0) { + $info['error'][] = 'decodeMPEGaudioHeader() failed to seek to next offset at '.$offset; + return false; + } + //$headerstring = fread($this->getid3->fp, 1441); // worst-case max length = 32kHz @ 320kbps layer 3 = 1441 bytes/frame + $headerstring = fread($this->getid3->fp, 226); // LAME header at offset 36 + 190 bytes of Xing/LAME data + + // MP3 audio frame structure: + // $aa $aa $aa $aa [$bb $bb] $cc... + // where $aa..$aa is the four-byte mpeg-audio header (below) + // $bb $bb is the optional 2-byte CRC + // and $cc... is the audio data + + $head4 = substr($headerstring, 0, 4); + + static $MPEGaudioHeaderDecodeCache = array(); + if (isset($MPEGaudioHeaderDecodeCache[$head4])) { + $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4]; + } else { + $MPEGheaderRawArray = self::MPEGaudioHeaderDecode($head4); + $MPEGaudioHeaderDecodeCache[$head4] = $MPEGheaderRawArray; + } + + static $MPEGaudioHeaderValidCache = array(); + if (!isset($MPEGaudioHeaderValidCache[$head4])) { // Not in cache + //$MPEGaudioHeaderValidCache[$head4] = self::MPEGaudioHeaderValid($MPEGheaderRawArray, false, true); // allow badly-formatted freeformat (from LAME 3.90 - 3.93.1) + $MPEGaudioHeaderValidCache[$head4] = self::MPEGaudioHeaderValid($MPEGheaderRawArray, false, false); + } + + // shortcut + if (!isset($info['mpeg']['audio'])) { + $info['mpeg']['audio'] = array(); + } + $thisfile_mpeg_audio = &$info['mpeg']['audio']; + + + if ($MPEGaudioHeaderValidCache[$head4]) { + $thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray; + } else { + $info['error'][] = 'Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset; + return false; + } + + if (!$FastMPEGheaderScan) { + $thisfile_mpeg_audio['version'] = $MPEGaudioVersionLookup[$thisfile_mpeg_audio['raw']['version']]; + $thisfile_mpeg_audio['layer'] = $MPEGaudioLayerLookup[$thisfile_mpeg_audio['raw']['layer']]; + + $thisfile_mpeg_audio['channelmode'] = $MPEGaudioChannelModeLookup[$thisfile_mpeg_audio['raw']['channelmode']]; + $thisfile_mpeg_audio['channels'] = (($thisfile_mpeg_audio['channelmode'] == 'mono') ? 1 : 2); + $thisfile_mpeg_audio['sample_rate'] = $MPEGaudioFrequencyLookup[$thisfile_mpeg_audio['version']][$thisfile_mpeg_audio['raw']['sample_rate']]; + $thisfile_mpeg_audio['protection'] = !$thisfile_mpeg_audio['raw']['protection']; + $thisfile_mpeg_audio['private'] = (bool) $thisfile_mpeg_audio['raw']['private']; + $thisfile_mpeg_audio['modeextension'] = $MPEGaudioModeExtensionLookup[$thisfile_mpeg_audio['layer']][$thisfile_mpeg_audio['raw']['modeextension']]; + $thisfile_mpeg_audio['copyright'] = (bool) $thisfile_mpeg_audio['raw']['copyright']; + $thisfile_mpeg_audio['original'] = (bool) $thisfile_mpeg_audio['raw']['original']; + $thisfile_mpeg_audio['emphasis'] = $MPEGaudioEmphasisLookup[$thisfile_mpeg_audio['raw']['emphasis']]; + + $info['audio']['channels'] = $thisfile_mpeg_audio['channels']; + $info['audio']['sample_rate'] = $thisfile_mpeg_audio['sample_rate']; + + if ($thisfile_mpeg_audio['protection']) { + $thisfile_mpeg_audio['crc'] = getid3_lib::BigEndian2Int(substr($headerstring, 4, 2)); + } + } + + if ($thisfile_mpeg_audio['raw']['bitrate'] == 15) { + // http://www.hydrogenaudio.org/?act=ST&f=16&t=9682&st=0 + $info['warning'][] = 'Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1'; + $thisfile_mpeg_audio['raw']['bitrate'] = 0; + } + $thisfile_mpeg_audio['padding'] = (bool) $thisfile_mpeg_audio['raw']['padding']; + $thisfile_mpeg_audio['bitrate'] = $MPEGaudioBitrateLookup[$thisfile_mpeg_audio['version']][$thisfile_mpeg_audio['layer']][$thisfile_mpeg_audio['raw']['bitrate']]; + + if (($thisfile_mpeg_audio['bitrate'] == 'free') && ($offset == $info['avdataoffset'])) { + // only skip multiple frame check if free-format bitstream found at beginning of file + // otherwise is quite possibly simply corrupted data + $recursivesearch = false; + } + + // For Layer 2 there are some combinations of bitrate and mode which are not allowed. + if (!$FastMPEGheaderScan && ($thisfile_mpeg_audio['layer'] == '2')) { + + $info['audio']['dataformat'] = 'mp2'; + switch ($thisfile_mpeg_audio['channelmode']) { + + case 'mono': + if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] <= 192000)) { + // these are ok + } else { + $info['error'][] = $thisfile_mpeg_audio['bitrate'].'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.'; + return false; + } + break; + + case 'stereo': + case 'joint stereo': + case 'dual channel': + if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] == 64000) || ($thisfile_mpeg_audio['bitrate'] >= 96000)) { + // these are ok + } else { + $info['error'][] = intval(round($thisfile_mpeg_audio['bitrate'] / 1000)).'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.'; + return false; + } + break; + + } + + } + + + if ($info['audio']['sample_rate'] > 0) { + $thisfile_mpeg_audio['framelength'] = self::MPEGaudioFrameLength($thisfile_mpeg_audio['bitrate'], $thisfile_mpeg_audio['version'], $thisfile_mpeg_audio['layer'], (int) $thisfile_mpeg_audio['padding'], $info['audio']['sample_rate']); + } + + $nextframetestoffset = $offset + 1; + if ($thisfile_mpeg_audio['bitrate'] != 'free') { + + $info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate']; + + if (isset($thisfile_mpeg_audio['framelength'])) { + $nextframetestoffset = $offset + $thisfile_mpeg_audio['framelength']; + } else { + $info['error'][] = 'Frame at offset('.$offset.') is has an invalid frame length.'; + return false; + } + + } + + $ExpectedNumberOfAudioBytes = 0; + + //////////////////////////////////////////////////////////////////////////////////// + // Variable-bitrate headers + + if (substr($headerstring, 4 + 32, 4) == 'VBRI') { + // Fraunhofer VBR header is hardcoded 'VBRI' at offset 0x24 (36) + // specs taken from http://minnie.tuhs.org/pipermail/mp3encoder/2001-January/001800.html + + $thisfile_mpeg_audio['bitrate_mode'] = 'vbr'; + $thisfile_mpeg_audio['VBR_method'] = 'Fraunhofer'; + $info['audio']['codec'] = 'Fraunhofer'; + + $SideInfoData = substr($headerstring, 4 + 2, 32); + + $FraunhoferVBROffset = 36; + + $thisfile_mpeg_audio['VBR_encoder_version'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 4, 2)); // VbriVersion + $thisfile_mpeg_audio['VBR_encoder_delay'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 6, 2)); // VbriDelay + $thisfile_mpeg_audio['VBR_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 8, 2)); // VbriQuality + $thisfile_mpeg_audio['VBR_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 10, 4)); // VbriStreamBytes + $thisfile_mpeg_audio['VBR_frames'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 14, 4)); // VbriStreamFrames + $thisfile_mpeg_audio['VBR_seek_offsets'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 18, 2)); // VbriTableSize + $thisfile_mpeg_audio['VBR_seek_scale'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 20, 2)); // VbriTableScale + $thisfile_mpeg_audio['VBR_entry_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 22, 2)); // VbriEntryBytes + $thisfile_mpeg_audio['VBR_entry_frames'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 24, 2)); // VbriEntryFrames + + $ExpectedNumberOfAudioBytes = $thisfile_mpeg_audio['VBR_bytes']; + + $previousbyteoffset = $offset; + for ($i = 0; $i < $thisfile_mpeg_audio['VBR_seek_offsets']; $i++) { + $Fraunhofer_OffsetN = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset, $thisfile_mpeg_audio['VBR_entry_bytes'])); + $FraunhoferVBROffset += $thisfile_mpeg_audio['VBR_entry_bytes']; + $thisfile_mpeg_audio['VBR_offsets_relative'][$i] = ($Fraunhofer_OffsetN * $thisfile_mpeg_audio['VBR_seek_scale']); + $thisfile_mpeg_audio['VBR_offsets_absolute'][$i] = ($Fraunhofer_OffsetN * $thisfile_mpeg_audio['VBR_seek_scale']) + $previousbyteoffset; + $previousbyteoffset += $Fraunhofer_OffsetN; + } + + + } else { + + // Xing VBR header is hardcoded 'Xing' at a offset 0x0D (13), 0x15 (21) or 0x24 (36) + // depending on MPEG layer and number of channels + + $VBRidOffset = self::XingVBRidOffset($thisfile_mpeg_audio['version'], $thisfile_mpeg_audio['channelmode']); + $SideInfoData = substr($headerstring, 4 + 2, $VBRidOffset - 4); + + if ((substr($headerstring, $VBRidOffset, strlen('Xing')) == 'Xing') || (substr($headerstring, $VBRidOffset, strlen('Info')) == 'Info')) { + // 'Xing' is traditional Xing VBR frame + // 'Info' is LAME-encoded CBR (This was done to avoid CBR files to be recognized as traditional Xing VBR files by some decoders.) + // 'Info' *can* legally be used to specify a VBR file as well, however. + + // http://www.multiweb.cz/twoinches/MP3inside.htm + //00..03 = "Xing" or "Info" + //04..07 = Flags: + // 0x01 Frames Flag set if value for number of frames in file is stored + // 0x02 Bytes Flag set if value for filesize in bytes is stored + // 0x04 TOC Flag set if values for TOC are stored + // 0x08 VBR Scale Flag set if values for VBR scale is stored + //08..11 Frames: Number of frames in file (including the first Xing/Info one) + //12..15 Bytes: File length in Bytes + //16..115 TOC (Table of Contents): + // Contains of 100 indexes (one Byte length) for easier lookup in file. Approximately solves problem with moving inside file. + // Each Byte has a value according this formula: + // (TOC[i] / 256) * fileLenInBytes + // So if song lasts eg. 240 sec. and you want to jump to 60. sec. (and file is 5 000 000 Bytes length) you can use: + // TOC[(60/240)*100] = TOC[25] + // and corresponding Byte in file is then approximately at: + // (TOC[25]/256) * 5000000 + //116..119 VBR Scale + + + // should be safe to leave this at 'vbr' and let it be overriden to 'cbr' if a CBR preset/mode is used by LAME +// if (substr($headerstring, $VBRidOffset, strlen('Info')) == 'Xing') { + $thisfile_mpeg_audio['bitrate_mode'] = 'vbr'; + $thisfile_mpeg_audio['VBR_method'] = 'Xing'; +// } else { +// $ScanAsCBR = true; +// $thisfile_mpeg_audio['bitrate_mode'] = 'cbr'; +// } + + $thisfile_mpeg_audio['xing_flags_raw'] = getid3_lib::BigEndian2Int(substr($headerstring, $VBRidOffset + 4, 4)); + + $thisfile_mpeg_audio['xing_flags']['frames'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000001); + $thisfile_mpeg_audio['xing_flags']['bytes'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000002); + $thisfile_mpeg_audio['xing_flags']['toc'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000004); + $thisfile_mpeg_audio['xing_flags']['vbr_scale'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000008); + + if ($thisfile_mpeg_audio['xing_flags']['frames']) { + $thisfile_mpeg_audio['VBR_frames'] = getid3_lib::BigEndian2Int(substr($headerstring, $VBRidOffset + 8, 4)); + //$thisfile_mpeg_audio['VBR_frames']--; // don't count header Xing/Info frame + } + if ($thisfile_mpeg_audio['xing_flags']['bytes']) { + $thisfile_mpeg_audio['VBR_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $VBRidOffset + 12, 4)); + } + + //if (($thisfile_mpeg_audio['bitrate'] == 'free') && !empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) { + if (!empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) { + + $framelengthfloat = $thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']; + + if ($thisfile_mpeg_audio['layer'] == '1') { + // BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12 + //$info['audio']['bitrate'] = ((($framelengthfloat / 4) - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 12; + $info['audio']['bitrate'] = ($framelengthfloat / 4) * $thisfile_mpeg_audio['sample_rate'] * (2 / $info['audio']['channels']) / 12; + } else { + // Bitrate = ((FrameLengthInBytes - Padding) * SampleRate) / 144 + //$info['audio']['bitrate'] = (($framelengthfloat - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 144; + $info['audio']['bitrate'] = $framelengthfloat * $thisfile_mpeg_audio['sample_rate'] * (2 / $info['audio']['channels']) / 144; + } + $thisfile_mpeg_audio['framelength'] = floor($framelengthfloat); + } + + if ($thisfile_mpeg_audio['xing_flags']['toc']) { + $LAMEtocData = substr($headerstring, $VBRidOffset + 16, 100); + for ($i = 0; $i < 100; $i++) { + $thisfile_mpeg_audio['toc'][$i] = ord($LAMEtocData{$i}); + } + } + if ($thisfile_mpeg_audio['xing_flags']['vbr_scale']) { + $thisfile_mpeg_audio['VBR_scale'] = getid3_lib::BigEndian2Int(substr($headerstring, $VBRidOffset + 116, 4)); + } + + + // http://gabriel.mp3-tech.org/mp3infotag.html + if (substr($headerstring, $VBRidOffset + 120, 4) == 'LAME') { + + // shortcut + $thisfile_mpeg_audio['LAME'] = array(); + $thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME']; + + + $thisfile_mpeg_audio_lame['long_version'] = substr($headerstring, $VBRidOffset + 120, 20); + $thisfile_mpeg_audio_lame['short_version'] = substr($thisfile_mpeg_audio_lame['long_version'], 0, 9); + + if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') { + + // extra 11 chars are not part of version string when LAMEtag present + unset($thisfile_mpeg_audio_lame['long_version']); + + // It the LAME tag was only introduced in LAME v3.90 + // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933 + + // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html + // are assuming a 'Xing' identifier offset of 0x24, which is the case for + // MPEG-1 non-mono, but not for other combinations + $LAMEtagOffsetContant = $VBRidOffset - 0x24; + + // shortcuts + $thisfile_mpeg_audio_lame['RGAD'] = array('track'=>array(), 'album'=>array()); + $thisfile_mpeg_audio_lame_RGAD = &$thisfile_mpeg_audio_lame['RGAD']; + $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track']; + $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album']; + $thisfile_mpeg_audio_lame['raw'] = array(); + $thisfile_mpeg_audio_lame_raw = &$thisfile_mpeg_audio_lame['raw']; + + // byte $9B VBR Quality + // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications. + // Actually overwrites original Xing bytes + unset($thisfile_mpeg_audio['VBR_scale']); + $thisfile_mpeg_audio_lame['vbr_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1)); + + // bytes $9C-$A4 Encoder short VersionString + $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9); + + // byte $A5 Info Tag revision + VBR method + $LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1)); + + $thisfile_mpeg_audio_lame['tag_revision'] = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4; + $thisfile_mpeg_audio_lame_raw['vbr_method'] = $LAMEtagRevisionVBRmethod & 0x0F; + $thisfile_mpeg_audio_lame['vbr_method'] = self::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']); + $thisfile_mpeg_audio['bitrate_mode'] = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3); // usually either 'cbr' or 'vbr', but truncates 'vbr-old / vbr-rh' to 'vbr' + + // byte $A6 Lowpass filter value + $thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100; + + // bytes $A7-$AE Replay Gain + // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html + // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude" + if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') { + // LAME 3.94a16 and later - 9.23 fixed point + // ie 0x0059E2EE / (2^23) = 5890798 / 8388608 = 0.7022378444671630859375 + $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = (float) ((getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608); + } else { + // LAME 3.94a15 and earlier - 32-bit floating point + // Actually 3.94a16 will fall in here too and be WRONG, but is hard to detect 3.94a16 vs 3.94a15 + $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = getid3_lib::LittleEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4)); + } + if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) { + unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']); + } else { + $thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']); + } + + $thisfile_mpeg_audio_lame_raw['RGAD_track'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2)); + $thisfile_mpeg_audio_lame_raw['RGAD_album'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2)); + + + if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) { + + $thisfile_mpeg_audio_lame_RGAD_track['raw']['name'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13; + $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10; + $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9; + $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF; + $thisfile_mpeg_audio_lame_RGAD_track['name'] = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['name']); + $thisfile_mpeg_audio_lame_RGAD_track['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']); + $thisfile_mpeg_audio_lame_RGAD_track['gain_db'] = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']); + + if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) { + $info['replay_gain']['track']['peak'] = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude']; + } + $info['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator']; + $info['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db']; + } else { + unset($thisfile_mpeg_audio_lame_RGAD['track']); + } + if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) { + + $thisfile_mpeg_audio_lame_RGAD_album['raw']['name'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13; + $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10; + $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9; + $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF; + $thisfile_mpeg_audio_lame_RGAD_album['name'] = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['name']); + $thisfile_mpeg_audio_lame_RGAD_album['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']); + $thisfile_mpeg_audio_lame_RGAD_album['gain_db'] = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']); + + if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) { + $info['replay_gain']['album']['peak'] = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude']; + } + $info['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator']; + $info['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db']; + } else { + unset($thisfile_mpeg_audio_lame_RGAD['album']); + } + if (empty($thisfile_mpeg_audio_lame_RGAD)) { + unset($thisfile_mpeg_audio_lame['RGAD']); + } + + + // byte $AF Encoding flags + ATH Type + $EncodingFlagsATHtype = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1)); + $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune'] = (bool) ($EncodingFlagsATHtype & 0x10); + $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20); + $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next'] = (bool) ($EncodingFlagsATHtype & 0x40); + $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev'] = (bool) ($EncodingFlagsATHtype & 0x80); + $thisfile_mpeg_audio_lame['ath_type'] = $EncodingFlagsATHtype & 0x0F; + + // byte $B0 if ABR {specified bitrate} else {minimal bitrate} + $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1)); + if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) { // Average BitRate (ABR) + $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate']; + } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { // Constant BitRate (CBR) + // ignore + } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) { // Variable BitRate (VBR) - minimum bitrate + $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate']; + } + + // bytes $B1-$B3 Encoder delays + $EncoderDelays = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3)); + $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12; + $thisfile_mpeg_audio_lame['end_padding'] = $EncoderDelays & 0x000FFF; + + // byte $B4 Misc + $MiscByte = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1)); + $thisfile_mpeg_audio_lame_raw['noise_shaping'] = ($MiscByte & 0x03); + $thisfile_mpeg_audio_lame_raw['stereo_mode'] = ($MiscByte & 0x1C) >> 2; + $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5; + $thisfile_mpeg_audio_lame_raw['source_sample_freq'] = ($MiscByte & 0xC0) >> 6; + $thisfile_mpeg_audio_lame['noise_shaping'] = $thisfile_mpeg_audio_lame_raw['noise_shaping']; + $thisfile_mpeg_audio_lame['stereo_mode'] = self::LAMEmiscStereoModeLookup($thisfile_mpeg_audio_lame_raw['stereo_mode']); + $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality']; + $thisfile_mpeg_audio_lame['source_sample_freq'] = self::LAMEmiscSourceSampleFrequencyLookup($thisfile_mpeg_audio_lame_raw['source_sample_freq']); + + // byte $B5 MP3 Gain + $thisfile_mpeg_audio_lame_raw['mp3_gain'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true); + $thisfile_mpeg_audio_lame['mp3_gain_db'] = (getid3_lib::RGADamplitude2dB(2) / 4) * $thisfile_mpeg_audio_lame_raw['mp3_gain']; + $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6)); + + // bytes $B6-$B7 Preset and surround info + $PresetSurroundBytes = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2)); + // Reserved = ($PresetSurroundBytes & 0xC000); + $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800); + $thisfile_mpeg_audio_lame['surround_info'] = self::LAMEsurroundInfoLookup($thisfile_mpeg_audio_lame_raw['surround_info']); + $thisfile_mpeg_audio_lame['preset_used_id'] = ($PresetSurroundBytes & 0x07FF); + $thisfile_mpeg_audio_lame['preset_used'] = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame); + if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) { + $info['warning'][] = 'Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org'; + } + if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) { + // this may change if 3.90.4 ever comes out + $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3'; + } + + // bytes $B8-$BB MusicLength + $thisfile_mpeg_audio_lame['audio_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4)); + $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']); + + // bytes $BC-$BD MusicCRC + $thisfile_mpeg_audio_lame['music_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2)); + + // bytes $BE-$BF CRC-16 of Info Tag + $thisfile_mpeg_audio_lame['lame_tag_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2)); + + + // LAME CBR + if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { + + $thisfile_mpeg_audio['bitrate_mode'] = 'cbr'; + $thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']); + $info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate']; + //if (empty($thisfile_mpeg_audio['bitrate']) || (!empty($thisfile_mpeg_audio_lame['bitrate_min']) && ($thisfile_mpeg_audio_lame['bitrate_min'] != 255))) { + // $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio_lame['bitrate_min']; + //} + + } + + } + } + + } else { + + // not Fraunhofer or Xing VBR methods, most likely CBR (but could be VBR with no header) + $thisfile_mpeg_audio['bitrate_mode'] = 'cbr'; + if ($recursivesearch) { + $thisfile_mpeg_audio['bitrate_mode'] = 'vbr'; + if ($this->RecursiveFrameScanning($offset, $nextframetestoffset, true)) { + $recursivesearch = false; + $thisfile_mpeg_audio['bitrate_mode'] = 'cbr'; + } + if ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') { + $info['warning'][] = 'VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.'; + } + } + + } + + } + + if (($ExpectedNumberOfAudioBytes > 0) && ($ExpectedNumberOfAudioBytes != ($info['avdataend'] - $info['avdataoffset']))) { + if ($ExpectedNumberOfAudioBytes > ($info['avdataend'] - $info['avdataoffset'])) { + if (isset($info['fileformat']) && ($info['fileformat'] == 'riff')) { + // ignore, audio data is broken into chunks so will always be data "missing" + } elseif (($ExpectedNumberOfAudioBytes - ($info['avdataend'] - $info['avdataoffset'])) == 1) { + $info['warning'][] = 'Last byte of data truncated (this is a known bug in Meracl ID3 Tag Writer before v1.3.5)'; + } else { + $info['warning'][] = 'Probable truncated file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, only found '.($info['avdataend'] - $info['avdataoffset']).' (short by '.($ExpectedNumberOfAudioBytes - ($info['avdataend'] - $info['avdataoffset'])).' bytes)'; + } + } else { + if ((($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes) == 1) { + // $prenullbytefileoffset = ftell($this->getid3->fp); + // fseek($this->getid3->fp, $info['avdataend'], SEEK_SET); + // $PossibleNullByte = fread($this->getid3->fp, 1); + // fseek($this->getid3->fp, $prenullbytefileoffset, SEEK_SET); + // if ($PossibleNullByte === "\x00") { + $info['avdataend']--; + // $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored'; + // } else { + // $info['warning'][] = 'Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($info['avdataend'] - $info['avdataoffset']).' ('.(($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)'; + // } + } else { + $info['warning'][] = 'Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($info['avdataend'] - $info['avdataoffset']).' ('.(($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)'; + } + } + } + + if (($thisfile_mpeg_audio['bitrate'] == 'free') && empty($info['audio']['bitrate'])) { + if (($offset == $info['avdataoffset']) && empty($thisfile_mpeg_audio['VBR_frames'])) { + $framebytelength = $this->FreeFormatFrameLength($offset, true); + if ($framebytelength > 0) { + $thisfile_mpeg_audio['framelength'] = $framebytelength; + if ($thisfile_mpeg_audio['layer'] == '1') { + // BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12 + $info['audio']['bitrate'] = ((($framebytelength / 4) - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 12; + } else { + // Bitrate = ((FrameLengthInBytes - Padding) * SampleRate) / 144 + $info['audio']['bitrate'] = (($framebytelength - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 144; + } + } else { + $info['error'][] = 'Error calculating frame length of free-format MP3 without Xing/LAME header'; + } + } + } + + if (isset($thisfile_mpeg_audio['VBR_frames']) ? $thisfile_mpeg_audio['VBR_frames'] : '') { + switch ($thisfile_mpeg_audio['bitrate_mode']) { + case 'vbr': + case 'abr': + $bytes_per_frame = 1152; + if (($thisfile_mpeg_audio['version'] == '1') && ($thisfile_mpeg_audio['layer'] == 1)) { + $bytes_per_frame = 384; + } elseif ((($thisfile_mpeg_audio['version'] == '2') || ($thisfile_mpeg_audio['version'] == '2.5')) && ($thisfile_mpeg_audio['layer'] == 3)) { + $bytes_per_frame = 576; + } + $thisfile_mpeg_audio['VBR_bitrate'] = (isset($thisfile_mpeg_audio['VBR_bytes']) ? (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($info['audio']['sample_rate'] / $bytes_per_frame) : 0); + if ($thisfile_mpeg_audio['VBR_bitrate'] > 0) { + $info['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate']; + $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate']; // to avoid confusion + } + break; + } + } + + // End variable-bitrate headers + //////////////////////////////////////////////////////////////////////////////////// + + if ($recursivesearch) { + + if (!$this->RecursiveFrameScanning($offset, $nextframetestoffset, $ScanAsCBR)) { + return false; + } + + } + + + //if (false) { + // // experimental side info parsing section - not returning anything useful yet + // + // $SideInfoBitstream = getid3_lib::BigEndian2Bin($SideInfoData); + // $SideInfoOffset = 0; + // + // if ($thisfile_mpeg_audio['version'] == '1') { + // if ($thisfile_mpeg_audio['channelmode'] == 'mono') { + // // MPEG-1 (mono) + // $thisfile_mpeg_audio['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 9); + // $SideInfoOffset += 9; + // $SideInfoOffset += 5; + // } else { + // // MPEG-1 (stereo, joint-stereo, dual-channel) + // $thisfile_mpeg_audio['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 9); + // $SideInfoOffset += 9; + // $SideInfoOffset += 3; + // } + // } else { // 2 or 2.5 + // if ($thisfile_mpeg_audio['channelmode'] == 'mono') { + // // MPEG-2, MPEG-2.5 (mono) + // $thisfile_mpeg_audio['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 8); + // $SideInfoOffset += 8; + // $SideInfoOffset += 1; + // } else { + // // MPEG-2, MPEG-2.5 (stereo, joint-stereo, dual-channel) + // $thisfile_mpeg_audio['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 8); + // $SideInfoOffset += 8; + // $SideInfoOffset += 2; + // } + // } + // + // if ($thisfile_mpeg_audio['version'] == '1') { + // for ($channel = 0; $channel < $info['audio']['channels']; $channel++) { + // for ($scfsi_band = 0; $scfsi_band < 4; $scfsi_band++) { + // $thisfile_mpeg_audio['scfsi'][$channel][$scfsi_band] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 2; + // } + // } + // } + // for ($granule = 0; $granule < (($thisfile_mpeg_audio['version'] == '1') ? 2 : 1); $granule++) { + // for ($channel = 0; $channel < $info['audio']['channels']; $channel++) { + // $thisfile_mpeg_audio['part2_3_length'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 12); + // $SideInfoOffset += 12; + // $thisfile_mpeg_audio['big_values'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 9); + // $SideInfoOffset += 9; + // $thisfile_mpeg_audio['global_gain'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 8); + // $SideInfoOffset += 8; + // if ($thisfile_mpeg_audio['version'] == '1') { + // $thisfile_mpeg_audio['scalefac_compress'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 4); + // $SideInfoOffset += 4; + // } else { + // $thisfile_mpeg_audio['scalefac_compress'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 9); + // $SideInfoOffset += 9; + // } + // $thisfile_mpeg_audio['window_switching_flag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // + // if ($thisfile_mpeg_audio['window_switching_flag'][$granule][$channel] == '1') { + // + // $thisfile_mpeg_audio['block_type'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 2); + // $SideInfoOffset += 2; + // $thisfile_mpeg_audio['mixed_block_flag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // + // for ($region = 0; $region < 2; $region++) { + // $thisfile_mpeg_audio['table_select'][$granule][$channel][$region] = substr($SideInfoBitstream, $SideInfoOffset, 5); + // $SideInfoOffset += 5; + // } + // $thisfile_mpeg_audio['table_select'][$granule][$channel][2] = 0; + // + // for ($window = 0; $window < 3; $window++) { + // $thisfile_mpeg_audio['subblock_gain'][$granule][$channel][$window] = substr($SideInfoBitstream, $SideInfoOffset, 3); + // $SideInfoOffset += 3; + // } + // + // } else { + // + // for ($region = 0; $region < 3; $region++) { + // $thisfile_mpeg_audio['table_select'][$granule][$channel][$region] = substr($SideInfoBitstream, $SideInfoOffset, 5); + // $SideInfoOffset += 5; + // } + // + // $thisfile_mpeg_audio['region0_count'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 4); + // $SideInfoOffset += 4; + // $thisfile_mpeg_audio['region1_count'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 3); + // $SideInfoOffset += 3; + // $thisfile_mpeg_audio['block_type'][$granule][$channel] = 0; + // } + // + // if ($thisfile_mpeg_audio['version'] == '1') { + // $thisfile_mpeg_audio['preflag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // } + // $thisfile_mpeg_audio['scalefac_scale'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // $thisfile_mpeg_audio['count1table_select'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // } + // } + //} + + return true; + } + + public function RecursiveFrameScanning(&$offset, &$nextframetestoffset, $ScanAsCBR) { + $info = &$this->getid3->info; + $firstframetestarray = array('error'=>'', 'warning'=>'', 'avdataend'=>$info['avdataend'], 'avdataoffset'=>$info['avdataoffset']); + $this->decodeMPEGaudioHeader($offset, $firstframetestarray, false); + + for ($i = 0; $i < GETID3_MP3_VALID_CHECK_FRAMES; $i++) { + // check next GETID3_MP3_VALID_CHECK_FRAMES frames for validity, to make sure we haven't run across a false synch + if (($nextframetestoffset + 4) >= $info['avdataend']) { + // end of file + return true; + } + + $nextframetestarray = array('error'=>'', 'warning'=>'', 'avdataend'=>$info['avdataend'], 'avdataoffset'=>$info['avdataoffset']); + if ($this->decodeMPEGaudioHeader($nextframetestoffset, $nextframetestarray, false)) { + if ($ScanAsCBR) { + // force CBR mode, used for trying to pick out invalid audio streams with valid(?) VBR headers, or VBR streams with no VBR header + if (!isset($nextframetestarray['mpeg']['audio']['bitrate']) || !isset($firstframetestarray['mpeg']['audio']['bitrate']) || ($nextframetestarray['mpeg']['audio']['bitrate'] != $firstframetestarray['mpeg']['audio']['bitrate'])) { + return false; + } + } + + + // next frame is OK, get ready to check the one after that + if (isset($nextframetestarray['mpeg']['audio']['framelength']) && ($nextframetestarray['mpeg']['audio']['framelength'] > 0)) { + $nextframetestoffset += $nextframetestarray['mpeg']['audio']['framelength']; + } else { + $info['error'][] = 'Frame at offset ('.$offset.') is has an invalid frame length.'; + return false; + } + + } elseif (!empty($firstframetestarray['mpeg']['audio']['framelength']) && (($nextframetestoffset + $firstframetestarray['mpeg']['audio']['framelength']) > $info['avdataend'])) { + + // it's not the end of the file, but there's not enough data left for another frame, so assume it's garbage/padding and return OK + return true; + + } else { + + // next frame is not valid, note the error and fail, so scanning can contiue for a valid frame sequence + $info['warning'][] = 'Frame at offset ('.$offset.') is valid, but the next one at ('.$nextframetestoffset.') is not.'; + + return false; + } + } + return true; + } + + public function FreeFormatFrameLength($offset, $deepscan=false) { + $info = &$this->getid3->info; + + fseek($this->getid3->fp, $offset, SEEK_SET); + $MPEGaudioData = fread($this->getid3->fp, 32768); + + $SyncPattern1 = substr($MPEGaudioData, 0, 4); + // may be different pattern due to padding + $SyncPattern2 = $SyncPattern1{0}.$SyncPattern1{1}.chr(ord($SyncPattern1{2}) | 0x02).$SyncPattern1{3}; + if ($SyncPattern2 === $SyncPattern1) { + $SyncPattern2 = $SyncPattern1{0}.$SyncPattern1{1}.chr(ord($SyncPattern1{2}) & 0xFD).$SyncPattern1{3}; + } + + $framelength = false; + $framelength1 = strpos($MPEGaudioData, $SyncPattern1, 4); + $framelength2 = strpos($MPEGaudioData, $SyncPattern2, 4); + if ($framelength1 > 4) { + $framelength = $framelength1; + } + if (($framelength2 > 4) && ($framelength2 < $framelength1)) { + $framelength = $framelength2; + } + if (!$framelength) { + + // LAME 3.88 has a different value for modeextension on the first frame vs the rest + $framelength1 = strpos($MPEGaudioData, substr($SyncPattern1, 0, 3), 4); + $framelength2 = strpos($MPEGaudioData, substr($SyncPattern2, 0, 3), 4); + + if ($framelength1 > 4) { + $framelength = $framelength1; + } + if (($framelength2 > 4) && ($framelength2 < $framelength1)) { + $framelength = $framelength2; + } + if (!$framelength) { + $info['error'][] = 'Cannot find next free-format synch pattern ('.getid3_lib::PrintHexBytes($SyncPattern1).' or '.getid3_lib::PrintHexBytes($SyncPattern2).') after offset '.$offset; + return false; + } else { + $info['warning'][] = 'ModeExtension varies between first frame and other frames (known free-format issue in LAME 3.88)'; + $info['audio']['codec'] = 'LAME'; + $info['audio']['encoder'] = 'LAME3.88'; + $SyncPattern1 = substr($SyncPattern1, 0, 3); + $SyncPattern2 = substr($SyncPattern2, 0, 3); + } + } + + if ($deepscan) { + + $ActualFrameLengthValues = array(); + $nextoffset = $offset + $framelength; + while ($nextoffset < ($info['avdataend'] - 6)) { + fseek($this->getid3->fp, $nextoffset - 1, SEEK_SET); + $NextSyncPattern = fread($this->getid3->fp, 6); + if ((substr($NextSyncPattern, 1, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 1, strlen($SyncPattern2)) == $SyncPattern2)) { + // good - found where expected + $ActualFrameLengthValues[] = $framelength; + } elseif ((substr($NextSyncPattern, 0, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 0, strlen($SyncPattern2)) == $SyncPattern2)) { + // ok - found one byte earlier than expected (last frame wasn't padded, first frame was) + $ActualFrameLengthValues[] = ($framelength - 1); + $nextoffset--; + } elseif ((substr($NextSyncPattern, 2, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 2, strlen($SyncPattern2)) == $SyncPattern2)) { + // ok - found one byte later than expected (last frame was padded, first frame wasn't) + $ActualFrameLengthValues[] = ($framelength + 1); + $nextoffset++; + } else { + $info['error'][] = 'Did not find expected free-format sync pattern at offset '.$nextoffset; + return false; + } + $nextoffset += $framelength; + } + if (count($ActualFrameLengthValues) > 0) { + $framelength = intval(round(array_sum($ActualFrameLengthValues) / count($ActualFrameLengthValues))); + } + } + return $framelength; + } + + public function getOnlyMPEGaudioInfoBruteForce() { + $MPEGaudioHeaderDecodeCache = array(); + $MPEGaudioHeaderValidCache = array(); + $MPEGaudioHeaderLengthCache = array(); + $MPEGaudioVersionLookup = self::MPEGaudioVersionArray(); + $MPEGaudioLayerLookup = self::MPEGaudioLayerArray(); + $MPEGaudioBitrateLookup = self::MPEGaudioBitrateArray(); + $MPEGaudioFrequencyLookup = self::MPEGaudioFrequencyArray(); + $MPEGaudioChannelModeLookup = self::MPEGaudioChannelModeArray(); + $MPEGaudioModeExtensionLookup = self::MPEGaudioModeExtensionArray(); + $MPEGaudioEmphasisLookup = self::MPEGaudioEmphasisArray(); + $LongMPEGversionLookup = array(); + $LongMPEGlayerLookup = array(); + $LongMPEGbitrateLookup = array(); + $LongMPEGpaddingLookup = array(); + $LongMPEGfrequencyLookup = array(); + $Distribution['bitrate'] = array(); + $Distribution['frequency'] = array(); + $Distribution['layer'] = array(); + $Distribution['version'] = array(); + $Distribution['padding'] = array(); + + $info = &$this->getid3->info; + fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); + + $max_frames_scan = 5000; + $frames_scanned = 0; + + $previousvalidframe = $info['avdataoffset']; + while (ftell($this->getid3->fp) < $info['avdataend']) { + set_time_limit(30); + $head4 = fread($this->getid3->fp, 4); + if (strlen($head4) < 4) { + break; + } + if ($head4{0} != "\xFF") { + for ($i = 1; $i < 4; $i++) { + if ($head4{$i} == "\xFF") { + fseek($this->getid3->fp, $i - 4, SEEK_CUR); + continue 2; + } + } + continue; + } + if (!isset($MPEGaudioHeaderDecodeCache[$head4])) { + $MPEGaudioHeaderDecodeCache[$head4] = self::MPEGaudioHeaderDecode($head4); + } + if (!isset($MPEGaudioHeaderValidCache[$head4])) { + $MPEGaudioHeaderValidCache[$head4] = self::MPEGaudioHeaderValid($MPEGaudioHeaderDecodeCache[$head4], false, false); + } + if ($MPEGaudioHeaderValidCache[$head4]) { + + if (!isset($MPEGaudioHeaderLengthCache[$head4])) { + $LongMPEGversionLookup[$head4] = $MPEGaudioVersionLookup[$MPEGaudioHeaderDecodeCache[$head4]['version']]; + $LongMPEGlayerLookup[$head4] = $MPEGaudioLayerLookup[$MPEGaudioHeaderDecodeCache[$head4]['layer']]; + $LongMPEGbitrateLookup[$head4] = $MPEGaudioBitrateLookup[$LongMPEGversionLookup[$head4]][$LongMPEGlayerLookup[$head4]][$MPEGaudioHeaderDecodeCache[$head4]['bitrate']]; + $LongMPEGpaddingLookup[$head4] = (bool) $MPEGaudioHeaderDecodeCache[$head4]['padding']; + $LongMPEGfrequencyLookup[$head4] = $MPEGaudioFrequencyLookup[$LongMPEGversionLookup[$head4]][$MPEGaudioHeaderDecodeCache[$head4]['sample_rate']]; + $MPEGaudioHeaderLengthCache[$head4] = self::MPEGaudioFrameLength( + $LongMPEGbitrateLookup[$head4], + $LongMPEGversionLookup[$head4], + $LongMPEGlayerLookup[$head4], + $LongMPEGpaddingLookup[$head4], + $LongMPEGfrequencyLookup[$head4]); + } + if ($MPEGaudioHeaderLengthCache[$head4] > 4) { + $WhereWeWere = ftell($this->getid3->fp); + fseek($this->getid3->fp, $MPEGaudioHeaderLengthCache[$head4] - 4, SEEK_CUR); + $next4 = fread($this->getid3->fp, 4); + if ($next4{0} == "\xFF") { + if (!isset($MPEGaudioHeaderDecodeCache[$next4])) { + $MPEGaudioHeaderDecodeCache[$next4] = self::MPEGaudioHeaderDecode($next4); + } + if (!isset($MPEGaudioHeaderValidCache[$next4])) { + $MPEGaudioHeaderValidCache[$next4] = self::MPEGaudioHeaderValid($MPEGaudioHeaderDecodeCache[$next4], false, false); + } + if ($MPEGaudioHeaderValidCache[$next4]) { + fseek($this->getid3->fp, -4, SEEK_CUR); + + getid3_lib::safe_inc($Distribution['bitrate'][$LongMPEGbitrateLookup[$head4]]); + getid3_lib::safe_inc($Distribution['layer'][$LongMPEGlayerLookup[$head4]]); + getid3_lib::safe_inc($Distribution['version'][$LongMPEGversionLookup[$head4]]); + getid3_lib::safe_inc($Distribution['padding'][intval($LongMPEGpaddingLookup[$head4])]); + getid3_lib::safe_inc($Distribution['frequency'][$LongMPEGfrequencyLookup[$head4]]); + if ($max_frames_scan && (++$frames_scanned >= $max_frames_scan)) { + $pct_data_scanned = (ftell($this->getid3->fp) - $info['avdataoffset']) / ($info['avdataend'] - $info['avdataoffset']); + $info['warning'][] = 'too many MPEG audio frames to scan, only scanned first '.$max_frames_scan.' frames ('.number_format($pct_data_scanned * 100, 1).'% of file) and extrapolated distribution, playtime and bitrate may be incorrect.'; + foreach ($Distribution as $key1 => $value1) { + foreach ($value1 as $key2 => $value2) { + $Distribution[$key1][$key2] = round($value2 / $pct_data_scanned); + } + } + break; + } + continue; + } + } + unset($next4); + fseek($this->getid3->fp, $WhereWeWere - 3, SEEK_SET); + } + + } + } + foreach ($Distribution as $key => $value) { + ksort($Distribution[$key], SORT_NUMERIC); + } + ksort($Distribution['version'], SORT_STRING); + $info['mpeg']['audio']['bitrate_distribution'] = $Distribution['bitrate']; + $info['mpeg']['audio']['frequency_distribution'] = $Distribution['frequency']; + $info['mpeg']['audio']['layer_distribution'] = $Distribution['layer']; + $info['mpeg']['audio']['version_distribution'] = $Distribution['version']; + $info['mpeg']['audio']['padding_distribution'] = $Distribution['padding']; + if (count($Distribution['version']) > 1) { + $info['error'][] = 'Corrupt file - more than one MPEG version detected'; + } + if (count($Distribution['layer']) > 1) { + $info['error'][] = 'Corrupt file - more than one MPEG layer detected'; + } + if (count($Distribution['frequency']) > 1) { + $info['error'][] = 'Corrupt file - more than one MPEG sample rate detected'; + } + + + $bittotal = 0; + foreach ($Distribution['bitrate'] as $bitratevalue => $bitratecount) { + if ($bitratevalue != 'free') { + $bittotal += ($bitratevalue * $bitratecount); + } + } + $info['mpeg']['audio']['frame_count'] = array_sum($Distribution['bitrate']); + if ($info['mpeg']['audio']['frame_count'] == 0) { + $info['error'][] = 'no MPEG audio frames found'; + return false; + } + $info['mpeg']['audio']['bitrate'] = ($bittotal / $info['mpeg']['audio']['frame_count']); + $info['mpeg']['audio']['bitrate_mode'] = ((count($Distribution['bitrate']) > 0) ? 'vbr' : 'cbr'); + $info['mpeg']['audio']['sample_rate'] = getid3_lib::array_max($Distribution['frequency'], true); + + $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate']; + $info['audio']['bitrate_mode'] = $info['mpeg']['audio']['bitrate_mode']; + $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate']; + $info['audio']['dataformat'] = 'mp'.getid3_lib::array_max($Distribution['layer'], true); + $info['fileformat'] = $info['audio']['dataformat']; + + return true; + } + + + public function getOnlyMPEGaudioInfo($avdataoffset, $BitrateHistogram=false) { + // looks for synch, decodes MPEG audio header + + $info = &$this->getid3->info; + + static $MPEGaudioVersionLookup; + static $MPEGaudioLayerLookup; + static $MPEGaudioBitrateLookup; + if (empty($MPEGaudioVersionLookup)) { + $MPEGaudioVersionLookup = self::MPEGaudioVersionArray(); + $MPEGaudioLayerLookup = self::MPEGaudioLayerArray(); + $MPEGaudioBitrateLookup = self::MPEGaudioBitrateArray(); + + } + + fseek($this->getid3->fp, $avdataoffset, SEEK_SET); + $sync_seek_buffer_size = min(128 * 1024, $info['avdataend'] - $avdataoffset); + if ($sync_seek_buffer_size <= 0) { + $info['error'][] = 'Invalid $sync_seek_buffer_size at offset '.$avdataoffset; + return false; + } + $header = fread($this->getid3->fp, $sync_seek_buffer_size); + $sync_seek_buffer_size = strlen($header); + $SynchSeekOffset = 0; + while ($SynchSeekOffset < $sync_seek_buffer_size) { + if ((($avdataoffset + $SynchSeekOffset) < $info['avdataend']) && !feof($this->getid3->fp)) { + + if ($SynchSeekOffset > $sync_seek_buffer_size) { + // if a synch's not found within the first 128k bytes, then give up + $info['error'][] = 'Could not find valid MPEG audio synch within the first '.round($sync_seek_buffer_size / 1024).'kB'; + if (isset($info['audio']['bitrate'])) { + unset($info['audio']['bitrate']); + } + if (isset($info['mpeg']['audio'])) { + unset($info['mpeg']['audio']); + } + if (empty($info['mpeg'])) { + unset($info['mpeg']); + } + return false; + + } elseif (feof($this->getid3->fp)) { + + $info['error'][] = 'Could not find valid MPEG audio synch before end of file'; + if (isset($info['audio']['bitrate'])) { + unset($info['audio']['bitrate']); + } + if (isset($info['mpeg']['audio'])) { + unset($info['mpeg']['audio']); + } + if (isset($info['mpeg']) && (!is_array($info['mpeg']) || (count($info['mpeg']) == 0))) { + unset($info['mpeg']); + } + return false; + } + } + + if (($SynchSeekOffset + 1) >= strlen($header)) { + $info['error'][] = 'Could not find valid MPEG synch before end of file'; + return false; + } + + if (($header{$SynchSeekOffset} == "\xFF") && ($header{($SynchSeekOffset + 1)} > "\xE0")) { // synch detected + if (!isset($FirstFrameThisfileInfo) && !isset($info['mpeg']['audio'])) { + $FirstFrameThisfileInfo = $info; + $FirstFrameAVDataOffset = $avdataoffset + $SynchSeekOffset; + if (!$this->decodeMPEGaudioHeader($FirstFrameAVDataOffset, $FirstFrameThisfileInfo, false)) { + // if this is the first valid MPEG-audio frame, save it in case it's a VBR header frame and there's + // garbage between this frame and a valid sequence of MPEG-audio frames, to be restored below + unset($FirstFrameThisfileInfo); + } + } + + $dummy = $info; // only overwrite real data if valid header found + if ($this->decodeMPEGaudioHeader($avdataoffset + $SynchSeekOffset, $dummy, true)) { + $info = $dummy; + $info['avdataoffset'] = $avdataoffset + $SynchSeekOffset; + switch (isset($info['fileformat']) ? $info['fileformat'] : '') { + case '': + case 'id3': + case 'ape': + case 'mp3': + $info['fileformat'] = 'mp3'; + $info['audio']['dataformat'] = 'mp3'; + break; + } + if (isset($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode']) && ($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr')) { + if (!(abs($info['audio']['bitrate'] - $FirstFrameThisfileInfo['audio']['bitrate']) <= 1)) { + // If there is garbage data between a valid VBR header frame and a sequence + // of valid MPEG-audio frames the VBR data is no longer discarded. + $info = $FirstFrameThisfileInfo; + $info['avdataoffset'] = $FirstFrameAVDataOffset; + $info['fileformat'] = 'mp3'; + $info['audio']['dataformat'] = 'mp3'; + $dummy = $info; + unset($dummy['mpeg']['audio']); + $GarbageOffsetStart = $FirstFrameAVDataOffset + $FirstFrameThisfileInfo['mpeg']['audio']['framelength']; + $GarbageOffsetEnd = $avdataoffset + $SynchSeekOffset; + if ($this->decodeMPEGaudioHeader($GarbageOffsetEnd, $dummy, true, true)) { + $info = $dummy; + $info['avdataoffset'] = $GarbageOffsetEnd; + $info['warning'][] = 'apparently-valid VBR header not used because could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd; + } else { + $info['warning'][] = 'using data from VBR header even though could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')'; + } + } + } + if (isset($info['mpeg']['audio']['bitrate_mode']) && ($info['mpeg']['audio']['bitrate_mode'] == 'vbr') && !isset($info['mpeg']['audio']['VBR_method'])) { + // VBR file with no VBR header + $BitrateHistogram = true; + } + + if ($BitrateHistogram) { + + $info['mpeg']['audio']['stereo_distribution'] = array('stereo'=>0, 'joint stereo'=>0, 'dual channel'=>0, 'mono'=>0); + $info['mpeg']['audio']['version_distribution'] = array('1'=>0, '2'=>0, '2.5'=>0); + + if ($info['mpeg']['audio']['version'] == '1') { + if ($info['mpeg']['audio']['layer'] == 3) { + $info['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 32000=>0, 40000=>0, 48000=>0, 56000=>0, 64000=>0, 80000=>0, 96000=>0, 112000=>0, 128000=>0, 160000=>0, 192000=>0, 224000=>0, 256000=>0, 320000=>0); + } elseif ($info['mpeg']['audio']['layer'] == 2) { + $info['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 32000=>0, 48000=>0, 56000=>0, 64000=>0, 80000=>0, 96000=>0, 112000=>0, 128000=>0, 160000=>0, 192000=>0, 224000=>0, 256000=>0, 320000=>0, 384000=>0); + } elseif ($info['mpeg']['audio']['layer'] == 1) { + $info['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 32000=>0, 64000=>0, 96000=>0, 128000=>0, 160000=>0, 192000=>0, 224000=>0, 256000=>0, 288000=>0, 320000=>0, 352000=>0, 384000=>0, 416000=>0, 448000=>0); + } + } elseif ($info['mpeg']['audio']['layer'] == 1) { + $info['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 32000=>0, 48000=>0, 56000=>0, 64000=>0, 80000=>0, 96000=>0, 112000=>0, 128000=>0, 144000=>0, 160000=>0, 176000=>0, 192000=>0, 224000=>0, 256000=>0); + } else { + $info['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 8000=>0, 16000=>0, 24000=>0, 32000=>0, 40000=>0, 48000=>0, 56000=>0, 64000=>0, 80000=>0, 96000=>0, 112000=>0, 128000=>0, 144000=>0, 160000=>0); + } + + $dummy = array('error'=>$info['error'], 'warning'=>$info['warning'], 'avdataend'=>$info['avdataend'], 'avdataoffset'=>$info['avdataoffset']); + $synchstartoffset = $info['avdataoffset']; + fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); + + // you can play with these numbers: + $max_frames_scan = 50000; + $max_scan_segments = 10; + + // don't play with these numbers: + $FastMode = false; + $SynchErrorsFound = 0; + $frames_scanned = 0; + $this_scan_segment = 0; + $frames_scan_per_segment = ceil($max_frames_scan / $max_scan_segments); + $pct_data_scanned = 0; + for ($current_segment = 0; $current_segment < $max_scan_segments; $current_segment++) { + $frames_scanned_this_segment = 0; + if (ftell($this->getid3->fp) >= $info['avdataend']) { + break; + } + $scan_start_offset[$current_segment] = max(ftell($this->getid3->fp), $info['avdataoffset'] + round($current_segment * (($info['avdataend'] - $info['avdataoffset']) / $max_scan_segments))); + if ($current_segment > 0) { + fseek($this->getid3->fp, $scan_start_offset[$current_segment], SEEK_SET); + $buffer_4k = fread($this->getid3->fp, 4096); + for ($j = 0; $j < (strlen($buffer_4k) - 4); $j++) { + if (($buffer_4k{$j} == "\xFF") && ($buffer_4k{($j + 1)} > "\xE0")) { // synch detected + if ($this->decodeMPEGaudioHeader($scan_start_offset[$current_segment] + $j, $dummy, false, false, $FastMode)) { + $calculated_next_offset = $scan_start_offset[$current_segment] + $j + $dummy['mpeg']['audio']['framelength']; + if ($this->decodeMPEGaudioHeader($calculated_next_offset, $dummy, false, false, $FastMode)) { + $scan_start_offset[$current_segment] += $j; + break; + } + } + } + } + } + $synchstartoffset = $scan_start_offset[$current_segment]; + while ($this->decodeMPEGaudioHeader($synchstartoffset, $dummy, false, false, $FastMode)) { + $FastMode = true; + $thisframebitrate = $MPEGaudioBitrateLookup[$MPEGaudioVersionLookup[$dummy['mpeg']['audio']['raw']['version']]][$MPEGaudioLayerLookup[$dummy['mpeg']['audio']['raw']['layer']]][$dummy['mpeg']['audio']['raw']['bitrate']]; + + if (empty($dummy['mpeg']['audio']['framelength'])) { + $SynchErrorsFound++; + $synchstartoffset++; + } else { + getid3_lib::safe_inc($info['mpeg']['audio']['bitrate_distribution'][$thisframebitrate]); + getid3_lib::safe_inc($info['mpeg']['audio']['stereo_distribution'][$dummy['mpeg']['audio']['channelmode']]); + getid3_lib::safe_inc($info['mpeg']['audio']['version_distribution'][$dummy['mpeg']['audio']['version']]); + $synchstartoffset += $dummy['mpeg']['audio']['framelength']; + } + $frames_scanned++; + if ($frames_scan_per_segment && (++$frames_scanned_this_segment >= $frames_scan_per_segment)) { + $this_pct_scanned = (ftell($this->getid3->fp) - $scan_start_offset[$current_segment]) / ($info['avdataend'] - $info['avdataoffset']); + if (($current_segment == 0) && (($this_pct_scanned * $max_scan_segments) >= 1)) { + // file likely contains < $max_frames_scan, just scan as one segment + $max_scan_segments = 1; + $frames_scan_per_segment = $max_frames_scan; + } else { + $pct_data_scanned += $this_pct_scanned; + break; + } + } + } + } + if ($pct_data_scanned > 0) { + $info['warning'][] = 'too many MPEG audio frames to scan, only scanned '.$frames_scanned.' frames in '.$max_scan_segments.' segments ('.number_format($pct_data_scanned * 100, 1).'% of file) and extrapolated distribution, playtime and bitrate may be incorrect.'; + foreach ($info['mpeg']['audio'] as $key1 => $value1) { + if (!preg_match('#_distribution$#i', $key1)) { + continue; + } + foreach ($value1 as $key2 => $value2) { + $info['mpeg']['audio'][$key1][$key2] = round($value2 / $pct_data_scanned); + } + } + } + + if ($SynchErrorsFound > 0) { + $info['warning'][] = 'Found '.$SynchErrorsFound.' synch errors in histogram analysis'; + //return false; + } + + $bittotal = 0; + $framecounter = 0; + foreach ($info['mpeg']['audio']['bitrate_distribution'] as $bitratevalue => $bitratecount) { + $framecounter += $bitratecount; + if ($bitratevalue != 'free') { + $bittotal += ($bitratevalue * $bitratecount); + } + } + if ($framecounter == 0) { + $info['error'][] = 'Corrupt MP3 file: framecounter == zero'; + return false; + } + $info['mpeg']['audio']['frame_count'] = getid3_lib::CastAsInt($framecounter); + $info['mpeg']['audio']['bitrate'] = ($bittotal / $framecounter); + + $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate']; + + + // Definitively set VBR vs CBR, even if the Xing/LAME/VBRI header says differently + $distinct_bitrates = 0; + foreach ($info['mpeg']['audio']['bitrate_distribution'] as $bitrate_value => $bitrate_count) { + if ($bitrate_count > 0) { + $distinct_bitrates++; + } + } + if ($distinct_bitrates > 1) { + $info['mpeg']['audio']['bitrate_mode'] = 'vbr'; + } else { + $info['mpeg']['audio']['bitrate_mode'] = 'cbr'; + } + $info['audio']['bitrate_mode'] = $info['mpeg']['audio']['bitrate_mode']; + + } + + break; // exit while() + } + } + + $SynchSeekOffset++; + if (($avdataoffset + $SynchSeekOffset) >= $info['avdataend']) { + // end of file/data + + if (empty($info['mpeg']['audio'])) { + + $info['error'][] = 'could not find valid MPEG synch before end of file'; + if (isset($info['audio']['bitrate'])) { + unset($info['audio']['bitrate']); + } + if (isset($info['mpeg']['audio'])) { + unset($info['mpeg']['audio']); + } + if (isset($info['mpeg']) && (!is_array($info['mpeg']) || empty($info['mpeg']))) { + unset($info['mpeg']); + } + return false; + + } + break; + } + + } + $info['audio']['channels'] = $info['mpeg']['audio']['channels']; + $info['audio']['channelmode'] = $info['mpeg']['audio']['channelmode']; + $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate']; + return true; + } + + + public static function MPEGaudioVersionArray() { + static $MPEGaudioVersion = array('2.5', false, '2', '1'); + return $MPEGaudioVersion; + } + + public static function MPEGaudioLayerArray() { + static $MPEGaudioLayer = array(false, 3, 2, 1); + return $MPEGaudioLayer; + } + + public static function MPEGaudioBitrateArray() { + static $MPEGaudioBitrate; + if (empty($MPEGaudioBitrate)) { + $MPEGaudioBitrate = array ( + '1' => array (1 => array('free', 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000), + 2 => array('free', 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000), + 3 => array('free', 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000) + ), + + '2' => array (1 => array('free', 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000), + 2 => array('free', 8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000), + ) + ); + $MPEGaudioBitrate['2'][3] = $MPEGaudioBitrate['2'][2]; + $MPEGaudioBitrate['2.5'] = $MPEGaudioBitrate['2']; + } + return $MPEGaudioBitrate; + } + + public static function MPEGaudioFrequencyArray() { + static $MPEGaudioFrequency; + if (empty($MPEGaudioFrequency)) { + $MPEGaudioFrequency = array ( + '1' => array(44100, 48000, 32000), + '2' => array(22050, 24000, 16000), + '2.5' => array(11025, 12000, 8000) + ); + } + return $MPEGaudioFrequency; + } + + public static function MPEGaudioChannelModeArray() { + static $MPEGaudioChannelMode = array('stereo', 'joint stereo', 'dual channel', 'mono'); + return $MPEGaudioChannelMode; + } + + public static function MPEGaudioModeExtensionArray() { + static $MPEGaudioModeExtension; + if (empty($MPEGaudioModeExtension)) { + $MPEGaudioModeExtension = array ( + 1 => array('4-31', '8-31', '12-31', '16-31'), + 2 => array('4-31', '8-31', '12-31', '16-31'), + 3 => array('', 'IS', 'MS', 'IS+MS') + ); + } + return $MPEGaudioModeExtension; + } + + public static function MPEGaudioEmphasisArray() { + static $MPEGaudioEmphasis = array('none', '50/15ms', false, 'CCIT J.17'); + return $MPEGaudioEmphasis; + } + + public static function MPEGaudioHeaderBytesValid($head4, $allowBitrate15=false) { + return self::MPEGaudioHeaderValid(self::MPEGaudioHeaderDecode($head4), false, $allowBitrate15); + } + + public static function MPEGaudioHeaderValid($rawarray, $echoerrors=false, $allowBitrate15=false) { + if (($rawarray['synch'] & 0x0FFE) != 0x0FFE) { + return false; + } + + static $MPEGaudioVersionLookup; + static $MPEGaudioLayerLookup; + static $MPEGaudioBitrateLookup; + static $MPEGaudioFrequencyLookup; + static $MPEGaudioChannelModeLookup; + static $MPEGaudioModeExtensionLookup; + static $MPEGaudioEmphasisLookup; + if (empty($MPEGaudioVersionLookup)) { + $MPEGaudioVersionLookup = self::MPEGaudioVersionArray(); + $MPEGaudioLayerLookup = self::MPEGaudioLayerArray(); + $MPEGaudioBitrateLookup = self::MPEGaudioBitrateArray(); + $MPEGaudioFrequencyLookup = self::MPEGaudioFrequencyArray(); + $MPEGaudioChannelModeLookup = self::MPEGaudioChannelModeArray(); + $MPEGaudioModeExtensionLookup = self::MPEGaudioModeExtensionArray(); + $MPEGaudioEmphasisLookup = self::MPEGaudioEmphasisArray(); + } + + if (isset($MPEGaudioVersionLookup[$rawarray['version']])) { + $decodedVersion = $MPEGaudioVersionLookup[$rawarray['version']]; + } else { + echo ($echoerrors ? "\n".'invalid Version ('.$rawarray['version'].')' : ''); + return false; + } + if (isset($MPEGaudioLayerLookup[$rawarray['layer']])) { + $decodedLayer = $MPEGaudioLayerLookup[$rawarray['layer']]; + } else { + echo ($echoerrors ? "\n".'invalid Layer ('.$rawarray['layer'].')' : ''); + return false; + } + if (!isset($MPEGaudioBitrateLookup[$decodedVersion][$decodedLayer][$rawarray['bitrate']])) { + echo ($echoerrors ? "\n".'invalid Bitrate ('.$rawarray['bitrate'].')' : ''); + if ($rawarray['bitrate'] == 15) { + // known issue in LAME 3.90 - 3.93.1 where free-format has bitrate ID of 15 instead of 0 + // let it go through here otherwise file will not be identified + if (!$allowBitrate15) { + return false; + } + } else { + return false; + } + } + if (!isset($MPEGaudioFrequencyLookup[$decodedVersion][$rawarray['sample_rate']])) { + echo ($echoerrors ? "\n".'invalid Frequency ('.$rawarray['sample_rate'].')' : ''); + return false; + } + if (!isset($MPEGaudioChannelModeLookup[$rawarray['channelmode']])) { + echo ($echoerrors ? "\n".'invalid ChannelMode ('.$rawarray['channelmode'].')' : ''); + return false; + } + if (!isset($MPEGaudioModeExtensionLookup[$decodedLayer][$rawarray['modeextension']])) { + echo ($echoerrors ? "\n".'invalid Mode Extension ('.$rawarray['modeextension'].')' : ''); + return false; + } + if (!isset($MPEGaudioEmphasisLookup[$rawarray['emphasis']])) { + echo ($echoerrors ? "\n".'invalid Emphasis ('.$rawarray['emphasis'].')' : ''); + return false; + } + // These are just either set or not set, you can't mess that up :) + // $rawarray['protection']; + // $rawarray['padding']; + // $rawarray['private']; + // $rawarray['copyright']; + // $rawarray['original']; + + return true; + } + + public static function MPEGaudioHeaderDecode($Header4Bytes) { + // AAAA AAAA AAAB BCCD EEEE FFGH IIJJ KLMM + // A - Frame sync (all bits set) + // B - MPEG Audio version ID + // C - Layer description + // D - Protection bit + // E - Bitrate index + // F - Sampling rate frequency index + // G - Padding bit + // H - Private bit + // I - Channel Mode + // J - Mode extension (Only if Joint stereo) + // K - Copyright + // L - Original + // M - Emphasis + + if (strlen($Header4Bytes) != 4) { + return false; + } + + $MPEGrawHeader['synch'] = (getid3_lib::BigEndian2Int(substr($Header4Bytes, 0, 2)) & 0xFFE0) >> 4; + $MPEGrawHeader['version'] = (ord($Header4Bytes{1}) & 0x18) >> 3; // BB + $MPEGrawHeader['layer'] = (ord($Header4Bytes{1}) & 0x06) >> 1; // CC + $MPEGrawHeader['protection'] = (ord($Header4Bytes{1}) & 0x01); // D + $MPEGrawHeader['bitrate'] = (ord($Header4Bytes{2}) & 0xF0) >> 4; // EEEE + $MPEGrawHeader['sample_rate'] = (ord($Header4Bytes{2}) & 0x0C) >> 2; // FF + $MPEGrawHeader['padding'] = (ord($Header4Bytes{2}) & 0x02) >> 1; // G + $MPEGrawHeader['private'] = (ord($Header4Bytes{2}) & 0x01); // H + $MPEGrawHeader['channelmode'] = (ord($Header4Bytes{3}) & 0xC0) >> 6; // II + $MPEGrawHeader['modeextension'] = (ord($Header4Bytes{3}) & 0x30) >> 4; // JJ + $MPEGrawHeader['copyright'] = (ord($Header4Bytes{3}) & 0x08) >> 3; // K + $MPEGrawHeader['original'] = (ord($Header4Bytes{3}) & 0x04) >> 2; // L + $MPEGrawHeader['emphasis'] = (ord($Header4Bytes{3}) & 0x03); // MM + + return $MPEGrawHeader; + } + + public static function MPEGaudioFrameLength(&$bitrate, &$version, &$layer, $padding, &$samplerate) { + static $AudioFrameLengthCache = array(); + + if (!isset($AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate])) { + $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate] = false; + if ($bitrate != 'free') { + + if ($version == '1') { + + if ($layer == '1') { + + // For Layer I slot is 32 bits long + $FrameLengthCoefficient = 48; + $SlotLength = 4; + + } else { // Layer 2 / 3 + + // for Layer 2 and Layer 3 slot is 8 bits long. + $FrameLengthCoefficient = 144; + $SlotLength = 1; + + } + + } else { // MPEG-2 / MPEG-2.5 + + if ($layer == '1') { + + // For Layer I slot is 32 bits long + $FrameLengthCoefficient = 24; + $SlotLength = 4; + + } elseif ($layer == '2') { + + // for Layer 2 and Layer 3 slot is 8 bits long. + $FrameLengthCoefficient = 144; + $SlotLength = 1; + + } else { // layer 3 + + // for Layer 2 and Layer 3 slot is 8 bits long. + $FrameLengthCoefficient = 72; + $SlotLength = 1; + + } + + } + + // FrameLengthInBytes = ((Coefficient * BitRate) / SampleRate) + Padding + if ($samplerate > 0) { + $NewFramelength = ($FrameLengthCoefficient * $bitrate) / $samplerate; + $NewFramelength = floor($NewFramelength / $SlotLength) * $SlotLength; // round to next-lower multiple of SlotLength (1 byte for Layer 2/3, 4 bytes for Layer I) + if ($padding) { + $NewFramelength += $SlotLength; + } + $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate] = (int) $NewFramelength; + } + } + } + return $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate]; + } + + public static function ClosestStandardMP3Bitrate($bit_rate) { + static $standard_bit_rates = array (320000, 256000, 224000, 192000, 160000, 128000, 112000, 96000, 80000, 64000, 56000, 48000, 40000, 32000, 24000, 16000, 8000); + static $bit_rate_table = array (0=>'-'); + $round_bit_rate = intval(round($bit_rate, -3)); + if (!isset($bit_rate_table[$round_bit_rate])) { + if ($round_bit_rate > max($standard_bit_rates)) { + $bit_rate_table[$round_bit_rate] = round($bit_rate, 2 - strlen($bit_rate)); + } else { + $bit_rate_table[$round_bit_rate] = max($standard_bit_rates); + foreach ($standard_bit_rates as $standard_bit_rate) { + if ($round_bit_rate >= $standard_bit_rate + (($bit_rate_table[$round_bit_rate] - $standard_bit_rate) / 2)) { + break; + } + $bit_rate_table[$round_bit_rate] = $standard_bit_rate; + } + } + } + return $bit_rate_table[$round_bit_rate]; + } + + public static function XingVBRidOffset($version, $channelmode) { + static $XingVBRidOffsetCache = array(); + if (empty($XingVBRidOffset)) { + $XingVBRidOffset = array ( + '1' => array ('mono' => 0x15, // 4 + 17 = 21 + 'stereo' => 0x24, // 4 + 32 = 36 + 'joint stereo' => 0x24, + 'dual channel' => 0x24 + ), + + '2' => array ('mono' => 0x0D, // 4 + 9 = 13 + 'stereo' => 0x15, // 4 + 17 = 21 + 'joint stereo' => 0x15, + 'dual channel' => 0x15 + ), + + '2.5' => array ('mono' => 0x15, + 'stereo' => 0x15, + 'joint stereo' => 0x15, + 'dual channel' => 0x15 + ) + ); + } + return $XingVBRidOffset[$version][$channelmode]; + } + + public static function LAMEvbrMethodLookup($VBRmethodID) { + static $LAMEvbrMethodLookup = array( + 0x00 => 'unknown', + 0x01 => 'cbr', + 0x02 => 'abr', + 0x03 => 'vbr-old / vbr-rh', + 0x04 => 'vbr-new / vbr-mtrh', + 0x05 => 'vbr-mt', + 0x06 => 'vbr (full vbr method 4)', + 0x08 => 'cbr (constant bitrate 2 pass)', + 0x09 => 'abr (2 pass)', + 0x0F => 'reserved' + ); + return (isset($LAMEvbrMethodLookup[$VBRmethodID]) ? $LAMEvbrMethodLookup[$VBRmethodID] : ''); + } + + public static function LAMEmiscStereoModeLookup($StereoModeID) { + static $LAMEmiscStereoModeLookup = array( + 0 => 'mono', + 1 => 'stereo', + 2 => 'dual mono', + 3 => 'joint stereo', + 4 => 'forced stereo', + 5 => 'auto', + 6 => 'intensity stereo', + 7 => 'other' + ); + return (isset($LAMEmiscStereoModeLookup[$StereoModeID]) ? $LAMEmiscStereoModeLookup[$StereoModeID] : ''); + } + + public static function LAMEmiscSourceSampleFrequencyLookup($SourceSampleFrequencyID) { + static $LAMEmiscSourceSampleFrequencyLookup = array( + 0 => '<= 32 kHz', + 1 => '44.1 kHz', + 2 => '48 kHz', + 3 => '> 48kHz' + ); + return (isset($LAMEmiscSourceSampleFrequencyLookup[$SourceSampleFrequencyID]) ? $LAMEmiscSourceSampleFrequencyLookup[$SourceSampleFrequencyID] : ''); + } + + public static function LAMEsurroundInfoLookup($SurroundInfoID) { + static $LAMEsurroundInfoLookup = array( + 0 => 'no surround info', + 1 => 'DPL encoding', + 2 => 'DPL2 encoding', + 3 => 'Ambisonic encoding' + ); + return (isset($LAMEsurroundInfoLookup[$SurroundInfoID]) ? $LAMEsurroundInfoLookup[$SurroundInfoID] : 'reserved'); + } + + public static function LAMEpresetUsedLookup($LAMEtag) { + + if ($LAMEtag['preset_used_id'] == 0) { + // no preset used (LAME >=3.93) + // no preset recorded (LAME <3.93) + return ''; + } + $LAMEpresetUsedLookup = array(); + + ///// THIS PART CANNOT BE STATIC . + for ($i = 8; $i <= 320; $i++) { + switch ($LAMEtag['vbr_method']) { + case 'cbr': + $LAMEpresetUsedLookup[$i] = '--alt-preset '.$LAMEtag['vbr_method'].' '.$i; + break; + case 'abr': + default: // other VBR modes shouldn't be here(?) + $LAMEpresetUsedLookup[$i] = '--alt-preset '.$i; + break; + } + } + + // named old-style presets (studio, phone, voice, etc) are handled in GuessEncoderOptions() + + // named alt-presets + $LAMEpresetUsedLookup[1000] = '--r3mix'; + $LAMEpresetUsedLookup[1001] = '--alt-preset standard'; + $LAMEpresetUsedLookup[1002] = '--alt-preset extreme'; + $LAMEpresetUsedLookup[1003] = '--alt-preset insane'; + $LAMEpresetUsedLookup[1004] = '--alt-preset fast standard'; + $LAMEpresetUsedLookup[1005] = '--alt-preset fast extreme'; + $LAMEpresetUsedLookup[1006] = '--alt-preset medium'; + $LAMEpresetUsedLookup[1007] = '--alt-preset fast medium'; + + // LAME 3.94 additions/changes + $LAMEpresetUsedLookup[1010] = '--preset portable'; // 3.94a15 Oct 21 2003 + $LAMEpresetUsedLookup[1015] = '--preset radio'; // 3.94a15 Oct 21 2003 + + $LAMEpresetUsedLookup[320] = '--preset insane'; // 3.94a15 Nov 12 2003 + $LAMEpresetUsedLookup[410] = '-V9'; + $LAMEpresetUsedLookup[420] = '-V8'; + $LAMEpresetUsedLookup[440] = '-V6'; + $LAMEpresetUsedLookup[430] = '--preset radio'; // 3.94a15 Nov 12 2003 + $LAMEpresetUsedLookup[450] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'portable'; // 3.94a15 Nov 12 2003 + $LAMEpresetUsedLookup[460] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'medium'; // 3.94a15 Nov 12 2003 + $LAMEpresetUsedLookup[470] = '--r3mix'; // 3.94b1 Dec 18 2003 + $LAMEpresetUsedLookup[480] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'standard'; // 3.94a15 Nov 12 2003 + $LAMEpresetUsedLookup[490] = '-V1'; + $LAMEpresetUsedLookup[500] = '--preset '.(($LAMEtag['raw']['vbr_method'] == 4) ? 'fast ' : '').'extreme'; // 3.94a15 Nov 12 2003 + + return (isset($LAMEpresetUsedLookup[$LAMEtag['preset_used_id']]) ? $LAMEpresetUsedLookup[$LAMEtag['preset_used_id']] : 'new/unknown preset: '.$LAMEtag['preset_used_id'].' - report to info@getid3.org'); + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.audio.ogg.php b/extensions/TimedMediaHandler/libs/getid3/module.audio.ogg.php new file mode 100644 index 00000000..a2a35aad --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.audio.ogg.php @@ -0,0 +1,671 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.audio.ogg.php // +// module for analyzing Ogg Vorbis, OggFLAC and Speex files // +// dependencies: module.audio.flac.php // +// /// +///////////////////////////////////////////////////////////////// + +getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.flac.php', __FILE__, true); + +class getid3_ogg extends getid3_handler +{ + // http://xiph.org/vorbis/doc/Vorbis_I_spec.html + public function Analyze() { + $info = &$this->getid3->info; + + $info['fileformat'] = 'ogg'; + + // Warn about illegal tags - only vorbiscomments are allowed + if (isset($info['id3v2'])) { + $info['warning'][] = 'Illegal ID3v2 tag present.'; + } + if (isset($info['id3v1'])) { + $info['warning'][] = 'Illegal ID3v1 tag present.'; + } + if (isset($info['ape'])) { + $info['warning'][] = 'Illegal APE tag present.'; + } + + + // Page 1 - Stream Header + + $this->fseek($info['avdataoffset']); + + $oggpageinfo = $this->ParseOggPageHeader(); + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo; + + if ($this->ftell() >= $this->getid3->fread_buffer_size()) { + $info['error'][] = 'Could not find start of Ogg page in the first '.$this->getid3->fread_buffer_size().' bytes (this might not be an Ogg-Vorbis file?)'; + unset($info['fileformat']); + unset($info['ogg']); + return false; + } + + $filedata = $this->fread($oggpageinfo['page_length']); + $filedataoffset = 0; + + if (substr($filedata, 0, 4) == 'fLaC') { + + $info['audio']['dataformat'] = 'flac'; + $info['audio']['bitrate_mode'] = 'vbr'; + $info['audio']['lossless'] = true; + + } elseif (substr($filedata, 1, 6) == 'vorbis') { + + $this->ParseVorbisPageHeader($filedata, $filedataoffset, $oggpageinfo); + + } elseif (substr($filedata, 0, 8) == 'Speex ') { + + // http://www.speex.org/manual/node10.html + + $info['audio']['dataformat'] = 'speex'; + $info['mime_type'] = 'audio/speex'; + $info['audio']['bitrate_mode'] = 'abr'; + $info['audio']['lossless'] = false; + + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_string'] = substr($filedata, $filedataoffset, 8); // hard-coded to 'Speex ' + $filedataoffset += 8; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version'] = substr($filedata, $filedataoffset, 20); + $filedataoffset += 20; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version_id'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['header_size'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['rate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode_bitstream_version'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['nb_channels'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['bitrate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['framesize'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['vbr'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['frames_per_packet'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['extra_headers'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['reserved1'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['reserved2'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + + $info['speex']['speex_version'] = trim($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version']); + $info['speex']['sample_rate'] = $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['rate']; + $info['speex']['channels'] = $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['nb_channels']; + $info['speex']['vbr'] = (bool) $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['vbr']; + $info['speex']['band_type'] = $this->SpeexBandModeLookup($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode']); + + $info['audio']['sample_rate'] = $info['speex']['sample_rate']; + $info['audio']['channels'] = $info['speex']['channels']; + if ($info['speex']['vbr']) { + $info['audio']['bitrate_mode'] = 'vbr'; + } + + + } elseif (substr($filedata, 0, 8) == "fishead\x00") { + + // Ogg Skeleton version 3.0 Format Specification + // http://xiph.org/ogg/doc/skeleton.html + $filedataoffset += 8; + $info['ogg']['skeleton']['fishead']['raw']['version_major'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 2)); + $filedataoffset += 2; + $info['ogg']['skeleton']['fishead']['raw']['version_minor'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 2)); + $filedataoffset += 2; + $info['ogg']['skeleton']['fishead']['raw']['presentationtime_numerator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8)); + $filedataoffset += 8; + $info['ogg']['skeleton']['fishead']['raw']['presentationtime_denominator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8)); + $filedataoffset += 8; + $info['ogg']['skeleton']['fishead']['raw']['basetime_numerator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8)); + $filedataoffset += 8; + $info['ogg']['skeleton']['fishead']['raw']['basetime_denominator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8)); + $filedataoffset += 8; + $info['ogg']['skeleton']['fishead']['raw']['utc'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 20)); + $filedataoffset += 20; + + $info['ogg']['skeleton']['fishead']['version'] = $info['ogg']['skeleton']['fishead']['raw']['version_major'].'.'.$info['ogg']['skeleton']['fishead']['raw']['version_minor']; + $info['ogg']['skeleton']['fishead']['presentationtime'] = $info['ogg']['skeleton']['fishead']['raw']['presentationtime_numerator'] / $info['ogg']['skeleton']['fishead']['raw']['presentationtime_denominator']; + $info['ogg']['skeleton']['fishead']['basetime'] = $info['ogg']['skeleton']['fishead']['raw']['basetime_numerator'] / $info['ogg']['skeleton']['fishead']['raw']['basetime_denominator']; + $info['ogg']['skeleton']['fishead']['utc'] = $info['ogg']['skeleton']['fishead']['raw']['utc']; + + + $counter = 0; + do { + $oggpageinfo = $this->ParseOggPageHeader(); + $info['ogg']['pageheader'][$oggpageinfo['page_seqno'].'.'.$counter++] = $oggpageinfo; + $filedata = $this->fread($oggpageinfo['page_length']); + $this->fseek($oggpageinfo['page_end_offset']); + + if (substr($filedata, 0, 8) == "fisbone\x00") { + + $filedataoffset = 8; + $info['ogg']['skeleton']['fisbone']['raw']['message_header_offset'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['skeleton']['fisbone']['raw']['serial_number'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['skeleton']['fisbone']['raw']['number_header_packets'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['skeleton']['fisbone']['raw']['granulerate_numerator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8)); + $filedataoffset += 8; + $info['ogg']['skeleton']['fisbone']['raw']['granulerate_denominator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8)); + $filedataoffset += 8; + $info['ogg']['skeleton']['fisbone']['raw']['basegranule'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8)); + $filedataoffset += 8; + $info['ogg']['skeleton']['fisbone']['raw']['preroll'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['skeleton']['fisbone']['raw']['granuleshift'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); + $filedataoffset += 1; + $info['ogg']['skeleton']['fisbone']['raw']['padding'] = substr($filedata, $filedataoffset, 3); + $filedataoffset += 3; + + } elseif (substr($filedata, 1, 6) == 'theora') { + + $info['video']['dataformat'] = 'theora'; + $info['error'][] = 'Ogg Theora not correctly handled in this version of getID3 ['.$this->getid3->version().']'; + //break; + + } elseif (substr($filedata, 1, 6) == 'vorbis') { + + $this->ParseVorbisPageHeader($filedata, $filedataoffset, $oggpageinfo); + + } else { + $info['error'][] = 'unexpected'; + //break; + } + //} while ($oggpageinfo['page_seqno'] == 0); + } while (($oggpageinfo['page_seqno'] == 0) && (substr($filedata, 0, 8) != "fisbone\x00")); + + $this->fseek($oggpageinfo['page_start_offset']); + + $info['error'][] = 'Ogg Skeleton not correctly handled in this version of getID3 ['.$this->getid3->version().']'; + //return false; + + } else { + + $info['error'][] = 'Expecting either "Speex " or "vorbis" identifier strings, found "'.substr($filedata, 0, 8).'"'; + unset($info['ogg']); + unset($info['mime_type']); + return false; + + } + + // Page 2 - Comment Header + $oggpageinfo = $this->ParseOggPageHeader(); + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo; + + switch ($info['audio']['dataformat']) { + case 'vorbis': + $filedata = $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']); + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type'] = getid3_lib::LittleEndian2Int(substr($filedata, 0, 1)); + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, 1, 6); // hard-coded to 'vorbis' + + $this->ParseVorbisComments(); + break; + + case 'flac': + $flac = new getid3_flac($this->getid3); + if (!$flac->parseMETAdata()) { + $info['error'][] = 'Failed to parse FLAC headers'; + return false; + } + unset($flac); + break; + + case 'speex': + $this->fseek($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length'], SEEK_CUR); + $this->ParseVorbisComments(); + break; + } + + + // Last Page - Number of Samples + if (!getid3_lib::intValueSupported($info['avdataend'])) { + + $info['warning'][] = 'Unable to parse Ogg end chunk file (PHP does not support file operations beyond '.round(PHP_INT_MAX / 1073741824).'GB)'; + + } else { + + $this->fseek(max($info['avdataend'] - $this->getid3->fread_buffer_size(), 0)); + $LastChunkOfOgg = strrev($this->fread($this->getid3->fread_buffer_size())); + if ($LastOggSpostion = strpos($LastChunkOfOgg, 'SggO')) { + $this->fseek($info['avdataend'] - ($LastOggSpostion + strlen('SggO'))); + $info['avdataend'] = $this->ftell(); + $info['ogg']['pageheader']['eos'] = $this->ParseOggPageHeader(); + $info['ogg']['samples'] = $info['ogg']['pageheader']['eos']['pcm_abs_position']; + if ($info['ogg']['samples'] == 0) { + $info['error'][] = 'Corrupt Ogg file: eos.number of samples == zero'; + return false; + } + if (!empty($info['audio']['sample_rate'])) { + $info['ogg']['bitrate_average'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / ($info['ogg']['samples'] / $info['audio']['sample_rate']); + } + } + + } + + if (!empty($info['ogg']['bitrate_average'])) { + $info['audio']['bitrate'] = $info['ogg']['bitrate_average']; + } elseif (!empty($info['ogg']['bitrate_nominal'])) { + $info['audio']['bitrate'] = $info['ogg']['bitrate_nominal']; + } elseif (!empty($info['ogg']['bitrate_min']) && !empty($info['ogg']['bitrate_max'])) { + $info['audio']['bitrate'] = ($info['ogg']['bitrate_min'] + $info['ogg']['bitrate_max']) / 2; + } + if (isset($info['audio']['bitrate']) && !isset($info['playtime_seconds'])) { + if ($info['audio']['bitrate'] == 0) { + $info['error'][] = 'Corrupt Ogg file: bitrate_audio == zero'; + return false; + } + $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $info['audio']['bitrate']); + } + + if (isset($info['ogg']['vendor'])) { + $info['audio']['encoder'] = preg_replace('/^Encoded with /', '', $info['ogg']['vendor']); + + // Vorbis only + if ($info['audio']['dataformat'] == 'vorbis') { + + // Vorbis 1.0 starts with Xiph.Org + if (preg_match('/^Xiph.Org/', $info['audio']['encoder'])) { + + if ($info['audio']['bitrate_mode'] == 'abr') { + + // Set -b 128 on abr files + $info['audio']['encoder_options'] = '-b '.round($info['ogg']['bitrate_nominal'] / 1000); + + } elseif (($info['audio']['bitrate_mode'] == 'vbr') && ($info['audio']['channels'] == 2) && ($info['audio']['sample_rate'] >= 44100) && ($info['audio']['sample_rate'] <= 48000)) { + // Set -q N on vbr files + $info['audio']['encoder_options'] = '-q '.$this->get_quality_from_nominal_bitrate($info['ogg']['bitrate_nominal']); + + } + } + + if (empty($info['audio']['encoder_options']) && !empty($info['ogg']['bitrate_nominal'])) { + $info['audio']['encoder_options'] = 'Nominal bitrate: '.intval(round($info['ogg']['bitrate_nominal'] / 1000)).'kbps'; + } + } + } + + return true; + } + + public function ParseVorbisPageHeader(&$filedata, &$filedataoffset, &$oggpageinfo) { + $info = &$this->getid3->info; + $info['audio']['dataformat'] = 'vorbis'; + $info['audio']['lossless'] = false; + + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); + $filedataoffset += 1; + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, $filedataoffset, 6); // hard-coded to 'vorbis' + $filedataoffset += 6; + $info['ogg']['bitstreamversion'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['numberofchannels'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); + $filedataoffset += 1; + $info['audio']['channels'] = $info['ogg']['numberofchannels']; + $info['ogg']['samplerate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + if ($info['ogg']['samplerate'] == 0) { + $info['error'][] = 'Corrupt Ogg file: sample rate == zero'; + return false; + } + $info['audio']['sample_rate'] = $info['ogg']['samplerate']; + $info['ogg']['samples'] = 0; // filled in later + $info['ogg']['bitrate_average'] = 0; // filled in later + $info['ogg']['bitrate_max'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['bitrate_nominal'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['bitrate_min'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $info['ogg']['blocksize_small'] = pow(2, getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0x0F); + $info['ogg']['blocksize_large'] = pow(2, (getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0xF0) >> 4); + $info['ogg']['stop_bit'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); // must be 1, marks end of packet + + $info['audio']['bitrate_mode'] = 'vbr'; // overridden if actually abr + if ($info['ogg']['bitrate_max'] == 0xFFFFFFFF) { + unset($info['ogg']['bitrate_max']); + $info['audio']['bitrate_mode'] = 'abr'; + } + if ($info['ogg']['bitrate_nominal'] == 0xFFFFFFFF) { + unset($info['ogg']['bitrate_nominal']); + } + if ($info['ogg']['bitrate_min'] == 0xFFFFFFFF) { + unset($info['ogg']['bitrate_min']); + $info['audio']['bitrate_mode'] = 'abr'; + } + return true; + } + + public function ParseOggPageHeader() { + // http://xiph.org/ogg/vorbis/doc/framing.html + $oggheader['page_start_offset'] = $this->ftell(); // where we started from in the file + + $filedata = $this->fread($this->getid3->fread_buffer_size()); + $filedataoffset = 0; + while ((substr($filedata, $filedataoffset++, 4) != 'OggS')) { + if (($this->ftell() - $oggheader['page_start_offset']) >= $this->getid3->fread_buffer_size()) { + // should be found before here + return false; + } + if ((($filedataoffset + 28) > strlen($filedata)) || (strlen($filedata) < 28)) { + if ($this->feof() || (($filedata .= $this->fread($this->getid3->fread_buffer_size())) === false)) { + // get some more data, unless eof, in which case fail + return false; + } + } + } + $filedataoffset += strlen('OggS') - 1; // page, delimited by 'OggS' + + $oggheader['stream_structver'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); + $filedataoffset += 1; + $oggheader['flags_raw'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); + $filedataoffset += 1; + $oggheader['flags']['fresh'] = (bool) ($oggheader['flags_raw'] & 0x01); // fresh packet + $oggheader['flags']['bos'] = (bool) ($oggheader['flags_raw'] & 0x02); // first page of logical bitstream (bos) + $oggheader['flags']['eos'] = (bool) ($oggheader['flags_raw'] & 0x04); // last page of logical bitstream (eos) + + $oggheader['pcm_abs_position'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8)); + $filedataoffset += 8; + $oggheader['stream_serialno'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $oggheader['page_seqno'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $oggheader['page_checksum'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4)); + $filedataoffset += 4; + $oggheader['page_segments'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); + $filedataoffset += 1; + $oggheader['page_length'] = 0; + for ($i = 0; $i < $oggheader['page_segments']; $i++) { + $oggheader['segment_table'][$i] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); + $filedataoffset += 1; + $oggheader['page_length'] += $oggheader['segment_table'][$i]; + } + $oggheader['header_end_offset'] = $oggheader['page_start_offset'] + $filedataoffset; + $oggheader['page_end_offset'] = $oggheader['header_end_offset'] + $oggheader['page_length']; + $this->fseek($oggheader['header_end_offset']); + + return $oggheader; + } + + // http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810005 + public function ParseVorbisComments() { + $info = &$this->getid3->info; + + $OriginalOffset = $this->ftell(); + $commentdataoffset = 0; + $VorbisCommentPage = 1; + + switch ($info['audio']['dataformat']) { + case 'vorbis': + case 'speex': + $CommentStartOffset = $info['ogg']['pageheader'][$VorbisCommentPage]['page_start_offset']; // Second Ogg page, after header block + $this->fseek($CommentStartOffset); + $commentdataoffset = 27 + $info['ogg']['pageheader'][$VorbisCommentPage]['page_segments']; + $commentdata = $this->fread(self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1) + $commentdataoffset); + + if ($info['audio']['dataformat'] == 'vorbis') { + $commentdataoffset += (strlen('vorbis') + 1); + } + break; + + case 'flac': + $CommentStartOffset = $info['flac']['VORBIS_COMMENT']['raw']['offset'] + 4; + $this->fseek($CommentStartOffset); + $commentdata = $this->fread($info['flac']['VORBIS_COMMENT']['raw']['block_length']); + break; + + default: + return false; + } + + $VendorSize = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4)); + $commentdataoffset += 4; + + $info['ogg']['vendor'] = substr($commentdata, $commentdataoffset, $VendorSize); + $commentdataoffset += $VendorSize; + + $CommentsCount = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4)); + $commentdataoffset += 4; + $info['avdataoffset'] = $CommentStartOffset + $commentdataoffset; + + $basicfields = array('TITLE', 'ARTIST', 'ALBUM', 'TRACKNUMBER', 'GENRE', 'DATE', 'DESCRIPTION', 'COMMENT'); + $ThisFileInfo_ogg_comments_raw = &$info['ogg']['comments_raw']; + for ($i = 0; $i < $CommentsCount; $i++) { + + $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] = $CommentStartOffset + $commentdataoffset; + + if ($this->ftell() < ($ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] + 4)) { + if ($oggpageinfo = $this->ParseOggPageHeader()) { + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo; + + $VorbisCommentPage++; + + // First, save what we haven't read yet + $AsYetUnusedData = substr($commentdata, $commentdataoffset); + + // Then take that data off the end + $commentdata = substr($commentdata, 0, $commentdataoffset); + + // Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct + $commentdata .= str_repeat("\x00", 27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']); + $commentdataoffset += (27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']); + + // Finally, stick the unused data back on the end + $commentdata .= $AsYetUnusedData; + + //$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']); + $commentdata .= $this->fread($this->OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1)); + } + + } + $ThisFileInfo_ogg_comments_raw[$i]['size'] = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4)); + + // replace avdataoffset with position just after the last vorbiscomment + $info['avdataoffset'] = $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] + $ThisFileInfo_ogg_comments_raw[$i]['size'] + 4; + + $commentdataoffset += 4; + while ((strlen($commentdata) - $commentdataoffset) < $ThisFileInfo_ogg_comments_raw[$i]['size']) { + if (($ThisFileInfo_ogg_comments_raw[$i]['size'] > $info['avdataend']) || ($ThisFileInfo_ogg_comments_raw[$i]['size'] < 0)) { + $info['warning'][] = 'Invalid Ogg comment size (comment #'.$i.', claims to be '.number_format($ThisFileInfo_ogg_comments_raw[$i]['size']).' bytes) - aborting reading comments'; + break 2; + } + + $VorbisCommentPage++; + + $oggpageinfo = $this->ParseOggPageHeader(); + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo; + + // First, save what we haven't read yet + $AsYetUnusedData = substr($commentdata, $commentdataoffset); + + // Then take that data off the end + $commentdata = substr($commentdata, 0, $commentdataoffset); + + // Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct + $commentdata .= str_repeat("\x00", 27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']); + $commentdataoffset += (27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']); + + // Finally, stick the unused data back on the end + $commentdata .= $AsYetUnusedData; + + //$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']); + if (!isset($info['ogg']['pageheader'][$VorbisCommentPage])) { + $info['warning'][] = 'undefined Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell(); + break; + } + $readlength = self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1); + if ($readlength <= 0) { + $info['warning'][] = 'invalid length Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell(); + break; + } + $commentdata .= $this->fread($readlength); + + //$filebaseoffset += $oggpageinfo['header_end_offset'] - $oggpageinfo['page_start_offset']; + } + $ThisFileInfo_ogg_comments_raw[$i]['offset'] = $commentdataoffset; + $commentstring = substr($commentdata, $commentdataoffset, $ThisFileInfo_ogg_comments_raw[$i]['size']); + $commentdataoffset += $ThisFileInfo_ogg_comments_raw[$i]['size']; + + if (!$commentstring) { + + // no comment? + $info['warning'][] = 'Blank Ogg comment ['.$i.']'; + + } elseif (strstr($commentstring, '=')) { + + $commentexploded = explode('=', $commentstring, 2); + $ThisFileInfo_ogg_comments_raw[$i]['key'] = strtoupper($commentexploded[0]); + $ThisFileInfo_ogg_comments_raw[$i]['value'] = (isset($commentexploded[1]) ? $commentexploded[1] : ''); + + if ($ThisFileInfo_ogg_comments_raw[$i]['key'] == 'METADATA_BLOCK_PICTURE') { + + // http://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE + // The unencoded format is that of the FLAC picture block. The fields are stored in big endian order as in FLAC, picture data is stored according to the relevant standard. + // http://flac.sourceforge.net/format.html#metadata_block_picture + $flac = new getid3_flac($this->getid3); + $flac->setStringMode(base64_decode($ThisFileInfo_ogg_comments_raw[$i]['value'])); + $flac->parsePICTURE(); + $info['ogg']['comments']['picture'][] = $flac->getid3->info['flac']['PICTURE'][0]; + unset($flac); + + } elseif ($ThisFileInfo_ogg_comments_raw[$i]['key'] == 'COVERART') { + + $data = base64_decode($ThisFileInfo_ogg_comments_raw[$i]['value']); + $this->notice('Found deprecated COVERART tag, it should be replaced in honor of METADATA_BLOCK_PICTURE structure'); + /** @todo use 'coverartmime' where available */ + $imageinfo = getid3_lib::GetDataImageSize($data); + if ($imageinfo === false || !isset($imageinfo['mime'])) { + $this->warning('COVERART vorbiscomment tag contains invalid image'); + continue; + } + + $ogg = new self($this->getid3); + $ogg->setStringMode($data); + $info['ogg']['comments']['picture'][] = array( + 'image_mime' => $imageinfo['mime'], + 'data' => $ogg->saveAttachment('coverart', 0, strlen($data), $imageinfo['mime']), + ); + unset($ogg); + + } else { + + $info['ogg']['comments'][strtolower($ThisFileInfo_ogg_comments_raw[$i]['key'])][] = $ThisFileInfo_ogg_comments_raw[$i]['value']; + + } + + } else { + + $info['warning'][] = '[known problem with CDex >= v1.40, < v1.50b7] Invalid Ogg comment name/value pair ['.$i.']: '.$commentstring; + + } + unset($ThisFileInfo_ogg_comments_raw[$i]); + } + unset($ThisFileInfo_ogg_comments_raw); + + + // Replay Gain Adjustment + // http://privatewww.essex.ac.uk/~djmrob/replaygain/ + if (isset($info['ogg']['comments']) && is_array($info['ogg']['comments'])) { + foreach ($info['ogg']['comments'] as $index => $commentvalue) { + switch ($index) { + case 'rg_audiophile': + case 'replaygain_album_gain': + $info['replay_gain']['album']['adjustment'] = (double) $commentvalue[0]; + unset($info['ogg']['comments'][$index]); + break; + + case 'rg_radio': + case 'replaygain_track_gain': + $info['replay_gain']['track']['adjustment'] = (double) $commentvalue[0]; + unset($info['ogg']['comments'][$index]); + break; + + case 'replaygain_album_peak': + $info['replay_gain']['album']['peak'] = (double) $commentvalue[0]; + unset($info['ogg']['comments'][$index]); + break; + + case 'rg_peak': + case 'replaygain_track_peak': + $info['replay_gain']['track']['peak'] = (double) $commentvalue[0]; + unset($info['ogg']['comments'][$index]); + break; + + case 'replaygain_reference_loudness': + $info['replay_gain']['reference_volume'] = (double) $commentvalue[0]; + unset($info['ogg']['comments'][$index]); + break; + + default: + // do nothing + break; + } + } + } + + $this->fseek($OriginalOffset); + + return true; + } + + public static function SpeexBandModeLookup($mode) { + static $SpeexBandModeLookup = array(); + if (empty($SpeexBandModeLookup)) { + $SpeexBandModeLookup[0] = 'narrow'; + $SpeexBandModeLookup[1] = 'wide'; + $SpeexBandModeLookup[2] = 'ultra-wide'; + } + return (isset($SpeexBandModeLookup[$mode]) ? $SpeexBandModeLookup[$mode] : null); + } + + + public static function OggPageSegmentLength($OggInfoArray, $SegmentNumber=1) { + for ($i = 0; $i < $SegmentNumber; $i++) { + $segmentlength = 0; + foreach ($OggInfoArray['segment_table'] as $key => $value) { + $segmentlength += $value; + if ($value < 255) { + break; + } + } + } + return $segmentlength; + } + + + public static function get_quality_from_nominal_bitrate($nominal_bitrate) { + + // decrease precision + $nominal_bitrate = $nominal_bitrate / 1000; + + if ($nominal_bitrate < 128) { + // q-1 to q4 + $qval = ($nominal_bitrate - 64) / 16; + } elseif ($nominal_bitrate < 256) { + // q4 to q8 + $qval = $nominal_bitrate / 32; + } elseif ($nominal_bitrate < 320) { + // q8 to q9 + $qval = ($nominal_bitrate + 256) / 64; + } else { + // q9 to q10 + $qval = ($nominal_bitrate + 1300) / 180; + } + //return $qval; // 5.031324 + //return intval($qval); // 5 + return round($qval, 1); // 5 or 4.9 + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.tag.id3v1.php b/extensions/TimedMediaHandler/libs/getid3/module.tag.id3v1.php new file mode 100644 index 00000000..fd9069e0 --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.tag.id3v1.php @@ -0,0 +1,359 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +// // +// module.tag.id3v1.php // +// module for analyzing ID3v1 tags // +// dependencies: NONE // +// /// +///////////////////////////////////////////////////////////////// + + +class getid3_id3v1 extends getid3_handler +{ + + public function Analyze() { + $info = &$this->getid3->info; + + if (!getid3_lib::intValueSupported($info['filesize'])) { + $info['warning'][] = 'Unable to check for ID3v1 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB'; + return false; + } + + fseek($this->getid3->fp, -256, SEEK_END); + $preid3v1 = fread($this->getid3->fp, 128); + $id3v1tag = fread($this->getid3->fp, 128); + + if (substr($id3v1tag, 0, 3) == 'TAG') { + + $info['avdataend'] = $info['filesize'] - 128; + + $ParsedID3v1['title'] = $this->cutfield(substr($id3v1tag, 3, 30)); + $ParsedID3v1['artist'] = $this->cutfield(substr($id3v1tag, 33, 30)); + $ParsedID3v1['album'] = $this->cutfield(substr($id3v1tag, 63, 30)); + $ParsedID3v1['year'] = $this->cutfield(substr($id3v1tag, 93, 4)); + $ParsedID3v1['comment'] = substr($id3v1tag, 97, 30); // can't remove nulls yet, track detection depends on them + $ParsedID3v1['genreid'] = ord(substr($id3v1tag, 127, 1)); + + // If second-last byte of comment field is null and last byte of comment field is non-null + // then this is ID3v1.1 and the comment field is 28 bytes long and the 30th byte is the track number + if (($id3v1tag{125} === "\x00") && ($id3v1tag{126} !== "\x00")) { + $ParsedID3v1['track'] = ord(substr($ParsedID3v1['comment'], 29, 1)); + $ParsedID3v1['comment'] = substr($ParsedID3v1['comment'], 0, 28); + } + $ParsedID3v1['comment'] = $this->cutfield($ParsedID3v1['comment']); + + $ParsedID3v1['genre'] = $this->LookupGenreName($ParsedID3v1['genreid']); + if (!empty($ParsedID3v1['genre'])) { + unset($ParsedID3v1['genreid']); + } + if (isset($ParsedID3v1['genre']) && (empty($ParsedID3v1['genre']) || ($ParsedID3v1['genre'] == 'Unknown'))) { + unset($ParsedID3v1['genre']); + } + + foreach ($ParsedID3v1 as $key => $value) { + $ParsedID3v1['comments'][$key][0] = $value; + } + + // ID3v1 data is supposed to be padded with NULL characters, but some taggers pad with spaces + $GoodFormatID3v1tag = $this->GenerateID3v1Tag( + $ParsedID3v1['title'], + $ParsedID3v1['artist'], + $ParsedID3v1['album'], + $ParsedID3v1['year'], + (isset($ParsedID3v1['genre']) ? $this->LookupGenreID($ParsedID3v1['genre']) : false), + $ParsedID3v1['comment'], + (!empty($ParsedID3v1['track']) ? $ParsedID3v1['track'] : '')); + $ParsedID3v1['padding_valid'] = true; + if ($id3v1tag !== $GoodFormatID3v1tag) { + $ParsedID3v1['padding_valid'] = false; + $info['warning'][] = 'Some ID3v1 fields do not use NULL characters for padding'; + } + + $ParsedID3v1['tag_offset_end'] = $info['filesize']; + $ParsedID3v1['tag_offset_start'] = $ParsedID3v1['tag_offset_end'] - 128; + + $info['id3v1'] = $ParsedID3v1; + } + + if (substr($preid3v1, 0, 3) == 'TAG') { + // The way iTunes handles tags is, well, brain-damaged. + // It completely ignores v1 if ID3v2 is present. + // This goes as far as adding a new v1 tag *even if there already is one* + + // A suspected double-ID3v1 tag has been detected, but it could be that + // the "TAG" identifier is a legitimate part of an APE or Lyrics3 tag + if (substr($preid3v1, 96, 8) == 'APETAGEX') { + // an APE tag footer was found before the last ID3v1, assume false "TAG" synch + } elseif (substr($preid3v1, 119, 6) == 'LYRICS') { + // a Lyrics3 tag footer was found before the last ID3v1, assume false "TAG" synch + } else { + // APE and Lyrics3 footers not found - assume double ID3v1 + $info['warning'][] = 'Duplicate ID3v1 tag detected - this has been known to happen with iTunes'; + $info['avdataend'] -= 128; + } + } + + return true; + } + + public static function cutfield($str) { + return trim(substr($str, 0, strcspn($str, "\x00"))); + } + + public static function ArrayOfGenres($allowSCMPXextended=false) { + static $GenreLookup = array( + 0 => 'Blues', + 1 => 'Classic Rock', + 2 => 'Country', + 3 => 'Dance', + 4 => 'Disco', + 5 => 'Funk', + 6 => 'Grunge', + 7 => 'Hip-Hop', + 8 => 'Jazz', + 9 => 'Metal', + 10 => 'New Age', + 11 => 'Oldies', + 12 => 'Other', + 13 => 'Pop', + 14 => 'R&B', + 15 => 'Rap', + 16 => 'Reggae', + 17 => 'Rock', + 18 => 'Techno', + 19 => 'Industrial', + 20 => 'Alternative', + 21 => 'Ska', + 22 => 'Death Metal', + 23 => 'Pranks', + 24 => 'Soundtrack', + 25 => 'Euro-Techno', + 26 => 'Ambient', + 27 => 'Trip-Hop', + 28 => 'Vocal', + 29 => 'Jazz+Funk', + 30 => 'Fusion', + 31 => 'Trance', + 32 => 'Classical', + 33 => 'Instrumental', + 34 => 'Acid', + 35 => 'House', + 36 => 'Game', + 37 => 'Sound Clip', + 38 => 'Gospel', + 39 => 'Noise', + 40 => 'Alt. Rock', + 41 => 'Bass', + 42 => 'Soul', + 43 => 'Punk', + 44 => 'Space', + 45 => 'Meditative', + 46 => 'Instrumental Pop', + 47 => 'Instrumental Rock', + 48 => 'Ethnic', + 49 => 'Gothic', + 50 => 'Darkwave', + 51 => 'Techno-Industrial', + 52 => 'Electronic', + 53 => 'Pop-Folk', + 54 => 'Eurodance', + 55 => 'Dream', + 56 => 'Southern Rock', + 57 => 'Comedy', + 58 => 'Cult', + 59 => 'Gangsta Rap', + 60 => 'Top 40', + 61 => 'Christian Rap', + 62 => 'Pop/Funk', + 63 => 'Jungle', + 64 => 'Native American', + 65 => 'Cabaret', + 66 => 'New Wave', + 67 => 'Psychedelic', + 68 => 'Rave', + 69 => 'Showtunes', + 70 => 'Trailer', + 71 => 'Lo-Fi', + 72 => 'Tribal', + 73 => 'Acid Punk', + 74 => 'Acid Jazz', + 75 => 'Polka', + 76 => 'Retro', + 77 => 'Musical', + 78 => 'Rock & Roll', + 79 => 'Hard Rock', + 80 => 'Folk', + 81 => 'Folk/Rock', + 82 => 'National Folk', + 83 => 'Swing', + 84 => 'Fast-Fusion', + 85 => 'Bebob', + 86 => 'Latin', + 87 => 'Revival', + 88 => 'Celtic', + 89 => 'Bluegrass', + 90 => 'Avantgarde', + 91 => 'Gothic Rock', + 92 => 'Progressive Rock', + 93 => 'Psychedelic Rock', + 94 => 'Symphonic Rock', + 95 => 'Slow Rock', + 96 => 'Big Band', + 97 => 'Chorus', + 98 => 'Easy Listening', + 99 => 'Acoustic', + 100 => 'Humour', + 101 => 'Speech', + 102 => 'Chanson', + 103 => 'Opera', + 104 => 'Chamber Music', + 105 => 'Sonata', + 106 => 'Symphony', + 107 => 'Booty Bass', + 108 => 'Primus', + 109 => 'Porn Groove', + 110 => 'Satire', + 111 => 'Slow Jam', + 112 => 'Club', + 113 => 'Tango', + 114 => 'Samba', + 115 => 'Folklore', + 116 => 'Ballad', + 117 => 'Power Ballad', + 118 => 'Rhythmic Soul', + 119 => 'Freestyle', + 120 => 'Duet', + 121 => 'Punk Rock', + 122 => 'Drum Solo', + 123 => 'A Cappella', + 124 => 'Euro-House', + 125 => 'Dance Hall', + 126 => 'Goa', + 127 => 'Drum & Bass', + 128 => 'Club-House', + 129 => 'Hardcore', + 130 => 'Terror', + 131 => 'Indie', + 132 => 'BritPop', + 133 => 'Negerpunk', + 134 => 'Polsk Punk', + 135 => 'Beat', + 136 => 'Christian Gangsta Rap', + 137 => 'Heavy Metal', + 138 => 'Black Metal', + 139 => 'Crossover', + 140 => 'Contemporary Christian', + 141 => 'Christian Rock', + 142 => 'Merengue', + 143 => 'Salsa', + 144 => 'Thrash Metal', + 145 => 'Anime', + 146 => 'JPop', + 147 => 'Synthpop', + + 255 => 'Unknown', + + 'CR' => 'Cover', + 'RX' => 'Remix' + ); + + static $GenreLookupSCMPX = array(); + if ($allowSCMPXextended && empty($GenreLookupSCMPX)) { + $GenreLookupSCMPX = $GenreLookup; + // http://www.geocities.co.jp/SiliconValley-Oakland/3664/alittle.html#GenreExtended + // Extended ID3v1 genres invented by SCMPX + // Note that 255 "Japanese Anime" conflicts with standard "Unknown" + $GenreLookupSCMPX[240] = 'Sacred'; + $GenreLookupSCMPX[241] = 'Northern Europe'; + $GenreLookupSCMPX[242] = 'Irish & Scottish'; + $GenreLookupSCMPX[243] = 'Scotland'; + $GenreLookupSCMPX[244] = 'Ethnic Europe'; + $GenreLookupSCMPX[245] = 'Enka'; + $GenreLookupSCMPX[246] = 'Children\'s Song'; + $GenreLookupSCMPX[247] = 'Japanese Sky'; + $GenreLookupSCMPX[248] = 'Japanese Heavy Rock'; + $GenreLookupSCMPX[249] = 'Japanese Doom Rock'; + $GenreLookupSCMPX[250] = 'Japanese J-POP'; + $GenreLookupSCMPX[251] = 'Japanese Seiyu'; + $GenreLookupSCMPX[252] = 'Japanese Ambient Techno'; + $GenreLookupSCMPX[253] = 'Japanese Moemoe'; + $GenreLookupSCMPX[254] = 'Japanese Tokusatsu'; + //$GenreLookupSCMPX[255] = 'Japanese Anime'; + } + + return ($allowSCMPXextended ? $GenreLookupSCMPX : $GenreLookup); + } + + public static function LookupGenreName($genreid, $allowSCMPXextended=true) { + switch ($genreid) { + case 'RX': + case 'CR': + break; + default: + if (!is_numeric($genreid)) { + return false; + } + $genreid = intval($genreid); // to handle 3 or '3' or '03' + break; + } + $GenreLookup = self::ArrayOfGenres($allowSCMPXextended); + return (isset($GenreLookup[$genreid]) ? $GenreLookup[$genreid] : false); + } + + public static function LookupGenreID($genre, $allowSCMPXextended=false) { + $GenreLookup = self::ArrayOfGenres($allowSCMPXextended); + $LowerCaseNoSpaceSearchTerm = strtolower(str_replace(' ', '', $genre)); + foreach ($GenreLookup as $key => $value) { + if (strtolower(str_replace(' ', '', $value)) == $LowerCaseNoSpaceSearchTerm) { + return $key; + } + } + return false; + } + + public static function StandardiseID3v1GenreName($OriginalGenre) { + if (($GenreID = self::LookupGenreID($OriginalGenre)) !== false) { + return self::LookupGenreName($GenreID); + } + return $OriginalGenre; + } + + public static function GenerateID3v1Tag($title, $artist, $album, $year, $genreid, $comment, $track='') { + $ID3v1Tag = 'TAG'; + $ID3v1Tag .= str_pad(trim(substr($title, 0, 30)), 30, "\x00", STR_PAD_RIGHT); + $ID3v1Tag .= str_pad(trim(substr($artist, 0, 30)), 30, "\x00", STR_PAD_RIGHT); + $ID3v1Tag .= str_pad(trim(substr($album, 0, 30)), 30, "\x00", STR_PAD_RIGHT); + $ID3v1Tag .= str_pad(trim(substr($year, 0, 4)), 4, "\x00", STR_PAD_LEFT); + if (!empty($track) && ($track > 0) && ($track <= 255)) { + $ID3v1Tag .= str_pad(trim(substr($comment, 0, 28)), 28, "\x00", STR_PAD_RIGHT); + $ID3v1Tag .= "\x00"; + if (gettype($track) == 'string') { + $track = (int) $track; + } + $ID3v1Tag .= chr($track); + } else { + $ID3v1Tag .= str_pad(trim(substr($comment, 0, 30)), 30, "\x00", STR_PAD_RIGHT); + } + if (($genreid < 0) || ($genreid > 147)) { + $genreid = 255; // 'unknown' genre + } + switch (gettype($genreid)) { + case 'string': + case 'integer': + $ID3v1Tag .= chr(intval($genreid)); + break; + default: + $ID3v1Tag .= chr(255); // 'unknown' genre + break; + } + + return $ID3v1Tag; + } + +} diff --git a/extensions/TimedMediaHandler/libs/getid3/module.tag.id3v2.php b/extensions/TimedMediaHandler/libs/getid3/module.tag.id3v2.php new file mode 100644 index 00000000..b08f9f9a --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/module.tag.id3v2.php @@ -0,0 +1,3414 @@ +<?php +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// See readme.txt for more details // +///////////////////////////////////////////////////////////////// +/// // +// module.tag.id3v2.php // +// module for analyzing ID3v2 tags // +// dependencies: module.tag.id3v1.php // +// /// +///////////////////////////////////////////////////////////////// + +getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true); + +class getid3_id3v2 extends getid3_handler +{ + public $StartingOffset = 0; + + public function Analyze() { + $info = &$this->getid3->info; + + // Overall tag structure: + // +-----------------------------+ + // | Header (10 bytes) | + // +-----------------------------+ + // | Extended Header | + // | (variable length, OPTIONAL) | + // +-----------------------------+ + // | Frames (variable length) | + // +-----------------------------+ + // | Padding | + // | (variable length, OPTIONAL) | + // +-----------------------------+ + // | Footer (10 bytes, OPTIONAL) | + // +-----------------------------+ + + // Header + // ID3v2/file identifier "ID3" + // ID3v2 version $04 00 + // ID3v2 flags (%ab000000 in v2.2, %abc00000 in v2.3, %abcd0000 in v2.4.x) + // ID3v2 size 4 * %0xxxxxxx + + + // shortcuts + $info['id3v2']['header'] = true; + $thisfile_id3v2 = &$info['id3v2']; + $thisfile_id3v2['flags'] = array(); + $thisfile_id3v2_flags = &$thisfile_id3v2['flags']; + + + fseek($this->getid3->fp, $this->StartingOffset, SEEK_SET); + $header = fread($this->getid3->fp, 10); + if (substr($header, 0, 3) == 'ID3' && strlen($header) == 10) { + + $thisfile_id3v2['majorversion'] = ord($header{3}); + $thisfile_id3v2['minorversion'] = ord($header{4}); + + // shortcut + $id3v2_majorversion = &$thisfile_id3v2['majorversion']; + + } else { + + unset($info['id3v2']); + return false; + + } + + if ($id3v2_majorversion > 4) { // this script probably won't correctly parse ID3v2.5.x and above (if it ever exists) + + $info['error'][] = 'this script only parses up to ID3v2.4.x - this tag is ID3v2.'.$id3v2_majorversion.'.'.$thisfile_id3v2['minorversion']; + return false; + + } + + $id3_flags = ord($header{5}); + switch ($id3v2_majorversion) { + case 2: + // %ab000000 in v2.2 + $thisfile_id3v2_flags['unsynch'] = (bool) ($id3_flags & 0x80); // a - Unsynchronisation + $thisfile_id3v2_flags['compression'] = (bool) ($id3_flags & 0x40); // b - Compression + break; + + case 3: + // %abc00000 in v2.3 + $thisfile_id3v2_flags['unsynch'] = (bool) ($id3_flags & 0x80); // a - Unsynchronisation + $thisfile_id3v2_flags['exthead'] = (bool) ($id3_flags & 0x40); // b - Extended header + $thisfile_id3v2_flags['experim'] = (bool) ($id3_flags & 0x20); // c - Experimental indicator + break; + + case 4: + // %abcd0000 in v2.4 + $thisfile_id3v2_flags['unsynch'] = (bool) ($id3_flags & 0x80); // a - Unsynchronisation + $thisfile_id3v2_flags['exthead'] = (bool) ($id3_flags & 0x40); // b - Extended header + $thisfile_id3v2_flags['experim'] = (bool) ($id3_flags & 0x20); // c - Experimental indicator + $thisfile_id3v2_flags['isfooter'] = (bool) ($id3_flags & 0x10); // d - Footer present + break; + } + + $thisfile_id3v2['headerlength'] = getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length + + $thisfile_id3v2['tag_offset_start'] = $this->StartingOffset; + $thisfile_id3v2['tag_offset_end'] = $thisfile_id3v2['tag_offset_start'] + $thisfile_id3v2['headerlength']; + + + + // create 'encoding' key - used by getid3::HandleAllTags() + // in ID3v2 every field can have it's own encoding type + // so force everything to UTF-8 so it can be handled consistantly + $thisfile_id3v2['encoding'] = 'UTF-8'; + + + // Frames + + // All ID3v2 frames consists of one frame header followed by one or more + // fields containing the actual information. The header is always 10 + // bytes and laid out as follows: + // + // Frame ID $xx xx xx xx (four characters) + // Size 4 * %0xxxxxxx + // Flags $xx xx + + $sizeofframes = $thisfile_id3v2['headerlength'] - 10; // not including 10-byte initial header + if (!empty($thisfile_id3v2['exthead']['length'])) { + $sizeofframes -= ($thisfile_id3v2['exthead']['length'] + 4); + } + if (!empty($thisfile_id3v2_flags['isfooter'])) { + $sizeofframes -= 10; // footer takes last 10 bytes of ID3v2 header, after frame data, before audio + } + if ($sizeofframes > 0) { + + $framedata = fread($this->getid3->fp, $sizeofframes); // read all frames from file into $framedata variable + + // if entire frame data is unsynched, de-unsynch it now (ID3v2.3.x) + if (!empty($thisfile_id3v2_flags['unsynch']) && ($id3v2_majorversion <= 3)) { + $framedata = $this->DeUnsynchronise($framedata); + } + // [in ID3v2.4.0] Unsynchronisation [S:6.1] is done on frame level, instead + // of on tag level, making it easier to skip frames, increasing the streamability + // of the tag. The unsynchronisation flag in the header [S:3.1] indicates that + // there exists an unsynchronised frame, while the new unsynchronisation flag in + // the frame header [S:4.1.2] indicates unsynchronisation. + + + //$framedataoffset = 10 + ($thisfile_id3v2['exthead']['length'] ? $thisfile_id3v2['exthead']['length'] + 4 : 0); // how many bytes into the stream - start from after the 10-byte header (and extended header length+4, if present) + $framedataoffset = 10; // how many bytes into the stream - start from after the 10-byte header + + + // Extended Header + if (!empty($thisfile_id3v2_flags['exthead'])) { + $extended_header_offset = 0; + + if ($id3v2_majorversion == 3) { + + // v2.3 definition: + //Extended header size $xx xx xx xx // 32-bit integer + //Extended Flags $xx xx + // %x0000000 %00000000 // v2.3 + // x - CRC data present + //Size of padding $xx xx xx xx + + $thisfile_id3v2['exthead']['length'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 4), 0); + $extended_header_offset += 4; + + $thisfile_id3v2['exthead']['flag_bytes'] = 2; + $thisfile_id3v2['exthead']['flag_raw'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, $thisfile_id3v2['exthead']['flag_bytes'])); + $extended_header_offset += $thisfile_id3v2['exthead']['flag_bytes']; + + $thisfile_id3v2['exthead']['flags']['crc'] = (bool) ($thisfile_id3v2['exthead']['flag_raw'] & 0x8000); + + $thisfile_id3v2['exthead']['padding_size'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 4)); + $extended_header_offset += 4; + + if ($thisfile_id3v2['exthead']['flags']['crc']) { + $thisfile_id3v2['exthead']['flag_data']['crc'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 4)); + $extended_header_offset += 4; + } + $extended_header_offset += $thisfile_id3v2['exthead']['padding_size']; + + } elseif ($id3v2_majorversion == 4) { + + // v2.4 definition: + //Extended header size 4 * %0xxxxxxx // 28-bit synchsafe integer + //Number of flag bytes $01 + //Extended Flags $xx + // %0bcd0000 // v2.4 + // b - Tag is an update + // Flag data length $00 + // c - CRC data present + // Flag data length $05 + // Total frame CRC 5 * %0xxxxxxx + // d - Tag restrictions + // Flag data length $01 + + $thisfile_id3v2['exthead']['length'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 4), true); + $extended_header_offset += 4; + + $thisfile_id3v2['exthead']['flag_bytes'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 1)); // should always be 1 + $extended_header_offset += 1; + + $thisfile_id3v2['exthead']['flag_raw'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, $thisfile_id3v2['exthead']['flag_bytes'])); + $extended_header_offset += $thisfile_id3v2['exthead']['flag_bytes']; + + $thisfile_id3v2['exthead']['flags']['update'] = (bool) ($thisfile_id3v2['exthead']['flag_raw'] & 0x40); + $thisfile_id3v2['exthead']['flags']['crc'] = (bool) ($thisfile_id3v2['exthead']['flag_raw'] & 0x20); + $thisfile_id3v2['exthead']['flags']['restrictions'] = (bool) ($thisfile_id3v2['exthead']['flag_raw'] & 0x10); + + if ($thisfile_id3v2['exthead']['flags']['update']) { + $ext_header_chunk_length = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 1)); // should be 0 + $extended_header_offset += 1; + } + + if ($thisfile_id3v2['exthead']['flags']['crc']) { + $ext_header_chunk_length = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 1)); // should be 5 + $extended_header_offset += 1; + $thisfile_id3v2['exthead']['flag_data']['crc'] = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, $ext_header_chunk_length), true, false); + $extended_header_offset += $ext_header_chunk_length; + } + + if ($thisfile_id3v2['exthead']['flags']['restrictions']) { + $ext_header_chunk_length = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 1)); // should be 1 + $extended_header_offset += 1; + + // %ppqrrstt + $restrictions_raw = getid3_lib::BigEndian2Int(substr($framedata, $extended_header_offset, 1)); + $extended_header_offset += 1; + $thisfile_id3v2['exthead']['flags']['restrictions']['tagsize'] = ($restrictions_raw & 0xC0) >> 6; // p - Tag size restrictions + $thisfile_id3v2['exthead']['flags']['restrictions']['textenc'] = ($restrictions_raw & 0x20) >> 5; // q - Text encoding restrictions + $thisfile_id3v2['exthead']['flags']['restrictions']['textsize'] = ($restrictions_raw & 0x18) >> 3; // r - Text fields size restrictions + $thisfile_id3v2['exthead']['flags']['restrictions']['imgenc'] = ($restrictions_raw & 0x04) >> 2; // s - Image encoding restrictions + $thisfile_id3v2['exthead']['flags']['restrictions']['imgsize'] = ($restrictions_raw & 0x03) >> 0; // t - Image size restrictions + + $thisfile_id3v2['exthead']['flags']['restrictions_text']['tagsize'] = $this->LookupExtendedHeaderRestrictionsTagSizeLimits($thisfile_id3v2['exthead']['flags']['restrictions']['tagsize']); + $thisfile_id3v2['exthead']['flags']['restrictions_text']['textenc'] = $this->LookupExtendedHeaderRestrictionsTextEncodings($thisfile_id3v2['exthead']['flags']['restrictions']['textenc']); + $thisfile_id3v2['exthead']['flags']['restrictions_text']['textsize'] = $this->LookupExtendedHeaderRestrictionsTextFieldSize($thisfile_id3v2['exthead']['flags']['restrictions']['textsize']); + $thisfile_id3v2['exthead']['flags']['restrictions_text']['imgenc'] = $this->LookupExtendedHeaderRestrictionsImageEncoding($thisfile_id3v2['exthead']['flags']['restrictions']['imgenc']); + $thisfile_id3v2['exthead']['flags']['restrictions_text']['imgsize'] = $this->LookupExtendedHeaderRestrictionsImageSizeSize($thisfile_id3v2['exthead']['flags']['restrictions']['imgsize']); + } + + if ($thisfile_id3v2['exthead']['length'] != $extended_header_offset) { + $info['warning'][] = 'ID3v2.4 extended header length mismatch (expecting '.intval($thisfile_id3v2['exthead']['length']).', found '.intval($extended_header_offset).')'; + } + } + + $framedataoffset += $extended_header_offset; + $framedata = substr($framedata, $extended_header_offset); + } // end extended header + + + while (isset($framedata) && (strlen($framedata) > 0)) { // cycle through until no more frame data is left to parse + if (strlen($framedata) <= $this->ID3v2HeaderLength($id3v2_majorversion)) { + // insufficient room left in ID3v2 header for actual data - must be padding + $thisfile_id3v2['padding']['start'] = $framedataoffset; + $thisfile_id3v2['padding']['length'] = strlen($framedata); + $thisfile_id3v2['padding']['valid'] = true; + for ($i = 0; $i < $thisfile_id3v2['padding']['length']; $i++) { + if ($framedata{$i} != "\x00") { + $thisfile_id3v2['padding']['valid'] = false; + $thisfile_id3v2['padding']['errorpos'] = $thisfile_id3v2['padding']['start'] + $i; + $info['warning'][] = 'Invalid ID3v2 padding found at offset '.$thisfile_id3v2['padding']['errorpos'].' (the remaining '.($thisfile_id3v2['padding']['length'] - $i).' bytes are considered invalid)'; + break; + } + } + break; // skip rest of ID3v2 header + } + if ($id3v2_majorversion == 2) { + // Frame ID $xx xx xx (three characters) + // Size $xx xx xx (24-bit integer) + // Flags $xx xx + + $frame_header = substr($framedata, 0, 6); // take next 6 bytes for header + $framedata = substr($framedata, 6); // and leave the rest in $framedata + $frame_name = substr($frame_header, 0, 3); + $frame_size = getid3_lib::BigEndian2Int(substr($frame_header, 3, 3), 0); + $frame_flags = 0; // not used for anything in ID3v2.2, just set to avoid E_NOTICEs + + } elseif ($id3v2_majorversion > 2) { + + // Frame ID $xx xx xx xx (four characters) + // Size $xx xx xx xx (32-bit integer in v2.3, 28-bit synchsafe in v2.4+) + // Flags $xx xx + + $frame_header = substr($framedata, 0, 10); // take next 10 bytes for header + $framedata = substr($framedata, 10); // and leave the rest in $framedata + + $frame_name = substr($frame_header, 0, 4); + if ($id3v2_majorversion == 3) { + $frame_size = getid3_lib::BigEndian2Int(substr($frame_header, 4, 4), 0); // 32-bit integer + } else { // ID3v2.4+ + $frame_size = getid3_lib::BigEndian2Int(substr($frame_header, 4, 4), 1); // 32-bit synchsafe integer (28-bit value) + } + + if ($frame_size < (strlen($framedata) + 4)) { + $nextFrameID = substr($framedata, $frame_size, 4); + if ($this->IsValidID3v2FrameName($nextFrameID, $id3v2_majorversion)) { + // next frame is OK + } elseif (($frame_name == "\x00".'MP3') || ($frame_name == "\x00\x00".'MP') || ($frame_name == ' MP3') || ($frame_name == 'MP3e')) { + // MP3ext known broken frames - "ok" for the purposes of this test + } elseif (($id3v2_majorversion == 4) && ($this->IsValidID3v2FrameName(substr($framedata, getid3_lib::BigEndian2Int(substr($frame_header, 4, 4), 0), 4), 3))) { + $info['warning'][] = 'ID3v2 tag written as ID3v2.4, but with non-synchsafe integers (ID3v2.3 style). Older versions of (Helium2; iTunes) are known culprits of this. Tag has been parsed as ID3v2.3'; + $id3v2_majorversion = 3; + $frame_size = getid3_lib::BigEndian2Int(substr($frame_header, 4, 4), 0); // 32-bit integer + } + } + + + $frame_flags = getid3_lib::BigEndian2Int(substr($frame_header, 8, 2)); + } + + if ((($id3v2_majorversion == 2) && ($frame_name == "\x00\x00\x00")) || ($frame_name == "\x00\x00\x00\x00")) { + // padding encountered + + $thisfile_id3v2['padding']['start'] = $framedataoffset; + $thisfile_id3v2['padding']['length'] = strlen($frame_header) + strlen($framedata); + $thisfile_id3v2['padding']['valid'] = true; + + $len = strlen($framedata); + for ($i = 0; $i < $len; $i++) { + if ($framedata{$i} != "\x00") { + $thisfile_id3v2['padding']['valid'] = false; + $thisfile_id3v2['padding']['errorpos'] = $thisfile_id3v2['padding']['start'] + $i; + $info['warning'][] = 'Invalid ID3v2 padding found at offset '.$thisfile_id3v2['padding']['errorpos'].' (the remaining '.($thisfile_id3v2['padding']['length'] - $i).' bytes are considered invalid)'; + break; + } + } + break; // skip rest of ID3v2 header + } + + if ($frame_name == 'COM ') { + $info['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by iTunes (versions "X v2.0.3", "v3.0.1" are known-guilty, probably others too)]'; + $frame_name = 'COMM'; + } + if (($frame_size <= strlen($framedata)) && ($this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion))) { + + unset($parsedFrame); + $parsedFrame['frame_name'] = $frame_name; + $parsedFrame['frame_flags_raw'] = $frame_flags; + $parsedFrame['data'] = substr($framedata, 0, $frame_size); + $parsedFrame['datalength'] = getid3_lib::CastAsInt($frame_size); + $parsedFrame['dataoffset'] = $framedataoffset; + + $this->ParseID3v2Frame($parsedFrame); + $thisfile_id3v2[$frame_name][] = $parsedFrame; + + $framedata = substr($framedata, $frame_size); + + } else { // invalid frame length or FrameID + + if ($frame_size <= strlen($framedata)) { + + if ($this->IsValidID3v2FrameName(substr($framedata, $frame_size, 4), $id3v2_majorversion)) { + + // next frame is valid, just skip the current frame + $framedata = substr($framedata, $frame_size); + $info['warning'][] = 'Next ID3v2 frame is valid, skipping current frame.'; + + } else { + + // next frame is invalid too, abort processing + //unset($framedata); + $framedata = null; + $info['error'][] = 'Next ID3v2 frame is also invalid, aborting processing.'; + + } + + } elseif ($frame_size == strlen($framedata)) { + + // this is the last frame, just skip + $info['warning'][] = 'This was the last ID3v2 frame.'; + + } else { + + // next frame is invalid too, abort processing + //unset($framedata); + $framedata = null; + $info['warning'][] = 'Invalid ID3v2 frame size, aborting.'; + + } + if (!$this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion)) { + + switch ($frame_name) { + case "\x00\x00".'MP': + case "\x00".'MP3': + case ' MP3': + case 'MP3e': + case "\x00".'MP': + case ' MP': + case 'MP3': + $info['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: !IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by "MP3ext (www.mutschler.de/mp3ext/)"]'; + break; + + default: + $info['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: !IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))).'; + break; + } + + } elseif (!isset($framedata) || ($frame_size > strlen($framedata))) { + + $info['error'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: $frame_size ('.$frame_size.') > strlen($framedata) ('.(isset($framedata) ? strlen($framedata) : 'null').')).'; + + } else { + + $info['error'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag).'; + + } + + } + $framedataoffset += ($frame_size + $this->ID3v2HeaderLength($id3v2_majorversion)); + + } + + } + + + // Footer + + // The footer is a copy of the header, but with a different identifier. + // ID3v2 identifier "3DI" + // ID3v2 version $04 00 + // ID3v2 flags %abcd0000 + // ID3v2 size 4 * %0xxxxxxx + + if (isset($thisfile_id3v2_flags['isfooter']) && $thisfile_id3v2_flags['isfooter']) { + $footer = fread($this->getid3->fp, 10); + if (substr($footer, 0, 3) == '3DI') { + $thisfile_id3v2['footer'] = true; + $thisfile_id3v2['majorversion_footer'] = ord($footer{3}); + $thisfile_id3v2['minorversion_footer'] = ord($footer{4}); + } + if ($thisfile_id3v2['majorversion_footer'] <= 4) { + $id3_flags = ord(substr($footer{5})); + $thisfile_id3v2_flags['unsynch_footer'] = (bool) ($id3_flags & 0x80); + $thisfile_id3v2_flags['extfoot_footer'] = (bool) ($id3_flags & 0x40); + $thisfile_id3v2_flags['experim_footer'] = (bool) ($id3_flags & 0x20); + $thisfile_id3v2_flags['isfooter_footer'] = (bool) ($id3_flags & 0x10); + + $thisfile_id3v2['footerlength'] = getid3_lib::BigEndian2Int(substr($footer, 6, 4), 1); + } + } // end footer + + if (isset($thisfile_id3v2['comments']['genre'])) { + foreach ($thisfile_id3v2['comments']['genre'] as $key => $value) { + unset($thisfile_id3v2['comments']['genre'][$key]); + $thisfile_id3v2['comments'] = getid3_lib::array_merge_noclobber($thisfile_id3v2['comments'], array('genre'=>$this->ParseID3v2GenreString($value))); + } + } + + if (isset($thisfile_id3v2['comments']['track'])) { + foreach ($thisfile_id3v2['comments']['track'] as $key => $value) { + if (strstr($value, '/')) { + list($thisfile_id3v2['comments']['tracknum'][$key], $thisfile_id3v2['comments']['totaltracks'][$key]) = explode('/', $thisfile_id3v2['comments']['track'][$key]); + } + } + } + + if (!isset($thisfile_id3v2['comments']['year']) && !empty($thisfile_id3v2['comments']['recording_time'][0]) && preg_match('#^([0-9]{4})#', trim($thisfile_id3v2['comments']['recording_time'][0]), $matches)) { + $thisfile_id3v2['comments']['year'] = array($matches[1]); + } + + + if (!empty($thisfile_id3v2['TXXX'])) { + // MediaMonkey does this, maybe others: write a blank RGAD frame, but put replay-gain adjustment values in TXXX frames + foreach ($thisfile_id3v2['TXXX'] as $txxx_array) { + switch ($txxx_array['description']) { + case 'replaygain_track_gain': + if (empty($info['replay_gain']['track']['adjustment']) && !empty($txxx_array['data'])) { + $info['replay_gain']['track']['adjustment'] = floatval(trim(str_replace('dB', '', $txxx_array['data']))); + } + break; + case 'replaygain_track_peak': + if (empty($info['replay_gain']['track']['peak']) && !empty($txxx_array['data'])) { + $info['replay_gain']['track']['peak'] = floatval($txxx_array['data']); + } + break; + case 'replaygain_album_gain': + if (empty($info['replay_gain']['album']['adjustment']) && !empty($txxx_array['data'])) { + $info['replay_gain']['album']['adjustment'] = floatval(trim(str_replace('dB', '', $txxx_array['data']))); + } + break; + } + } + } + + + // Set avdataoffset + $info['avdataoffset'] = $thisfile_id3v2['headerlength']; + if (isset($thisfile_id3v2['footer'])) { + $info['avdataoffset'] += 10; + } + + return true; + } + + + public function ParseID3v2GenreString($genrestring) { + // Parse genres into arrays of genreName and genreID + // ID3v2.2.x, ID3v2.3.x: '(21)' or '(4)Eurodisco' or '(51)(39)' or '(55)((I think...)' + // ID3v2.4.x: '21' $00 'Eurodisco' $00 + $clean_genres = array(); + if (strpos($genrestring, "\x00") === false) { + $genrestring = preg_replace('#\(([0-9]{1,3})\)#', '$1'."\x00", $genrestring); + } + $genre_elements = explode("\x00", $genrestring); + foreach ($genre_elements as $element) { + $element = trim($element); + if ($element) { + if (preg_match('#^[0-9]{1,3}#', $element)) { + $clean_genres[] = getid3_id3v1::LookupGenreName($element); + } else { + $clean_genres[] = str_replace('((', '(', $element); + } + } + } + return $clean_genres; + } + + + public function ParseID3v2Frame(&$parsedFrame) { + + // shortcuts + $info = &$this->getid3->info; + $id3v2_majorversion = $info['id3v2']['majorversion']; + + $parsedFrame['framenamelong'] = $this->FrameNameLongLookup($parsedFrame['frame_name']); + if (empty($parsedFrame['framenamelong'])) { + unset($parsedFrame['framenamelong']); + } + $parsedFrame['framenameshort'] = $this->FrameNameShortLookup($parsedFrame['frame_name']); + if (empty($parsedFrame['framenameshort'])) { + unset($parsedFrame['framenameshort']); + } + + if ($id3v2_majorversion >= 3) { // frame flags are not part of the ID3v2.2 standard + if ($id3v2_majorversion == 3) { + // Frame Header Flags + // %abc00000 %ijk00000 + $parsedFrame['flags']['TagAlterPreservation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x8000); // a - Tag alter preservation + $parsedFrame['flags']['FileAlterPreservation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x4000); // b - File alter preservation + $parsedFrame['flags']['ReadOnly'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x2000); // c - Read only + $parsedFrame['flags']['compression'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0080); // i - Compression + $parsedFrame['flags']['Encryption'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0040); // j - Encryption + $parsedFrame['flags']['GroupingIdentity'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0020); // k - Grouping identity + + } elseif ($id3v2_majorversion == 4) { + // Frame Header Flags + // %0abc0000 %0h00kmnp + $parsedFrame['flags']['TagAlterPreservation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x4000); // a - Tag alter preservation + $parsedFrame['flags']['FileAlterPreservation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x2000); // b - File alter preservation + $parsedFrame['flags']['ReadOnly'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x1000); // c - Read only + $parsedFrame['flags']['GroupingIdentity'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0040); // h - Grouping identity + $parsedFrame['flags']['compression'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0008); // k - Compression + $parsedFrame['flags']['Encryption'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0004); // m - Encryption + $parsedFrame['flags']['Unsynchronisation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0002); // n - Unsynchronisation + $parsedFrame['flags']['DataLengthIndicator'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0001); // p - Data length indicator + + // Frame-level de-unsynchronisation - ID3v2.4 + if ($parsedFrame['flags']['Unsynchronisation']) { + $parsedFrame['data'] = $this->DeUnsynchronise($parsedFrame['data']); + } + + if ($parsedFrame['flags']['DataLengthIndicator']) { + $parsedFrame['data_length_indicator'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 0, 4), 1); + $parsedFrame['data'] = substr($parsedFrame['data'], 4); + } + } + + // Frame-level de-compression + if ($parsedFrame['flags']['compression']) { + $parsedFrame['decompressed_size'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 0, 4)); + if (!function_exists('gzuncompress')) { + $info['warning'][] = 'gzuncompress() support required to decompress ID3v2 frame "'.$parsedFrame['frame_name'].'"'; + } else { + if ($decompresseddata = @gzuncompress(substr($parsedFrame['data'], 4))) { + //if ($decompresseddata = @gzuncompress($parsedFrame['data'])) { + $parsedFrame['data'] = $decompresseddata; + unset($decompresseddata); + } else { + $info['warning'][] = 'gzuncompress() failed on compressed contents of ID3v2 frame "'.$parsedFrame['frame_name'].'"'; + } + } + } + } + + if (!empty($parsedFrame['flags']['DataLengthIndicator'])) { + if ($parsedFrame['data_length_indicator'] != strlen($parsedFrame['data'])) { + $info['warning'][] = 'ID3v2 frame "'.$parsedFrame['frame_name'].'" should be '.$parsedFrame['data_length_indicator'].' bytes long according to DataLengthIndicator, but found '.strlen($parsedFrame['data']).' bytes of data'; + } + } + + if (isset($parsedFrame['datalength']) && ($parsedFrame['datalength'] == 0)) { + + $warning = 'Frame "'.$parsedFrame['frame_name'].'" at offset '.$parsedFrame['dataoffset'].' has no data portion'; + switch ($parsedFrame['frame_name']) { + case 'WCOM': + $warning .= ' (this is known to happen with files tagged by RioPort)'; + break; + + default: + break; + } + $info['warning'][] = $warning; + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'UFID')) || // 4.1 UFID Unique file identifier + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'UFI'))) { // 4.1 UFI Unique file identifier + // There may be more than one 'UFID' frame in a tag, + // but only one with the same 'Owner identifier'. + // <Header for 'Unique file identifier', ID: 'UFID'> + // Owner identifier <text string> $00 + // Identifier <up to 64 bytes binary data> + $exploded = explode("\x00", $parsedFrame['data'], 2); + $parsedFrame['ownerid'] = (isset($exploded[0]) ? $exploded[0] : ''); + $parsedFrame['data'] = (isset($exploded[1]) ? $exploded[1] : ''); + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'TXXX')) || // 4.2.2 TXXX User defined text information frame + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'TXX'))) { // 4.2.2 TXX User defined text information frame + // There may be more than one 'TXXX' frame in each tag, + // but only one with the same description. + // <Header for 'User defined text information frame', ID: 'TXXX'> + // Text encoding $xx + // Description <text string according to encoding> $00 (00) + // Value <text string according to encoding> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_description) === 0) { + $frame_description = ''; + } + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $parsedFrame['description'] = $frame_description; + $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); + if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = trim(getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data'])); + } + //unset($parsedFrame['data']); do not unset, may be needed elsewhere, e.g. for replaygain + + + } elseif ($parsedFrame['frame_name']{0} == 'T') { // 4.2. T??[?] Text information frame + // There may only be one text information frame of its kind in an tag. + // <Header for 'Text information frame', ID: 'T000' - 'TZZZ', + // excluding 'TXXX' described in 4.2.6.> + // Text encoding $xx + // Information <text string(s) according to encoding> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + + $parsedFrame['data'] = (string) substr($parsedFrame['data'], $frame_offset); + + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { + // ID3v2.3 specs say that TPE1 (and others) can contain multiple artist values separated with / + // This of course breaks when an artist name contains slash character, e.g. "AC/DC" + // MP3tag (maybe others) implement alternative system where multiple artists are null-separated, which makes more sense + // getID3 will split null-separated artists into multiple artists and leave slash-separated ones to the user + switch ($parsedFrame['encoding']) { + case 'UTF-16': + case 'UTF-16BE': + case 'UTF-16LE': + $wordsize = 2; + break; + case 'ISO-8859-1': + case 'UTF-8': + default: + $wordsize = 1; + break; + } + $Txxx_elements = array(); + $Txxx_elements_start_offset = 0; + for ($i = 0; $i < strlen($parsedFrame['data']); $i += $wordsize) { + if (substr($parsedFrame['data'], $i, $wordsize) == str_repeat("\x00", $wordsize)) { + $Txxx_elements[] = substr($parsedFrame['data'], $Txxx_elements_start_offset, $i - $Txxx_elements_start_offset); + $Txxx_elements_start_offset = $i + $wordsize; + } + } + $Txxx_elements[] = substr($parsedFrame['data'], $Txxx_elements_start_offset, $i - $Txxx_elements_start_offset); + foreach ($Txxx_elements as $Txxx_element) { + $string = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $Txxx_element); + if (!empty($string)) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = $string; + } + } + unset($string, $wordsize, $i, $Txxx_elements, $Txxx_element, $Txxx_elements_start_offset); + } + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'WXXX')) || // 4.3.2 WXXX User defined URL link frame + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'WXX'))) { // 4.3.2 WXX User defined URL link frame + // There may be more than one 'WXXX' frame in each tag, + // but only one with the same description + // <Header for 'User defined URL link frame', ID: 'WXXX'> + // Text encoding $xx + // Description <text string according to encoding> $00 (00) + // URL <text string> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + + if (ord($frame_description) === 0) { + $frame_description = ''; + } + $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); + + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding)); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + if ($frame_terminatorpos) { + // there are null bytes after the data - this is not according to spec + // only use data up to first null byte + $frame_urldata = (string) substr($parsedFrame['data'], 0, $frame_terminatorpos); + } else { + // no null bytes following data, just use all data + $frame_urldata = (string) $parsedFrame['data']; + } + + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $parsedFrame['url'] = $frame_urldata; + $parsedFrame['description'] = $frame_description; + if (!empty($parsedFrame['framenameshort']) && $parsedFrame['url']) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['url']); + } + unset($parsedFrame['data']); + + + } elseif ($parsedFrame['frame_name']{0} == 'W') { // 4.3. W??? URL link frames + // There may only be one URL link frame of its kind in a tag, + // except when stated otherwise in the frame description + // <Header for 'URL link frame', ID: 'W000' - 'WZZZ', excluding 'WXXX' + // described in 4.3.2.> + // URL <text string> + + $parsedFrame['url'] = trim($parsedFrame['data']); + if (!empty($parsedFrame['framenameshort']) && $parsedFrame['url']) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = $parsedFrame['url']; + } + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion == 3) && ($parsedFrame['frame_name'] == 'IPLS')) || // 4.4 IPLS Involved people list (ID3v2.3 only) + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'IPL'))) { // 4.4 IPL Involved people list (ID3v2.2 only) + // http://id3.org/id3v2.3.0#sec4.4 + // There may only be one 'IPL' frame in each tag + // <Header for 'User defined URL link frame', ID: 'IPL'> + // Text encoding $xx + // People list strings <textstrings> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($parsedFrame['encodingid']); + $parsedFrame['data_raw'] = (string) substr($parsedFrame['data'], $frame_offset); + + // http://www.getid3.org/phpBB3/viewtopic.php?t=1369 + // "this tag typically contains null terminated strings, which are associated in pairs" + // "there are users that use the tag incorrectly" + $IPLS_parts = array(); + if (strpos($parsedFrame['data_raw'], "\x00") !== false) { + $IPLS_parts_unsorted = array(); + if (((strlen($parsedFrame['data_raw']) % 2) == 0) && ((substr($parsedFrame['data_raw'], 0, 2) == "\xFF\xFE") || (substr($parsedFrame['data_raw'], 0, 2) == "\xFE\xFF"))) { + // UTF-16, be careful looking for null bytes since most 2-byte characters may contain one; you need to find twin null bytes, and on even padding + $thisILPS = ''; + for ($i = 0; $i < strlen($parsedFrame['data_raw']); $i += 2) { + $twobytes = substr($parsedFrame['data_raw'], $i, 2); + if ($twobytes === "\x00\x00") { + $IPLS_parts_unsorted[] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $thisILPS); + $thisILPS = ''; + } else { + $thisILPS .= $twobytes; + } + } + if (strlen($thisILPS) > 2) { // 2-byte BOM + $IPLS_parts_unsorted[] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $thisILPS); + } + } else { + // ISO-8859-1 or UTF-8 or other single-byte-null character set + $IPLS_parts_unsorted = explode("\x00", $parsedFrame['data_raw']); + } + if (count($IPLS_parts_unsorted) == 1) { + // just a list of names, e.g. "Dino Baptiste, Jimmy Copley, John Gordon, Bernie Marsden, Sharon Watson" + foreach ($IPLS_parts_unsorted as $key => $value) { + $IPLS_parts_sorted = preg_split('#[;,\\r\\n\\t]#', $value); + $position = ''; + foreach ($IPLS_parts_sorted as $person) { + $IPLS_parts[] = array('position'=>$position, 'person'=>$person); + } + } + } elseif ((count($IPLS_parts_unsorted) % 2) == 0) { + $position = ''; + $person = ''; + foreach ($IPLS_parts_unsorted as $key => $value) { + if (($key % 2) == 0) { + $position = $value; + } else { + $person = $value; + $IPLS_parts[] = array('position'=>$position, 'person'=>$person); + $position = ''; + $person = ''; + } + } + } else { + foreach ($IPLS_parts_unsorted as $key => $value) { + $IPLS_parts[] = array($value); + } + } + + } else { + $IPLS_parts = preg_split('#[;,\\r\\n\\t]#', $parsedFrame['data_raw']); + } + $parsedFrame['data'] = $IPLS_parts; + + if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = $parsedFrame['data']; + } + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'MCDI')) || // 4.4 MCDI Music CD identifier + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'MCI'))) { // 4.5 MCI Music CD identifier + // There may only be one 'MCDI' frame in each tag + // <Header for 'Music CD identifier', ID: 'MCDI'> + // CD TOC <binary data> + + if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = $parsedFrame['data']; + } + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'ETCO')) || // 4.5 ETCO Event timing codes + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'ETC'))) { // 4.6 ETC Event timing codes + // There may only be one 'ETCO' frame in each tag + // <Header for 'Event timing codes', ID: 'ETCO'> + // Time stamp format $xx + // Where time stamp format is: + // $01 (32-bit value) MPEG frames from beginning of file + // $02 (32-bit value) milliseconds from beginning of file + // Followed by a list of key events in the following format: + // Type of event $xx + // Time stamp $xx (xx ...) + // The 'Time stamp' is set to zero if directly at the beginning of the sound + // or after the previous event. All events MUST be sorted in chronological order. + + $frame_offset = 0; + $parsedFrame['timestampformat'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + + while ($frame_offset < strlen($parsedFrame['data'])) { + $parsedFrame['typeid'] = substr($parsedFrame['data'], $frame_offset++, 1); + $parsedFrame['type'] = $this->ETCOEventLookup($parsedFrame['typeid']); + $parsedFrame['timestamp'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4)); + $frame_offset += 4; + } + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'MLLT')) || // 4.6 MLLT MPEG location lookup table + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'MLL'))) { // 4.7 MLL MPEG location lookup table + // There may only be one 'MLLT' frame in each tag + // <Header for 'Location lookup table', ID: 'MLLT'> + // MPEG frames between reference $xx xx + // Bytes between reference $xx xx xx + // Milliseconds between reference $xx xx xx + // Bits for bytes deviation $xx + // Bits for milliseconds dev. $xx + // Then for every reference the following data is included; + // Deviation in bytes %xxx.... + // Deviation in milliseconds %xxx.... + + $frame_offset = 0; + $parsedFrame['framesbetweenreferences'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 0, 2)); + $parsedFrame['bytesbetweenreferences'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 2, 3)); + $parsedFrame['msbetweenreferences'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 5, 3)); + $parsedFrame['bitsforbytesdeviation'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 8, 1)); + $parsedFrame['bitsformsdeviation'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 9, 1)); + $parsedFrame['data'] = substr($parsedFrame['data'], 10); + while ($frame_offset < strlen($parsedFrame['data'])) { + $deviationbitstream .= getid3_lib::BigEndian2Bin(substr($parsedFrame['data'], $frame_offset++, 1)); + } + $reference_counter = 0; + while (strlen($deviationbitstream) > 0) { + $parsedFrame[$reference_counter]['bytedeviation'] = bindec(substr($deviationbitstream, 0, $parsedFrame['bitsforbytesdeviation'])); + $parsedFrame[$reference_counter]['msdeviation'] = bindec(substr($deviationbitstream, $parsedFrame['bitsforbytesdeviation'], $parsedFrame['bitsformsdeviation'])); + $deviationbitstream = substr($deviationbitstream, $parsedFrame['bitsforbytesdeviation'] + $parsedFrame['bitsformsdeviation']); + $reference_counter++; + } + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'SYTC')) || // 4.7 SYTC Synchronised tempo codes + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'STC'))) { // 4.8 STC Synchronised tempo codes + // There may only be one 'SYTC' frame in each tag + // <Header for 'Synchronised tempo codes', ID: 'SYTC'> + // Time stamp format $xx + // Tempo data <binary data> + // Where time stamp format is: + // $01 (32-bit value) MPEG frames from beginning of file + // $02 (32-bit value) milliseconds from beginning of file + + $frame_offset = 0; + $parsedFrame['timestampformat'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $timestamp_counter = 0; + while ($frame_offset < strlen($parsedFrame['data'])) { + $parsedFrame[$timestamp_counter]['tempo'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ($parsedFrame[$timestamp_counter]['tempo'] == 255) { + $parsedFrame[$timestamp_counter]['tempo'] += ord(substr($parsedFrame['data'], $frame_offset++, 1)); + } + $parsedFrame[$timestamp_counter]['timestamp'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4)); + $frame_offset += 4; + $timestamp_counter++; + } + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'USLT')) || // 4.8 USLT Unsynchronised lyric/text transcription + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'ULT'))) { // 4.9 ULT Unsynchronised lyric/text transcription + // There may be more than one 'Unsynchronised lyrics/text transcription' frame + // in each tag, but only one with the same language and content descriptor. + // <Header for 'Unsynchronised lyrics/text transcription', ID: 'USLT'> + // Text encoding $xx + // Language $xx xx xx + // Content descriptor <text string according to encoding> $00 (00) + // Lyrics/text <full text string according to encoding> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $frame_language = substr($parsedFrame['data'], $frame_offset, 3); + $frame_offset += 3; + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_description) === 0) { + $frame_description = ''; + } + $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); + + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $parsedFrame['data'] = $parsedFrame['data']; + $parsedFrame['language'] = $frame_language; + $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false); + $parsedFrame['description'] = $frame_description; + if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']); + } + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'SYLT')) || // 4.9 SYLT Synchronised lyric/text + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'SLT'))) { // 4.10 SLT Synchronised lyric/text + // There may be more than one 'SYLT' frame in each tag, + // but only one with the same language and content descriptor. + // <Header for 'Synchronised lyrics/text', ID: 'SYLT'> + // Text encoding $xx + // Language $xx xx xx + // Time stamp format $xx + // $01 (32-bit value) MPEG frames from beginning of file + // $02 (32-bit value) milliseconds from beginning of file + // Content type $xx + // Content descriptor <text string according to encoding> $00 (00) + // Terminated text to be synced (typically a syllable) + // Sync identifier (terminator to above string) $00 (00) + // Time stamp $xx (xx ...) + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $frame_language = substr($parsedFrame['data'], $frame_offset, 3); + $frame_offset += 3; + $parsedFrame['timestampformat'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['contenttypeid'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['contenttype'] = $this->SYTLContentTypeLookup($parsedFrame['contenttypeid']); + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $parsedFrame['language'] = $frame_language; + $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false); + + $timestampindex = 0; + $frame_remainingdata = substr($parsedFrame['data'], $frame_offset); + while (strlen($frame_remainingdata)) { + $frame_offset = 0; + $frame_terminatorpos = strpos($frame_remainingdata, $this->TextEncodingTerminatorLookup($frame_textencoding)); + if ($frame_terminatorpos === false) { + $frame_remainingdata = ''; + } else { + if (ord(substr($frame_remainingdata, $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $parsedFrame['lyrics'][$timestampindex]['data'] = substr($frame_remainingdata, $frame_offset, $frame_terminatorpos - $frame_offset); + + $frame_remainingdata = substr($frame_remainingdata, $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); + if (($timestampindex == 0) && (ord($frame_remainingdata{0}) != 0)) { + // timestamp probably omitted for first data item + } else { + $parsedFrame['lyrics'][$timestampindex]['timestamp'] = getid3_lib::BigEndian2Int(substr($frame_remainingdata, 0, 4)); + $frame_remainingdata = substr($frame_remainingdata, 4); + } + $timestampindex++; + } + } + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'COMM')) || // 4.10 COMM Comments + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'COM'))) { // 4.11 COM Comments + // There may be more than one comment frame in each tag, + // but only one with the same language and content descriptor. + // <Header for 'Comment', ID: 'COMM'> + // Text encoding $xx + // Language $xx xx xx + // Short content descrip. <text string according to encoding> $00 (00) + // The actual text <full text string according to encoding> + + if (strlen($parsedFrame['data']) < 5) { + + $info['warning'][] = 'Invalid data (too short) for "'.$parsedFrame['frame_name'].'" frame at offset '.$parsedFrame['dataoffset']; + + } else { + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $frame_language = substr($parsedFrame['data'], $frame_offset, 3); + $frame_offset += 3; + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_description) === 0) { + $frame_description = ''; + } + $frame_text = (string) substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); + + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $parsedFrame['language'] = $frame_language; + $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false); + $parsedFrame['description'] = $frame_description; + $parsedFrame['data'] = $frame_text; + if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']); + } + + } + + } elseif (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'RVA2')) { // 4.11 RVA2 Relative volume adjustment (2) (ID3v2.4+ only) + // There may be more than one 'RVA2' frame in each tag, + // but only one with the same identification string + // <Header for 'Relative volume adjustment (2)', ID: 'RVA2'> + // Identification <text string> $00 + // The 'identification' string is used to identify the situation and/or + // device where this adjustment should apply. The following is then + // repeated for every channel: + // Type of channel $xx + // Volume adjustment $xx xx + // Bits representing peak $xx + // Peak volume $xx (xx ...) + + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00"); + $frame_idstring = substr($parsedFrame['data'], 0, $frame_terminatorpos); + if (ord($frame_idstring) === 0) { + $frame_idstring = ''; + } + $frame_remainingdata = substr($parsedFrame['data'], $frame_terminatorpos + strlen("\x00")); + $parsedFrame['description'] = $frame_idstring; + $RVA2channelcounter = 0; + while (strlen($frame_remainingdata) >= 5) { + $frame_offset = 0; + $frame_channeltypeid = ord(substr($frame_remainingdata, $frame_offset++, 1)); + $parsedFrame[$RVA2channelcounter]['channeltypeid'] = $frame_channeltypeid; + $parsedFrame[$RVA2channelcounter]['channeltype'] = $this->RVA2ChannelTypeLookup($frame_channeltypeid); + $parsedFrame[$RVA2channelcounter]['volumeadjust'] = getid3_lib::BigEndian2Int(substr($frame_remainingdata, $frame_offset, 2), false, true); // 16-bit signed + $frame_offset += 2; + $parsedFrame[$RVA2channelcounter]['bitspeakvolume'] = ord(substr($frame_remainingdata, $frame_offset++, 1)); + if (($parsedFrame[$RVA2channelcounter]['bitspeakvolume'] < 1) || ($parsedFrame[$RVA2channelcounter]['bitspeakvolume'] > 4)) { + $info['warning'][] = 'ID3v2::RVA2 frame['.$RVA2channelcounter.'] contains invalid '.$parsedFrame[$RVA2channelcounter]['bitspeakvolume'].'-byte bits-representing-peak value'; + break; + } + $frame_bytespeakvolume = ceil($parsedFrame[$RVA2channelcounter]['bitspeakvolume'] / 8); + $parsedFrame[$RVA2channelcounter]['peakvolume'] = getid3_lib::BigEndian2Int(substr($frame_remainingdata, $frame_offset, $frame_bytespeakvolume)); + $frame_remainingdata = substr($frame_remainingdata, $frame_offset + $frame_bytespeakvolume); + $RVA2channelcounter++; + } + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion == 3) && ($parsedFrame['frame_name'] == 'RVAD')) || // 4.12 RVAD Relative volume adjustment (ID3v2.3 only) + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'RVA'))) { // 4.12 RVA Relative volume adjustment (ID3v2.2 only) + // There may only be one 'RVA' frame in each tag + // <Header for 'Relative volume adjustment', ID: 'RVA'> + // ID3v2.2 => Increment/decrement %000000ba + // ID3v2.3 => Increment/decrement %00fedcba + // Bits used for volume descr. $xx + // Relative volume change, right $xx xx (xx ...) // a + // Relative volume change, left $xx xx (xx ...) // b + // Peak volume right $xx xx (xx ...) + // Peak volume left $xx xx (xx ...) + // ID3v2.3 only, optional (not present in ID3v2.2): + // Relative volume change, right back $xx xx (xx ...) // c + // Relative volume change, left back $xx xx (xx ...) // d + // Peak volume right back $xx xx (xx ...) + // Peak volume left back $xx xx (xx ...) + // ID3v2.3 only, optional (not present in ID3v2.2): + // Relative volume change, center $xx xx (xx ...) // e + // Peak volume center $xx xx (xx ...) + // ID3v2.3 only, optional (not present in ID3v2.2): + // Relative volume change, bass $xx xx (xx ...) // f + // Peak volume bass $xx xx (xx ...) + + $frame_offset = 0; + $frame_incrdecrflags = getid3_lib::BigEndian2Bin(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['incdec']['right'] = (bool) substr($frame_incrdecrflags, 6, 1); + $parsedFrame['incdec']['left'] = (bool) substr($frame_incrdecrflags, 7, 1); + $parsedFrame['bitsvolume'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $frame_bytesvolume = ceil($parsedFrame['bitsvolume'] / 8); + $parsedFrame['volumechange']['right'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + if ($parsedFrame['incdec']['right'] === false) { + $parsedFrame['volumechange']['right'] *= -1; + } + $frame_offset += $frame_bytesvolume; + $parsedFrame['volumechange']['left'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + if ($parsedFrame['incdec']['left'] === false) { + $parsedFrame['volumechange']['left'] *= -1; + } + $frame_offset += $frame_bytesvolume; + $parsedFrame['peakvolume']['right'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + $frame_offset += $frame_bytesvolume; + $parsedFrame['peakvolume']['left'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + $frame_offset += $frame_bytesvolume; + if ($id3v2_majorversion == 3) { + $parsedFrame['data'] = substr($parsedFrame['data'], $frame_offset); + if (strlen($parsedFrame['data']) > 0) { + $parsedFrame['incdec']['rightrear'] = (bool) substr($frame_incrdecrflags, 4, 1); + $parsedFrame['incdec']['leftrear'] = (bool) substr($frame_incrdecrflags, 5, 1); + $parsedFrame['volumechange']['rightrear'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + if ($parsedFrame['incdec']['rightrear'] === false) { + $parsedFrame['volumechange']['rightrear'] *= -1; + } + $frame_offset += $frame_bytesvolume; + $parsedFrame['volumechange']['leftrear'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + if ($parsedFrame['incdec']['leftrear'] === false) { + $parsedFrame['volumechange']['leftrear'] *= -1; + } + $frame_offset += $frame_bytesvolume; + $parsedFrame['peakvolume']['rightrear'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + $frame_offset += $frame_bytesvolume; + $parsedFrame['peakvolume']['leftrear'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + $frame_offset += $frame_bytesvolume; + } + $parsedFrame['data'] = substr($parsedFrame['data'], $frame_offset); + if (strlen($parsedFrame['data']) > 0) { + $parsedFrame['incdec']['center'] = (bool) substr($frame_incrdecrflags, 3, 1); + $parsedFrame['volumechange']['center'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + if ($parsedFrame['incdec']['center'] === false) { + $parsedFrame['volumechange']['center'] *= -1; + } + $frame_offset += $frame_bytesvolume; + $parsedFrame['peakvolume']['center'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + $frame_offset += $frame_bytesvolume; + } + $parsedFrame['data'] = substr($parsedFrame['data'], $frame_offset); + if (strlen($parsedFrame['data']) > 0) { + $parsedFrame['incdec']['bass'] = (bool) substr($frame_incrdecrflags, 2, 1); + $parsedFrame['volumechange']['bass'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + if ($parsedFrame['incdec']['bass'] === false) { + $parsedFrame['volumechange']['bass'] *= -1; + } + $frame_offset += $frame_bytesvolume; + $parsedFrame['peakvolume']['bass'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesvolume)); + $frame_offset += $frame_bytesvolume; + } + } + unset($parsedFrame['data']); + + + } elseif (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'EQU2')) { // 4.12 EQU2 Equalisation (2) (ID3v2.4+ only) + // There may be more than one 'EQU2' frame in each tag, + // but only one with the same identification string + // <Header of 'Equalisation (2)', ID: 'EQU2'> + // Interpolation method $xx + // $00 Band + // $01 Linear + // Identification <text string> $00 + // The following is then repeated for every adjustment point + // Frequency $xx xx + // Volume adjustment $xx xx + + $frame_offset = 0; + $frame_interpolationmethod = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_idstring = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_idstring) === 0) { + $frame_idstring = ''; + } + $parsedFrame['description'] = $frame_idstring; + $frame_remainingdata = substr($parsedFrame['data'], $frame_terminatorpos + strlen("\x00")); + while (strlen($frame_remainingdata)) { + $frame_frequency = getid3_lib::BigEndian2Int(substr($frame_remainingdata, 0, 2)) / 2; + $parsedFrame['data'][$frame_frequency] = getid3_lib::BigEndian2Int(substr($frame_remainingdata, 2, 2), false, true); + $frame_remainingdata = substr($frame_remainingdata, 4); + } + $parsedFrame['interpolationmethod'] = $frame_interpolationmethod; + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion == 3) && ($parsedFrame['frame_name'] == 'EQUA')) || // 4.12 EQUA Equalisation (ID3v2.3 only) + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'EQU'))) { // 4.13 EQU Equalisation (ID3v2.2 only) + // There may only be one 'EQUA' frame in each tag + // <Header for 'Relative volume adjustment', ID: 'EQU'> + // Adjustment bits $xx + // This is followed by 2 bytes + ('adjustment bits' rounded up to the + // nearest byte) for every equalisation band in the following format, + // giving a frequency range of 0 - 32767Hz: + // Increment/decrement %x (MSB of the Frequency) + // Frequency (lower 15 bits) + // Adjustment $xx (xx ...) + + $frame_offset = 0; + $parsedFrame['adjustmentbits'] = substr($parsedFrame['data'], $frame_offset++, 1); + $frame_adjustmentbytes = ceil($parsedFrame['adjustmentbits'] / 8); + + $frame_remainingdata = (string) substr($parsedFrame['data'], $frame_offset); + while (strlen($frame_remainingdata) > 0) { + $frame_frequencystr = getid3_lib::BigEndian2Bin(substr($frame_remainingdata, 0, 2)); + $frame_incdec = (bool) substr($frame_frequencystr, 0, 1); + $frame_frequency = bindec(substr($frame_frequencystr, 1, 15)); + $parsedFrame[$frame_frequency]['incdec'] = $frame_incdec; + $parsedFrame[$frame_frequency]['adjustment'] = getid3_lib::BigEndian2Int(substr($frame_remainingdata, 2, $frame_adjustmentbytes)); + if ($parsedFrame[$frame_frequency]['incdec'] === false) { + $parsedFrame[$frame_frequency]['adjustment'] *= -1; + } + $frame_remainingdata = substr($frame_remainingdata, 2 + $frame_adjustmentbytes); + } + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'RVRB')) || // 4.13 RVRB Reverb + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'REV'))) { // 4.14 REV Reverb + // There may only be one 'RVRB' frame in each tag. + // <Header for 'Reverb', ID: 'RVRB'> + // Reverb left (ms) $xx xx + // Reverb right (ms) $xx xx + // Reverb bounces, left $xx + // Reverb bounces, right $xx + // Reverb feedback, left to left $xx + // Reverb feedback, left to right $xx + // Reverb feedback, right to right $xx + // Reverb feedback, right to left $xx + // Premix left to right $xx + // Premix right to left $xx + + $frame_offset = 0; + $parsedFrame['left'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2)); + $frame_offset += 2; + $parsedFrame['right'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2)); + $frame_offset += 2; + $parsedFrame['bouncesL'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['bouncesR'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['feedbackLL'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['feedbackLR'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['feedbackRR'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['feedbackRL'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['premixLR'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['premixRL'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'APIC')) || // 4.14 APIC Attached picture + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'PIC'))) { // 4.15 PIC Attached picture + // There may be several pictures attached to one file, + // each in their individual 'APIC' frame, but only one + // with the same content descriptor + // <Header for 'Attached picture', ID: 'APIC'> + // Text encoding $xx + // ID3v2.3+ => MIME type <text string> $00 + // ID3v2.2 => Image format $xx xx xx + // Picture type $xx + // Description <text string according to encoding> $00 (00) + // Picture data <binary data> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + + if ($id3v2_majorversion == 2 && strlen($parsedFrame['data']) > $frame_offset) { + $frame_imagetype = substr($parsedFrame['data'], $frame_offset, 3); + if (strtolower($frame_imagetype) == 'ima') { + // complete hack for mp3Rage (www.chaoticsoftware.com) that puts ID3v2.3-formatted + // MIME type instead of 3-char ID3v2.2-format image type (thanks xbhoffĆpacbell*net) + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_mimetype) === 0) { + $frame_mimetype = ''; + } + $frame_imagetype = strtoupper(str_replace('image/', '', strtolower($frame_mimetype))); + if ($frame_imagetype == 'JPEG') { + $frame_imagetype = 'JPG'; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + } else { + $frame_offset += 3; + } + } + if ($id3v2_majorversion > 2 && strlen($parsedFrame['data']) > $frame_offset) { + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_mimetype) === 0) { + $frame_mimetype = ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + } + + $frame_picturetype = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + + if ($frame_offset >= $parsedFrame['datalength']) { + $info['warning'][] = 'data portion of APIC frame is missing at offset '.($parsedFrame['dataoffset'] + 8 + $frame_offset); + } else { + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_description) === 0) { + $frame_description = ''; + } + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + if ($id3v2_majorversion == 2) { + $parsedFrame['imagetype'] = $frame_imagetype; + } else { + $parsedFrame['mime'] = $frame_mimetype; + } + $parsedFrame['picturetypeid'] = $frame_picturetype; + $parsedFrame['picturetype'] = $this->APICPictureTypeLookup($frame_picturetype); + $parsedFrame['description'] = $frame_description; + $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); + $parsedFrame['datalength'] = strlen($parsedFrame['data']); + + $parsedFrame['image_mime'] = ''; + $imageinfo = array(); + $imagechunkcheck = getid3_lib::GetDataImageSize($parsedFrame['data'], $imageinfo); + if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) { + $parsedFrame['image_mime'] = 'image/'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]); + if ($imagechunkcheck[0]) { + $parsedFrame['image_width'] = $imagechunkcheck[0]; + } + if ($imagechunkcheck[1]) { + $parsedFrame['image_height'] = $imagechunkcheck[1]; + } + } + + do { + if ($this->getid3->option_save_attachments === false) { + // skip entirely + unset($parsedFrame['data']); + break; + } + if ($this->getid3->option_save_attachments === true) { + // great +/* + } elseif (is_int($this->getid3->option_save_attachments)) { + if ($this->getid3->option_save_attachments < $parsedFrame['data_length']) { + // too big, skip + $info['warning'][] = 'attachment at '.$frame_offset.' is too large to process inline ('.number_format($parsedFrame['data_length']).' bytes)'; + unset($parsedFrame['data']); + break; + } +*/ + } elseif (is_string($this->getid3->option_save_attachments)) { + $dir = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->getid3->option_save_attachments), DIRECTORY_SEPARATOR); + if (!is_dir($dir) || !is_writable($dir)) { + // cannot write, skip + $info['warning'][] = 'attachment at '.$frame_offset.' cannot be saved to "'.$dir.'" (not writable)'; + unset($parsedFrame['data']); + break; + } + } + // if we get this far, must be OK + if (is_string($this->getid3->option_save_attachments)) { + $destination_filename = $dir.DIRECTORY_SEPARATOR.md5($info['filenamepath']).'_'.$frame_offset; + if (!file_exists($destination_filename) || is_writable($destination_filename)) { + file_put_contents($destination_filename, $parsedFrame['data']); + } else { + $info['warning'][] = 'attachment at '.$frame_offset.' cannot be saved to "'.$destination_filename.'" (not writable)'; + } + $parsedFrame['data_filename'] = $destination_filename; + unset($parsedFrame['data']); + } else { + if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { + if (!isset($info['id3v2']['comments']['picture'])) { + $info['id3v2']['comments']['picture'] = array(); + } + $info['id3v2']['comments']['picture'][] = array('data'=>$parsedFrame['data'], 'image_mime'=>$parsedFrame['image_mime']); + } + } + } while (false); + } + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'GEOB')) || // 4.15 GEOB General encapsulated object + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'GEO'))) { // 4.16 GEO General encapsulated object + // There may be more than one 'GEOB' frame in each tag, + // but only one with the same content descriptor + // <Header for 'General encapsulated object', ID: 'GEOB'> + // Text encoding $xx + // MIME type <text string> $00 + // Filename <text string according to encoding> $00 (00) + // Content description <text string according to encoding> $00 (00) + // Encapsulated object <binary data> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_mimetype) === 0) { + $frame_mimetype = ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_filename = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_filename) === 0) { + $frame_filename = ''; + } + $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)); + + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_description) === 0) { + $frame_description = ''; + } + $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)); + + $parsedFrame['objectdata'] = (string) substr($parsedFrame['data'], $frame_offset); + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $parsedFrame['mime'] = $frame_mimetype; + $parsedFrame['filename'] = $frame_filename; + $parsedFrame['description'] = $frame_description; + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'PCNT')) || // 4.16 PCNT Play counter + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'CNT'))) { // 4.17 CNT Play counter + // There may only be one 'PCNT' frame in each tag. + // When the counter reaches all one's, one byte is inserted in + // front of the counter thus making the counter eight bits bigger + // <Header for 'Play counter', ID: 'PCNT'> + // Counter $xx xx xx xx (xx ...) + + $parsedFrame['data'] = getid3_lib::BigEndian2Int($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'POPM')) || // 4.17 POPM Popularimeter + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'POP'))) { // 4.18 POP Popularimeter + // There may be more than one 'POPM' frame in each tag, + // but only one with the same email address + // <Header for 'Popularimeter', ID: 'POPM'> + // Email to user <text string> $00 + // Rating $xx + // Counter $xx xx xx xx (xx ...) + + $frame_offset = 0; + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_emailaddress = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_emailaddress) === 0) { + $frame_emailaddress = ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + $frame_rating = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['counter'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset)); + $parsedFrame['email'] = $frame_emailaddress; + $parsedFrame['rating'] = $frame_rating; + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'RBUF')) || // 4.18 RBUF Recommended buffer size + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'BUF'))) { // 4.19 BUF Recommended buffer size + // There may only be one 'RBUF' frame in each tag + // <Header for 'Recommended buffer size', ID: 'RBUF'> + // Buffer size $xx xx xx + // Embedded info flag %0000000x + // Offset to next tag $xx xx xx xx + + $frame_offset = 0; + $parsedFrame['buffersize'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 3)); + $frame_offset += 3; + + $frame_embeddedinfoflags = getid3_lib::BigEndian2Bin(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['flags']['embededinfo'] = (bool) substr($frame_embeddedinfoflags, 7, 1); + $parsedFrame['nexttagoffset'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4)); + unset($parsedFrame['data']); + + + } elseif (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'CRM')) { // 4.20 Encrypted meta frame (ID3v2.2 only) + // There may be more than one 'CRM' frame in a tag, + // but only one with the same 'owner identifier' + // <Header for 'Encrypted meta frame', ID: 'CRM'> + // Owner identifier <textstring> $00 (00) + // Content/explanation <textstring> $00 (00) + // Encrypted datablock <binary data> + + $frame_offset = 0; + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_description) === 0) { + $frame_description = ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $parsedFrame['ownerid'] = $frame_ownerid; + $parsedFrame['data'] = (string) substr($parsedFrame['data'], $frame_offset); + $parsedFrame['description'] = $frame_description; + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'AENC')) || // 4.19 AENC Audio encryption + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'CRA'))) { // 4.21 CRA Audio encryption + // There may be more than one 'AENC' frames in a tag, + // but only one with the same 'Owner identifier' + // <Header for 'Audio encryption', ID: 'AENC'> + // Owner identifier <text string> $00 + // Preview start $xx xx + // Preview length $xx xx + // Encryption info <binary data> + + $frame_offset = 0; + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_ownerid) === 0) { + $frame_ownerid == ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + $parsedFrame['ownerid'] = $frame_ownerid; + $parsedFrame['previewstart'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2)); + $frame_offset += 2; + $parsedFrame['previewlength'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2)); + $frame_offset += 2; + $parsedFrame['encryptioninfo'] = (string) substr($parsedFrame['data'], $frame_offset); + unset($parsedFrame['data']); + + + } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'LINK')) || // 4.20 LINK Linked information + (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'LNK'))) { // 4.22 LNK Linked information + // There may be more than one 'LINK' frame in a tag, + // but only one with the same contents + // <Header for 'Linked information', ID: 'LINK'> + // ID3v2.3+ => Frame identifier $xx xx xx xx + // ID3v2.2 => Frame identifier $xx xx xx + // URL <text string> $00 + // ID and additional data <text string(s)> + + $frame_offset = 0; + if ($id3v2_majorversion == 2) { + $parsedFrame['frameid'] = substr($parsedFrame['data'], $frame_offset, 3); + $frame_offset += 3; + } else { + $parsedFrame['frameid'] = substr($parsedFrame['data'], $frame_offset, 4); + $frame_offset += 4; + } + + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_url = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_url) === 0) { + $frame_url = ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + $parsedFrame['url'] = $frame_url; + + $parsedFrame['additionaldata'] = (string) substr($parsedFrame['data'], $frame_offset); + if (!empty($parsedFrame['framenameshort']) && $parsedFrame['url']) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = utf8_encode($parsedFrame['url']); + } + unset($parsedFrame['data']); + + + } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'POSS')) { // 4.21 POSS Position synchronisation frame (ID3v2.3+ only) + // There may only be one 'POSS' frame in each tag + // <Head for 'Position synchronisation', ID: 'POSS'> + // Time stamp format $xx + // Position $xx (xx ...) + + $frame_offset = 0; + $parsedFrame['timestampformat'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['position'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset)); + unset($parsedFrame['data']); + + + } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'USER')) { // 4.22 USER Terms of use (ID3v2.3+ only) + // There may be more than one 'Terms of use' frame in a tag, + // but only one with the same 'Language' + // <Header for 'Terms of use frame', ID: 'USER'> + // Text encoding $xx + // Language $xx xx xx + // The actual text <text string according to encoding> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $frame_language = substr($parsedFrame['data'], $frame_offset, 3); + $frame_offset += 3; + $parsedFrame['language'] = $frame_language; + $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false); + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $parsedFrame['data'] = (string) substr($parsedFrame['data'], $frame_offset); + if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { + $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']); + } + unset($parsedFrame['data']); + + + } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'OWNE')) { // 4.23 OWNE Ownership frame (ID3v2.3+ only) + // There may only be one 'OWNE' frame in a tag + // <Header for 'Ownership frame', ID: 'OWNE'> + // Text encoding $xx + // Price paid <text string> $00 + // Date of purch. <text string> + // Seller <text string according to encoding> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_pricepaid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $parsedFrame['pricepaid']['currencyid'] = substr($frame_pricepaid, 0, 3); + $parsedFrame['pricepaid']['currency'] = $this->LookupCurrencyUnits($parsedFrame['pricepaid']['currencyid']); + $parsedFrame['pricepaid']['value'] = substr($frame_pricepaid, 3); + + $parsedFrame['purchasedate'] = substr($parsedFrame['data'], $frame_offset, 8); + if (!$this->IsValidDateStampString($parsedFrame['purchasedate'])) { + $parsedFrame['purchasedateunix'] = mktime (0, 0, 0, substr($parsedFrame['purchasedate'], 4, 2), substr($parsedFrame['purchasedate'], 6, 2), substr($parsedFrame['purchasedate'], 0, 4)); + } + $frame_offset += 8; + + $parsedFrame['seller'] = (string) substr($parsedFrame['data'], $frame_offset); + unset($parsedFrame['data']); + + + } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'COMR')) { // 4.24 COMR Commercial frame (ID3v2.3+ only) + // There may be more than one 'commercial frame' in a tag, + // but no two may be identical + // <Header for 'Commercial frame', ID: 'COMR'> + // Text encoding $xx + // Price string <text string> $00 + // Valid until <text string> + // Contact URL <text string> $00 + // Received as $xx + // Name of seller <text string according to encoding> $00 (00) + // Description <text string according to encoding> $00 (00) + // Picture MIME type <string> $00 + // Seller logo <binary data> + + $frame_offset = 0; + $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { + $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; + } + + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_pricestring = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + $frame_offset = $frame_terminatorpos + strlen("\x00"); + $frame_rawpricearray = explode('/', $frame_pricestring); + foreach ($frame_rawpricearray as $key => $val) { + $frame_currencyid = substr($val, 0, 3); + $parsedFrame['price'][$frame_currencyid]['currency'] = $this->LookupCurrencyUnits($frame_currencyid); + $parsedFrame['price'][$frame_currencyid]['value'] = substr($val, 3); + } + + $frame_datestring = substr($parsedFrame['data'], $frame_offset, 8); + $frame_offset += 8; + + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_contacturl = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $frame_receivedasid = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_sellername = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_sellername) === 0) { + $frame_sellername = ''; + } + $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)); + + $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset); + if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) { + $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 + } + $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_description) === 0) { + $frame_description = ''; + } + $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)); + + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_mimetype = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $frame_sellerlogo = substr($parsedFrame['data'], $frame_offset); + + $parsedFrame['encodingid'] = $frame_textencoding; + $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); + + $parsedFrame['pricevaliduntil'] = $frame_datestring; + $parsedFrame['contacturl'] = $frame_contacturl; + $parsedFrame['receivedasid'] = $frame_receivedasid; + $parsedFrame['receivedas'] = $this->COMRReceivedAsLookup($frame_receivedasid); + $parsedFrame['sellername'] = $frame_sellername; + $parsedFrame['description'] = $frame_description; + $parsedFrame['mime'] = $frame_mimetype; + $parsedFrame['logo'] = $frame_sellerlogo; + unset($parsedFrame['data']); + + + } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'ENCR')) { // 4.25 ENCR Encryption method registration (ID3v2.3+ only) + // There may be several 'ENCR' frames in a tag, + // but only one containing the same symbol + // and only one containing the same owner identifier + // <Header for 'Encryption method registration', ID: 'ENCR'> + // Owner identifier <text string> $00 + // Method symbol $xx + // Encryption data <binary data> + + $frame_offset = 0; + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_ownerid) === 0) { + $frame_ownerid = ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $parsedFrame['ownerid'] = $frame_ownerid; + $parsedFrame['methodsymbol'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['data'] = (string) substr($parsedFrame['data'], $frame_offset); + + + } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'GRID')) { // 4.26 GRID Group identification registration (ID3v2.3+ only) + + // There may be several 'GRID' frames in a tag, + // but only one containing the same symbol + // and only one containing the same owner identifier + // <Header for 'Group ID registration', ID: 'GRID'> + // Owner identifier <text string> $00 + // Group symbol $xx + // Group dependent data <binary data> + + $frame_offset = 0; + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_ownerid) === 0) { + $frame_ownerid = ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $parsedFrame['ownerid'] = $frame_ownerid; + $parsedFrame['groupsymbol'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['data'] = (string) substr($parsedFrame['data'], $frame_offset); + + + } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'PRIV')) { // 4.27 PRIV Private frame (ID3v2.3+ only) + // The tag may contain more than one 'PRIV' frame + // but only with different contents + // <Header for 'Private frame', ID: 'PRIV'> + // Owner identifier <text string> $00 + // The private data <binary data> + + $frame_offset = 0; + $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); + $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset); + if (ord($frame_ownerid) === 0) { + $frame_ownerid = ''; + } + $frame_offset = $frame_terminatorpos + strlen("\x00"); + + $parsedFrame['ownerid'] = $frame_ownerid; + $parsedFrame['data'] = (string) substr($parsedFrame['data'], $frame_offset); + + + } elseif (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'SIGN')) { // 4.28 SIGN Signature frame (ID3v2.4+ only) + // There may be more than one 'signature frame' in a tag, + // but no two may be identical + // <Header for 'Signature frame', ID: 'SIGN'> + // Group symbol $xx + // Signature <binary data> + + $frame_offset = 0; + $parsedFrame['groupsymbol'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $parsedFrame['data'] = (string) substr($parsedFrame['data'], $frame_offset); + + + } elseif (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'SEEK')) { // 4.29 SEEK Seek frame (ID3v2.4+ only) + // There may only be one 'seek frame' in a tag + // <Header for 'Seek frame', ID: 'SEEK'> + // Minimum offset to next tag $xx xx xx xx + + $frame_offset = 0; + $parsedFrame['data'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4)); + + + } elseif (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'ASPI')) { // 4.30 ASPI Audio seek point index (ID3v2.4+ only) + // There may only be one 'audio seek point index' frame in a tag + // <Header for 'Seek Point Index', ID: 'ASPI'> + // Indexed data start (S) $xx xx xx xx + // Indexed data length (L) $xx xx xx xx + // Number of index points (N) $xx xx + // Bits per index point (b) $xx + // Then for every index point the following data is included: + // Fraction at index (Fi) $xx (xx) + + $frame_offset = 0; + $parsedFrame['datastart'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4)); + $frame_offset += 4; + $parsedFrame['indexeddatalength'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4)); + $frame_offset += 4; + $parsedFrame['indexpoints'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2)); + $frame_offset += 2; + $parsedFrame['bitsperpoint'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); + $frame_bytesperpoint = ceil($parsedFrame['bitsperpoint'] / 8); + for ($i = 0; $i < $frame_indexpoints; $i++) { + $parsedFrame['indexes'][$i] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesperpoint)); + $frame_offset += $frame_bytesperpoint; + } + unset($parsedFrame['data']); + + } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'RGAD')) { // Replay Gain Adjustment + // http://privatewww.essex.ac.uk/~djmrob/replaygain/file_format_id3v2.html + // There may only be one 'RGAD' frame in a tag + // <Header for 'Replay Gain Adjustment', ID: 'RGAD'> + // Peak Amplitude $xx $xx $xx $xx + // Radio Replay Gain Adjustment %aaabbbcd %dddddddd + // Audiophile Replay Gain Adjustment %aaabbbcd %dddddddd + // a - name code + // b - originator code + // c - sign bit + // d - replay gain adjustment + + $frame_offset = 0; + $parsedFrame['peakamplitude'] = getid3_lib::BigEndian2Float(substr($parsedFrame['data'], $frame_offset, 4)); + $frame_offset += 4; + $rg_track_adjustment = getid3_lib::Dec2Bin(substr($parsedFrame['data'], $frame_offset, 2)); + $frame_offset += 2; + $rg_album_adjustment = getid3_lib::Dec2Bin(substr($parsedFrame['data'], $frame_offset, 2)); + $frame_offset += 2; + $parsedFrame['raw']['track']['name'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 0, 3)); + $parsedFrame['raw']['track']['originator'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 3, 3)); + $parsedFrame['raw']['track']['signbit'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 6, 1)); + $parsedFrame['raw']['track']['adjustment'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 7, 9)); + $parsedFrame['raw']['album']['name'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 0, 3)); + $parsedFrame['raw']['album']['originator'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 3, 3)); + $parsedFrame['raw']['album']['signbit'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 6, 1)); + $parsedFrame['raw']['album']['adjustment'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 7, 9)); + $parsedFrame['track']['name'] = getid3_lib::RGADnameLookup($parsedFrame['raw']['track']['name']); + $parsedFrame['track']['originator'] = getid3_lib::RGADoriginatorLookup($parsedFrame['raw']['track']['originator']); + $parsedFrame['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($parsedFrame['raw']['track']['adjustment'], $parsedFrame['raw']['track']['signbit']); + $parsedFrame['album']['name'] = getid3_lib::RGADnameLookup($parsedFrame['raw']['album']['name']); + $parsedFrame['album']['originator'] = getid3_lib::RGADoriginatorLookup($parsedFrame['raw']['album']['originator']); + $parsedFrame['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($parsedFrame['raw']['album']['adjustment'], $parsedFrame['raw']['album']['signbit']); + + $info['replay_gain']['track']['peak'] = $parsedFrame['peakamplitude']; + $info['replay_gain']['track']['originator'] = $parsedFrame['track']['originator']; + $info['replay_gain']['track']['adjustment'] = $parsedFrame['track']['adjustment']; + $info['replay_gain']['album']['originator'] = $parsedFrame['album']['originator']; + $info['replay_gain']['album']['adjustment'] = $parsedFrame['album']['adjustment']; + + unset($parsedFrame['data']); + + } + + return true; + } + + + public function DeUnsynchronise($data) { + return str_replace("\xFF\x00", "\xFF", $data); + } + + public function LookupExtendedHeaderRestrictionsTagSizeLimits($index) { + static $LookupExtendedHeaderRestrictionsTagSizeLimits = array( + 0x00 => 'No more than 128 frames and 1 MB total tag size', + 0x01 => 'No more than 64 frames and 128 KB total tag size', + 0x02 => 'No more than 32 frames and 40 KB total tag size', + 0x03 => 'No more than 32 frames and 4 KB total tag size', + ); + return (isset($LookupExtendedHeaderRestrictionsTagSizeLimits[$index]) ? $LookupExtendedHeaderRestrictionsTagSizeLimits[$index] : ''); + } + + public function LookupExtendedHeaderRestrictionsTextEncodings($index) { + static $LookupExtendedHeaderRestrictionsTextEncodings = array( + 0x00 => 'No restrictions', + 0x01 => 'Strings are only encoded with ISO-8859-1 or UTF-8', + ); + return (isset($LookupExtendedHeaderRestrictionsTextEncodings[$index]) ? $LookupExtendedHeaderRestrictionsTextEncodings[$index] : ''); + } + + public function LookupExtendedHeaderRestrictionsTextFieldSize($index) { + static $LookupExtendedHeaderRestrictionsTextFieldSize = array( + 0x00 => 'No restrictions', + 0x01 => 'No string is longer than 1024 characters', + 0x02 => 'No string is longer than 128 characters', + 0x03 => 'No string is longer than 30 characters', + ); + return (isset($LookupExtendedHeaderRestrictionsTextFieldSize[$index]) ? $LookupExtendedHeaderRestrictionsTextFieldSize[$index] : ''); + } + + public function LookupExtendedHeaderRestrictionsImageEncoding($index) { + static $LookupExtendedHeaderRestrictionsImageEncoding = array( + 0x00 => 'No restrictions', + 0x01 => 'Images are encoded only with PNG or JPEG', + ); + return (isset($LookupExtendedHeaderRestrictionsImageEncoding[$index]) ? $LookupExtendedHeaderRestrictionsImageEncoding[$index] : ''); + } + + public function LookupExtendedHeaderRestrictionsImageSizeSize($index) { + static $LookupExtendedHeaderRestrictionsImageSizeSize = array( + 0x00 => 'No restrictions', + 0x01 => 'All images are 256x256 pixels or smaller', + 0x02 => 'All images are 64x64 pixels or smaller', + 0x03 => 'All images are exactly 64x64 pixels, unless required otherwise', + ); + return (isset($LookupExtendedHeaderRestrictionsImageSizeSize[$index]) ? $LookupExtendedHeaderRestrictionsImageSizeSize[$index] : ''); + } + + public function LookupCurrencyUnits($currencyid) { + + $begin = __LINE__; + + /** This is not a comment! + + + AED Dirhams + AFA Afghanis + ALL Leke + AMD Drams + ANG Guilders + AOA Kwanza + ARS Pesos + ATS Schillings + AUD Dollars + AWG Guilders + AZM Manats + BAM Convertible Marka + BBD Dollars + BDT Taka + BEF Francs + BGL Leva + BHD Dinars + BIF Francs + BMD Dollars + BND Dollars + BOB Bolivianos + BRL Brazil Real + BSD Dollars + BTN Ngultrum + BWP Pulas + BYR Rubles + BZD Dollars + CAD Dollars + CDF Congolese Francs + CHF Francs + CLP Pesos + CNY Yuan Renminbi + COP Pesos + CRC Colones + CUP Pesos + CVE Escudos + CYP Pounds + CZK Koruny + DEM Deutsche Marks + DJF Francs + DKK Kroner + DOP Pesos + DZD Algeria Dinars + EEK Krooni + EGP Pounds + ERN Nakfa + ESP Pesetas + ETB Birr + EUR Euro + FIM Markkaa + FJD Dollars + FKP Pounds + FRF Francs + GBP Pounds + GEL Lari + GGP Pounds + GHC Cedis + GIP Pounds + GMD Dalasi + GNF Francs + GRD Drachmae + GTQ Quetzales + GYD Dollars + HKD Dollars + HNL Lempiras + HRK Kuna + HTG Gourdes + HUF Forints + IDR Rupiahs + IEP Pounds + ILS New Shekels + IMP Pounds + INR Rupees + IQD Dinars + IRR Rials + ISK Kronur + ITL Lire + JEP Pounds + JMD Dollars + JOD Dinars + JPY Yen + KES Shillings + KGS Soms + KHR Riels + KMF Francs + KPW Won + KWD Dinars + KYD Dollars + KZT Tenge + LAK Kips + LBP Pounds + LKR Rupees + LRD Dollars + LSL Maloti + LTL Litai + LUF Francs + LVL Lati + LYD Dinars + MAD Dirhams + MDL Lei + MGF Malagasy Francs + MKD Denars + MMK Kyats + MNT Tugriks + MOP Patacas + MRO Ouguiyas + MTL Liri + MUR Rupees + MVR Rufiyaa + MWK Kwachas + MXN Pesos + MYR Ringgits + MZM Meticais + NAD Dollars + NGN Nairas + NIO Gold Cordobas + NLG Guilders + NOK Krone + NPR Nepal Rupees + NZD Dollars + OMR Rials + PAB Balboa + PEN Nuevos Soles + PGK Kina + PHP Pesos + PKR Rupees + PLN Zlotych + PTE Escudos + PYG Guarani + QAR Rials + ROL Lei + RUR Rubles + RWF Rwanda Francs + SAR Riyals + SBD Dollars + SCR Rupees + SDD Dinars + SEK Kronor + SGD Dollars + SHP Pounds + SIT Tolars + SKK Koruny + SLL Leones + SOS Shillings + SPL Luigini + SRG Guilders + STD Dobras + SVC Colones + SYP Pounds + SZL Emalangeni + THB Baht + TJR Rubles + TMM Manats + TND Dinars + TOP Pa'anga + TRL Liras + TTD Dollars + TVD Tuvalu Dollars + TWD New Dollars + TZS Shillings + UAH Hryvnia + UGX Shillings + USD Dollars + UYU Pesos + UZS Sums + VAL Lire + VEB Bolivares + VND Dong + VUV Vatu + WST Tala + XAF Francs + XAG Ounces + XAU Ounces + XCD Dollars + XDR Special Drawing Rights + XPD Ounces + XPF Francs + XPT Ounces + YER Rials + YUM New Dinars + ZAR Rand + ZMK Kwacha + ZWD Zimbabwe Dollars + + */ + + return getid3_lib::EmbeddedLookup($currencyid, $begin, __LINE__, __FILE__, 'id3v2-currency-units'); + } + + + public function LookupCurrencyCountry($currencyid) { + + $begin = __LINE__; + + /** This is not a comment! + + AED United Arab Emirates + AFA Afghanistan + ALL Albania + AMD Armenia + ANG Netherlands Antilles + AOA Angola + ARS Argentina + ATS Austria + AUD Australia + AWG Aruba + AZM Azerbaijan + BAM Bosnia and Herzegovina + BBD Barbados + BDT Bangladesh + BEF Belgium + BGL Bulgaria + BHD Bahrain + BIF Burundi + BMD Bermuda + BND Brunei Darussalam + BOB Bolivia + BRL Brazil + BSD Bahamas + BTN Bhutan + BWP Botswana + BYR Belarus + BZD Belize + CAD Canada + CDF Congo/Kinshasa + CHF Switzerland + CLP Chile + CNY China + COP Colombia + CRC Costa Rica + CUP Cuba + CVE Cape Verde + CYP Cyprus + CZK Czech Republic + DEM Germany + DJF Djibouti + DKK Denmark + DOP Dominican Republic + DZD Algeria + EEK Estonia + EGP Egypt + ERN Eritrea + ESP Spain + ETB Ethiopia + EUR Euro Member Countries + FIM Finland + FJD Fiji + FKP Falkland Islands (Malvinas) + FRF France + GBP United Kingdom + GEL Georgia + GGP Guernsey + GHC Ghana + GIP Gibraltar + GMD Gambia + GNF Guinea + GRD Greece + GTQ Guatemala + GYD Guyana + HKD Hong Kong + HNL Honduras + HRK Croatia + HTG Haiti + HUF Hungary + IDR Indonesia + IEP Ireland (Eire) + ILS Israel + IMP Isle of Man + INR India + IQD Iraq + IRR Iran + ISK Iceland + ITL Italy + JEP Jersey + JMD Jamaica + JOD Jordan + JPY Japan + KES Kenya + KGS Kyrgyzstan + KHR Cambodia + KMF Comoros + KPW Korea + KWD Kuwait + KYD Cayman Islands + KZT Kazakstan + LAK Laos + LBP Lebanon + LKR Sri Lanka + LRD Liberia + LSL Lesotho + LTL Lithuania + LUF Luxembourg + LVL Latvia + LYD Libya + MAD Morocco + MDL Moldova + MGF Madagascar + MKD Macedonia + MMK Myanmar (Burma) + MNT Mongolia + MOP Macau + MRO Mauritania + MTL Malta + MUR Mauritius + MVR Maldives (Maldive Islands) + MWK Malawi + MXN Mexico + MYR Malaysia + MZM Mozambique + NAD Namibia + NGN Nigeria + NIO Nicaragua + NLG Netherlands (Holland) + NOK Norway + NPR Nepal + NZD New Zealand + OMR Oman + PAB Panama + PEN Peru + PGK Papua New Guinea + PHP Philippines + PKR Pakistan + PLN Poland + PTE Portugal + PYG Paraguay + QAR Qatar + ROL Romania + RUR Russia + RWF Rwanda + SAR Saudi Arabia + SBD Solomon Islands + SCR Seychelles + SDD Sudan + SEK Sweden + SGD Singapore + SHP Saint Helena + SIT Slovenia + SKK Slovakia + SLL Sierra Leone + SOS Somalia + SPL Seborga + SRG Suriname + STD SĆ£o Tome and Principe + SVC El Salvador + SYP Syria + SZL Swaziland + THB Thailand + TJR Tajikistan + TMM Turkmenistan + TND Tunisia + TOP Tonga + TRL Turkey + TTD Trinidad and Tobago + TVD Tuvalu + TWD Taiwan + TZS Tanzania + UAH Ukraine + UGX Uganda + USD United States of America + UYU Uruguay + UZS Uzbekistan + VAL Vatican City + VEB Venezuela + VND Viet Nam + VUV Vanuatu + WST Samoa + XAF CommunautĆ© FinanciĆØre Africaine + XAG Silver + XAU Gold + XCD East Caribbean + XDR International Monetary Fund + XPD Palladium + XPF Comptoirs FranƧais du Pacifique + XPT Platinum + YER Yemen + YUM Yugoslavia + ZAR South Africa + ZMK Zambia + ZWD Zimbabwe + + */ + + return getid3_lib::EmbeddedLookup($currencyid, $begin, __LINE__, __FILE__, 'id3v2-currency-country'); + } + + + + public static function LanguageLookup($languagecode, $casesensitive=false) { + + if (!$casesensitive) { + $languagecode = strtolower($languagecode); + } + + // http://www.id3.org/id3v2.4.0-structure.txt + // [4. ID3v2 frame overview] + // The three byte language field, present in several frames, is used to + // describe the language of the frame's content, according to ISO-639-2 + // [ISO-639-2]. The language should be represented in lower case. If the + // language is not known the string "XXX" should be used. + + + // ISO 639-2 - http://www.id3.org/iso639-2.html + + $begin = __LINE__; + + /** This is not a comment! + + XXX unknown + xxx unknown + aar Afar + abk Abkhazian + ace Achinese + ach Acoli + ada Adangme + afa Afro-Asiatic (Other) + afh Afrihili + afr Afrikaans + aka Akan + akk Akkadian + alb Albanian + ale Aleut + alg Algonquian Languages + amh Amharic + ang English, Old (ca. 450-1100) + apa Apache Languages + ara Arabic + arc Aramaic + arm Armenian + arn Araucanian + arp Arapaho + art Artificial (Other) + arw Arawak + asm Assamese + ath Athapascan Languages + ava Avaric + ave Avestan + awa Awadhi + aym Aymara + aze Azerbaijani + bad Banda + bai Bamileke Languages + bak Bashkir + bal Baluchi + bam Bambara + ban Balinese + baq Basque + bas Basa + bat Baltic (Other) + bej Beja + bel Byelorussian + bem Bemba + ben Bengali + ber Berber (Other) + bho Bhojpuri + bih Bihari + bik Bikol + bin Bini + bis Bislama + bla Siksika + bnt Bantu (Other) + bod Tibetan + bra Braj + bre Breton + bua Buriat + bug Buginese + bul Bulgarian + bur Burmese + cad Caddo + cai Central American Indian (Other) + car Carib + cat Catalan + cau Caucasian (Other) + ceb Cebuano + cel Celtic (Other) + ces Czech + cha Chamorro + chb Chibcha + che Chechen + chg Chagatai + chi Chinese + chm Mari + chn Chinook jargon + cho Choctaw + chr Cherokee + chu Church Slavic + chv Chuvash + chy Cheyenne + cop Coptic + cor Cornish + cos Corsican + cpe Creoles and Pidgins, English-based (Other) + cpf Creoles and Pidgins, French-based (Other) + cpp Creoles and Pidgins, Portuguese-based (Other) + cre Cree + crp Creoles and Pidgins (Other) + cus Cushitic (Other) + cym Welsh + cze Czech + dak Dakota + dan Danish + del Delaware + deu German + din Dinka + div Divehi + doi Dogri + dra Dravidian (Other) + dua Duala + dum Dutch, Middle (ca. 1050-1350) + dut Dutch + dyu Dyula + dzo Dzongkha + efi Efik + egy Egyptian (Ancient) + eka Ekajuk + ell Greek, Modern (1453-) + elx Elamite + eng English + enm English, Middle (ca. 1100-1500) + epo Esperanto + esk Eskimo (Other) + esl Spanish + est Estonian + eus Basque + ewe Ewe + ewo Ewondo + fan Fang + fao Faroese + fas Persian + fat Fanti + fij Fijian + fin Finnish + fiu Finno-Ugrian (Other) + fon Fon + fra French + fre French + frm French, Middle (ca. 1400-1600) + fro French, Old (842- ca. 1400) + fry Frisian + ful Fulah + gaa Ga + gae Gaelic (Scots) + gai Irish + gay Gayo + gdh Gaelic (Scots) + gem Germanic (Other) + geo Georgian + ger German + gez Geez + gil Gilbertese + glg Gallegan + gmh German, Middle High (ca. 1050-1500) + goh German, Old High (ca. 750-1050) + gon Gondi + got Gothic + grb Grebo + grc Greek, Ancient (to 1453) + gre Greek, Modern (1453-) + grn Guarani + guj Gujarati + hai Haida + hau Hausa + haw Hawaiian + heb Hebrew + her Herero + hil Hiligaynon + him Himachali + hin Hindi + hmo Hiri Motu + hun Hungarian + hup Hupa + hye Armenian + iba Iban + ibo Igbo + ice Icelandic + ijo Ijo + iku Inuktitut + ilo Iloko + ina Interlingua (International Auxiliary language Association) + inc Indic (Other) + ind Indonesian + ine Indo-European (Other) + ine Interlingue + ipk Inupiak + ira Iranian (Other) + iri Irish + iro Iroquoian uages + isl Icelandic + ita Italian + jav Javanese + jaw Javanese + jpn Japanese + jpr Judeo-Persian + jrb Judeo-Arabic + kaa Kara-Kalpak + kab Kabyle + kac Kachin + kal Greenlandic + kam Kamba + kan Kannada + kar Karen + kas Kashmiri + kat Georgian + kau Kanuri + kaw Kawi + kaz Kazakh + kha Khasi + khi Khoisan (Other) + khm Khmer + kho Khotanese + kik Kikuyu + kin Kinyarwanda + kir Kirghiz + kok Konkani + kom Komi + kon Kongo + kor Korean + kpe Kpelle + kro Kru + kru Kurukh + kua Kuanyama + kum Kumyk + kur Kurdish + kus Kusaie + kut Kutenai + lad Ladino + lah Lahnda + lam Lamba + lao Lao + lat Latin + lav Latvian + lez Lezghian + lin Lingala + lit Lithuanian + lol Mongo + loz Lozi + ltz Letzeburgesch + lub Luba-Katanga + lug Ganda + lui Luiseno + lun Lunda + luo Luo (Kenya and Tanzania) + mac Macedonian + mad Madurese + mag Magahi + mah Marshall + mai Maithili + mak Macedonian + mak Makasar + mal Malayalam + man Mandingo + mao Maori + map Austronesian (Other) + mar Marathi + mas Masai + max Manx + may Malay + men Mende + mga Irish, Middle (900 - 1200) + mic Micmac + min Minangkabau + mis Miscellaneous (Other) + mkh Mon-Kmer (Other) + mlg Malagasy + mlt Maltese + mni Manipuri + mno Manobo Languages + moh Mohawk + mol Moldavian + mon Mongolian + mos Mossi + mri Maori + msa Malay + mul Multiple Languages + mun Munda Languages + mus Creek + mwr Marwari + mya Burmese + myn Mayan Languages + nah Aztec + nai North American Indian (Other) + nau Nauru + nav Navajo + nbl Ndebele, South + nde Ndebele, North + ndo Ndongo + nep Nepali + new Newari + nic Niger-Kordofanian (Other) + niu Niuean + nla Dutch + nno Norwegian (Nynorsk) + non Norse, Old + nor Norwegian + nso Sotho, Northern + nub Nubian Languages + nya Nyanja + nym Nyamwezi + nyn Nyankole + nyo Nyoro + nzi Nzima + oci Langue d'Oc (post 1500) + oji Ojibwa + ori Oriya + orm Oromo + osa Osage + oss Ossetic + ota Turkish, Ottoman (1500 - 1928) + oto Otomian Languages + paa Papuan-Australian (Other) + pag Pangasinan + pal Pahlavi + pam Pampanga + pan Panjabi + pap Papiamento + pau Palauan + peo Persian, Old (ca 600 - 400 B.C.) + per Persian + phn Phoenician + pli Pali + pol Polish + pon Ponape + por Portuguese + pra Prakrit uages + pro Provencal, Old (to 1500) + pus Pushto + que Quechua + raj Rajasthani + rar Rarotongan + roa Romance (Other) + roh Rhaeto-Romance + rom Romany + ron Romanian + rum Romanian + run Rundi + rus Russian + sad Sandawe + sag Sango + sah Yakut + sai South American Indian (Other) + sal Salishan Languages + sam Samaritan Aramaic + san Sanskrit + sco Scots + scr Serbo-Croatian + sel Selkup + sem Semitic (Other) + sga Irish, Old (to 900) + shn Shan + sid Sidamo + sin Singhalese + sio Siouan Languages + sit Sino-Tibetan (Other) + sla Slavic (Other) + slk Slovak + slo Slovak + slv Slovenian + smi Sami Languages + smo Samoan + sna Shona + snd Sindhi + sog Sogdian + som Somali + son Songhai + sot Sotho, Southern + spa Spanish + sqi Albanian + srd Sardinian + srr Serer + ssa Nilo-Saharan (Other) + ssw Siswant + ssw Swazi + suk Sukuma + sun Sudanese + sus Susu + sux Sumerian + sve Swedish + swa Swahili + swe Swedish + syr Syriac + tah Tahitian + tam Tamil + tat Tatar + tel Telugu + tem Timne + ter Tereno + tgk Tajik + tgl Tagalog + tha Thai + tib Tibetan + tig Tigre + tir Tigrinya + tiv Tivi + tli Tlingit + tmh Tamashek + tog Tonga (Nyasa) + ton Tonga (Tonga Islands) + tru Truk + tsi Tsimshian + tsn Tswana + tso Tsonga + tuk Turkmen + tum Tumbuka + tur Turkish + tut Altaic (Other) + twi Twi + tyv Tuvinian + uga Ugaritic + uig Uighur + ukr Ukrainian + umb Umbundu + und Undetermined + urd Urdu + uzb Uzbek + vai Vai + ven Venda + vie Vietnamese + vol VolapĆ¼k + vot Votic + wak Wakashan Languages + wal Walamo + war Waray + was Washo + wel Welsh + wen Sorbian Languages + wol Wolof + xho Xhosa + yao Yao + yap Yap + yid Yiddish + yor Yoruba + zap Zapotec + zen Zenaga + zha Zhuang + zho Chinese + zul Zulu + zun Zuni + + */ + + return getid3_lib::EmbeddedLookup($languagecode, $begin, __LINE__, __FILE__, 'id3v2-languagecode'); + } + + + public static function ETCOEventLookup($index) { + if (($index >= 0x17) && ($index <= 0xDF)) { + return 'reserved for future use'; + } + if (($index >= 0xE0) && ($index <= 0xEF)) { + return 'not predefined synch 0-F'; + } + if (($index >= 0xF0) && ($index <= 0xFC)) { + return 'reserved for future use'; + } + + static $EventLookup = array( + 0x00 => 'padding (has no meaning)', + 0x01 => 'end of initial silence', + 0x02 => 'intro start', + 0x03 => 'main part start', + 0x04 => 'outro start', + 0x05 => 'outro end', + 0x06 => 'verse start', + 0x07 => 'refrain start', + 0x08 => 'interlude start', + 0x09 => 'theme start', + 0x0A => 'variation start', + 0x0B => 'key change', + 0x0C => 'time change', + 0x0D => 'momentary unwanted noise (Snap, Crackle & Pop)', + 0x0E => 'sustained noise', + 0x0F => 'sustained noise end', + 0x10 => 'intro end', + 0x11 => 'main part end', + 0x12 => 'verse end', + 0x13 => 'refrain end', + 0x14 => 'theme end', + 0x15 => 'profanity', + 0x16 => 'profanity end', + 0xFD => 'audio end (start of silence)', + 0xFE => 'audio file ends', + 0xFF => 'one more byte of events follows' + ); + + return (isset($EventLookup[$index]) ? $EventLookup[$index] : ''); + } + + public static function SYTLContentTypeLookup($index) { + static $SYTLContentTypeLookup = array( + 0x00 => 'other', + 0x01 => 'lyrics', + 0x02 => 'text transcription', + 0x03 => 'movement/part name', // (e.g. 'Adagio') + 0x04 => 'events', // (e.g. 'Don Quijote enters the stage') + 0x05 => 'chord', // (e.g. 'Bb F Fsus') + 0x06 => 'trivia/\'pop up\' information', + 0x07 => 'URLs to webpages', + 0x08 => 'URLs to images' + ); + + return (isset($SYTLContentTypeLookup[$index]) ? $SYTLContentTypeLookup[$index] : ''); + } + + public static function APICPictureTypeLookup($index, $returnarray=false) { + static $APICPictureTypeLookup = array( + 0x00 => 'Other', + 0x01 => '32x32 pixels \'file icon\' (PNG only)', + 0x02 => 'Other file icon', + 0x03 => 'Cover (front)', + 0x04 => 'Cover (back)', + 0x05 => 'Leaflet page', + 0x06 => 'Media (e.g. label side of CD)', + 0x07 => 'Lead artist/lead performer/soloist', + 0x08 => 'Artist/performer', + 0x09 => 'Conductor', + 0x0A => 'Band/Orchestra', + 0x0B => 'Composer', + 0x0C => 'Lyricist/text writer', + 0x0D => 'Recording Location', + 0x0E => 'During recording', + 0x0F => 'During performance', + 0x10 => 'Movie/video screen capture', + 0x11 => 'A bright coloured fish', + 0x12 => 'Illustration', + 0x13 => 'Band/artist logotype', + 0x14 => 'Publisher/Studio logotype' + ); + if ($returnarray) { + return $APICPictureTypeLookup; + } + return (isset($APICPictureTypeLookup[$index]) ? $APICPictureTypeLookup[$index] : ''); + } + + public static function COMRReceivedAsLookup($index) { + static $COMRReceivedAsLookup = array( + 0x00 => 'Other', + 0x01 => 'Standard CD album with other songs', + 0x02 => 'Compressed audio on CD', + 0x03 => 'File over the Internet', + 0x04 => 'Stream over the Internet', + 0x05 => 'As note sheets', + 0x06 => 'As note sheets in a book with other sheets', + 0x07 => 'Music on other media', + 0x08 => 'Non-musical merchandise' + ); + + return (isset($COMRReceivedAsLookup[$index]) ? $COMRReceivedAsLookup[$index] : ''); + } + + public static function RVA2ChannelTypeLookup($index) { + static $RVA2ChannelTypeLookup = array( + 0x00 => 'Other', + 0x01 => 'Master volume', + 0x02 => 'Front right', + 0x03 => 'Front left', + 0x04 => 'Back right', + 0x05 => 'Back left', + 0x06 => 'Front centre', + 0x07 => 'Back centre', + 0x08 => 'Subwoofer' + ); + + return (isset($RVA2ChannelTypeLookup[$index]) ? $RVA2ChannelTypeLookup[$index] : ''); + } + + public static function FrameNameLongLookup($framename) { + + $begin = __LINE__; + + /** This is not a comment! + + AENC Audio encryption + APIC Attached picture + ASPI Audio seek point index + BUF Recommended buffer size + CNT Play counter + COM Comments + COMM Comments + COMR Commercial frame + CRA Audio encryption + CRM Encrypted meta frame + ENCR Encryption method registration + EQU Equalisation + EQU2 Equalisation (2) + EQUA Equalisation + ETC Event timing codes + ETCO Event timing codes + GEO General encapsulated object + GEOB General encapsulated object + GRID Group identification registration + IPL Involved people list + IPLS Involved people list + LINK Linked information + LNK Linked information + MCDI Music CD identifier + MCI Music CD Identifier + MLL MPEG location lookup table + MLLT MPEG location lookup table + OWNE Ownership frame + PCNT Play counter + PIC Attached picture + POP Popularimeter + POPM Popularimeter + POSS Position synchronisation frame + PRIV Private frame + RBUF Recommended buffer size + REV Reverb + RVA Relative volume adjustment + RVA2 Relative volume adjustment (2) + RVAD Relative volume adjustment + RVRB Reverb + SEEK Seek frame + SIGN Signature frame + SLT Synchronised lyric/text + STC Synced tempo codes + SYLT Synchronised lyric/text + SYTC Synchronised tempo codes + TAL Album/Movie/Show title + TALB Album/Movie/Show title + TBP BPM (Beats Per Minute) + TBPM BPM (beats per minute) + TCM Composer + TCMP Part of a compilation + TCO Content type + TCOM Composer + TCON Content type + TCOP Copyright message + TCP Part of a compilation + TCR Copyright message + TDA Date + TDAT Date + TDEN Encoding time + TDLY Playlist delay + TDOR Original release time + TDRC Recording time + TDRL Release time + TDTG Tagging time + TDY Playlist delay + TEN Encoded by + TENC Encoded by + TEXT Lyricist/Text writer + TFLT File type + TFT File type + TIM Time + TIME Time + TIPL Involved people list + TIT1 Content group description + TIT2 Title/songname/content description + TIT3 Subtitle/Description refinement + TKE Initial key + TKEY Initial key + TLA Language(s) + TLAN Language(s) + TLE Length + TLEN Length + TMCL Musician credits list + TMED Media type + TMOO Mood + TMT Media type + TOA Original artist(s)/performer(s) + TOAL Original album/movie/show title + TOF Original filename + TOFN Original filename + TOL Original Lyricist(s)/text writer(s) + TOLY Original lyricist(s)/text writer(s) + TOPE Original artist(s)/performer(s) + TOR Original release year + TORY Original release year + TOT Original album/Movie/Show title + TOWN File owner/licensee + TP1 Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group + TP2 Band/Orchestra/Accompaniment + TP3 Conductor/Performer refinement + TP4 Interpreted, remixed, or otherwise modified by + TPA Part of a set + TPB Publisher + TPE1 Lead performer(s)/Soloist(s) + TPE2 Band/orchestra/accompaniment + TPE3 Conductor/performer refinement + TPE4 Interpreted, remixed, or otherwise modified by + TPOS Part of a set + TPRO Produced notice + TPUB Publisher + TRC ISRC (International Standard Recording Code) + TRCK Track number/Position in set + TRD Recording dates + TRDA Recording dates + TRK Track number/Position in set + TRSN Internet radio station name + TRSO Internet radio station owner + TS2 Album-Artist sort order + TSA Album sort order + TSC Composer sort order + TSI Size + TSIZ Size + TSO2 Album-Artist sort order + TSOA Album sort order + TSOC Composer sort order + TSOP Performer sort order + TSOT Title sort order + TSP Performer sort order + TSRC ISRC (international standard recording code) + TSS Software/hardware and settings used for encoding + TSSE Software/Hardware and settings used for encoding + TSST Set subtitle + TST Title sort order + TT1 Content group description + TT2 Title/Songname/Content description + TT3 Subtitle/Description refinement + TXT Lyricist/text writer + TXX User defined text information frame + TXXX User defined text information frame + TYE Year + TYER Year + UFI Unique file identifier + UFID Unique file identifier + ULT Unsychronised lyric/text transcription + USER Terms of use + USLT Unsynchronised lyric/text transcription + WAF Official audio file webpage + WAR Official artist/performer webpage + WAS Official audio source webpage + WCM Commercial information + WCOM Commercial information + WCOP Copyright/Legal information + WCP Copyright/Legal information + WOAF Official audio file webpage + WOAR Official artist/performer webpage + WOAS Official audio source webpage + WORS Official Internet radio station homepage + WPAY Payment + WPB Publishers official webpage + WPUB Publishers official webpage + WXX User defined URL link frame + WXXX User defined URL link frame + TFEA Featured Artist + TSTU Recording Studio + rgad Replay Gain Adjustment + + */ + + return getid3_lib::EmbeddedLookup($framename, $begin, __LINE__, __FILE__, 'id3v2-framename_long'); + + // Last three: + // from Helium2 [www.helium2.com] + // from http://privatewww.essex.ac.uk/~djmrob/replaygain/file_format_id3v2.html + } + + + public static function FrameNameShortLookup($framename) { + + $begin = __LINE__; + + /** This is not a comment! + + AENC audio_encryption + APIC attached_picture + ASPI audio_seek_point_index + BUF recommended_buffer_size + CNT play_counter + COM comment + COMM comment + COMR commercial_frame + CRA audio_encryption + CRM encrypted_meta_frame + ENCR encryption_method_registration + EQU equalisation + EQU2 equalisation + EQUA equalisation + ETC event_timing_codes + ETCO event_timing_codes + GEO general_encapsulated_object + GEOB general_encapsulated_object + GRID group_identification_registration + IPL involved_people_list + IPLS involved_people_list + LINK linked_information + LNK linked_information + MCDI music_cd_identifier + MCI music_cd_identifier + MLL mpeg_location_lookup_table + MLLT mpeg_location_lookup_table + OWNE ownership_frame + PCNT play_counter + PIC attached_picture + POP popularimeter + POPM popularimeter + POSS position_synchronisation_frame + PRIV private_frame + RBUF recommended_buffer_size + REV reverb + RVA relative_volume_adjustment + RVA2 relative_volume_adjustment + RVAD relative_volume_adjustment + RVRB reverb + SEEK seek_frame + SIGN signature_frame + SLT synchronised_lyric + STC synced_tempo_codes + SYLT synchronised_lyric + SYTC synchronised_tempo_codes + TAL album + TALB album + TBP bpm + TBPM bpm + TCM composer + TCMP part_of_a_compilation + TCO genre + TCOM composer + TCON genre + TCOP copyright_message + TCP part_of_a_compilation + TCR copyright_message + TDA date + TDAT date + TDEN encoding_time + TDLY playlist_delay + TDOR original_release_time + TDRC recording_time + TDRL release_time + TDTG tagging_time + TDY playlist_delay + TEN encoded_by + TENC encoded_by + TEXT lyricist + TFLT file_type + TFT file_type + TIM time + TIME time + TIPL involved_people_list + TIT1 content_group_description + TIT2 title + TIT3 subtitle + TKE initial_key + TKEY initial_key + TLA language + TLAN language + TLE length + TLEN length + TMCL musician_credits_list + TMED media_type + TMOO mood + TMT media_type + TOA original_artist + TOAL original_album + TOF original_filename + TOFN original_filename + TOL original_lyricist + TOLY original_lyricist + TOPE original_artist + TOR original_year + TORY original_year + TOT original_album + TOWN file_owner + TP1 artist + TP2 band + TP3 conductor + TP4 remixer + TPA part_of_a_set + TPB publisher + TPE1 artist + TPE2 band + TPE3 conductor + TPE4 remixer + TPOS part_of_a_set + TPRO produced_notice + TPUB publisher + TRC isrc + TRCK track_number + TRD recording_dates + TRDA recording_dates + TRK track_number + TRSN internet_radio_station_name + TRSO internet_radio_station_owner + TS2 album_artist_sort_order + TSA album_sort_order + TSC composer_sort_order + TSI size + TSIZ size + TSO2 album_artist_sort_order + TSOA album_sort_order + TSOC composer_sort_order + TSOP performer_sort_order + TSOT title_sort_order + TSP performer_sort_order + TSRC isrc + TSS encoder_settings + TSSE encoder_settings + TSST set_subtitle + TST title_sort_order + TT1 content_group_description + TT2 title + TT3 subtitle + TXT lyricist + TXX text + TXXX text + TYE year + TYER year + UFI unique_file_identifier + UFID unique_file_identifier + ULT unsychronised_lyric + USER terms_of_use + USLT unsynchronised_lyric + WAF url_file + WAR url_artist + WAS url_source + WCM commercial_information + WCOM commercial_information + WCOP copyright + WCP copyright + WOAF url_file + WOAR url_artist + WOAS url_source + WORS url_station + WPAY url_payment + WPB url_publisher + WPUB url_publisher + WXX url_user + WXXX url_user + TFEA featured_artist + TSTU recording_studio + rgad replay_gain_adjustment + + */ + + return getid3_lib::EmbeddedLookup($framename, $begin, __LINE__, __FILE__, 'id3v2-framename_short'); + } + + public static function TextEncodingTerminatorLookup($encoding) { + // http://www.id3.org/id3v2.4.0-structure.txt + // Frames that allow different types of text encoding contains a text encoding description byte. Possible encodings: + static $TextEncodingTerminatorLookup = array( + 0 => "\x00", // $00 ISO-8859-1. Terminated with $00. + 1 => "\x00\x00", // $01 UTF-16 encoded Unicode with BOM. All strings in the same frame SHALL have the same byteorder. Terminated with $00 00. + 2 => "\x00\x00", // $02 UTF-16BE encoded Unicode without BOM. Terminated with $00 00. + 3 => "\x00", // $03 UTF-8 encoded Unicode. Terminated with $00. + 255 => "\x00\x00" + ); + return (isset($TextEncodingTerminatorLookup[$encoding]) ? $TextEncodingTerminatorLookup[$encoding] : ''); + } + + public static function TextEncodingNameLookup($encoding) { + // http://www.id3.org/id3v2.4.0-structure.txt + // Frames that allow different types of text encoding contains a text encoding description byte. Possible encodings: + static $TextEncodingNameLookup = array( + 0 => 'ISO-8859-1', // $00 ISO-8859-1. Terminated with $00. + 1 => 'UTF-16', // $01 UTF-16 encoded Unicode with BOM. All strings in the same frame SHALL have the same byteorder. Terminated with $00 00. + 2 => 'UTF-16BE', // $02 UTF-16BE encoded Unicode without BOM. Terminated with $00 00. + 3 => 'UTF-8', // $03 UTF-8 encoded Unicode. Terminated with $00. + 255 => 'UTF-16BE' + ); + return (isset($TextEncodingNameLookup[$encoding]) ? $TextEncodingNameLookup[$encoding] : 'ISO-8859-1'); + } + + public static function IsValidID3v2FrameName($framename, $id3v2majorversion) { + switch ($id3v2majorversion) { + case 2: + return preg_match('#[A-Z][A-Z0-9]{2}#', $framename); + break; + + case 3: + case 4: + return preg_match('#[A-Z][A-Z0-9]{3}#', $framename); + break; + } + return false; + } + + public static function IsANumber($numberstring, $allowdecimal=false, $allownegative=false) { + for ($i = 0; $i < strlen($numberstring); $i++) { + if ((chr($numberstring{$i}) < chr('0')) || (chr($numberstring{$i}) > chr('9'))) { + if (($numberstring{$i} == '.') && $allowdecimal) { + // allowed + } elseif (($numberstring{$i} == '-') && $allownegative && ($i == 0)) { + // allowed + } else { + return false; + } + } + } + return true; + } + + public static function IsValidDateStampString($datestamp) { + if (strlen($datestamp) != 8) { + return false; + } + if (!self::IsANumber($datestamp, false)) { + return false; + } + $year = substr($datestamp, 0, 4); + $month = substr($datestamp, 4, 2); + $day = substr($datestamp, 6, 2); + if (($year == 0) || ($month == 0) || ($day == 0)) { + return false; + } + if ($month > 12) { + return false; + } + if ($day > 31) { + return false; + } + if (($day > 30) && (($month == 4) || ($month == 6) || ($month == 9) || ($month == 11))) { + return false; + } + if (($day > 29) && ($month == 2)) { + return false; + } + return true; + } + + public static function ID3v2HeaderLength($majorversion) { + return (($majorversion == 2) ? 6 : 10); + } + +} + diff --git a/extensions/TimedMediaHandler/libs/getid3/readme.txt b/extensions/TimedMediaHandler/libs/getid3/readme.txt new file mode 100644 index 00000000..ebd004eb --- /dev/null +++ b/extensions/TimedMediaHandler/libs/getid3/readme.txt @@ -0,0 +1,591 @@ +///////////////////////////////////////////////////////////////// +/// getID3() by James Heinrich <info@getid3.org> // +// available at http://getid3.sourceforge.net // +// or http://www.getid3.org // +///////////////////////////////////////////////////////////////// +// // +// changelog.txt - part of getID3() // +// See readme.txt for more details // +// /// +///////////////////////////////////////////////////////////////// + + This code is released under the GNU GPL: + http://www.gnu.org/copyleft/gpl.html + + +---------------------------------------------+ + | If you do use this code somewhere, send me | + | an email and tell me how/where you used it. | + | | + | If you want to donate, there is a link on | + | http://www.getid3.org for PayPal donations. | + +---------------------------------------------+ + + + +Quick Start +=========================================================================== + +Q: How can I check that getID3() works on my server/files? +A: Unzip getID3() to a directory, then access /demos/demo.browse.php + + + +Support +=========================================================================== + +Q: I have a question, or I found a bug. What do I do? +A: The preferred method of support requests and/or bug reports is the + forum at http://support.getid3.org/ + + + +Sourceforge Notification +=========================================================================== + +It's highly recommended that you sign up for notification from +Sourceforge for when new versions are released. Please visit: +http://sourceforge.net/project/showfiles.php?group_id=55859 +and click the little "monitor package" icon/link. If you're +previously signed up for the mailing list, be aware that it has +been discontinued, only the automated Sourceforge notification +will be used from now on. + + + +What does getID3() do? +=========================================================================== + +Reads & parses (to varying degrees): + ā¬ tags: + * APE (v1 and v2) + * ID3v1 (& ID3v1.1) + * ID3v2 (v2.4, v2.3, v2.2) + * Lyrics3 (v1 & v2) + + ā¬ audio-lossy: + * MP3/MP2/MP1 + * MPC / Musepack + * Ogg (Vorbis, OggFLAC, Speex) + * AC3 + * DTS + * RealAudio + * Speex + * DSS + * VQF + + ā¬ audio-lossless: + * AIFF + * AU + * Bonk + * CD-audio (*.cda) + * FLAC + * LA (Lossless Audio) + * LiteWave + * LPAC + * MIDI + * Monkey's Audio + * OptimFROG + * RKAU + * Shorten + * TTA + * VOC + * WAV (RIFF) + * WavPack + + ā¬ audio-video: + * ASF: ASF, Windows Media Audio (WMA), Windows Media Video (WMV) + * AVI (RIFF) + * Flash + * Matroska (MKV) + * MPEG-1 / MPEG-2 + * NSV (Nullsoft Streaming Video) + * Quicktime + * RealVideo + + ā¬ still image: + * BMP + * GIF + * JPEG + * PNG + * TIFF + * SWF (Flash) + * PhotoCD + + ā¬ data: + * ISO-9660 CD-ROM image (directory structure) + * SZIP (limited support) + * ZIP (directory structure) + * TAR + * CUE + + +Writes: + * ID3v1 (& ID3v1.1) + * ID3v2 (v2.3 & v2.4) + * VorbisComment on OggVorbis + * VorbisComment on FLAC (not OggFLAC) + * APE v2 + * Lyrics3 (delete only) + + + +Requirements +=========================================================================== + +* PHP 4.2.0 (or higher) for getID3() 1.7.x (and earlier) +* PHP 5.3.0 (or higher) for getID3() 1.8.x (and up) +* PHP 5.0.0 (or higher) for getID3() 2.0.x (and up) +* at least 4MB memory for PHP. 8MB is highly recommended. + 12MB is required with all modules loaded. + + + +Usage +=========================================================================== + +See /demos/demo.basic.php for a very basic use of getID3() with no +fancy output, just scanning one file. + +See structure.txt for the returned data structure. + +*> For an example of a complete directory-browsing, <* +*> file-scanning implementation of getID3(), please run <* +*> /demos/demo.browse.php <* + +See /demos/demo.mysql.php for a sample recursive scanning code that +scans every file in a given directory, and all sub-directories, stores +the results in a database and allows various analysis / maintenance +operations + +To analyze remote files over HTTP or FTP you need to copy the file +locally first before running getID3(). Your code would look something +like this: + +// Copy remote file locally to scan with getID3() +$remotefilename = 'http://www.example.com/filename.mp3'; +if ($fp_remote = fopen($remotefilename, 'rb')) { + $localtempfilename = tempnam('/tmp', 'getID3'); + if ($fp_local = fopen($localtempfilename, 'wb')) { + while ($buffer = fread($fp_remote, 8192)) { + fwrite($fp_local, $buffer); + } + fclose($fp_local); + + // Initialize getID3 engine + $getID3 = new getID3; + + $ThisFileInfo = $getID3->analyze($filename); + + // Delete temporary file + unlink($localtempfilename); + } + fclose($fp_remote); +} + + +See /demos/demo.write.php for how to write tags. + + + +What does the returned data structure look like? +=========================================================================== + +See structure.txt + +It is recommended that you look at the output of +/demos/demo.browse.php scanning the file(s) you're interested in to +confirm what data is actually returned for any particular filetype in +general, and your files in particular, as the actual data returned +may vary considerably depending on what information is available in +the file itself. + + + +Notes +=========================================================================== + +getID3() 1.x: +If the format parser encounters a critical problem, it will return +something in $fileinfo['error'], describing the encountered error. If +a less critical error or notice is generated it will appear in +$fileinfo['warning']. Both keys may contain more than one warning or +error. If something is returned in ['error'] then the file was not +correctly parsed and returned data may or may not be correct and/or +complete. If something is returned in ['warning'] (and not ['error']) +then the data that is returned is OK - usually getID3() is reporting +errors in the file that have been worked around due to known bugs in +other programs. Some warnings may indicate that the data that is +returned is OK but that some data could not be extracted due to +errors in the file. + +getID3() 2.x: +See above except errors are thrown (so you will only get one error). + + + +Disclaimer +=========================================================================== + +getID3() has been tested on many systems, on many types of files, +under many operating systems, and is generally believe to be stable +and safe. That being said, there is still the chance there is an +undiscovered and/or unfixed bug that may potentially corrupt your +file, especially within the writing functions. By using getID3() you +agree that it's not my fault if any of your files are corrupted. +In fact, I'm not liable for anything :) + + + +License +=========================================================================== + +GNU General Public License - see license.txt + +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 2 +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, write to: +Free Software Foundation, Inc. +59 Temple Place - Suite 330 +Boston, MA 02111-1307, USA. + +FAQ: +Q: Can I use getID3() in my program? Do I need a commercial license? +A: You're generally free to use getID3 however you see fit. The only + case in which you would require a commercial license is if you're + selling your closed-source program that integrates getID3. If you + sell your program including a copy of getID3, that's fine as long + as you include a copy of the sourcecode when you sell it. Or you + can distribute your code without getID3 and say "download it from + getid3.sourceforge.net" + + + +Why is it called "getID3()" if it does so much more than just that? +=========================================================================== + +v0.1 did in fact just do that. I don't have a copy of code that old, but I +could essentially write it today with a one-line function: + function getID3($filename) { return unpack('a3TAG/a30title/a30artist/a30album/a4year/a28comment/c1track/c1genreid', substr(file_get_contents($filename), -128)); } + + +Future Plans +=========================================================================== +http://www.getid3.org/phpBB3/viewforum.php?f=7 + +* Better support for MP4 container format +* Scan for appended ID3v2 tag at end of file per ID3v2.4 specs (Section 5.0) +* Support for JPEG-2000 (http://www.morgan-multimedia.com/jpeg2000_overview.htm) +* Support for MOD (mod/stm/s3m/it/xm/mtm/ult/669) +* Support for ACE (thanks Vince) +* Support for Ogg other than Vorbis, Speex and OggFlac (ie. Ogg+Xvid) +* Ability to create Xing/LAME VBR header for VBR MP3s that are missing VBR header +* Ability to "clean" ID3v2 padding (replace invalid padding with valid padding) +* Warn if MP3s change version mid-stream (in full-scan mode) +* check for corrupt/broken mid-file MP3 streams in histogram scan +* Support for lossless-compression formats + (http://www.firstpr.com.au/audiocomp/lossless/#Links) + (http://compression.ca/act-sound.html) + (http://web.inter.nl.net/users/hvdh/lossless/lossless.htm) +* Support for RIFF-INFO chunks + * http://lotto.st-andrews.ac.uk/~njh/tag_interchange.html + (thanks Nick Humfrey <njhĆsurgeradio*co*uk>) + * http://abcavi.narod.ru/sof/abcavi/infotags.htm + (thanks Kibi) +* Better support for Bink video +* http://www.hr/josip/DSP/AudioFile2.html +* http://www.pcisys.net/~melanson/codecs/ +* Detect mp3PRO +* Support for PSD +* Support for JPC +* Support for JP2 +* Support for JPX +* Support for JB2 +* Support for IFF +* Support for ICO +* Support for ANI +* Support for EXE (comments, author, etc) (thanks p*quaedackersĆplanet*nl) +* Support for DVD-IFO (region, subtitles, aspect ratio, etc) + (thanks p*quaedackersĆplanet*nl) +* More complete support for SWF - parsing encapsulated MP3 and/or JPEG content + (thanks n8n8Ćyahoo*com) +* Support for a2b +* Optional scan-through-frames for AVI verification + (thanks rockcohenĆmassive-interactive*nl) +* Support for TTF (thanks infoĆbutterflyx*com) +* Support for DSS (http://www.getid3.org/phpBB3/viewtopic.php?t=171) +* Support for SMAF (http://smaf-yamaha.com/what/demo.html) + http://www.getid3.org/phpBB3/viewtopic.php?t=182 +* Support for AMR (http://www.getid3.org/phpBB3/viewtopic.php?t=195) +* Support for 3gpp (http://www.getid3.org/phpBB3/viewtopic.php?t=195) +* Support for ID4 (http://www.wackysoft.cjb.net grizlyY2KĆhotmail*com) +* Parse XML data returned in Ogg comments +* Parse XML data from Quicktime SMIL metafiles (klausrathĆmac*com) +* ID3v2 genre string creator function +* More complete parsing of JPG +* Support for all old-style ASF packets +* ASF/WMA/WMV tag writing +* Parse declared T??? ID3v2 text information frames, where appropriate + (thanks Christian Fritz for the idea) +* Recognize encoder: + http://www.guerillasoft.com/EncSpot2/index.html + http://ff123.net/identify.html + http://www.hydrogenaudio.org/?act=ST&f=16&t=9414 + http://www.hydrogenaudio.org/?showtopic=11785 +* Support for other OS/2 bitmap structures: Bitmap Array('BA'), + Color Icon('CI'), Color Pointer('CP'), Icon('IC'), Pointer ('PT') + http://netghost.narod.ru/gff/graphics/summary/os2bmp.htm +* Support for WavPack RAW mode +* ASF/WMA/WMV data packet parsing +* ID3v2FrameFlagsLookupTagAlter() +* ID3v2FrameFlagsLookupFileAlter() +* obey ID3v2 tag alter/preserve/discard rules +* http://www.geocities.com/SiliconValley/Sector/9654/Softdoc/Illyrium/Aolyr.htm +* proper checking for LINK/LNK frame validity in ID3v2 writing +* proper checking for ASPI-TLEN frame validity in ID3v2 writing +* proper checking for COMR frame validity in ID3v2 writing +* http://www.geocities.co.jp/SiliconValley-Oakland/3664/index.html +* decode GEOB ID3v2 structure as encoded by RealJukebox, + decode NCON ID3v2 structure as encoded by MusicMatch + (probably won't happen - the formats are proprietary) + + + +Known Bugs/Issues in getID3() that may be fixed eventually +=========================================================================== +http://www.getid3.org/phpBB3/viewtopic.php?t=25 + +* Cannot determine bitrate for MPEG video with VBR video data + (need documentation) +* Interlace/progressive cannot be determined for MPEG video + (need documentation) +* MIDI playtime is sometimes inaccurate +* AAC-RAW mode files cannot be identified +* WavPack-RAW mode files cannot be identified +* mp4 files report lots of "Unknown QuickTime atom type" + (need documentation) +* Encrypted ASF/WMA/WMV files warn about "unhandled GUID + ASF_Content_Encryption_Object" +* Bitrate split between audio and video cannot be calculated for + NSV, only the total bitrate. (need documentation) +* All Ogg formats (Vorbis, OggFLAC, Speex) are affected by the + problem of large VorbisComments spanning multiple Ogg pages, but + but only OggVorbis files can be processed with vorbiscomment. +* The version of "head" supplied with Mac OS 10.2.8 (maybe other + versions too) does only understands a single option (-n) and + therefore fails. getID3 ignores this and returns wrong md5_data. + + + +Known Bugs/Issues in getID3() that cannot be fixed +-------------------------------------------------- +http://www.getid3.org/phpBB3/viewtopic.php?t=25 + +* 32-bit PHP installations only: + Files larger than 2GB cannot always be parsed fully by getID3() + due to limitations in the 32-bit PHP filesystem functions. + NOTE: Since v1.7.8b3 there is partial support for larger-than- + 2GB files, most of which will parse OK, as long as no critical + data is located beyond the 2GB offset. + Known will-work: + * all file formats on 64-bit PHP + * ZIP (format doesn't support files >2GB) + * FLAC (current encoders don't support files >2GB) + Known will-not-work: + * ID3v1 tags (always located at end-of-file) + * Lyrics3 tags (always located at end-of-file) + * APE tags (always located at end-of-file) + Maybe-will-work: + * Quicktime (will work if needed metadata is before 2GB offset, + that is if the file has been hinted/optimized for streaming) + * RIFF.WAV (should work fine, but gives warnings about not being + able to parse all chunks) + * RIFF.AVI (playtime will probably be wrong, is only based on + "movi" chunk that fits in the first 2GB, should issue error + to show that playtime is incorrect. Other data should be mostly + correct, assuming that data is constant throughout the file) + + + +Known Bugs/Issues in other programs +----------------------------------- +http://www.getid3.org/phpBB3/viewtopic.php?t=25 + +* Windows Media Player (up to v11) and iTunes (up to v10+) do + not correctly handle ID3v2.3 tags with UTF-16BE+BOM + encoding (they assume the data is UTF-16LE+BOM and either + crash (WMP) or output Asian character set (iTunes) +* Winamp (up to v2.80 at least) does not support ID3v2.4 tags, + only ID3v2.3 + see: http://forums.winamp.com/showthread.php?postid=387524 +* Some versions of Helium2 (www.helium2.com) do not write + ID3v2.4-compliant Frame Sizes, even though the tag is marked + as ID3v2.4) (detected by getID3()) +* MP3ext V3.3.17 places a non-compliant padding string at the end + of the ID3v2 header. This is supposedly fixed in v3.4b21 but + only if you manually add a registry key. This fix is not yet + confirmed. (detected by getID3()) +* CDex v1.40 (fixed by v1.50b7) writes non-compliant Ogg comment + strings, supposed to be in the format "NAME=value" but actually + written just "value" (detected by getID3()) +* Oggenc 0.9-rc3 flags the encoded file as ABR whether it's + actually ABR or VBR. +* iTunes (versions "X v2.0.3", "v3.0.1" are known-guilty, probably + other versions are too) writes ID3v2.3 comment tags using a + frame name 'COM ' which is not valid for ID3v2.3+ (it's an + ID3v2.2-style frame name) (detected by getID3()) +* MP2enc does not encode mono CBR MP2 files properly (half speed + sound and double playtime) +* MP2enc does not encode mono VBR MP2 files properly (actually + encoded as stereo) +* tooLAME does not encode mono VBR MP2 files properly (actually + encoded as stereo) +* AACenc encodes files in VBR mode (actually ABR) even if CBR is + specified +* AAC/ADIF - bitrate_mode = cbr for vbr files +* LAME 3.90-3.92 prepends one frame of null data (space for the + LAME/VBR header, but it never gets written) when encoding in CBR + mode with the DLL +* Ahead Nero encodes TwinVQF with a DSIZ value (which is supposed + to be the filesize in bytes) of "0" for TwinVQF v1.0 and "1" for + TwinVQF v2.0 (detected by getID3()) +* Ahead Nero encodes TwinVQF files 1 second shorter than they + should be +* AAC-ADTS files are always actually encoded VBR, even if CBR mode + is specified (the CBR-mode switches on the encoder enable ABR + mode, not CBR as such, but it's not possible to tell the + difference between such ABR files and true VBR) +* STREAMINFO.audio_signature in OggFLAC is always null. "The reason + it's like that is because there is no seeking support in + libOggFLAC yet, so it has no way to go back and write the + computed sum after encoding. Seeking support in Ogg FLAC is the + #1 item for the next release." - Josh Coalson (FLAC developer) + NOTE: getID3() will calculate md5_data in a method similar to + other file formats, but that value cannot be compared to the + md5_data value from FLAC data in a FLAC file format. +* STREAMINFO.audio_signature is not calculated in FLAC v0.3.0 & + v0.4.0 - getID3() will calculate md5_data in a method similar to + other file formats, but that value cannot be compared to the + md5_data value from FLAC v0.5.0+ +* RioPort (various versions including 2.0 and 3.11) tags ID3v2 with + a WCOM frame that has no data portion +* Earlier versions of Coolplayer adds illegal ID3 tags to Ogg Vorbis + files, thus making them corrupt. +* Meracl ID3 Tag Writer v1.3.4 (and older) incorrectly truncates the + last byte of data from an MP3 file when appending a new ID3v1 tag. + (detected by getID3()) +* Lossless-Audio files encoded with and without the -noseek switch + do actually differ internally and therefore cannot match md5_data +* iTunes has been known to append a new ID3v1 tag on the end of an + existing ID3v1 tag when ID3v2 tag is also present + (detected by getID3()) +* MediaMonkey may write a blank RGAD ID3v2 frame but put actual + replay gain adjustments in a series of user-defined TXXX frames + (detected and handled by getID3() since v1.9.2) + + + + +Reference material: +=========================================================================== + +[www.id3.org material now mirrored at http://id3lib.sourceforge.net/id3/] +* http://www.id3.org/id3v2.4.0-structure.txt +* http://www.id3.org/id3v2.4.0-frames.txt +* http://www.id3.org/id3v2.4.0-changes.txt +* http://www.id3.org/id3v2.3.0.txt +* http://www.id3.org/id3v2-00.txt +* http://www.id3.org/mp3frame.html +* http://minnie.tuhs.org/pipermail/mp3encoder/2001-January/001800.html <mathewhendry@hotmail.com> +* http://www.dv.co.yu/mpgscript/mpeghdr.htm +* http://www.mp3-tech.org/programmer/frame_header.html +* http://users.belgacom.net/gc247244/extra/tag.html +* http://gabriel.mp3-tech.org/mp3infotag.html +* http://www.id3.org/iso4217.html +* http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT +* http://www.xiph.org/ogg/vorbis/doc/framing.html +* http://www.xiph.org/ogg/vorbis/doc/v-comment.html +* http://leknor.com/code/php/class.ogg.php.txt +* http://www.id3.org/iso639-2.html +* http://www.id3.org/lyrics3.html +* http://www.id3.org/lyrics3200.html +* http://www.psc.edu/general/software/packages/ieee/ieee.html +* http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html +* http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html +* http://www.jmcgowan.com/avi.html +* http://www.wotsit.org/ +* http://www.herdsoft.com/ti/davincie/davp3xo2.htm +* http://www.mathdogs.com/vorbis-illuminated/bitstream-appendix.html +* "Standard MIDI File Format" by Dustin Caldwell (from www.wotsit.org) +* http://midistudio.com/Help/GMSpecs_Patches.htm +* http://www.xiph.org/archives/vorbis/200109/0459.html +* http://www.replaygain.org/ +* http://www.lossless-audio.com/ +* http://download.microsoft.com/download/winmediatech40/Doc/1.0/WIN98MeXP/EN-US/ASF_Specification_v.1.0.exe +* http://mediaxw.sourceforge.net/files/doc/Active%20Streaming%20Format%20(ASF)%201.0%20Specification.pdf +* http://www.uni-jena.de/~pfk/mpp/sv8/ (archived at http://www.hydrogenaudio.org/musepack/klemm/www.personal.uni-jena.de/~pfk/mpp/sv8/) +* http://jfaul.de/atl/ +* http://www.uni-jena.de/~pfk/mpp/ (archived at http://www.hydrogenaudio.org/musepack/klemm/www.personal.uni-jena.de/~pfk/mpp/) +* http://www.libpng.org/pub/png/spec/png-1.2-pdg.html +* http://www.real.com/devzone/library/creating/rmsdk/doc/rmff.htm +* http://www.fastgraph.com/help/bmp_os2_header_format.html +* http://netghost.narod.ru/gff/graphics/summary/os2bmp.htm +* http://flac.sourceforge.net/format.html +* http://www.research.att.com/projects/mpegaudio/mpeg2.html +* http://www.audiocoding.com/wiki/index.php?page=AAC +* http://libmpeg.org/mpeg4/doc/w2203tfs.pdf +* http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt +* http://developer.apple.com/techpubs/quicktime/qtdevdocs/RM/frameset.htm +* http://www.nullsoft.com/nsv/ +* http://www.wotsit.org/download.asp?f=iso9660 +* http://sandbox.mc.edu/~bennet/cs110/tc/tctod.html +* http://www.cdroller.com/htm/readdata.html +* http://www.speex.org/manual/node10.html +* http://www.harmony-central.com/Computer/Programming/aiff-file-format.doc +* http://www.faqs.org/rfcs/rfc2361.html +* http://ghido.shelter.ro/ +* http://www.ebu.ch/tech_t3285.pdf +* http://www.sr.se/utveckling/tu/bwf +* http://ftp.aessc.org/pub/aes46-2002.pdf +* http://cartchunk.org:8080/ +* http://www.broadcastpapers.com/radio/cartchunk01.htm +* http://www.hr/josip/DSP/AudioFile2.html +* http://home.attbi.com/~chris.bagwell/AudioFormats-11.html +* http://www.pure-mac.com/extkey.html +* http://cesnet.dl.sourceforge.net/sourceforge/bonkenc/bonk-binary-format-0.9.txt +* http://www.headbands.com/gspot/ +* http://www.openswf.org/spec/SWFfileformat.html +* http://j-faul.virtualave.net/ +* http://www.btinternet.com/~AnthonyJ/Atari/programming/avr_format.html +* http://cui.unige.ch/OSG/info/AudioFormats/ap11.html +* http://sswf.sourceforge.net/SWFalexref.html +* http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt +* http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm +* http://developer.apple.com/quicktime/icefloe/dispatch012.html +* http://www.csdn.net/Dev/Format/graphics/PCD.htm +* http://tta.iszf.irk.ru/ +* http://www.atsc.org/standards/a_52a.pdf +* http://www.alanwood.net/unicode/ +* http://www.freelists.org/archives/matroska-devel/07-2003/msg00010.html +* http://www.its.msstate.edu/net/real/reports/config/tags.stats +* http://homepages.slingshot.co.nz/~helmboy/quicktime/formats/qtm-layout.txt +* http://brennan.young.net/Comp/LiveStage/things.html +* http://www.multiweb.cz/twoinches/MP3inside.htm +* http://www.geocities.co.jp/SiliconValley-Oakland/3664/alittle.html#GenreExtended +* http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/ +* http://www.unicode.org/unicode/faq/utf_bom.html +* http://tta.corecodec.org/?menu=format +* http://www.scvi.net/nsvformat.htm +* http://pda.etsi.org/pda/queryform.asp +* http://cpansearch.perl.org/src/RGIBSON/Audio-DSS-0.02/lib/Audio/DSS.pm +* http://trac.musepack.net/trac/wiki/SV8Specification +* http://wyday.com/cuesharp/specification.php +* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/maintenance/cleanupTranscodes.php b/extensions/TimedMediaHandler/maintenance/cleanupTranscodes.php new file mode 100644 index 00000000..01c7b004 --- /dev/null +++ b/extensions/TimedMediaHandler/maintenance/cleanupTranscodes.php @@ -0,0 +1,46 @@ +<?php +/** + * cleanup transcodes no longer defined in $wgEnabledTranscodeSet + * + */ +$IP = getenv( 'MW_INSTALL_PATH' ); +if ( $IP === false ) { + $IP = dirname( __FILE__ ) . '/../../..'; +} +require_once( "$IP/maintenance/Maintenance.php" ); + +class CleanupTranscodes extends Maintenance { + + public function __construct() { + parent::__construct(); + $this->addOption( "key", "remove all transcodes for given key", false, true ); + $this->addOption( "all", "remove all transcodes", false, false ); + $this->mDescription = "cleanup transcodes left over after changing encoding profiles."; + } + public function execute() { + global $wgEnabledTranscodeSet; + + if ( $this->hasOption( "all" ) ) { + $where = array(); + } elseif ( $this->hasOption( "key" ) ) { + $where = array( 'transcode_key' => $this->getOption( 'key' ) ); + } else { + $where = 'transcode_key NOT IN ("'. implode('", "', $wgEnabledTranscodeSet ).'")'; + } + $this->output( "Cleanup transcodes:\n" ); + $dbr = wfGetDB( DB_SLAVE ); + $res = $dbr->select( 'transcode', '*', $where, __METHOD__ ); + foreach ( $res as $row ) { + $this->output( + 'remove: '. $row->transcode_image_name . ' ' . $row->transcode_key . "\n" + ); + $title = Title::newFromText( $row->transcode_image_name, NS_FILE ); + $file = wfLocalFile( $title ); + WebVideoTranscode::removeTranscodes( $file, $row->transcode_key ); + } + $this->output( "Finished!\n" ); + } +} + +$maintClass = 'CleanupTranscodes'; // Tells it to run the class +require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/extensions/TimedMediaHandler/maintenance/moveTranscoded.php b/extensions/TimedMediaHandler/maintenance/moveTranscoded.php new file mode 100644 index 00000000..1ff6717c --- /dev/null +++ b/extensions/TimedMediaHandler/maintenance/moveTranscoded.php @@ -0,0 +1,56 @@ +<?php +/** + * move transcoded files from thumb to transcoded container + * + */ +$IP = getenv( 'MW_INSTALL_PATH' ); +if ( $IP === false ) { + $IP = dirname( __FILE__ ) . '/../../..'; +} +require_once( "$IP/maintenance/Maintenance.php" ); + +class MoveTranscoded extends Maintenance { + + public function __construct() { + parent::__construct(); + $this->mDescription = "move transcoded files from thumb to transcoded container."; + } + public function execute() { + global $wgEnabledTranscodeSet; + + $this->output( "Move transcoded files:\n" ); + $dbr = wfGetDB( DB_SLAVE ); + $res = $dbr->select( 'transcode', '*', array(), __METHOD__ ); + foreach ( $res as $row ) { + $title = Title::newFromText( $row->transcode_image_name, NS_FILE ); + $file = wfLocalFile( $title ); + if ( !$file ) { + continue; + } + $oldPath = $file->getThumbPath( $file->getName() . '.' . $row->transcode_key ); + + $newPath = WebVideoTranscode::getDerivativeFilePath( $file, $row->transcode_key ); + if ($oldPath != $newPath) { + if( $file->repo->fileExists( $oldPath ) ){ + if( $file->repo->fileExists( $newPath ) ){ + $res = $file->repo->quickPurge( $oldPath ); + if( !$res ){ + wfDebug( "Could not delete file $oldPath\n" ); + } else { + $this->output( "deleted $oldPath, exists in transcoded container\n" ); + } + } else { + $this->output( " $oldPath => $newPath\n" ); + $file->repo->quickImport( $oldPath, $newPath ); + $file->repo->quickPurge( $oldPath ); + } + } + } + + } + $this->output( "Finished!\n" ); + } +} + +$maintClass = 'MoveTranscoded'; // Tells it to run the class +require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/extensions/TimedMediaHandler/maintenance/resetTranscodes.php b/extensions/TimedMediaHandler/maintenance/resetTranscodes.php new file mode 100644 index 00000000..ca3493ed --- /dev/null +++ b/extensions/TimedMediaHandler/maintenance/resetTranscodes.php @@ -0,0 +1,41 @@ +<?php +/** + * reset stalled transcodes + * + */ +$IP = getenv( 'MW_INSTALL_PATH' ); +if ( $IP === false ) { + $IP = dirname( __FILE__ ) . '/../../..'; +} +require_once( "$IP/maintenance/Maintenance.php" ); + +class ResetTranscodes extends Maintenance { + + public function __construct() { + parent::__construct(); + $this->mDescription = "Reset stalled transcodes, that are no longer in the job queue."; + } + public function execute() { + global $wgEnabledTranscodeSet; + $where = array( + "transcode_time_startwork" => NULL, + "transcode_time_error" => NULL + ); + $dbr = wfGetDB( DB_SLAVE ); + $res = $dbr->select( 'transcode', '*', $where, __METHOD__ ); + foreach ( $res as $row ) { + $title = Title::newFromText( $row->transcode_image_name, NS_FILE ); + // re-insert WebVideoTranscodeJob, + // will only be added if not in queue + // due to deduplication + $job = new WebVideoTranscodeJob( $title, array( + 'transcodeMode' => 'derivative', + 'transcodeKey' => $row->transcode_key, + ) ); + $job->insert(); + } + } +} + +$maintClass = 'ResetTranscodes'; // Tells it to run the class +require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/extensions/TimedMediaHandler/maintenance/retryTranscodes.php b/extensions/TimedMediaHandler/maintenance/retryTranscodes.php new file mode 100644 index 00000000..be1ab9ee --- /dev/null +++ b/extensions/TimedMediaHandler/maintenance/retryTranscodes.php @@ -0,0 +1,55 @@ +<?php +/** + * Retry transcodes for a given key or error. + * This script can be used after updating/fixing + * the encoding pipeline to rerun transcodes + * that are known to work now. + * + */ +$IP = getenv( 'MW_INSTALL_PATH' ); +if ( $IP === false ) { + $IP = dirname( __FILE__ ) . '/../../..'; +} +require_once( "$IP/maintenance/Maintenance.php" ); + +class RetryTranscodes extends Maintenance { + + public function __construct() { + parent::__construct(); + $this->addOption( "key", "retry all failed transcodes for given key", false, true ); + $this->addOption( "error", "retry all failed transcodes matching error substring", false, true); + $this->mDescription = "retry transcodes for given key or error"; + } + public function execute() { + if ( !$this->hasOption( "error" ) && !$this->hasOption( "key" ) ) { + $this->output("You have to provide --key and/or --error\n"); + return; + } + $dbw = wfGetDB( DB_MASTER ); + $cond = array(); + $cond[] = 'transcode_time_error IS NOT NULL'; + if ( $this->hasOption( "key" ) ) { + $cond['transcode_key'] = $this->getOption( 'key' ); + } + if ( $this->hasOption( "error" ) ) { + $cond[] = "transcode_error " . $dbw->buildLike( $dbw->anyString(), + $this->getOption( 'error' ), $dbw->anyString() ); + } + do { + $res = $dbw->select( 'transcode', 'transcode_id', + $cond, __METHOD__, array( 'LIMIT' => 100 ) ); + $ids = array(); + foreach ( $res as $row ) { + $ids[] = $row->transcode_id; + } + if ( $ids ) { + $dbw->delete( 'transcode', + array( 'transcode_id' => $ids ), __METHOD__ ); + wfWaitForSlaves(); + } + } while ($ids); + } +} + +$maintClass = 'RetryTranscodes'; // Tells it to run the class +require_once( RUN_MAINTENANCE_IF_MAIN ); diff --git a/extensions/TimedMediaHandler/mwEmbedLoader.php b/extensions/TimedMediaHandler/mwEmbedLoader.php new file mode 100644 index 00000000..ae03a3dd --- /dev/null +++ b/extensions/TimedMediaHandler/mwEmbedLoader.php @@ -0,0 +1,24 @@ +<?php +// This is a stub entry point to load.php This is need to support valid paths for the stand alone +// mwEmbed module html test files. + +// This is useful for running stand alone test of mwEmbed components in the TimedMediaHandler +// extension. ( ie MwEmbedModules/EmbedPlayer/tests/*.html files ) + +$_GET['modules'] = 'startup'; +$_GET['only'] = 'scripts'; + +// NOTE this won't work so well with symbolic links +$loaderPath = dirname(__FILE__) . '/../../load.php'; +if( is_file( $loaderPath ) ){ + chdir( dirname( $loaderPath ) ); + include_once( $loaderPath ); +} else { + print "if( console && typeof console.log == 'function' ){ console.log('Error can't find load.php for stand alone tests' ) }"; +} +// Bootstrap some js code to make the "loader" work in stand alone tests: +// Note this has to be wrapped in a document.write to run after other document.writes +$pageStartupScript = ResourceLoader::makeInlineScript( + Xml::encodeJsCall( 'mw.loader.go', array() ) +); +echo Xml::encodeJsCall( 'document.write', array( $pageStartupScript ) ); diff --git a/extensions/TimedMediaHandler/package.json b/extensions/TimedMediaHandler/package.json new file mode 100644 index 00000000..30067c35 --- /dev/null +++ b/extensions/TimedMediaHandler/package.json @@ -0,0 +1,14 @@ +{ + "private": true, + "scripts": { + "test": "grunt test" + }, + "devDependencies": { + "grunt": "0.4.5", + "grunt-cli": "0.1.13", + "grunt-contrib-jshint": "0.11.3", + "grunt-banana-checker": "0.2.2", + "grunt-jscs": "1.8.0", + "grunt-jsonlint": "1.0.4" + } +} diff --git a/extensions/TimedMediaHandler/resources/PopUpThumbVideo.css b/extensions/TimedMediaHandler/resources/PopUpThumbVideo.css new file mode 100644 index 00000000..3ba0572a --- /dev/null +++ b/extensions/TimedMediaHandler/resources/PopUpThumbVideo.css @@ -0,0 +1,29 @@ +.PopUpMediaTransform a .play-btn-large{ + position : absolute; + top: 50%; + left : 50%; + width: 70px; + height: 53px; + margin-left: -35px; + margin-top: -25px; + /* @embed */ + background-image:url('player_big_play_button.png'); +} +.PopUpMediaTransform a .play-btn-large :hover{ + /* @embed */ + background-image:url('player_big_play_button_hover.png'); +} +.PopUpMediaTransform { + position : relative; + display: inline-block; +} +/* Should hopefully be only visible to screen readers */ +.mw-tmh-playtext { + display: block; + height: 0; + overflow: hidden; +} + +li.gallerybox div.thumb div.PopUpMediaTransform { + margin: 0 auto; +} diff --git a/extensions/TimedMediaHandler/resources/download_sprite.png b/extensions/TimedMediaHandler/resources/download_sprite.png Binary files differnew file mode 100644 index 00000000..541d4a99 --- /dev/null +++ b/extensions/TimedMediaHandler/resources/download_sprite.png diff --git a/extensions/TimedMediaHandler/resources/embedPlayerIframe.css b/extensions/TimedMediaHandler/resources/embedPlayerIframe.css new file mode 100644 index 00000000..eb6e9003 --- /dev/null +++ b/extensions/TimedMediaHandler/resources/embedPlayerIframe.css @@ -0,0 +1,7 @@ +body { + margin-left: 0px; + margin-top: 0px; + margin-right: 0px; + margin-bottom: 0px; + overflow: hidden; +} diff --git a/extensions/TimedMediaHandler/resources/ext.tmh.OgvJsSupport.js b/extensions/TimedMediaHandler/resources/ext.tmh.OgvJsSupport.js new file mode 100644 index 00000000..af3fd9f5 --- /dev/null +++ b/extensions/TimedMediaHandler/resources/ext.tmh.OgvJsSupport.js @@ -0,0 +1,67 @@ +( function( $, mw ) { + + var support = mw.OgvJsSupport = { + /** + * Ensure that the OGVPlayer class is loaded before continuing. + * + * @return jQuery.Deferred + */ + loadOgvJs: function() { + return $.Deferred( function( deferred ) { + if ( typeof OGVPlayer === 'undefined' ) { + mw.loader.using( 'ext.tmh.OgvJs', function() { + OGVLoader.base = support.basePath(); + deferred.resolve(); + } ); + } else { + deferred.resolve(); + } + }); + }, + + /** + * Get the base path of ogv.js and friends. + * + * @return string + */ + basePath: function() { + var ext = mw.config.get( 'wgExtensionAssetsPath' ), + binPlayers = ext + '/TimedMediaHandler/MwEmbedModules/EmbedPlayer/binPlayers'; + return binPlayers + '/ogv.js'; + }, + + /** + * Return a stub audio context + * + * This is used for iOS Safari to enable Web Audio by triggering an empty + * audio output channel during a user input event handler. Without that, + * audio is left disabled and won't work when we start things up after an + * asynchronous code load. + * + * @return AudioContext + */ + initAudioContext: function() { + var AudioContext = window.AudioContext || window.webkitAudioContext; + if ( AudioContext ) { + var context = new AudioContext(), + node; + if ( context.createScriptProcessor ) { + node = context.createScriptProcessor( 1024, 0, 2 ); + } else if ( context.createJavaScriptNode ) { + node = context.createJavaScriptNode( 1024, 0, 2 ); + } else { + throw new Error( 'Bad version of web audio API?' ); + } + + // Don't actually run any audio, just start & stop the node + node.connect( context.destination ); + node.disconnect(); + + return context; + } else { + return null; + } + } + }; + +} )( jQuery, mediaWiki ); diff --git a/extensions/TimedMediaHandler/resources/ext.tmh.TimedTextSelector.js b/extensions/TimedMediaHandler/resources/ext.tmh.TimedTextSelector.js new file mode 100644 index 00000000..b53bb6f8 --- /dev/null +++ b/extensions/TimedMediaHandler/resources/ext.tmh.TimedTextSelector.js @@ -0,0 +1,8 @@ +( function ( $, mw ) { + $( function () { + $( '#timedmedia-tt-go' ).click( function () { + window.location = mw.config.get( 'wgScript' ) + '?title=' + mw.util.wikiUrlencode( mw.config.get( 'wgPageName' ) ) + '.' + $( '#timedmedia-tt-input' ).val() + '.srt&action=edit'; + } ); + } ); + +} )( jQuery, mediaWiki ); diff --git a/extensions/TimedMediaHandler/resources/ext.tmh.transcodetable.js b/extensions/TimedMediaHandler/resources/ext.tmh.transcodetable.js new file mode 100644 index 00000000..a8c8f98d --- /dev/null +++ b/extensions/TimedMediaHandler/resources/ext.tmh.transcodetable.js @@ -0,0 +1,90 @@ +/** +* Javascript to support transcode table on image page +*/ +( function ( mw, $ ) { + $( document ).ready( function () { + var errorPopup, $errorLink; + + errorPopup = function () { + // pop up dialog + mw.addDialog( { + 'width': '640', + 'height': '480', + 'title': $(this).attr( 'title' ), + 'content': $('<textarea />') + .css( { + 'width':'99%', + 'height':'99%' + } ) + .text( $(this).attr('data-error') ) + } ) + .css( 'overflow', 'hidden' ); + return false; + }; + + // Old version. Need to keep for a little while in case of cached pages. + $( '.mw-filepage-transcodestatus .errorlink' ).click( errorPopup ); + // New version. + $errorLink = $( '.mw-filepage-transcodestatus .mw-tmh-pseudo-error-link' ); + $errorLink.wrapInner( function () { + var $this = $( this ); + return $( '<a />' ).attr( { + href: '#', + title: $this.text(), + 'data-error': $this.attr( 'data-error' ) + } ).click( errorPopup ); + } ); + + // Reset transcode action: + $( '.mw-filepage-transcodereset a' ).click( function () { + var tKey = $( this ).attr( 'data-transcodekey' ), + buttons = {}; + + buttons[ mw.msg( 'mwe-ok' ) ] = function () { + var api, + _thisDialog = this, + cancelBtn = {}; + + // Only show cancel button while loading: + cancelBtn[ mw.msg( 'mwe-cancel' ) ] = function () { + $(this).dialog( 'close' ); + }; + $( _thisDialog ).dialog( 'option', 'buttons', cancelBtn ); + + $( this ).loadingSpinner(); + + api = new mw.Api(); + api.postWithEditToken( { + 'action' : 'transcodereset', + 'transcodekey' : tKey, + 'title' : mw.config.get('wgPageName') + } ).done( function () { + // Refresh the page + location.reload(); + } ).fail( function ( code, data ) { + if( data.error && data.error.info ){ + $( _thisDialog ).text( data.error.info ); + } else { + $( _thisDialog ).text( mw.msg( 'timedmedia-reset-error' ) ); + } + var okBtn = {}; + okBtn[ mw.msg('mwe-ok') ] = function() { $(this).dialog( 'close' ); }; + $( _thisDialog ).dialog( 'option', 'buttons', okBtn ); + } ); + }; + buttons[ mw.msg( 'mwe-cancel' ) ] = function () { + $( this ).dialog( 'close' ); + }; + // pop up dialog + mw.addDialog( { + 'width': '400', + 'height': '200', + 'title': mw.msg( 'timedmedia-reset' ), + 'content': mw.msg( 'timedmedia-reset-confirm' ), + 'buttons': buttons + } ) + .css( 'overflow', 'hidden' ); + return false; + }); + }); +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/resources/mw.MediaWikiPlayer.loader.js b/extensions/TimedMediaHandler/resources/mw.MediaWikiPlayer.loader.js new file mode 100644 index 00000000..6167418b --- /dev/null +++ b/extensions/TimedMediaHandler/resources/mw.MediaWikiPlayer.loader.js @@ -0,0 +1,8 @@ +( function ( mw, $ ) { + // Add MediaWikiSupportPlayer dependency on players with a mediaWiki title + $( mw ).bind( 'EmbedPlayerUpdateDependencies', function ( event, embedPlayer, dependencySet ) { + if ( $( embedPlayer ).attr( 'data-mwtitle' ) ) { + $.merge( dependencySet, ['mw.MediaWikiPlayerSupport'] ); + } + } ); +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/resources/mw.MediaWikiPlayerSupport.js b/extensions/TimedMediaHandler/resources/mw.MediaWikiPlayerSupport.js new file mode 100644 index 00000000..16ce367c --- /dev/null +++ b/extensions/TimedMediaHandler/resources/mw.MediaWikiPlayerSupport.js @@ -0,0 +1,380 @@ +( function ( mw, $ ) { + /** + * Merge in the default video attributes supported by embedPlayer: + */ + mw.mergeConfig( 'EmbedPlayer.Attributes', { + // A apiTitleKey for looking up subtitles, credits and related videos + 'data-mwtitle': null, + + // The apiProvider where to lookup the title key + 'data-mwprovider': null + } ); + + // Add mediaWiki player support to target embedPlayer + $( mw ).bind( 'EmbedPlayerNewPlayer', function ( event, embedPlayer ) { + mw.addMediaWikiPlayerSupport( embedPlayer ); + }); + + /** + * Closure function wraps mediaWiki embedPlayer bindings + */ + mw.addMediaWikiPlayerSupport = function ( embedPlayer ) { + var apiTitleKey, apiProvider, $creditsCache = false; + // Set some local variables: + if ( !embedPlayer['data-mwtitle'] ) { + return false; + } else { + apiTitleKey = embedPlayer['data-mwtitle']; + // legacy support ( set as attribute ) + embedPlayer.apiTitleKey = apiTitleKey; + } + // Set local apiProvider via config if not defined + apiProvider = embedPlayer['data-mwprovider']; + if ( !apiProvider ) { + apiProvider = mw.config.get( 'EmbedPlayer.ApiProvider' ); + } + + /** + * Loads mediaWiki sources for a given embedPlayer + * @param {function} callback Function called once player sources have been added + */ + function loadPlayerSources( callback ) { + // Setup the request + var request = { + 'prop': 'imageinfo', + // In case the user added File: or Image: to the apiKey: + 'titles': 'File:' + decodeURIComponent( apiTitleKey ).replace( /^(File:|Image:)/, '' ), + 'iiprop': 'url|size|dimensions|metadata', + 'iiurlwidth': embedPlayer.getWidth(), + 'redirects': true // automatically resolve redirects + }; + + // Run the request: + mw.getJSON( mw.getApiProviderURL( apiProvider ), request, function ( data ) { + var i, page, imageinfo; + if ( data.query.pages ) { + for ( i in data.query.pages ) { + if ( i === '-1' ) { + callback( false ); + return ; + } + page = data.query.pages[i]; + } + } else { + callback( false ); + return ; + } + // Make sure we have imageinfo: + if ( !page.imageinfo || !page.imageinfo[0] ) { + callback( false ); + return ; + } + imageinfo = page.imageinfo[0]; + + // TODO these should call public methods rather than update internals: + + // Update the poster + embedPlayer.poster = imageinfo.thumburl; + + // Add the media src + embedPlayer.mediaElement.tryAddSource( + $( '<source />' ) + .attr( 'src', imageinfo.url ) + .get( 0 ) + ); + + // Set the duration + if ( imageinfo.metadata[2].name === 'length' ) { + embedPlayer.duration = imageinfo.metadata[2].value; + } + + // Set the width height + // Make sure we have an accurate aspect ratio + if ( imageinfo.height !== 0 && imageinfo.width !== 0 ) { + embedPlayer.height = Math.floor( embedPlayer.width * ( imageinfo.height / imageinfo.width ) ); + } + + // Update the css for the player interface + $( embedPlayer ).css( 'height', embedPlayer.height ); + + callback(); + }); + } + + /** + * Build a clip credit from the resource wikiText page + * + * TODO parse the resource page template + * + * @param {String} resourceHTML Resource wiki text page contents + */ + function doCreditLine( resourceHTML, articleUrl ) { + var authUrl, $page, $author, $authorText, $links, $date, $authorLink, + imgSize = {}, + // Get the title string ( again a "Title" like js object could help out here. ) + titleStr = embedPlayer.apiTitleKey.replace( /_/g, ' ' ), + // Setup the initial credits line: + $creditLine = $( '<div />' ); + + // Add the title: + $creditLine.append( + $( '<span>' ).html( + mw.msg( 'mwe-embedplayer-credit-title', + // get the link + $( '<div>' ).append( + $( '<a/>' ).attr( { + 'href': articleUrl, + 'title': titleStr + } ) + .text( titleStr ) + )[0].innerHTML + ) + ) + ); + + // Parse some data from the page info template if possible: + $page = $( resourceHTML ); + + // Look for author: + $author = $page.find( '#fileinfotpl_aut' ); + if ( $author.length ) { + // Get the real author sibling of fileinfotpl_aut + $authorText = $author.next(); + // Remove white space: + $authorText.find( 'br' ).remove(); + + // Update link to be absolute per page url context: + $links = $authorText.find( 'a' ); + if ( $links.length ) { + $links.each( function ( i, authorLink ) { + $authorLink = $( authorLink ); + authUrl = $authorLink.attr( 'href' ); + authUrl = mw.absoluteUrl( authUrl, articleUrl ); + $authorLink.attr( 'href', authUrl ); + }); + } + $creditLine.append( $( '<br />' ), + mw.msg( 'mwe-embedplayer-credit-author', $authorText.html() ) + ); + } + + // Look for date: + $date = $page.find( '#fileinfotpl_date' ); + if ( $date.length ) { + // Get the real date sibling of fileinfotpl_date + $date = $date.next(); + + // remove white space: + $date.find( 'br' ).remove(); + $creditLine.append( $( '<br />' ), + mw.msg( 'mwe-embedplayer-credit-date', $date.html() ) + ); + } + + // Build out the image and credit line + if ( embedPlayer.isAudio() ) { + imgSize.height = imgSize.width = ( embedPlayer.controlBuilder.getOverlayWidth() < 250 ) ? 45 : 80; + } else { + imgSize.width = ( embedPlayer.controlBuilder.getOverlayWidth() < 250 ) ? 45 : 120; + imgSize.height = Math.floor( imgSize.width * ( embedPlayer.getHeight() / embedPlayer.getWidth() ) ); + } + return $( '<div/>' ).addClass( 'creditline' ) + .append( + $( '<a/>' ).attr( { + 'href': articleUrl, + 'title': titleStr + } ).html( + $( '<img/>' ).attr( { + 'border': 0, + 'src': embedPlayer.poster + } ).css( imgSize ) + ) + ) + .append( + $creditLine + ); + } + + /** + * Issues a request to populate the credits box + */ + function showCredits( $target, callback ) { + var apiUrl, fileTitle, request; + if ( $creditsCache ) { + $target.html( $creditsCache ); + callback( true ); + return; + } + // Setup shortcuts: + apiUrl = mw.getApiProviderURL( apiProvider ); + fileTitle = 'File:' + decodeURIComponent( apiTitleKey ).replace( /^File:|^Image:/, ''); + + // Get the image page ( cache for 1 hour ) + request = { + 'action': 'parse', + 'page': fileTitle, + 'smaxage': 3600, + 'maxage': 3600 + }; + mw.getJSON( apiUrl, request, function ( data ) { + var descUrl = apiUrl.replace( 'api.php', 'index.php'); + descUrl += '?title=' + encodeURIComponent( fileTitle ); + if ( data && data.parse && data.parse.text && data.parse.text['*'] ) { + // TODO improve provider 'concept' to support page title link + $creditsCache = doCreditLine( data.parse.text['*'], descUrl ); + } else { + $creditsCache = doCreditLine( false, descUrl ); + } + $target.html( $creditsCache ); + callback( true ); + } ); + } + /** + * Adds embedPlayer Bindings + */ + + // Show credits when requested + $( embedPlayer ).bindQueueCallback( 'showCredits', function ( $target, callback ) { + if ( $target.data( 'playerId') !== embedPlayer.id ) { + // bad event trigger + return ; + } + // Only request the credits once: + showCredits( $target, callback ); + }); + + // Show credits on clip complete: + $( embedPlayer ).bind( 'onEndedDone', function ( event, id ) { + if ( embedPlayer.id !== id ) { + // possible event trigger error. ( skip ) + return ; + } + // dont show credits for audio elements, + // seek to begining instead + if ( embedPlayer.isAudio() ) { + embedPlayer.setCurrentTime( 0 ); + return ; + } + var cb = embedPlayer.controlBuilder; + cb.checkMenuOverlay(); + cb.showMenuOverlay(); + cb.showMenuItem( 'credits' ); + }); + + $( embedPlayer ).bind( 'showInlineDownloadLink', function () { + // Add recommend HTML5 player if we have non-native playback: + if ( embedPlayer.controlBuilder.checkNativeWarning( ) ) { + embedPlayer.controlBuilder.addWarningBinding( + 'EmbedPlayer.ShowNativeWarning', + mw.msg( 'mwe-embedplayer-for_best_experience', + $( '<div>' ).append( + $( '<a />' ).attr({ + 'href': 'http://www.mediawiki.org/wiki/Extension:TimedMediaHandler/Client_download', + 'target': '_new' + }) + )[0].innerHTML + ), + true + ); + } + }); + + $( embedPlayer ).bind( 'TimedText_BuildCCMenu', function ( event, $menu, id ) { + var _this, + pageTitle, + addTextPage, + $li; + if ( id !== embedPlayer.id ) { + _this = $( '#' + id )[0].timedText; + embedPlayer = _this.embedPlayer; + } + // Put in the "Make Transcript" link if config enabled and we have an api key + if ( embedPlayer.apiTitleKey ) { + // check if not already there: + if ( $menu.find( '.add-timed-text' ).length ) { + // add text link already present + return ; + } + + pageTitle = 'TimedText:' + + decodeURIComponent( embedPlayer.apiTitleKey ).replace( /^File:|^Image:/, '' ); + addTextPage = mw.getApiProviderURL( apiProvider ) + .replace( 'api.php', 'index.php') + + '?title=' + encodeURIComponent( pageTitle ); + + $li = $.getLineItem( mw.msg( 'mwe-timedtext-upload-timed-text'), 'script', function () { + window.location = addTextPage; + }); + + $li.addClass( 'add-timed-text') + .find( 'a' ) + .attr( { + 'href': addTextPage, + 'target': '_new' + } ); + $menu.append( + $li + ); + } + }); + + $( embedPlayer ).bindQueueCallback( 'checkPlayerSourcesEvent', function ( callback ) { + // Only load source if none are available: + if ( embedPlayer.mediaElement.sources.length === 0 ) { + loadPlayerSources( callback ); + } else { + // No source to load, issue callback directly + callback(); + } + } ); + $( mw ).bindQueueCallback( 'TimedText_LoadTextSource', function ( source, callback ) { + if ( !source.mwtitle || !source.mwprovider ) { + callback(); + return ; + } + // Load via api + var apiUrl = mw.getApiProviderURL( source.mwprovider ), + // Get the image page ( cache for 1 hour ) + request = { + 'action': 'parse', + 'page': source.mwtitle, + 'smaxage': 3600, + 'maxage': 3600 + }; + mw.getJSON( apiUrl, request, function ( data ) { + if ( data && data.parse && data.parse.text && data.parse.text['*'] ) { + source.loaded = true; + source.mimeType = 'text/mw-srt'; + source.captions = source.getCaptions( data.parse.text['*'] ); + callback(); + } else { + mw.log( 'Error: MediaWiki api error in getting timed text:', data ); + callback(); + } + }); + }); + + $( embedPlayer ).bind( 'getShareIframeSrc', function ( event, callback, id ) { + if ( id !== embedPlayer.id ) { + embedPlayer = $( '#' + id )[0]; + } + var iframeUrl = false; + // Do a special check for wikimediacommons provider as a known shared reop + if ( embedPlayer['data-mwprovider'] === 'wikimediacommons' ) { + iframeUrl = '//commons.wikimedia.org/wiki/File:' + decodeURIComponent( embedPlayer.apiTitleKey ).replace( /^(File:|Image:)/, '' ); + } else { + // use the local wiki: + if ( mw.config.get( 'wgServer' ) && mw.config.get( 'wgArticlePath' ) ) { + iframeUrl = mw.config.get( 'wgServer' ) + + mw.config.get( 'wgArticlePath' ).replace( /\$1/, 'File:' + + decodeURIComponent( embedPlayer.apiTitleKey ).replace( /^(File:|Image:)/, '' ) ); + } + } + if ( iframeUrl ) { + iframeUrl += '?embedplayer=yes'; + } + callback( iframeUrl ); + }); + }; + +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/resources/mw.PopUpThumbVideo.js b/extensions/TimedMediaHandler/resources/mw.PopUpThumbVideo.js new file mode 100644 index 00000000..c0aa30df --- /dev/null +++ b/extensions/TimedMediaHandler/resources/mw.PopUpThumbVideo.js @@ -0,0 +1,44 @@ +/** +* Simple script to add pop-up video dialog link support for video thumbnails +*/ +( function ( mw, $ ) { + $( document ).ready( function () { + $('.PopUpMediaTransform a').each( function () { + var link, title, + parent = $( this ).parent(); + if ( parent.attr( 'videopayload' ) ) { + $( this ).click( function ( /*event*/ ) { + var thisref = this; + + mw.loader.using( 'mw.MwEmbedSupport', function () { + var $videoContainer = $( $( thisref ).parent().attr( 'videopayload' ) ); + mw.addDialog({ + 'width': 'auto', + 'height': 'auto', + 'title': mw.html.escape( $videoContainer.find( 'video, audio' ).attr( 'data-mwtitle' ) ), + 'content': $videoContainer, + 'close': function(){ + // On close destroy the dialog rather than just hiding it, + // so it doesn't eat up resources or keep playing. + $( this ).remove(); + return true; + }, + 'open': function() { + $( this ).find( 'video, audio' ).embedPlayer(); + } + }) + .css( 'overflow', 'hidden' ); + } ); + // don't follow file link + return false; + } ); + } else if ( parent.attr( 'data-videopayload' ) ) { + link = $( this ).attr( 'href' ); + title = mw.Title.newFromImg( { src: link } ); + if ( title && title.getPrefixedDb() !== mw.config.get( 'wgPageName' ) ) { + $( this ).attr( 'href', title.getUrl() ); + } + } /* else fall back to linking directly to media file */ + } ); + } ); +} )( mediaWiki, jQuery ); diff --git a/extensions/TimedMediaHandler/resources/mw.TMHGalleryHook.js b/extensions/TimedMediaHandler/resources/mw.TMHGalleryHook.js new file mode 100644 index 00000000..fd23690e --- /dev/null +++ b/extensions/TimedMediaHandler/resources/mw.TMHGalleryHook.js @@ -0,0 +1,46 @@ +/** +* Simple script to add pop-up video dialog link support for video thumbnails +*/ +( function ( mw ) { + // Hook to allow dynamically resizing videos in image galleries + mw.hook( 'mediawiki.page.gallery.resize' ).add( function ( info ) { + var $mwPlayerContainer, + $popUp, + $tmhVideo, + $mwContainer = info.$imageDiv.find( '.mediaContainer' ); + if ( info.resolved ) { + // Everything is already done here. + return; + } + + $mwContainer = info.$imageDiv.find( '.mediaContainer' ); + if ( $mwContainer.length ) { + // Add some padding, so caption doesn't overlap video controls if + // we are overlaying the caption on top of the image. + if ( !info.$outerDiv.parent().hasClass( 'mw-gallery-packed' ) ) { + info.$outerDiv.find( 'div.gallerytext' ).css( 'padding-bottom', '20px' ); + } + + info.$imageDiv.width( info.imgWidth ); + $mwContainer.width( info.imgWidth ); + $mwPlayerContainer = $mwContainer.children( '.mwPlayerContainer' ); + if ( $mwPlayerContainer.length ) { + // Case 1: HTML5 player already loaded + $mwPlayerContainer.width( info.imgWidth ).height( info.imgHeight ); + $mwPlayerContainer.find( 'img.playerPoster' ).width( info.imgWidth ).height( info.imgHeight ); + } else { + // Case 2: Raw video element + $tmhVideo = info.$imageDiv.find( 'video' ); + $tmhVideo.width( info.imgWidth ).height( info.imgHeight ); + } + info.resolved = true; + return; + } + + $popUp = info.$imageDiv.find( '.PopUpMediaTransform' ); + if ( $popUp.length ) { + info.$imageDiv.width( info.imgWidth ); + $popUp.add( $popUp.find( 'img' ) ).width( info.imgWidth ).height( info.imgHeight ); + } + } ); +} )( mediaWiki ); diff --git a/extensions/TimedMediaHandler/resources/player_big_play_button.png b/extensions/TimedMediaHandler/resources/player_big_play_button.png Binary files differnew file mode 100644 index 00000000..041fea9c --- /dev/null +++ b/extensions/TimedMediaHandler/resources/player_big_play_button.png diff --git a/extensions/TimedMediaHandler/resources/player_big_play_button_hover.png b/extensions/TimedMediaHandler/resources/player_big_play_button_hover.png Binary files differnew file mode 100644 index 00000000..3517563e --- /dev/null +++ b/extensions/TimedMediaHandler/resources/player_big_play_button_hover.png diff --git a/extensions/TimedMediaHandler/resources/transcodeTable.css b/extensions/TimedMediaHandler/resources/transcodeTable.css new file mode 100644 index 00000000..795ce134 --- /dev/null +++ b/extensions/TimedMediaHandler/resources/transcodeTable.css @@ -0,0 +1,14 @@ +.mw-filepage-transcodestatus .download-btn { + background-image: url('download_sprite.png'); + width: 49px; + height: 36px; + background-repeat:no-repeat; + background-position: -50px; +} +.mw-filepage-transcodestatus .download-btn:hover { + background-position: 0 0; +} +.mw-filepage-transcodestatus .download-btn span { + /* Text hidden by the above image */ + display: none; +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/ApiTestCaseVideoUpload.php b/extensions/TimedMediaHandler/tests/phpunit/ApiTestCaseVideoUpload.php new file mode 100644 index 00000000..9dd4cb52 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/ApiTestCaseVideoUpload.php @@ -0,0 +1,130 @@ +<?php +/** + * Abstract test class to support Video Tests with video uploads + * @author dale + */ + +if ( !defined( 'MEDIAWIKI' ) ) { + exit; +} + +// Include core class ApiTestCaseUpload ( not part of base autoLoader ) +global $IP; +require_once( "$IP/tests/phpunit/includes/api/ApiTestCaseUpload.php" ); + +abstract class ApiTestCaseVideoUpload extends ApiTestCaseUpload { + /** + * @return Array set of test files with associated metadata + */ + static function mediaFilesProvider(){ + return array( + array( + // Double wrap the file array to match phpunit data provider conventions + array( + 'mime' => 'application/ogg', + 'filePath' => dirname( __FILE__ ) . '/media/test5seconds.electricsheep.300x400.ogv', + "size" => 301477, + "width" => 400, + "height" => 300, + "mediatype" => "VIDEO", + "bandwidth" => 452216, + "framerate" => 30 + ) + ), + array( + array( + 'mime' => 'video/webm', + 'filePath' => dirname( __FILE__ ) . '/media/shuttle10seconds.1080x608.webm', + "size" => 699018, + "width" => 1080, + "height" => 608, + "mediatype" => "VIDEO", + "bandwidth" => 522142, + "framerate" => 29.97 + ) + ) + ); + } + /** + * Fixture -- run after every test + * Clean up temporary files etc. + * + */ + protected function tearDown() { + parent::tearDown(); + + $testMediaFiles = $this->mediaFilesProvider(); + foreach( $testMediaFiles as $file ){ + $file = $file[0]; + // Clean up and delete all files + $this->deleteFileByFilename( $file['filePath'] ); + } + } + + /** + * Do login + */ + protected function doLogin( $user = 'sysop' ) { + $user = self::$users['uploader']; + + $params = array( + 'action' => 'login', + 'lgname' => $user->username, + 'lgpassword' => $user->password + ); + list( $result, , $session ) = $this->doApiRequest( $params ); + $token = $result['login']['token']; + + $params = array( + 'action' => 'login', + 'lgtoken' => $token, + 'lgname' => $user->username, + 'lgpassword' => $user->password + ); + list( $result, , $session ) = $this->doApiRequest( $params, $session ); + return $session; + } + + /** + * uploads a file: + */ + public function uploadFile( $file ){ + global $wgUser; + // get a session object + $session = $this->doLogin(); + // Update the global user: + $wgUser = self::$users['uploader']->getUser(); + + // Upload the media file: + $fileName = basename( $file['filePath'] ); + + // remove if already in thd db: + $this->deleteFileByFileName( $fileName ); + $this->deleteFileByContent( $file['filePath'] ); + + if ( !$this->fakeUploadFile( 'file', $fileName, $file['mime'], $file['filePath'] ) ) { + $this->markTestIncomplete( "Couldn't upload file!\n" ); + } + + $params = array( + 'action' => 'upload', + 'filename' => $fileName, + 'file' => 'dummy content', + 'comment' => 'dummy comment', + 'text' => "This is the page text for $fileName", + // This uploadFile function supports video tests not a test upload warnings + 'ignorewarnings' => true + ); + + try{ + list( $result, , ) = $this->doApiRequestWithToken( $params, $session ); + } catch( Exception $e ) { + // Could not upload mark test that called uploadFile as incomplete + $this->markTestIncomplete( $e->getMessage() ); + } + + return $result; + + } + +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/README b/extensions/TimedMediaHandler/tests/phpunit/README new file mode 100644 index 00000000..dd9eba39 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/README @@ -0,0 +1,11 @@ + +Some TimedMediaHandler testing notes: + + We have a base class ApiTestCaseVideoUpload that establishes the uploads. Actual uploading + is tested in the core uploading support so we focus these tests on timed media handler functionality + + We sometimes combine a few tests because fixtures don't play well with dataProvider + since the mediawiki test framework nukes the db every time you run the next test in + a given dataProvider data set. + + diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestApiUploadVideo.php b/extensions/TimedMediaHandler/tests/phpunit/TestApiUploadVideo.php new file mode 100644 index 00000000..ebc38ddf --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/TestApiUploadVideo.php @@ -0,0 +1,34 @@ +<?php +/** + * TestApiUploadVideo test case. + * + * NOTE: This build heavily on ApiUploadTest ( would need to refactor ApiUploadTest for this to work better ) + * + * @ingroup timedmedia + * @since 0.2 + * @author Michael Dale + */ + +/** + * @group Database + * @group Destructive + * @group medium + */ +class TestApiUploadVideo extends ApiTestCaseVideoUpload { + + /** + * @dataProvider mediaFilesProvider + */ + public function testUploadVideoFiles( $file ){ + + $result = $this->uploadFile( $file ); + + // Run asserts + $this->assertTrue( isset( $result['upload'] ) ); + $this->assertEquals( 'Success', $result['upload']['result'] ); + $this->assertEquals( filesize( $file['filePath'] ), ( int )$result['upload']['imageinfo']['size'] ); + $this->assertEquals( $file['mime'], $result['upload']['imageinfo']['mime'] ); + + } + +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestOggHandler.php b/extensions/TimedMediaHandler/tests/phpunit/TestOggHandler.php new file mode 100644 index 00000000..3c058974 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/TestOggHandler.php @@ -0,0 +1,67 @@ +<?php +class TestOggHandler extends MediaWikiMediaTestCase { + + /** @var OggHandlerTMH */ + private $handler; + + function getFilePath() { + return __DIR__ . '/media'; + } + + function setUp() { + parent::setUp(); + $this->handler = new OggHandlerTMH; + } + + /** + * @dataProvider providerGetCommonMetaArray + * @param $filename String name of file + * @param $expected Array + */ + function testGetCommonMetaArray( $filename, $expected ) { + $testFile = $this->dataFile( $filename, 'application/ogg' ); + $this->assertEquals( $expected, $this->handler->getCommonMetaArray( $testFile ) ); + } + + function providerGetCommonMetaArray() { + return array( + array( 'test5seconds.electricsheep.300x400.ogv', + array( + 'Software' => array( 'Lavf53.21.1' ), + 'ObjectName' => array( 'Electric Sheep' ), + 'UserComment' => array( 'š' ) + ) + ), + array( 'doubleTag.oga', + array( + 'Artist' => array( 'Brian', 'Bawolff' ), + 'Software' => array( 'Lavf55.10.2' ) + ) + ), + array( 'broken-file.ogg', + array() + ), + ); + } + + /** + * @dataProvider providerGetWebType + * @param $filename String name of file + * @param $expected String Mime type (including codecs) + */ + function testGetWebType( $filename, $expected ) { + $testFile = $this->dataFile( $filename, 'application/ogg' ); + $this->assertEquals( $expected, $this->handler->getWebType( $testFile ) ); + } + + function providerGetWebType() { + return array( + array( 'test5seconds.electricsheep.300x400.ogv', 'video/ogg; codecs="theora"' ), + array( 'doubleTag.oga', 'audio/ogg; codecs="vorbis"' ), + // XXX: This behaviour is somewhat questionable. It perhaps should be + // application/ogg in this case. + array( 'broken-file.ogg', 'audio/ogg' ), + ); + } + +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestTimeParsing.php b/extensions/TimedMediaHandler/tests/phpunit/TestTimeParsing.php new file mode 100644 index 00000000..b4ec6ba9 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/TestTimeParsing.php @@ -0,0 +1,42 @@ +<?php +/** + * TestTimeParsing test . + * + * @ingroup timedmedia + * @since 0.2 + * @author Michael Dale + */ + + +class TestTimeParsing extends PHPUnit_Framework_TestCase { + /** + * Test time string to np2 + */ + function testSeconds2NptFormat() { + // Some time conversions: + $this->assertEquals( TimedMediaHandler::seconds2npt( 100 ), '0:1:40' ); + $this->assertEquals( TimedMediaHandler::seconds2npt( 0 ), '0:0:0' ); + $this->assertEquals( TimedMediaHandler::seconds2npt( 3601 ), '1:0:1' ); + + // Test failures: + $this->assertEquals( TimedMediaHandler::seconds2npt( 'foo' ), false ); + $this->assertEquals( TimedMediaHandler::seconds2npt( -1 ), false ); + } + + /** + * Test time parsing to seconds + */ + function testParseTimeString() { + // Some time conversions: + $this->assertEquals( TimedMediaHandler::parseTimeString( 100 ), 100 ); + $this->assertEquals( TimedMediaHandler::parseTimeString( '1:0:0' ), 3600 ); + $this->assertEquals( TimedMediaHandler::parseTimeString( -1 ), 0 ); + // Test longer than duration check ( should return time -1 ) + $this->assertEquals( TimedMediaHandler::parseTimeString( 10, 9 ), 8 ); + + // Test failures: + $this->assertEquals( TimedMediaHandler::parseTimeString( '1:1:1:1' ), false ); + $this->assertEquals( TimedMediaHandler::parseTimeString( 'abc' ), false ); + + } +}
\ No newline at end of file diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaHandler.php b/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaHandler.php new file mode 100644 index 00000000..2ca350a0 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaHandler.php @@ -0,0 +1,47 @@ +<?php +class TestTimedMediaHandler extends MediaWikiTestCase { + + /** @var TimedMediaHandler */ + private $handler; + + function setUp() { + $this->handler = new TimedMediaHandler; + parent::setUp(); + } + + /** + * @dataProvider providerParseParamString + * @param $str String a thumbnail parameter string + * @param $expected Array Expected thumbnailing parameters + */ + function testParseParamString( $str, $expected ) { + $result = $this->handler->parseParamString( $str ); + $this->assertEquals( $result, $expected ); + } + + function providerParseParamString() { + return array( + array( + 'mid', + array(), + ), + array( + '220px-', + array( 'width' => 220 ), + ), + array( + 'seek=30', + array( 'thumbtime' => 30.0 ), + ), + array( + 'seek=15.72', + array( 'thumbtime' => 15.72 ), + ), + array( + '180px-seek=15', + array( 'thumbtime' => 15, 'width' => 180 ), + ), + ); + + } +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaTransformOutput.php b/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaTransformOutput.php new file mode 100644 index 00000000..9bcc89fb --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/TestTimedMediaTransformOutput.php @@ -0,0 +1,142 @@ +<?php +class TestTimedMediaTransformOutput extends MediaWikiMediaTestCase { + + private $sortMethod; + private $thumbObj; + + function getFilePath() { + return __DIR__ . '/media'; + } + + protected function setUp() { + parent::setUp(); + + // Disable video thumbnail generation. Not needed for this test. + $reflection = new ReflectionClass( $this->repo ); + $reflectionProperty = $reflection->getProperty( 'transformVia404' ); + $reflectionProperty->setAccessible( true ); + $reflectionProperty->setValue( $this->repo, true ); + + $this->setMWGlobals( 'wgMinimumVideoPlayerSize', '400' ); + } + + /** + * @param $width int The requested width of the thumbnail + * @param $minVideoSize int The min width a non-pop up video is acceptable + * @param $expectPopup boolean Do we expect a pop up video + * + * @dataProvider providerIsPopUp + */ + function testIsPopUp( $width, $minVideoSize, $expectPopup ) { + $this->setMwGlobals( 'wgMinimumVideoPlayerSize', $minVideoSize ); + + // Note this file has a width of 400px and a height of 300px + $file = $this->dataFile( 'test5seconds.electricsheep.300x400.ogv', 'application/ogg' ); + $thumbnail = $file->transform( array( 'width' => $width ) ); + $this->assertTrue( $thumbnail && !$thumbnail->isError() ); + + $reflection = new ReflectionClass( $thumbnail ); + $reflMethod = $reflection->getMethod( 'useImagePopUp' ); + $reflMethod->setAccessible( true ); + + $actual = $reflMethod->invoke( $thumbnail ); + $this->assertEquals( $actual, $expectPopup ); + + } + + function providerIsPopUp() { + return array( + array( 400, 800, false ), + array( 300, 800, true ), + array( 300, 200, false ), + array( 300, 300, false ) + ); + } + + /** + * @param $thumbWidth int Requested width + * @param $sources array + * @param $sortedSources array + * @dataProvider providerSortMediaByBandwidth + */ + function testSortMediaByBandwidth( $thumbWidth, $sources, $sortedSources ) { + $params = array( + 'width' => $thumbWidth, + 'height' => $thumbWidth * 9 / 16, + 'isVideo' => true, + 'fillwindow' => false, + 'file' => new FakeDimensionFile( array( 1820, 1024 ) ) + ); + $this->thumbObj = new TimedMediaTransformOutput( $params ); + + $reflection = new ReflectionClass( $this->thumbObj ); + $this->sortMethod = $reflection->getMethod( 'sortMediaByBandwidth' ); + $this->sortMethod->setAccessible( true ); + + usort( $sources, array( $this, 'callSortMethodHelper' ) ); + $this->assertEquals( $sortedSources, $sources ); + } + + public function callSortMethodHelper( $a, $b ) { + return $this->sortMethod->invoke( $this->thumbObj, $a, $b ); + } + + + function providerSortMediaByBandwidth() { + return array( + array( + 600, + array( + array( 'width' => 1000, 'bandwidth' => 2000 ), + array( 'width' => 1000, 'bandwidth' => 7000 ), + array( 'width' => 1000, 'bandwidth' => 1000 ), + ), + array( + array( 'width' => 1000, 'bandwidth' => 1000 ), + array( 'width' => 1000, 'bandwidth' => 2000 ), + array( 'width' => 1000, 'bandwidth' => 7000 ), + ), + ), + array( + 600, + array( + array( 'width' => 200, 'bandwidth' => 2000 ), + array( 'width' => 1000, 'bandwidth' => 7000 ), + array( 'width' => 200, 'bandwidth' => 1000 ), + ), + array( + array( 'width' => 1000, 'bandwidth' => 7000 ), + array( 'width' => 200, 'bandwidth' => 1000 ), + array( 'width' => 200, 'bandwidth' => 2000 ), + ), + ), + array( + /* Pop up viewer in this case */ + 100, + array( + array( 'width' => 700, 'bandwidth' => 2000 ), + array( 'width' => 1000, 'bandwidth' => 7000 ), + array( 'width' => 700, 'bandwidth' => 1000 ), + ), + array( + array( 'width' => 1000, 'bandwidth' => 7000 ), + array( 'width' => 700, 'bandwidth' => 1000 ), + array( 'width' => 700, 'bandwidth' => 2000 ), + ), + ), + array( + 600, + array( + array( 'width' => 700, 'bandwidth' => 2000 ), + array( 'width' => 800, 'bandwidth' => 7000 ), + array( 'width' => 1000, 'bandwidth' => 1000 ), + ), + array( + array( 'width' => 1000, 'bandwidth' => 1000 ), + array( 'width' => 700, 'bandwidth' => 2000 ), + array( 'width' => 800, 'bandwidth' => 7000 ), + ), + ), + ); + } +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestVideoThumbnail.php b/extensions/TimedMediaHandler/tests/phpunit/TestVideoThumbnail.php new file mode 100644 index 00000000..b3c9ef87 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/TestVideoThumbnail.php @@ -0,0 +1,80 @@ +<?php +/** + * @ingroup timedmedia + * @author dale + * @group medium + */ +class TestVideoThumbnail extends ApiTestCaseVideoUpload { + + /** + * Once video files are uploaded test thumbnail generating + * + * @dataProvider mediaFilesProvider + * Broken as per bug 61877 + * @group Broken + */ + function testApiThumbnails( $file ){ + // Upload the file to the mediaWiki system + $result = $this->uploadFile( $file); + + // Do a API request and check for valid thumbnails: + $fileName = basename( $file['filePath'] ); + $params = array( + 'action' => 'query', + 'titles' => 'File:' . $fileName, + 'prop' => 'imageinfo', + 'iiprop' => "url|size|thumbmime", + ); + + // Do a request for a small ( 200px ) thumbnail + list($result,,) = $this->doApiRequest( + array_merge( $params, array( + 'iiurlwidth' => '200' + ) + ) + ); + + // Check The thumbnail output: + $this->assertTrue( isset( $result['query'] ) ); + + $page = current( $result['query']['pages'] ); + $this->assertTrue( isset( $page['imageinfo'] ) ); + + $imageInfo = current( $page['imageinfo'] ); + + // Make sure we got a 200 wide pixel image: + $this->assertEquals( 200, ( int )$imageInfo['thumbwidth'] ); + + // Thumbnails should be image/jpeg: + $this->assertEquals( 'image/jpeg', $imageInfo['thumbmime'] ); + + // Make sure the thumbnail url is valid and the correct size ( assuming php has getimagesize function) + if( function_exists( 'getimagesize' ) ){ + list($width ,,,) = getimagesize ( $imageInfo[ 'thumburl'] ); + $this->assertEquals( 200, $width ); + } + + /** + * We combine tests because fixtures don't play well with dataProvider + * see README for more info + */ + + // Test a larger thumbnail with 1 second time offset + list( $result,, ) = $this->doApiRequest( + array_merge( $params, array( + 'iiurlwidth' => '600', + 'iiurlparam' => '1' + ) + ) + ); + $page = current( $result['query']['pages'] ); + $imageInfo = current( $page['imageinfo'] ); + // Thumb should max out at source size ( no upscale ) + $targetWidth = ( ( int )$file['width'] < 600 ) ? ( int )$file['width'] : 600; + $this->assertEquals( $targetWidth, ( int )$imageInfo['thumbwidth'] ); + if( function_exists( 'getimagesize' ) ){ + list( $srcImageWidth ,,,) = getimagesize ( $imageInfo[ 'thumburl'] ); + $this->assertEquals( $targetWidth, $srcImageWidth ); + } + } +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestVideoTranscode.php b/extensions/TimedMediaHandler/tests/phpunit/TestVideoTranscode.php new file mode 100644 index 00000000..af0e6f1f --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/TestVideoTranscode.php @@ -0,0 +1,121 @@ +<?php +/** + * @ingroup timedmedia + * @author michael dale + * @group medium + */ +class TestVideoTranscode extends ApiTestCaseVideoUpload { + + /** + * Once video files are uploaded test transcoding + * + * Test if a transcode job is added for a file once requested + * + * @dataProvider mediaFilesProvider + * Broken as per bug 61878 + * @group Broken + */ + function testTranscodeJobs( $file ){ + // Upload the file to the mediaWiki system + $result = $this->uploadFile( $file ); + + // Check for derivatives ( should trigger adding jobs ) + $fileName = basename( $file['filePath'] ); + $params = array( + 'action' => 'query', + 'titles' => 'File:' . $fileName, + 'prop' => 'videoinfo', + 'viprop' => "derivatives", + ); + list($result,,) = $this->doApiRequest( $params ); + + // Get the $derivatives: + $derivatives = $this->getDerivativesFromResult( $result ); + // Only the "source" asset will be present at first: + $source = current( $derivatives ); + + // Check that the source matches the api bandwidth property: + $this->assertEquals( $file['bandwidth'], $source['bandwidth'] ); + + // Check if the transcode jobs were added: + // get results: query jobs table + $db = wfGetDB( DB_MASTER ); + $res = $db->select( 'transcode', '*', array( + 'transcode_image_name' => ucfirst( $fileName ) + ) ); + // Make sure we target at least one ogg and one webm: + $hasOgg = $hasWebM = false; + $targetEncodes = array(); + foreach( $res as $row ){ + $codec = WebVideoTranscode::$derivativeSettings[ $row->transcode_key ]['videoCodec']; + if( $codec == 'theora' ){ + $hasOgg = true; + } + if( $codec == 'vp8' ){ + $hasWebM = true; + } + $targetEncodes[ $row->transcode_key ] = $row; + }; + // Make sure we have ogg and webm: + $this->assertTrue( $hasOgg && $hasWebM ); + + // Now run the transcode job queue + $this->runTranscodeJobs(); + + $res = $db->select( 'transcode', '*', array( + 'transcode_image_name' => ucfirst( $fileName ) + ) ); + + // Now check if the derivatives were created: + list($result,,) = $this->doApiRequest( $params ); + $derivatives = $this->getDerivativesFromResult( $result ); + + // Check that every requested encode was encoded: + foreach( $targetEncodes as $transcodeKey => $row ){ + $targetEncodeFound = false; + foreach( $derivatives as $derv ){ + // The transcode key is always the last part of the file name: + if( substr( $derv['src'], -1 * strlen( $transcodeKey ) ) == $transcodeKey ){ + $targetEncodeFound = true; + } + } + // Test that target encode was found: + $this->assertTrue( $targetEncodeFound ); + } + + } + + // Run Transcode job + function runTranscodeJobs(){ + $dbw = wfGetDB( DB_MASTER ); + $type = 'webVideoTranscode'; + // Set the condition to only run the webVideoTranscode + $conds = array( "job_cmd" => $type ); + + while ( $dbw->selectField( 'job', 'job_id', $conds, 'runJobs.php' ) ) { + for ( ; ; ) { + $job = Job::pop_type( $type ); + if ( !$job ) + break; + + wfWaitForSlaves( 5 ); + $t = microtime( true ); + $offset = $job->id; + $status = $job->run(); + $t = microtime( true ) - $t; + $timeMs = intval( $t * 1000 ); + } + } + } + + function getDerivativesFromResult( $result ){ + // Only the source should be listed initially: + $this->assertTrue( isset( $result['query']['pages'] ) ); + $page = current( $result['query']['pages'] ); + + $videoInfo = current( $page['videoinfo'] ); + $this->assertTrue( isset( $videoInfo['derivatives'] ) ); + + return $videoInfo['derivatives']; + } +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/TestWebMHandler.php b/extensions/TimedMediaHandler/tests/phpunit/TestWebMHandler.php new file mode 100644 index 00000000..2d73f46d --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/TestWebMHandler.php @@ -0,0 +1,52 @@ +<?php +class TestOggHandler extends MediaWikiMediaTestCase { + + /** @var OggHandlerTMH */ + private $handler; + + function getFilePath() { + return __DIR__ . '/media'; + } + + function setUp() { + parent::setUp(); + $this->handler = new WebMHandler; + } + + /** + * @dataProvider providerGetStreamTypes + * @param $filename String name of file + * @param $expected array List of codecs in file + */ + function testGetStreamTypes( $filename, $expected ) { + $testFile = $this->dataFile( $filename, 'video/webm' ); + $this->assertEquals( $expected, $this->handler->getStreamTypes( $testFile ) ); + } + + function providerGetStreamTypes() { + return array( + array( 'shuttle10seconds.1080x608.webm', array( 'VP8' ) ), + array( 'VP9-tractor.webm', array( 'VP9' ) ), + array( 'bear-vp9-opus.webm', array( 'Opus', 'VP9' ) ) + ); + } + + + /** + * @dataProvider providerGetWebType + * @param $filename String name of file + * @param $expected String Mime type + */ + function testGetWebType( $filename, $expected ) { + $testFile = $this->dataFile( $filename, 'video/webm' ); + $this->assertEquals( $expected, $this->handler->getWebType( $testFile ) ); + } + + function providerGetWebType() { + return array( + array( 'shuttle10seconds.1080x608.webm', 'video/webm; codecs="vp8"' ), + array( 'VP9-tractor.webm', 'video/webm; codecs="vp9"' ), + array( 'bear-vp9-opus.webm', 'video/webm; codecs="opus, vp9"' ) + ); + } +} diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/README b/extensions/TimedMediaHandler/tests/phpunit/media/README new file mode 100644 index 00000000..b21871ea --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/media/README @@ -0,0 +1,38 @@ +doubleTag.oga and broken-file.ogg were created by Brian Wolff and is released into the public domain + +VP9-tractor.webm is from http://base-n.de/webm/VP9%20Sample.html and was encoded from a public domain +file located at http://media.xiph.org/video/derf/y4m/ + +bear-vp9-opus.webm comes from the chromnium project at the url +http://code.metager.de/source/raw/chromium/media/test/data/bear-vp9-opus.webm +which has the following copyright notice: + +1 // Copyright 2014 The Chromium Authors. All rights reserved. +2 // +3 // Redistribution and use in source and binary forms, with or without +4 // modification, are permitted provided that the following conditions are +5 // met: +6 // +7 // * Redistributions of source code must retain the above copyright +8 // notice, this list of conditions and the following disclaimer. +9 // * Redistributions in binary form must reproduce the above +10 // copyright notice, this list of conditions and the following disclaimer +11 // in the documentation and/or other materials provided with the +12 // distribution. +13 // * Neither the name of Google Inc. nor the names of its +14 // contributors may be used to endorse or promote products derived from +15 // this software without specific prior written permission. +16 // +17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/VP9-tractor.webm b/extensions/TimedMediaHandler/tests/phpunit/media/VP9-tractor.webm Binary files differnew file mode 100644 index 00000000..bbe96f5d --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/media/VP9-tractor.webm diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/bear-vp9-opus.webm b/extensions/TimedMediaHandler/tests/phpunit/media/bear-vp9-opus.webm Binary files differnew file mode 100644 index 00000000..80355cfa --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/media/bear-vp9-opus.webm diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/broken-file.ogg b/extensions/TimedMediaHandler/tests/phpunit/media/broken-file.ogg Binary files differnew file mode 100644 index 00000000..c9fc4fd5 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/media/broken-file.ogg diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/doubleTag.oga b/extensions/TimedMediaHandler/tests/phpunit/media/doubleTag.oga Binary files differnew file mode 100644 index 00000000..f7fac168 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/media/doubleTag.oga diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/shuttle10seconds.1080x608.webm b/extensions/TimedMediaHandler/tests/phpunit/media/shuttle10seconds.1080x608.webm Binary files differnew file mode 100644 index 00000000..a7b865b1 --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/media/shuttle10seconds.1080x608.webm diff --git a/extensions/TimedMediaHandler/tests/phpunit/media/test5seconds.electricsheep.300x400.ogv b/extensions/TimedMediaHandler/tests/phpunit/media/test5seconds.electricsheep.300x400.ogv Binary files differnew file mode 100644 index 00000000..a73ec5bf --- /dev/null +++ b/extensions/TimedMediaHandler/tests/phpunit/media/test5seconds.electricsheep.300x400.ogv diff --git a/extensions/TimedMediaHandler/version b/extensions/TimedMediaHandler/version new file mode 100644 index 00000000..20e3a345 --- /dev/null +++ b/extensions/TimedMediaHandler/version @@ -0,0 +1,5 @@ +TimedMediaHandler: 7cab54e2e482d51df69e4b9c880182b23cabf0bc + +2016-01-27T22:15:53 + +7cab54e diff --git a/robots.txt b/robots.txt new file mode 100644 index 00000000..42018bd9 --- /dev/null +++ b/robots.txt @@ -0,0 +1,8 @@ +# No me indexes el historial loco +User-Agent: * +Disallow: /index.php + +# Dejar que Internet Archive indexe las pƔginas en bruto +User-Agent: ia_archiver +Allow: /*&action=raw + diff --git a/skins/ArchLinux/ArchLinuxTemplate.php b/skins/ArchLinux/ArchLinuxTemplate.php index 52c23aec..3e10befc 100644 --- a/skins/ArchLinux/ArchLinuxTemplate.php +++ b/skins/ArchLinux/ArchLinuxTemplate.php @@ -46,26 +46,17 @@ class ArchLinuxTemplate extends BaseTemplate { ?> <div id="archnavbar"><!-- Arch Linux global navigation bar --> - <div id="archnavbarlogo"> - <p><a id="logo" href="<?php if (isset($wgArchHome)) { echo $wgArchHome; } ?>"></a></p> - </div> - <div id="archnavbarmenu"> - <ul id="archnavbarlist"> - <?php - if (isset($wgArchNavBar)) { - foreach ($wgArchNavBar as $name => $url) { - if ((isset($wgArchNavBarSelected) && $this->data['title'] == $name && in_array($name, $wgArchNavBarSelected)) - || (!(isset($wgArchNavBarSelected) && in_array($this->data['title'], $wgArchNavBarSelected)) && isset($wgArchNavBarSelectedDefault) && $name == $wgArchNavBarSelectedDefault)) { - $anbClass = ' class="anb-selected"'; - } else { - $anbClass = ''; - } - echo '<li id="anb-'.strtolower($name).'"'.$anbClass.'><a href="'.$url.'">'.$name.'</a></li>'; - } - } - ?> - </ul> - </div> + <div id="archnavbarlogo"><h1><a href="https://www.parabola.nu/">Parabola GNU/Linux-libre</a></h1></div> + <div id="archnavbarmenu"> + <ul id="archnavbarlist"> + <li id="anb-home"><a href="https://www.parabola.nu/" title="Parabola news, packages, projects and more">Home</a></li> + <li id="anb-packages"><a href="https://www.parabola.nu/packages/" title="Package Database">Packages</a></li> + <li id="anb-wiki" class="anb-selected"><a href="https://wiki.parabola.nu/" title="Community documentation">Wiki</a></li> + <li id="anb-bugs"><a href="https://labs.parabola.nu" title="Issue Tracker">Bugs</a></li> + <li id="anb-projects"><a href="https://projects.parabola.nu/" title="Our Code">Projects</a></li> + <li id="anb-download"><a href="https://wiki.parabola.nu/Get_Parabola" title="Get Parabola">Download</a></li> + </ul> + </div> </div><!-- #archnavbar --> <div id="globalWrapper"> diff --git a/skins/ArchLinux/archlogo.png b/skins/ArchLinux/archlogo.png Binary files differindex 42b79e27..8726397a 100644 --- a/skins/ArchLinux/archlogo.png +++ b/skins/ArchLinux/archlogo.png diff --git a/skins/ArchLinux/archnavbar.css b/skins/ArchLinux/archnavbar.css index 1e769857..574d8b2b 100644 --- a/skins/ArchLinux/archnavbar.css +++ b/skins/ArchLinux/archnavbar.css @@ -5,15 +5,15 @@ */ /* container for the entire bar */ -#archnavbar { height: 40px !important; padding: 10px 15px !important; background: #333 !important; border-bottom: 5px #08c solid !important; } -#archnavbarlogo { float: left !important; margin: 0 !important; padding: 0 !important; height: 40px !important; width: 190px !important; background: url('archlogo.png') no-repeat !important; } +#archnavbar { height: 40px !important; padding: 10px 15px !important; background: #000 !important; border-bottom: 5px #787DAB solid !important; } +#archnavbarlogo { float: left !important; margin: -5px 0 0 0 !important; padding: 0 !important; height: 50px !important; width: 324px !important; background: url('archlogo.png') no-repeat !important; } /* move the heading/paragraph text offscreen */ #archnavbarlogo p { margin: 0 !important; padding: 0 !important; text-indent: -9999px !important; } -#archnavbarlogo h1 { margin: 0 !important; padding: 0 !important; text-indent: -9999px !important; } +#archnavbarlogo h1 { margin: 0 !important; padding: 0 !important; text-indent: -9999px !important; border-bottom: 0px !important; } /* make the link the same size as the logo */ -#archnavbarlogo a { display: block !important; height: 40px !important; width: 190px !important; } +#archnavbarlogo a { display: block !important; height: 50px !important; width: 324px !important; } /* display the list inline, float it to the right and style it */ #archnavbar ul { display: inline !important; float: right !important; list-style: none !important; margin: 0 !important; padding: 0 !important; } @@ -22,4 +22,3 @@ /* style the links */ #archnavbar ul#archnavbarlist li a { color: #999; font-weight: bold !important; text-decoration: none !important; } #archnavbar ul li a:hover { color: white !important; text-decoration: underline !important; } - diff --git a/skins/ArchLinux/favicon.ico b/skins/ArchLinux/favicon.ico Binary files differindex 8ef6f130..c67bbd61 100644 --- a/skins/ArchLinux/favicon.ico +++ b/skins/ArchLinux/favicon.ico diff --git a/skins/ArchLinux/skin.json b/skins/ArchLinux/skin.json index 0729e1cf..e45a8341 100644 --- a/skins/ArchLinux/skin.json +++ b/skins/ArchLinux/skin.json @@ -1,8 +1,8 @@ { "name": "ArchLinux", "author": [ "Pierre Schmitz" ], - "url": "https://www.archlinux.org", - "description": "MediaWiki skin based on MonoBook", + "url": "https://www.parabola.nu", + "description": "MediaWiki skin based on MonoBook, customized for Parabola", "license-name": "GPL-2.0+", "type": "skin", "ValidSkinNames": { |