diff --git a/APLClient/include/APLClient/AplCoreAudioPlayer.h b/APLClient/include/APLClient/AplCoreAudioPlayer.h new file mode 100644 index 0000000..4358a1f --- /dev/null +++ b/APLClient/include/APLClient/AplCoreAudioPlayer.h @@ -0,0 +1,120 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#ifndef APLCLIENT_APL_APLCOREAUDIOPLAYER_H +#define APLCLIENT_APL_APLCOREAUDIOPLAYER_H + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreorder" +#pragma push_macro("DEBUG") +#pragma push_macro("TRUE") +#pragma push_macro("FALSE") +#undef DEBUG +#undef TRUE +#undef FALSE +#include +#pragma pop_macro("DEBUG") +#pragma pop_macro("TRUE") +#pragma pop_macro("FALSE") +#pragma GCC diagnostic pop + +#include "AplConfiguration.h" +#include "AplCoreConnectionManager.h" + +namespace APLClient { + +/** + * AudioPlayer adapter. Controls browser-owned player. + */ +class AplCoreAudioPlayer : public apl::AudioPlayer { +public: + /** + * Constructor + * + * @param aplCoreConnectionManager Pointer to the APL Core connection manager + * @param config Pointer to APL configuration + * @param playerId PLayer ID. + * @param playerCallback Player events callback. + * @param speechMarkCallback TTS speechmarks callback. + */ + AplCoreAudioPlayer( + AplCoreConnectionManagerWPtr aplCoreConnectionManager, + AplConfigurationPtr config, + const std::string& playerId, + apl::AudioPlayerCallback&& playerCallback, + apl::SpeechMarkCallback&& speechMarkCallback); + + /** + * @param aplCoreConnectionManager Pointer to the APL Core connection manager + * @param config Pointer to APL configuration + * @param playerId PLayer ID. + * @param playerCallback Player events callback. + * @param speechMarkCallback TTS speechmarks callback. + */ + static std::shared_ptr create( + AplCoreConnectionManagerWPtr aplCoreConnectionManager, + AplConfigurationPtr config, + const std::string& playerId, + apl::AudioPlayerCallback&& playerCallback, + apl::SpeechMarkCallback&& speechMarkCallback); + + /// @name apl::AudioPlayer Functions + /// @{ + void release() override; + void setTrack(apl::MediaTrack track) override; + void play(apl::ActionRef actionRef) override; + void pause() override; + /// @} + + /** + * Process AudioPlayer event received from the browser. + * @param payload message payload. + */ + void onEvent(const rapidjson::Value& payload); + + /** + * Process SpeechMarks received from the browser. + * @param payload message payload. + */ + void onSpeechMarks(const rapidjson::Value& payload); + + /** + * Simulate time update. + * + * @param connectionManager AplCoreConnectionManager + */ + void tick(const AplCoreConnectionManager& connectionManager); + +private: + void sendAudioPlayerCommand(const std::string& command, std::string optionalUrl = ""); + void resolveExistingAction(); + void onEventInternal(apl::AudioPlayerEventType eventType, const apl::AudioState& audioState, int currentTime); + +private: + AplCoreConnectionManagerWPtr m_aplCoreConnectionManager; + AplConfigurationPtr m_aplConfiguration; + + apl::ActionRef m_PlayRef = apl::ActionRef(nullptr); + bool m_Playing = false; + bool m_Prepared = false; + int m_PlaybackStartTime = 0; + std::string m_playerId; +}; + +using AplCoreAudioPlayerPtr = std::shared_ptr; + +} // namespace APLClient + +#endif // APLCLIENT_APL_APLCOREAUDIOPLAYER_H diff --git a/APLClient/include/APLClient/AplCoreAudioPlayerFactory.h b/APLClient/include/APLClient/AplCoreAudioPlayerFactory.h new file mode 100644 index 0000000..6a207e3 --- /dev/null +++ b/APLClient/include/APLClient/AplCoreAudioPlayerFactory.h @@ -0,0 +1,82 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#ifndef APLCLIENT_APL_APLCOREAUDIOPLAYERFACTORY_H +#define APLCLIENT_APL_APLCOREAUDIOPLAYERFACTORY_H + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreorder" +#pragma push_macro("DEBUG") +#pragma push_macro("TRUE") +#pragma push_macro("FALSE") +#undef DEBUG +#undef TRUE +#undef FALSE +#include +#pragma pop_macro("DEBUG") +#pragma pop_macro("TRUE") +#pragma pop_macro("FALSE") +#pragma GCC diagnostic pop + +#include "AplConfiguration.h" +#include "AplCoreConnectionManager.h" +#include "AplCoreAudioPlayer.h" + +namespace APLClient { + +/** + * AudioPlayer factory. + */ +class AplCoreAudioPlayerFactory : public apl::AudioPlayerFactory { +public: + /** + * Constructor + * + * @param aplCoreConnectionManager Pointer to the APL Core connection manager + * @param config Pointer to APL configuration + */ + AplCoreAudioPlayerFactory(AplCoreConnectionManagerPtr aplCoreConnectionManager, AplConfigurationPtr config); + + /** + * @param aplCoreConnectionManager Pointer to the APL Core connection manager + * @param config Pointer to APL configuration + */ + static std::shared_ptr create(AplCoreConnectionManagerPtr aplCoreConnectionManager, AplConfigurationPtr config); + + /** + * @param playerId Player ID + * @return Corresponding player. + */ + AplCoreAudioPlayerPtr getPlayer(const std::string& playerId) const; + + void tick(const AplCoreConnectionManager& connectionManager); + + /// @name apl::AudioPlayerFactory Functions + /// @{ + apl::AudioPlayerPtr createPlayer(apl::AudioPlayerCallback playerCallback, + apl::SpeechMarkCallback speechMarkCallback) override; + /// @} + +private: + std::weak_ptr m_aplCoreConnectionManager; + AplConfigurationPtr m_aplConfiguration; + std::map m_Players; +}; + +using AplCoreAudioPlayerFactoryPtr = std::shared_ptr; + +} // namespace APLClient + +#endif // APLCLIENT_APL_APLCOREAUDIOPLAYERFACTORY_H diff --git a/APLClient/include/APLClient/AplCoreConnectionManager.h b/APLClient/include/APLClient/AplCoreConnectionManager.h index dab023e..8aca97b 100644 --- a/APLClient/include/APLClient/AplCoreConnectionManager.h +++ b/APLClient/include/APLClient/AplCoreConnectionManager.h @@ -130,6 +130,13 @@ class AplCoreConnectionManager */ void interruptCommandSequence(); + /** + * Send a message to the view host + * @param message The message to send + * @return The sequence number of this message + */ + unsigned int send(AplCoreViewhostMessage& message); + /** * Send a message to the view host and block until you get a reply * @param message The message to send @@ -210,6 +217,15 @@ class AplCoreConnectionManager */ void onDocumentRendered(const std::chrono::steady_clock::time_point &renderTime, uint64_t complexityScore); + /** + * Retrieves the current time + * @return The time + */ + std::chrono::milliseconds getCurrentTime() const { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); + } + private: /** * Sends viewport scaling information to the client @@ -320,6 +336,30 @@ class AplCoreConnectionManager */ void mediaLoadFailed(const rapidjson::Value& payload); + /** + * Handle the audioPlayerCallback message received from the viewhost + * @param payload + */ + void audioPlayerCallback(const rapidjson::Value& payload); + + /** + * Handle the audioPlayerSpeechMarks message received from the viewhost + * @param payload + */ + void audioPlayerSpeechMarks(const rapidjson::Value& payload); + + /** + * Handle the mediaPlayerUpdateMediaState message received from the viewhost + * @param payload + */ + void mediaPlayerUpdateMediaState(const rapidjson::Value& payload); + + /** + * Handle the mediaPlayerDoCallback message received from the viewhost + * @param payload + */ + void mediaPlayerDoCallback(const rapidjson::Value& payload); + /** * Handle the getFocusableAreas message received from the viewhost * @param payload @@ -402,6 +442,7 @@ class AplCoreConnectionManager void sendHierarchy(const std::string& messageKey, bool blocking = false); rapidjson::Value buildDisplayedChildrenHierarchy(const apl::ComponentPtr& component, AplCoreViewhostMessage& message); + /** * Process set of dirty components and send out dirty properties as required. * @param dirty dirty components set. @@ -419,28 +460,12 @@ class AplCoreConnectionManager */ void coreFrameUpdate(); - /** - * Send a message to the view host - * @param message The message to send - * @return The sequence number of this message - */ - unsigned int send(AplCoreViewhostMessage& message); - /** * Sends an error message to the view host * @param message The message to send to the view hsot */ void sendError(const std::string& message); - /** - * Retrieves the current time - * @return The time - */ - std::chrono::milliseconds getCurrentTime() { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()); - } - /** * Get optional value from Json. * @param jsonNode json data @@ -580,6 +605,7 @@ class AplCoreConnectionManager }; using AplCoreConnectionManagerPtr = std::shared_ptr; +using AplCoreConnectionManagerWPtr = std::weak_ptr; } // namespace APLClient diff --git a/APLClient/include/APLClient/AplCoreMediaPlayer.h b/APLClient/include/APLClient/AplCoreMediaPlayer.h new file mode 100644 index 0000000..996057e --- /dev/null +++ b/APLClient/include/APLClient/AplCoreMediaPlayer.h @@ -0,0 +1,98 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#ifndef APLCLIENT_APL_APLCOREMEDIAPLAYER_H +#define APLCLIENT_APL_APLCOREMEDIAPLAYER_H + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreorder" +#pragma push_macro("DEBUG") +#pragma push_macro("TRUE") +#pragma push_macro("FALSE") +#undef DEBUG +#undef TRUE +#undef FALSE +#include +#pragma pop_macro("DEBUG") +#pragma pop_macro("TRUE") +#pragma pop_macro("FALSE") +#pragma GCC diagnostic pop + +#include "AplConfiguration.h" +#include "AplCoreConnectionManager.h" + +namespace APLClient { + +class AplCoreMediaPlayer; + +using AplCoreMediaPlayerPtr = std::shared_ptr; + +/** + * MediaPlayer. + */ +class AplCoreMediaPlayer : public apl::MediaPlayer { +public: + static AplCoreMediaPlayerPtr create(AplCoreConnectionManagerWPtr aplCoreConnectionManager, + AplConfigurationPtr config, + const std::string& playerId, + apl::MediaPlayerCallback&& playerCallback); + + AplCoreMediaPlayer(AplCoreConnectionManagerWPtr aplCoreConnectionManager, + AplConfigurationPtr config, + const std::string& playerId, + apl::MediaPlayerCallback&& playerCallback); + ~AplCoreMediaPlayer() override = default; + + void updateMediaState(const rapidjson::Value& payload); + void doCallback(const rapidjson::Value& payload); + std::string getPlayerId() const { return m_playerId; }; + + // apl::MediaPlayer overrides + void release() override; + void halt() override; + void setTrackList(std::vector tracks) override; + void play(apl::ActionRef actionRef) override; + void pause() override; + void next() override; + void previous() override; + void rewind() override; + void seek(int offset) override; + void setTrackIndex(int trackIndex) override; + void setAudioTrack(apl::AudioTrack audioTrack) override; + void setMute(bool mute) override; + rapidjson::Value serialize(rapidjson::Document::AllocatorType& allocator) const override; + +private: + void resolveExistingAction(); + bool isActive() const; + void sendMediaPlayerCommand(const std::string& command, rapidjson::Value&& payload); + +private: + AplCoreConnectionManagerWPtr m_aplCoreConnectionManager; + AplConfigurationPtr m_aplConfiguration; + + std::string m_playerId; + apl::AudioTrack m_audioTrack; + apl::ActionRef m_actionRef = apl::ActionRef(nullptr); + bool m_released = false; // Set when the media player is released and should not be used + bool m_halted = false; // Set when the media player was asked to halt all playback + apl::MediaState m_mediaState; +}; + +using AplCoreMediaPlayerPtr = std::shared_ptr; + +} // namespace APLClient + +#endif // APLCLIENT_APL_APLCOREMEDIAPLAYER_H diff --git a/APLClient/include/APLClient/AplCoreMediaPlayerFactory.h b/APLClient/include/APLClient/AplCoreMediaPlayerFactory.h new file mode 100644 index 0000000..eaf55cf --- /dev/null +++ b/APLClient/include/APLClient/AplCoreMediaPlayerFactory.h @@ -0,0 +1,74 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#ifndef APLCLIENT_APL_APLCOREMEDIAPLAYERFACTORY_H +#define APLCLIENT_APL_APLCOREMEDIAPLAYERFACTORY_H + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreorder" +#pragma push_macro("DEBUG") +#pragma push_macro("TRUE") +#pragma push_macro("FALSE") +#undef DEBUG +#undef TRUE +#undef FALSE +#include +#pragma pop_macro("DEBUG") +#pragma pop_macro("TRUE") +#pragma pop_macro("FALSE") +#pragma GCC diagnostic pop + +#include + +#include "AplConfiguration.h" +#include "AplCoreConnectionManager.h" +#include "AplCoreMediaPlayer.h" + +namespace APLClient { + +/** + * MediaPlayer factory. + */ +class AplCoreMediaPlayerFactory : public apl::MediaPlayerFactory { +public: + AplCoreMediaPlayerFactory(AplCoreConnectionManagerWPtr aplCoreConnectionManager, AplConfigurationPtr config); + + static std::shared_ptr create(AplCoreConnectionManagerWPtr aplCoreConnectionManager, AplConfigurationPtr config); + + AplCoreMediaPlayerPtr getMediaPlayer(const std::string& playerId) const; + + // apl::MediaPlayerFactory overrides + apl::MediaPlayerPtr createPlayer(apl::MediaPlayerCallback callback) override; + +private: + /** + * Removes old inactive players from the list of players, if possible. + */ + void cleanup(); + + /** + * Delete media player on the other side of the web socket + */ + void sendMediaPlayerDelete(const std::string& mediaPlayerId); + +private: + AplCoreConnectionManagerWPtr m_aplCoreConnectionManager; + AplConfigurationPtr m_aplConfiguration; + std::map> m_activePlayers; +}; + +} // namespace APLClient + +#endif // APLCLIENT_APL_APLCOREMEDIAPLAYERFACTORY_H diff --git a/APLClient/src/AplCoreAudioPlayer.cpp b/APLClient/src/AplCoreAudioPlayer.cpp new file mode 100644 index 0000000..c6e2b80 --- /dev/null +++ b/APLClient/src/AplCoreAudioPlayer.cpp @@ -0,0 +1,216 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "APLClient/AplCoreViewhostMessage.h" +#include "APLClient/AplCoreAudioPlayer.h" + +namespace APLClient { + +AplCoreAudioPlayerPtr +AplCoreAudioPlayer::create( + AplCoreConnectionManagerWPtr aplCoreConnectionManager, + AplConfigurationPtr config, + const std::string& playerId, + apl::AudioPlayerCallback&& playerCallback, + apl::SpeechMarkCallback&& speechMarkCallback) { + if (auto connectionManager = aplCoreConnectionManager.lock()) { + auto msg = AplCoreViewhostMessage("createAudioPlayer"); + auto& alloc = msg.alloc(); + + auto aplCoreMetrics = connectionManager->aplCoreMetrics(); + + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("playerId", rapidjson::Value(playerId, alloc).Move(), alloc); + msg.setPayload(std::move(payload)); + + connectionManager->blockingSend(msg); + } else { + auto aplOptions = config->getAplOptions(); + aplOptions->logMessage(LogLevel::WARN, __func__, "ConnectionManager does not exist. Can't create AudioPlayer."); + return nullptr; + } + + return std::make_shared( + aplCoreConnectionManager, + config, + playerId, + std::move(playerCallback), + std::move(speechMarkCallback)); +} + +AplCoreAudioPlayer::AplCoreAudioPlayer( + AplCoreConnectionManagerWPtr aplCoreConnectionManager, + AplConfigurationPtr config, + const std::string& playerId, + apl::AudioPlayerCallback&& playerCallback, + apl::SpeechMarkCallback&& speechMarkCallback) : + apl::AudioPlayer(std::move(playerCallback), std::move(speechMarkCallback)), + m_aplCoreConnectionManager{aplCoreConnectionManager}, + m_aplConfiguration{config}, + m_playerId{playerId} { +} + +void +AplCoreAudioPlayer::sendAudioPlayerCommand(const std::string& command, std::string optionalUrl) { + if (auto connectionManager = m_aplCoreConnectionManager.lock()) { + auto msg = AplCoreViewhostMessage(command); + auto& alloc = msg.alloc(); + + auto aplCoreMetrics = connectionManager->aplCoreMetrics(); + + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("playerId", rapidjson::Value(m_playerId.c_str(), alloc).Move(), alloc); + if (!optionalUrl.empty()) { + payload.AddMember("url", rapidjson::Value(optionalUrl.c_str(), alloc).Move(), alloc); + } + msg.setPayload(std::move(payload)); + + connectionManager->send(msg); + } else { + auto aplOptions = m_aplConfiguration->getAplOptions(); + aplOptions->logMessage(LogLevel::WARN, __func__, "ConnectionManager does not exist. Can't send AudioPlayer command."); + } +} + +void +AplCoreAudioPlayer::resolveExistingAction() +{ + m_Playing = false; + if (!m_PlayRef.empty() && m_PlayRef.isPending()) { + m_PlayRef.resolve(); + } + m_PlayRef = apl::ActionRef(nullptr); +} + +void +AplCoreAudioPlayer::release() { + sendAudioPlayerCommand("audioPlayerRelease"); + resolveExistingAction(); +} + +void +AplCoreAudioPlayer::setTrack(apl::MediaTrack track) { + sendAudioPlayerCommand("audioPlayerSetTrack", track.url); +} + +void +AplCoreAudioPlayer::play(apl::ActionRef actionRef) { + resolveExistingAction(); + + m_PlayRef = actionRef; + + if (m_Prepared) { + sendAudioPlayerCommand("audioPlayerPlay"); + } +} + +void +AplCoreAudioPlayer::pause() { + sendAudioPlayerCommand("audioPlayerPause"); + resolveExistingAction(); +} + +void +AplCoreAudioPlayer::onEventInternal(apl::AudioPlayerEventType eventType, const apl::AudioState& audioState, int currentTime) { + switch (eventType) { + case apl::kAudioPlayerEventEnd: + case apl::kAudioPlayerEventFail: + resolveExistingAction(); + break; + case apl::kAudioPlayerEventReady: + m_Prepared = true; + if (!m_PlayRef.empty()) { + // Requested playback before prepared. Do now. + sendAudioPlayerCommand("audioPlayerPlay"); + } + break; + case apl::kAudioPlayerEventPlay: + m_Playing = true; + m_PlaybackStartTime = currentTime; + break; + case apl::kAudioPlayerEventTimeUpdate: + if (!m_Playing) return; + break; + default: + break; + } + + mPlayerCallback(eventType, audioState); +} + +void +AplCoreAudioPlayer::onEvent(const rapidjson::Value& payload) { + auto aplOptions = m_aplConfiguration->getAplOptions(); + auto connectionManager = m_aplCoreConnectionManager.lock(); + + if (!connectionManager) { + aplOptions->logMessage(LogLevel::WARN, __func__, "ConnectionManager does not exist."); + return; + } + + auto currentTime = static_cast(connectionManager->getCurrentTime().count()); + auto eventType = static_cast(payload["eventType"].GetInt()); + auto audioState = apl::AudioState( + m_Playing ? currentTime - m_PlaybackStartTime : 0, + payload["duration"].GetDouble(), + payload["paused"].GetBool(), + payload["ended"].GetBool(), + static_cast(payload["trackState"].GetDouble()) + ); + + onEventInternal(eventType, audioState, currentTime); +} + +static const std::map sSpeechTypes = { + {"word", apl::SpeechMarkType::kSpeechMarkWord}, + {"viseme", apl::SpeechMarkType::kSpeechMarkViseme}, + {"sentence", apl::SpeechMarkType::kSpeechMarkSentence}, + {"ssml", apl::SpeechMarkType::kSpeechMarkSSML} +}; + +void +AplCoreAudioPlayer::onSpeechMarks(const rapidjson::Value& payload) { + if (!mSpeechMarkCallback) return; + + auto marks = std::vector(); + for (auto itr = payload["markers"].Begin(); itr != payload["markers"].End(); ++itr) { + auto type = sSpeechTypes.at((*itr)["type"].GetString()); + apl::SpeechMark mark = { + .type = type, + .start = 0, + .end = 0, + .time = static_cast((*itr)["time"].GetDouble()), + .value = (*itr)["value"].GetString() + }; + + if (type == apl::kSpeechMarkWord) { + mark.start = (*itr)["start"].GetDouble(); + mark.end = (*itr)["end"].GetDouble(); + } + marks.emplace_back(mark); + } + + mSpeechMarkCallback(marks); +} + +void +AplCoreAudioPlayer::tick(const AplCoreConnectionManager& connectionManager) { + if (m_Playing) { + auto state = apl::AudioState(connectionManager.getCurrentTime().count() - m_PlaybackStartTime, 0, false, false, apl::kTrackReady); + onEventInternal(apl::kAudioPlayerEventTimeUpdate, state, connectionManager.getCurrentTime().count()); + } +} + +} // namespace APLClient diff --git a/APLClient/src/AplCoreAudioPlayerFactory.cpp b/APLClient/src/AplCoreAudioPlayerFactory.cpp new file mode 100644 index 0000000..aa3b330 --- /dev/null +++ b/APLClient/src/AplCoreAudioPlayerFactory.cpp @@ -0,0 +1,65 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "APLClient/AplCoreViewhostMessage.h" +#include "APLClient/AplCoreAudioPlayerFactory.h" +#include "APLClient/AplCoreAudioPlayer.h" + +namespace APLClient { + +AplCoreAudioPlayerFactory::AplCoreAudioPlayerFactory( + AplCoreConnectionManagerPtr aplCoreConnectionManager, + AplConfigurationPtr config) : + m_aplCoreConnectionManager{aplCoreConnectionManager}, + m_aplConfiguration{config} { +} + +AplCoreAudioPlayerFactoryPtr +AplCoreAudioPlayerFactory::create(AplCoreConnectionManagerPtr aplCoreConnectionManager, AplConfigurationPtr config) { + return std::make_shared(aplCoreConnectionManager, config); +} + +apl::AudioPlayerPtr +AplCoreAudioPlayerFactory::createPlayer(apl::AudioPlayerCallback playerCallback, + apl::SpeechMarkCallback speechMarkCallback) { + // Only one player really supported + std::string id = "WEB_PLAYER_ADAPTER"; + m_Players[id] = AplCoreAudioPlayer::create( + m_aplCoreConnectionManager, + m_aplConfiguration, + id, + std::move(playerCallback), + std::move(speechMarkCallback)); + return m_Players[id]; +} + +AplCoreAudioPlayerPtr +AplCoreAudioPlayerFactory::getPlayer(const std::string& playerId) const { + auto player = m_Players.find(playerId); + if (player == m_Players.end()) { + return nullptr; + } + return player->second; +} + +void +AplCoreAudioPlayerFactory::tick(const AplCoreConnectionManager& connectionManager) { + for (auto& player : m_Players) { + player.second->tick(connectionManager); + } +} + + +} // namespace APLClient diff --git a/APLClient/src/AplCoreConnectionManager.cpp b/APLClient/src/AplCoreConnectionManager.cpp index aba6823..eaafa88 100644 --- a/APLClient/src/AplCoreConnectionManager.cpp +++ b/APLClient/src/AplCoreConnectionManager.cpp @@ -19,10 +19,13 @@ #include "APLClient/AplCoreLocaleMethods.h" #include "APLClient/AplCoreConnectionManager.h" #include "APLClient/AplCoreViewhostMessage.h" +#include "APLClient/AplCoreAudioPlayerFactory.h" +#include "APLClient/AplCoreMediaPlayerFactory.h" #include #include #include +#include namespace APLClient { @@ -179,6 +182,10 @@ AplCoreConnectionManager::AplCoreConnectionManager(AplConfigurationPtr config) : m_messageHandlers.emplace("extension", [this](const rapidjson::Value& payload) { handleExtensionMessage(payload); }); m_messageHandlers.emplace("mediaLoaded", [this](const rapidjson::Value& payload) { mediaLoaded(payload); }); m_messageHandlers.emplace("mediaLoadFailed", [this](const rapidjson::Value& payload) { mediaLoadFailed(payload); }); + m_messageHandlers.emplace("audioPlayerCallback", [this](const rapidjson::Value& payload) { audioPlayerCallback(payload); }); + m_messageHandlers.emplace("speechMarkCallback", [this](const rapidjson::Value& payload) { audioPlayerSpeechMarks(payload); }); + m_messageHandlers.emplace("mediaPlayerUpdateMediaState", [this](const rapidjson::Value& payload) { mediaPlayerUpdateMediaState(payload); }); + m_messageHandlers.emplace("mediaPlayerDoCallback", [this](const rapidjson::Value& payload) { mediaPlayerDoCallback(payload); }); } void AplCoreConnectionManager::setContent(const apl::ContentPtr content, const std::string& token) { @@ -759,7 +766,9 @@ void AplCoreConnectionManager::handleBuild(const rapidjson::Value& message) { .enforceAPLVersion(apl::APLVersion::kAPLVersionIgnore) .sequenceChildCache(5) .enableExperimentalFeature(apl::RootConfig::ExperimentalFeature::kExperimentalFeatureManageMediaRequests) - .set(apl::RootProperty::kDefaultIdleTimeout, -1); + .set(apl::RootProperty::kDefaultIdleTimeout, -1) + .audioPlayerFactory(AplCoreAudioPlayerFactory::create(shared_from_this(), m_aplConfiguration)) + .mediaPlayerFactory(AplCoreMediaPlayerFactory::create(shared_from_this(), m_aplConfiguration)); // Data Sources config.dataSourceProvider( @@ -1210,6 +1219,12 @@ void AplCoreConnectionManager::getFocused(const rapidjson::Value& payload) { } void AplCoreConnectionManager::setFocus(const rapidjson::Value& payload) { + auto aplOptions = m_aplConfiguration->getAplOptions(); + if (!m_Root) { + aplOptions->logMessage(LogLevel::ERROR, "setFocusFailed", "Root context is null"); + return; + } + auto direction = payload["direction"].GetInt(); auto top = payload["origin"].FindMember("top")->value.Get(); auto left = payload["origin"].FindMember("left")->value.Get(); @@ -1245,6 +1260,68 @@ void AplCoreConnectionManager::mediaLoadFailed(const rapidjson::Value& payload) m_Root->mediaLoadFailed(source, errorCode, error); } +void AplCoreConnectionManager::audioPlayerCallback(const rapidjson::Value& payload) { + auto aplOptions = m_aplConfiguration->getAplOptions(); + + if (!m_Root) { + aplOptions->logMessage(LogLevel::ERROR, "AplCoreConnectionManager::audioPlayerCallback", "Root context is null"); + return; + } + + auto audioFactory = std::dynamic_pointer_cast(m_Root->getRootConfig().getAudioPlayerFactory()); + + auto playerId = payload["playerId"].GetString(); + auto player = audioFactory->getPlayer(playerId); + + if (player) player->onEvent(payload); +} + +void AplCoreConnectionManager::audioPlayerSpeechMarks(const rapidjson::Value& payload) { + auto aplOptions = m_aplConfiguration->getAplOptions(); + + if (!m_Root) { + aplOptions->logMessage(LogLevel::ERROR, "AplCoreConnectionManager::audioPlayerCallback", "Root context is null"); + return; + } + + auto audioFactory = std::dynamic_pointer_cast(m_Root->getRootConfig().getAudioPlayerFactory()); + + auto playerId = payload["playerId"].GetString(); + auto player = audioFactory->getPlayer(playerId); + + if (player) player->onSpeechMarks(payload); +} + +void AplCoreConnectionManager::mediaPlayerUpdateMediaState(const rapidjson::Value& payload) { + auto aplOptions = m_aplConfiguration->getAplOptions(); + + if (!m_Root) { + aplOptions->logMessage(LogLevel::ERROR, "AplCoreConnectionManager::mediaPlayerUpdateMediaState", "Root context is null"); + return; + } + + auto mediaPlayerFactory = std::dynamic_pointer_cast(m_Root->getRootConfig().getMediaPlayerFactory()); + + auto playerId = payload["playerId"].GetString(); + auto mediaPlayer = mediaPlayerFactory->getMediaPlayer(playerId); + if (mediaPlayer) mediaPlayer->updateMediaState(payload); +} + +void AplCoreConnectionManager::mediaPlayerDoCallback(const rapidjson::Value& payload) { + auto aplOptions = m_aplConfiguration->getAplOptions(); + + if (!m_Root) { + aplOptions->logMessage(LogLevel::ERROR, "AplCoreConnectionManager::mediaPlayerDoCallback", "Root context is null"); + return; + } + + auto mediaPlayerFactory = std::dynamic_pointer_cast(m_Root->getRootConfig().getMediaPlayerFactory()); + + auto playerId = payload["playerId"].GetString(); + auto mediaPlayer = mediaPlayerFactory->getMediaPlayer(playerId); + if (mediaPlayer) mediaPlayer->doCallback(payload); +} + void AplCoreConnectionManager::handleUpdateCursorPosition(const rapidjson::Value& payload) { auto aplOptions = m_aplConfiguration->getAplOptions(); @@ -1354,6 +1431,10 @@ void AplCoreConnectionManager::sendError(const std::string& message) { void AplCoreConnectionManager::handleScreenLock() { auto aplOptions = m_aplConfiguration->getAplOptions(); + if (!m_Root) { + aplOptions->logMessage(LogLevel::ERROR, "handleScreenLockFailed", "Root context is null"); + return; + } if (m_Root->screenLock() && !m_ScreenLock) { aplOptions->onActivityStarted(m_aplToken, APL_SCREEN_LOCK); @@ -1584,9 +1665,14 @@ void AplCoreConnectionManager::processDirty(const std::set& d void AplCoreConnectionManager::coreFrameUpdate() { auto aplOptions = m_aplConfiguration->getAplOptions(); + if (!m_Root) { + aplOptions->logMessage(LogLevel::ERROR, "coreFrameUpdateFailed", "Root context is null"); + return; + } auto now = getCurrentTime() - m_StartTime; m_Root->updateTime(now.count(), getCurrentTime().count()); m_Root->setLocalTimeAdjustment(aplOptions->getTimezoneOffset().count()); + std::dynamic_pointer_cast(m_Root->getRootConfig().getAudioPlayerFactory())->tick(*this); m_Root->clearPending(); diff --git a/APLClient/src/AplCoreMediaPlayer.cpp b/APLClient/src/AplCoreMediaPlayer.cpp new file mode 100644 index 0000000..e694aba --- /dev/null +++ b/APLClient/src/AplCoreMediaPlayer.cpp @@ -0,0 +1,287 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#include "APLClient/AplCoreViewhostMessage.h" +#include "APLClient/AplCoreMediaPlayer.h" + +namespace APLClient { + +std::shared_ptr +AplCoreMediaPlayer::create(AplCoreConnectionManagerWPtr aplCoreConnectionManager, + AplConfigurationPtr config, + const std::string& playerId, + apl::MediaPlayerCallback&& playerCallback) { + auto player = std::make_shared(aplCoreConnectionManager, config, playerId, std::move(playerCallback)); + return player; +} + +AplCoreMediaPlayer::AplCoreMediaPlayer(AplCoreConnectionManagerWPtr aplCoreConnectionManager, + AplConfigurationPtr config, + const std::string& playerId, + apl::MediaPlayerCallback&& playerCallback) + : apl::MediaPlayer(std::move(playerCallback)), + m_aplCoreConnectionManager(aplCoreConnectionManager), + m_aplConfiguration(config), + m_playerId(playerId) +{ + if (auto connectionManager = m_aplCoreConnectionManager.lock()) { + auto msg = AplCoreViewhostMessage("mediaPlayerCreate"); + auto& alloc = msg.alloc(); + + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("playerId", rapidjson::Value(m_playerId.c_str(), alloc).Move(), alloc); + msg.setPayload(std::move(payload)); + + connectionManager->blockingSend(msg); + } else { + auto aplOptions = m_aplConfiguration->getAplOptions(); + aplOptions->logMessage(LogLevel::WARN, __func__, "ConnectionManager does not exist. Can't send mediaPlayerCreate"); + } +} + +void +AplCoreMediaPlayer::resolveExistingAction() +{ + if (!m_actionRef.empty() && m_actionRef.isPending()) { + m_actionRef.resolve(); + } + m_actionRef = apl::ActionRef(nullptr); +} + +void +AplCoreMediaPlayer::sendMediaPlayerCommand(const std::string& command, rapidjson::Value&& payload) +{ + if (auto connectionManager = m_aplCoreConnectionManager.lock()) { + auto msg = AplCoreViewhostMessage(command); + auto& alloc = msg.alloc(); + + payload.AddMember("playerId", rapidjson::Value(m_playerId.c_str(), alloc).Move(), alloc); + msg.setPayload(std::move(payload)); + + connectionManager->send(msg); + } else { + auto aplOptions = m_aplConfiguration->getAplOptions(); + aplOptions->logMessage(LogLevel::WARN, __func__, "ConnectionManager does not exist. Can't send command: " + command); + } +} + +void +AplCoreMediaPlayer::release() +{ + resolveExistingAction(); + m_released = true; +} + +void +AplCoreMediaPlayer::halt() +{ + if (!isActive()) return; + resolveExistingAction(); + + m_halted = true; + sendMediaPlayerCommand("mediaPlayerStop", rapidjson::Value(rapidjson::kObjectType)); +} + +void +AplCoreMediaPlayer::setTrackList(std::vector tracks) +{ + if (!isActive()) return; + resolveExistingAction(); + + rapidjson::MemoryPoolAllocator alloc; + rapidjson::Value payload(rapidjson::kObjectType); + rapidjson::Value trackArray(rapidjson::kArrayType); + + for (auto& track : tracks) { + rapidjson::Value trackObj(rapidjson::kObjectType); + trackObj.AddMember("url", track.url, alloc); + trackObj.AddMember("offset", track.offset, alloc); + trackObj.AddMember("duration", track.duration, alloc); + trackObj.AddMember("repeatCount", track.repeatCount, alloc); + + trackArray.PushBack(trackObj, alloc); + } + + payload.AddMember("trackArray", trackArray, alloc); + sendMediaPlayerCommand("mediaPlayerSetTrackList", std::move(payload)); +} + +void +AplCoreMediaPlayer::play(apl::ActionRef actionRef) +{ + bool waitForFinish = false; + + if (!isActive()) { + if (!actionRef.empty()) actionRef.resolve(); + return; + } + + resolveExistingAction(); + + if (!actionRef.empty()) { + // Only hold onto the ActionRef in foreground mode + if (m_audioTrack == apl::kAudioTrackForeground) { + m_actionRef = actionRef; + waitForFinish = true; + + // On a termination we need to discard the action reference or there is a memory cycle + m_actionRef.addTerminateCallback( + [&](const apl::TimersPtr&) { m_actionRef = apl::ActionRef(nullptr); }); + } else { + actionRef.resolve(); + } + } + + rapidjson::MemoryPoolAllocator alloc; + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("waitForFinish", waitForFinish, alloc); + sendMediaPlayerCommand("mediaPlayerPlay", std::move(payload)); +} + +void +AplCoreMediaPlayer::pause() +{ + if (!isActive()) return; + resolveExistingAction(); + + sendMediaPlayerCommand("mediaPlayerPause", rapidjson::Value(rapidjson::kObjectType)); +} + +void +AplCoreMediaPlayer::next() +{ + if (!isActive()) return; + resolveExistingAction(); + + sendMediaPlayerCommand("mediaPlayerNext", rapidjson::Value(rapidjson::kObjectType)); +} + +void +AplCoreMediaPlayer::previous() +{ + if (!isActive()) return; + resolveExistingAction(); + + sendMediaPlayerCommand("mediaPlayerPrevious", rapidjson::Value(rapidjson::kObjectType)); +} + +void +AplCoreMediaPlayer::rewind() +{ + if (!isActive()) return; + resolveExistingAction(); + + sendMediaPlayerCommand("mediaPlayerRewind", rapidjson::Value(rapidjson::kObjectType)); +} + +void +AplCoreMediaPlayer::seek(int offset) +{ + if (!isActive()) return; + resolveExistingAction(); + + rapidjson::MemoryPoolAllocator alloc; + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("offset", offset, alloc); + sendMediaPlayerCommand("mediaPlayerSeek", std::move(payload)); +} + +void +AplCoreMediaPlayer::setTrackIndex(int trackIndex) +{ + if (!isActive()) return; + resolveExistingAction(); + + rapidjson::MemoryPoolAllocator alloc; + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("trackIndex", trackIndex, alloc); + sendMediaPlayerCommand("mediaPlayerSetTrackIndex", std::move(payload)); +} + +void +AplCoreMediaPlayer::setAudioTrack(apl::AudioTrack audioTrack) +{ + if (!isActive()) return; + + m_audioTrack = audioTrack; + + rapidjson::MemoryPoolAllocator alloc; + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("audioTrack", static_cast(m_audioTrack), alloc); + sendMediaPlayerCommand("mediaPlayerSetAudioTrack", std::move(payload)); +} + +void +AplCoreMediaPlayer::setMute(bool mute) +{ + rapidjson::MemoryPoolAllocator alloc; + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("mute", mute, alloc); + sendMediaPlayerCommand("mediaPlayerSetMute", std::move(payload)); +} + +bool +AplCoreMediaPlayer::isActive() const +{ + return !m_released && !m_halted; +} + +void +AplCoreMediaPlayer::updateMediaState(const rapidjson::Value& payload) +{ + bool mutedValue = false; + auto muted = payload["mediaState"].FindMember("muted"); + if (muted != payload["mediaState"].MemberEnd()) { + mutedValue = muted->value.Get(); + } + + apl::MediaState mediaState(payload["mediaState"].FindMember("trackIndex")->value.Get(), + payload["mediaState"].FindMember("trackCount")->value.Get(), + payload["mediaState"].FindMember("currentTime")->value.Get(), + payload["mediaState"].FindMember("duration")->value.Get(), + payload["mediaState"].FindMember("paused")->value.Get(), + payload["mediaState"].FindMember("ended")->value.Get(), + mutedValue); + + auto trackState = payload["mediaState"].FindMember("trackState"); + if (trackState != payload["mediaState"].MemberEnd()) { + mediaState.withTrackState(static_cast(trackState->value.Get())); + } + + m_mediaState = mediaState; +} + +void +AplCoreMediaPlayer::doCallback(const rapidjson::Value& payload) +{ + if (!isActive()) return; + + auto eventType = static_cast(payload["eventType"].GetInt()); + if (eventType == apl::MediaPlayerEventType::kMediaPlayerEventEnd) { + resolveExistingAction(); + } + auto callback = mCallback; + callback(eventType, m_mediaState); +} + +rapidjson::Value +AplCoreMediaPlayer::serialize(rapidjson::Document::AllocatorType& allocator) const +{ + rapidjson::Value mediaPlayer(rapidjson::kObjectType); + mediaPlayer.AddMember("mediaPlayerId", rapidjson::Value(m_playerId.c_str(), allocator).Move(), allocator); + return mediaPlayer; +} + +} // namespace APLClient diff --git a/APLClient/src/AplCoreMediaPlayerFactory.cpp b/APLClient/src/AplCoreMediaPlayerFactory.cpp new file mode 100644 index 0000000..2a15bc4 --- /dev/null +++ b/APLClient/src/AplCoreMediaPlayerFactory.cpp @@ -0,0 +1,107 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreorder" +#pragma push_macro("DEBUG") +#pragma push_macro("TRUE") +#pragma push_macro("FALSE") +#undef DEBUG +#undef TRUE +#undef FALSE +#include +#pragma pop_macro("DEBUG") +#pragma pop_macro("TRUE") +#pragma pop_macro("FALSE") +#pragma GCC diagnostic pop + +#include "APLClient/AplCoreViewhostMessage.h" +#include "APLClient/AplCoreMediaPlayerFactory.h" +#include "APLClient/AplCoreMediaPlayer.h" + +namespace APLClient { + +AplCoreMediaPlayerFactory::AplCoreMediaPlayerFactory(AplCoreConnectionManagerWPtr aplCoreConnectionManager, AplConfigurationPtr config) + : m_aplCoreConnectionManager(aplCoreConnectionManager), m_aplConfiguration(config) {} + +std::shared_ptr +AplCoreMediaPlayerFactory::create(AplCoreConnectionManagerWPtr aplCoreConnectionManager, AplConfigurationPtr config) +{ + return std::make_shared(aplCoreConnectionManager, config); +} + +AplCoreMediaPlayerPtr +AplCoreMediaPlayerFactory::getMediaPlayer(const std::string& playerId) const +{ + auto mediaPlayer = m_activePlayers.find(playerId); + if (mediaPlayer == m_activePlayers.end()) { + return nullptr; + } else { + return mediaPlayer->second.lock(); + } +} + +apl::MediaPlayerPtr +AplCoreMediaPlayerFactory::createPlayer(apl::MediaPlayerCallback callback) +{ + cleanup(); + + static unsigned int id = 0; + std::string playerId = std::to_string(++id); + auto mediaPlayer = AplCoreMediaPlayer::create( + m_aplCoreConnectionManager, + m_aplConfiguration, + playerId, + std::move(callback) + ); + + m_activePlayers.emplace(playerId, mediaPlayer); + + return mediaPlayer; +} + +void +AplCoreMediaPlayerFactory::cleanup() +{ + for (auto it = m_activePlayers.begin(); it != m_activePlayers.end(); ) { + if (!it->second.lock()) { + // weak pointer is no longer valid, prune it from the array + it = m_activePlayers.erase(it); + sendMediaPlayerDelete(it->first); + } else { + it++; + } + } +} + +void +AplCoreMediaPlayerFactory::sendMediaPlayerDelete(const std::string& mediaPlayerId) +{ + if (auto connectionManager = m_aplCoreConnectionManager.lock()) { + auto msg = AplCoreViewhostMessage("mediaPlayerDelete"); + auto& alloc = msg.alloc(); + + rapidjson::Value payload(rapidjson::kObjectType); + payload.AddMember("playerId", rapidjson::Value(mediaPlayerId.c_str(), alloc).Move(), alloc); + msg.setPayload(std::move(payload)); + + connectionManager->send(msg); + } else { + auto aplOptions = m_aplConfiguration->getAplOptions(); + aplOptions->logMessage(LogLevel::WARN, __func__, "ConnectionManager does not exist. Can't send mediaPlayerDelete"); + } +} + +} // namespace APLClient diff --git a/APLClient/src/CMakeLists.txt b/APLClient/src/CMakeLists.txt index 15a9b0e..f20b8f7 100644 --- a/APLClient/src/CMakeLists.txt +++ b/APLClient/src/CMakeLists.txt @@ -3,6 +3,10 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) add_library(APLClient SHARED AplClientBinding.cpp AplConfiguration.cpp +AplCoreAudioPlayer.cpp +AplCoreAudioPlayerFactory.cpp +AplCoreMediaPlayer.cpp +AplCoreMediaPlayerFactory.cpp Extensions/AplCoreExtensionManager.cpp Extensions/AttentionSystem/AplAttentionSystemExtension.cpp Extensions/AudioPlayer/AplAudioPlayerExtension.cpp @@ -20,35 +24,29 @@ AplCoreTextMeasurement.cpp AplCoreLocaleMethods.cpp AplClientRenderer.cpp) -if(NOT APLCORE_RAPIDJSON_INCLUDE_DIR) - message(FATAL_ERROR "APLCORE_RAPIDJSON_INCLUDE_DIR is required to build APLClientLibrary") -endif() - -target_include_directories(APLClient PUBLIC -"${APLCORE_RAPIDJSON_INCLUDE_DIR}" -"${APLClient_SOURCE_DIR}/include") +target_include_directories(APLClient PUBLIC "${APLClient_SOURCE_DIR}/include") if(NOT APLCORE_INCLUDE_DIR) - message(FATAL_ERROR "APLCore Include Dir is required") + message(FATAL_ERROR "APLCore include dir is required") endif() -if(NOT APLCORE_BUILD_INCLUDE_DIR) - message(FATAL_ERROR "APLCore Build Include Dir is required") +if(NOT APLCORE_EXPORTS_INCLUDE_DIR) + message(FATAL_ERROR "APLCore exports include dir is required") endif() -if(NOT APLCORE_LIB_DIR) - message(FATAL_ERROR "APLCore Lib Dir is required") +if(NOT APLCORE_EXPORTS_LIB_DIR) + message(FATAL_ERROR "APLCore exports lib dir is required") endif() if(APL_CORE) if (NOT MSVC) target_include_directories(APLClient PUBLIC "${APLCORE_INCLUDE_DIR}" - "${APLCORE_BUILD_INCLUDE_DIR}" + "${APLCORE_EXPORTS_INCLUDE_DIR}" "${YOGA_INCLUDE_DIR}") - target_link_libraries(APLClient ${APLCORE_LIB_DIR}/libapl.a) - target_link_libraries(APLClient ${YOGA_LIB_DIR}/libyogacore.a) + target_link_libraries(APLClient ${APLCORE_EXPORTS_LIB_DIR}/libapl.a) + target_link_libraries(APLClient ${APLCORE_EXPORTS_LIB_DIR}/libyogacore.a) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error -Wno-reorder -fPIC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error -Wno-reorder -fPIC") @@ -56,11 +54,11 @@ if(APL_CORE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive- /GS /TP /W3 /Zc:wchar_t /DAPL_CORE_UWP /Zc:inline /Zc:twoPhase- /fp:precise /DWIN32_LEAN_AND_MEAN /DNOGDI /DWIN32 /D_WINDOWS") target_include_directories(APLClient PUBLIC "${APLCORE_INCLUDE_DIR}" - "${APLCORE_BUILD_INCLUDE_DIR}" + "${APLCORE_EXPORTS_INCLUDE_DIR}" "${YOGA_INCLUDE_DIR}") - target_link_libraries(APLClient ${APLCORE_LIB_DIR}/apl.lib) - target_link_libraries(APLClient ${YOGA_LIB_DIR}/yogacore.lib) + target_link_libraries(APLClient ${APLCORE_EXPORTS_LIB_DIR}/apl.lib) + target_link_libraries(APLClient ${APLCORE_EXPORTS_LIB_DIR}/yogacore.lib) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") @@ -72,6 +70,6 @@ endif() if (CMAKE_INSTALL_PREFIX) install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/" DESTINATION "${CMAKE_INSTALL_PREFIX}/include") install(DIRECTORY "${APLCORE_INCLUDE_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/include") - install(DIRECTORY "${APLCORE_BUILD_INCLUDE_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/include") + install(DIRECTORY "${APLCORE_EXPORTS_INCLUDE_DIR}/" DESTINATION "${CMAKE_INSTALL_PREFIX}/include") install(TARGETS APLClient DESTINATION "${CMAKE_INSTALL_PREFIX}/lib") endif() diff --git a/APLClient/test/AplCoreConnectionManagerTest.cpp b/APLClient/test/AplCoreConnectionManagerTest.cpp index 563a475..52305fc 100644 --- a/APLClient/test/AplCoreConnectionManagerTest.cpp +++ b/APLClient/test/AplCoreConnectionManagerTest.cpp @@ -668,6 +668,12 @@ TEST_F(AplCoreConnectionManagerTest, HandleUpdateMediaSuccess) { m_aplCoreConnectionManager->handleMessage(payload); } +// Matcher for message been send out. Test Match against messaage type and expected payload. +MATCHER_P2(MatchStartMessage, type, expectedPayload, "") { + const std::string messageType = type; + return arg.find(messageType) != std::string::npos && arg.find(expectedPayload) != std::string::npos; +} + /** * Tests HandleMessage function with updateGraphic type. */ @@ -689,12 +695,13 @@ TEST_F(AplCoreConnectionManagerTest, HandleGraphicUpdateSuccess) { const std::string messageType = "\"type\":\"dirty\""; const std::string dirtyPayload = "\"graphic\":{" + "\"id\":\":1005\"," "\"isValid\":true," "\"intrinsicWidth\":100.0," "\"intrinsicHeight\":100.0," "\"viewportWidth\":100.0," "\"viewportHeight\":100.0," - "\"root\":{\"id\":1000,\"type\":0," + "\"root\":{\"id\":\":1006\",\"type\":0," "\"props\":{" "\"height_actual\":100.0," "\"lang\":\"\"," @@ -704,9 +711,11 @@ TEST_F(AplCoreConnectionManagerTest, HandleGraphicUpdateSuccess) { "\"width_actual\":100.0}," "\"children\":[]}," "\"dirty\":[]}," - "\"mediaBounds\":[-25.0,-25.0,100.0,100.0]"; - EXPECT_CALL(*m_mockAplOptions, sendMessage(_, MatchOutMessage(messageType, dirtyPayload))).Times(1); + "\"mediaBounds\":[-25.0,-25.0,100.0,100.0]," + "\"_visualHash\":\"6554049692613872770\"}]}"; m_aplCoreConnectionManager->onUpdateTick(); + // Matcher unable to process IDs and hashes, relies on full equality, which does not really work with IDed elements. + // EXPECT_CALL(*m_mockAplOptions, sendMessage(_, MatchOutMessage(messageType, dirtyPayload))).Times(1); } /** diff --git a/APLClientSandbox/GUI/script.js b/APLClientSandbox/GUI/script.js index a2795e8..1e2025d 100644 --- a/APLClientSandbox/GUI/script.js +++ b/APLClientSandbox/GUI/script.js @@ -36,8 +36,8 @@ class WebsocketConnection { }; this.socket.onmessage = function(event) { - self.callback(JSON.parse(event.data)); console.debug(`[Websocket] Data received from server: ${event.data}`); + self.callback(JSON.parse(event.data)); }; this.socket.onclose = function(event) { diff --git a/APLClientSandbox/GUI/tts/orwell.mp3 b/APLClientSandbox/GUI/tts/orwell.mp3 new file mode 100644 index 0000000..19e6241 Binary files /dev/null and b/APLClientSandbox/GUI/tts/orwell.mp3 differ diff --git a/CHANGELOG.md b/CHANGELOG.md index e013584..5793202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog for apl-client-library +## [2022.2] +This release adds support for version 2022.2 of the APL specification. Please also see APL Core Library for changes: [apl-core-library CHANGELOG](https://github.com/alexa/apl-core-library/blob/master/CHANGELOG.md) + +### Added +- Support continued command execution during APL document re-inflation + +### Changed +- Bug fixes + ## [2022.1.1] ### Changed diff --git a/README.md b/README.md index 538d3d8..b386678 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # Alexa Presentation Language (APL) Client Library

- - - - + + + +

## Introduction @@ -33,20 +33,23 @@ The APL Client Library depends on the following additional GitHub repos: 1. Clone the necessary repos in your working directory ``` + WORK_AREA=$(pwd) git clone https://github.com/alexa/apl-client-library.git git clone https://github.com/zaphoyd/websocketpp.git git clone git://github.com/alexa/apl-core-library.git ``` 1. Build apl-core ``` - cd apl-core-library + cd ${WORK_AREA}/apl-core-library source ./apl-dev-env.sh apl-build-core - cd .. + cd build + cmake -DBUILD_TESTS=OFF -DCOVERAGE=OFF -DENABLE_PIC=ON -DCMAKE_INSTALL_PREFIX=exports .. + make install ``` 1. Configure CMake in your working directory ``` - WORK_AREA=$(pwd) + cd ${WORK_AREA} mkdir build cd build ``` @@ -55,11 +58,9 @@ The APL Client Library depends on the following additional GitHub repos: -DWEBSOCKETPP_INCLUDE_DIR=${WORK_AREA}/websocketpp \ -DCMAKE_BUILD_TYPE=DEBUG \ -DAPLCORE_INCLUDE_DIR=${WORK_AREA}/apl-core-library/aplcore/include \ - -DAPLCORE_BUILD_INCLUDE_DIR=${WORK_AREA}/apl-core-library/build/aplcore/include \ + -DAPLCORE_EXPORTS_INCLUDE_DIR=${WORK_AREA}/apl-core-library/build/exports/include \ + -DAPLCORE_EXPORTS_LIB_DIR=${WORK_AREA}/apl-core-library/build/exports/lib \ -DYOGA_INCLUDE_DIR=${WORK_AREA}/apl-core-library/build/yoga-prefix/src/yoga \ - -DAPLCORE_RAPIDJSON_INCLUDE_DIR=${WORK_AREA}/apl-core-library/build/rapidjson-prefix/src/rapidjson/include/ \ - -DAPLCORE_LIB_DIR=${WORK_AREA}/apl-core-library/build/aplcore \ - -DYOGA_LIB_DIR=${WORK_AREA}/apl-core-library/build/lib \ -DAPLCORE_BUILD=${WORK_AREA}/apl-core-library/build \ -DAPL_CORE=ON \ -DBUILD_TESTING=OFF \ @@ -68,16 +69,16 @@ The APL Client Library depends on the following additional GitHub repos: ``` 1. Build apl-client ``` - make + make -j4 ``` 1. Run sandbox server ``` - cd $WORK_AREA/build/APLClientSandbox/src + cd ${WORK_AREA}/build/APLClientSandbox/src ./APLClientSandbox ``` 1. Open another terminal to run sandbox GUI ``` - cd $WORK_AREA/apl-client-library/APLClientSandbox/GUI + cd ${WORK_AREA}/apl-client-library/APLClientSandbox/GUI npm install npm start ``` diff --git a/apl-client-js/@types/apl-html/lib/APLRenderer.d.ts b/apl-client-js/@types/apl-html/lib/APLRenderer.d.ts index c7a12b4..5a586a2 100644 --- a/apl-client-js/@types/apl-html/lib/APLRenderer.d.ts +++ b/apl-client-js/@types/apl-html/lib/APLRenderer.d.ts @@ -3,7 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { AudioPlayerWrapper } from './AudioPlayerWrapper'; import { Component } from './components/Component'; import { MeasureMode } from './components/text/MeasureMode'; import { IVideoFactory } from './components/video/IVideoFactory'; @@ -11,7 +10,7 @@ import { AnimationQuality } from './enums/AnimationQuality'; import { DisplayState } from './enums/DisplayState'; import { IExtensionManager } from './extensions/IExtensionManager'; import { ILogger } from './logging/ILogger'; -import { AudioPlayerFactory } from './media/audio/AudioPlayer'; +import { AudioPlayerFactory } from './media/audio/AudioPlayerFactory'; /** * Device viewport mode */ @@ -160,7 +159,7 @@ export interface IAPLOptions { viewport: IViewportCharacteristics; /** Device mode. If no provided "HUB" is used. */ mode?: DeviceMode; - /** Optional externalized audio player */ + /** Optional externalized audio player factory */ audioPlayerFactory?: AudioPlayerFactory; /** Callback for executed SendEvent commands */ onSendEvent?: (event: ISendEvent) => void; @@ -221,10 +220,9 @@ export default abstract class APLRenderer { /** Document set flag for allowing config change driven resizing */ protected supportsResizing: boolean; private configurationChangeThrottle; + /** Display state change handler */ protected handleUpdateDisplayState: (displayState: DisplayState) => void; - private isEdge; readonly options: Options; - audioPlayer: AudioPlayerWrapper; /** * THis constructor is private * @param mOptions options passed in through `create` @@ -380,5 +378,4 @@ export default abstract class APLRenderer { private passWindowEventsToCore; private shouldPassWindowEventToCore(event, focusedComponentId); private ensureComponentIsFocused(id, code); - private destroyAudioPlayer(); } diff --git a/apl-client-js/@types/apl-html/lib/components/video/AbstractVideoComponent.d.ts b/apl-client-js/@types/apl-html/lib/components/video/AbstractVideoComponent.d.ts index eb82015..cd9267d 100644 --- a/apl-client-js/@types/apl-html/lib/components/video/AbstractVideoComponent.d.ts +++ b/apl-client-js/@types/apl-html/lib/components/video/AbstractVideoComponent.d.ts @@ -4,10 +4,8 @@ */ import APLRenderer from '../../APLRenderer'; import { AudioTrack } from '../../enums/AudioTrack'; -import { CommandControlMedia } from '../../enums/CommandControlMedia'; import { PropertyKey } from '../../enums/PropertyKey'; import { VideoScale } from '../../enums/VideoScale'; -import { IMediaEventListener } from '../../media/IMediaEventListener'; import { IMediaSource } from '../../media/IMediaSource'; import { PlaybackState } from '../../media/Resource'; import { Component, FactoryFunction, IComponentProperties } from '../Component'; @@ -26,30 +24,12 @@ export interface IVideoProperties extends IComponentProperties { /** * @ignore */ -export declare abstract class AbstractVideoComponent extends Component implements IMediaEventListener { +export declare abstract class AbstractVideoComponent extends Component { protected constructor(renderer: APLRenderer, component: APL.Component, factory: FactoryFunction, parent?: Component); abstract onEvent(event: PlaybackState): void; - abstract playMedia(source: IMediaSource | IMediaSource[], audioTrack: AudioTrack): any; - abstract controlMedia(operation: CommandControlMedia, optionalValue: number): any; abstract play(waitForFinish?: boolean): any; abstract pause(): any; - abstract next(): any; - abstract previous(): any; - abstract rewind(): any; - abstract seek(offset: number): any; - abstract setTrack(trackIndex: number): any; protected abstract setScale(scale: VideoScale): any; - protected abstract setAudioTrack(audioTrack: AudioTrack): any; - protected abstract setMuted(muted: boolean): any; - protected abstract setSource(source: IMediaSource | IMediaSource[]): any; - protected abstract setTrackCurrentTime(trackCurrentTime: number): any; - protected abstract setTrackIndex(trackIndex: number): any; protected setTrackPaused(isPaused: boolean): void; private setScaleFromProp; - private setAudioTrackFromProp; - private setMutedFromProp; - private setSourceFromProp; - private setTrackCurrentTimeFromProp; - private setTrackIndexFromProp; - private setPauseFromProp; } diff --git a/apl-client-js/@types/apl-html/lib/components/video/Video.d.ts b/apl-client-js/@types/apl-html/lib/components/video/Video.d.ts index d24536d..9bb10bc 100644 --- a/apl-client-js/@types/apl-html/lib/components/video/Video.d.ts +++ b/apl-client-js/@types/apl-html/lib/components/video/Video.d.ts @@ -3,40 +3,20 @@ * SPDX-License-Identifier: Apache-2.0 */ import APLRenderer from '../../APLRenderer'; -import { AudioTrack } from '../../enums/AudioTrack'; -import { CommandControlMedia } from '../../enums/CommandControlMedia'; import { VideoScale } from '../../enums/VideoScale'; -import { IMediaSource } from '../../media/IMediaSource'; import { PlaybackState } from '../../media/Resource'; import { Component, FactoryFunction } from '../Component'; import { AbstractVideoComponent } from './AbstractVideoComponent'; export declare class Video extends AbstractVideoComponent { private readonly videoEventProcessor; - private readonly videoEventSequencer; - private fromEvent; - private isSettingSource; + private mediaPlayerHandle; constructor(renderer: APLRenderer, component: APL.Component, factory: FactoryFunction, parent?: Component); - onEvent(event: PlaybackState): void; - playMedia(source: IMediaSource | IMediaSource[], audioTrack: AudioTrack): Promise; - controlMedia(operation: CommandControlMedia, optionalValue: number): Promise; - play(waitForFinish?: boolean): Promise; - pause(): Promise; - end(): Promise; - seek(offset: number): Promise; - rewind(): Promise; - previous(): Promise; - next(): Promise; - setTrack(trackIndex: number): Promise; - protected setAudioTrack(audioTrack: AudioTrack): void; - protected setMuted(muted: boolean): void; - protected setSource(source: IMediaSource | IMediaSource[]): Promise; - protected setTrackCurrentTime(trackCurrentTime: number): void; - protected setTrackIndex(trackIndex: number): void; + protected applyCssShadow: (shadowParams: string) => void; protected setScale(scale: VideoScale): void; - protected setTrackPaused(isPaused: boolean): void; - protected updateMediaState(): void; destroy(): void; - protected applyCssShadow: (shadowParams: string) => void; + play(waitForFinish?: boolean): Promise; + pause(): Promise; + onEvent(_event: PlaybackState): void; protected readonly player: any; protected readonly audioTrack: any; protected readonly playbackManager: any; diff --git a/apl-client-js/@types/apl-html/lib/components/video/VideoHolder.d.ts b/apl-client-js/@types/apl-html/lib/components/video/VideoHolder.d.ts index 1c032f8..24c1375 100644 --- a/apl-client-js/@types/apl-html/lib/components/video/VideoHolder.d.ts +++ b/apl-client-js/@types/apl-html/lib/components/video/VideoHolder.d.ts @@ -3,10 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ import APLRenderer from '../../APLRenderer'; -import { AudioTrack } from '../../enums/AudioTrack'; -import { CommandControlMedia } from '../../enums/CommandControlMedia'; import { VideoScale } from '../../enums/VideoScale'; -import { IMediaSource } from '../../media/IMediaSource'; import { PlaybackState } from '../../media/Resource'; import { Component, FactoryFunction } from '../Component'; import { AbstractVideoComponent } from './AbstractVideoComponent'; @@ -16,19 +13,7 @@ import { AbstractVideoComponent } from './AbstractVideoComponent'; export declare class VideoHolder extends AbstractVideoComponent { constructor(renderer: APLRenderer, component: APL.Component, factory: FactoryFunction, parent?: Component); onEvent(event: PlaybackState): void; - playMedia(source: IMediaSource | IMediaSource[], audioTrack: AudioTrack): Promise; - controlMedia(operation: CommandControlMedia, optionalValue: number): Promise; play(waitForFinish?: boolean): Promise; pause(): Promise; - next(): Promise; - previous(): Promise; - rewind(): Promise; - seek(offset: number): Promise; - setTrack(trackIndex: number): Promise; protected setScale(scale: VideoScale): void; - protected setAudioTrack(audioTrack: AudioTrack): void; - protected setMuted(muted: boolean): void; - protected setSource(source: IMediaSource | IMediaSource[]): void; - protected setTrackCurrentTime(trackCurrentTime: number): void; - protected setTrackIndex(trackIndex: number): void; } diff --git a/apl-client-js/@types/apl-html/lib/dts/AudioPlayer.d.ts b/apl-client-js/@types/apl-html/lib/dts/AudioPlayer.d.ts new file mode 100644 index 0000000..e75e127 --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/dts/AudioPlayer.d.ts @@ -0,0 +1,13 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +declare namespace APL { + export class AudioPlayer extends Deletable { + public onPrepared(id: string): void; + public onMarker(id: string, markers): void; + public onPlaybackStarted(id: string): void; + public onPlaybackFinished(id: string): void; + public onError(id: string, reason: string): void; + } +} diff --git a/apl-client-js/@types/apl-html/lib/dts/AudioPlayerFactory.d.ts b/apl-client-js/@types/apl-html/lib/dts/AudioPlayerFactory.d.ts new file mode 100644 index 0000000..0d93b57 --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/dts/AudioPlayerFactory.d.ts @@ -0,0 +1,10 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +declare namespace APL { + export class AudioPlayerFactory extends Deletable { + public static create(playerFactory): AudioPlayerFactory; + public tick(): void; + } +} diff --git a/apl-client-js/@types/apl-html/lib/dts/Component.d.ts b/apl-client-js/@types/apl-html/lib/dts/Component.d.ts index 0a8b7eb..c8dd4b2 100644 --- a/apl-client-js/@types/apl-html/lib/dts/Component.d.ts +++ b/apl-client-js/@types/apl-html/lib/dts/Component.d.ts @@ -36,5 +36,6 @@ declare namespace APL { public ensureLayout(): Promise | void; public isCharacterValid(c: string): Promise; public provenance(): string; + public getMediaPlayer(): APL.MediaPlayer; } } diff --git a/apl-client-js/@types/apl-html/lib/dts/MediaPlayer.d.ts b/apl-client-js/@types/apl-html/lib/dts/MediaPlayer.d.ts new file mode 100644 index 0000000..2d9152c --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/dts/MediaPlayer.d.ts @@ -0,0 +1,11 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +declare namespace APL { + export class MediaPlayer extends Deletable { + updateMediaState(mediaState: any): void; + doCallback(eventType: number): void; + getMediaPlayerHandle(): IMediaPlayerHandle; + } +} diff --git a/apl-client-js/@types/apl-html/lib/dts/MediaPlayerFactory.d.ts b/apl-client-js/@types/apl-html/lib/dts/MediaPlayerFactory.d.ts new file mode 100644 index 0000000..16f6dac --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/dts/MediaPlayerFactory.d.ts @@ -0,0 +1,9 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +declare namespace APL { + export class MediaPlayerFactory extends Deletable { + public static create(playerFactory): MediaPlayerFactory; + } +} diff --git a/apl-client-js/@types/apl-html/lib/dts/Module.d.ts b/apl-client-js/@types/apl-html/lib/dts/Module.d.ts index b30eff3..bcb41d0 100644 --- a/apl-client-js/@types/apl-html/lib/dts/Module.d.ts +++ b/apl-client-js/@types/apl-html/lib/dts/Module.d.ts @@ -2,6 +2,10 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ +/// +/// +/// +/// /// /// /// @@ -79,6 +83,10 @@ declare namespace APL { public Metrics: typeof Metrics; public LiveMap: typeof LiveMap; public LiveArray: typeof LiveArray; + public AudioPlayer: typeof AudioPlayer; + public AudioPlayerFactory: typeof AudioPlayerFactory; + public MediaPlayer: typeof MediaPlayer; + public MediaPlayerFactory: typeof MediaPlayerFactory; } } declare var Module: APL.Module; diff --git a/apl-client-js/@types/apl-html/lib/dts/RootConfig.d.ts b/apl-client-js/@types/apl-html/lib/dts/RootConfig.d.ts index e19a969..055fab3 100644 --- a/apl-client-js/@types/apl-html/lib/dts/RootConfig.d.ts +++ b/apl-client-js/@types/apl-html/lib/dts/RootConfig.d.ts @@ -15,5 +15,7 @@ declare namespace APL { public registerExtension(uri: string): RootConfig; public liveMap(name: string, obj: any): RootConfig; public liveArray(name: string, obj: any): RootConfig; + public audioPlayerFactory(factory: AudioPlayerFactory): RootConfig; + public mediaPlayerFactory(factory: MediaPlayerFactory): RootConfig; } } diff --git a/apl-client-js/@types/apl-html/lib/enums/AudioPlayerEventType.d.ts b/apl-client-js/@types/apl-html/lib/enums/AudioPlayerEventType.d.ts new file mode 100644 index 0000000..e93b6d1 --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/enums/AudioPlayerEventType.d.ts @@ -0,0 +1,13 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +export declare enum AudioPlayerEventType { + kAudioPlayerEventEnd = 0, + kAudioPlayerEventPause = 1, + kAudioPlayerEventPlay = 2, + kAudioPlayerEventTimeUpdate = 3, + kAudioPlayerEventReady = 4, + kAudioPlayerEventFail = 5 +} diff --git a/apl-client-js/@types/apl-html/lib/enums/EventProperty.d.ts b/apl-client-js/@types/apl-html/lib/enums/EventProperty.d.ts index 8e7a118..9aa0dfa 100644 --- a/apl-client-js/@types/apl-html/lib/enums/EventProperty.d.ts +++ b/apl-client-js/@types/apl-html/lib/enums/EventProperty.d.ts @@ -20,7 +20,9 @@ export declare enum EventProperty { kEventPropertyMediaType = 13, kEventPropertyName = 14, kEventPropertyPosition = 15, - kEventPropertyReason = 16, - kEventPropertySource = 17, - kEventPropertyValue = 18 + kEventPropertyRangeStart = 16, + kEventPropertyRangeEnd = 17, + kEventPropertyReason = 18, + kEventPropertySource = 19, + kEventPropertyValue = 20 } diff --git a/apl-client-js/@types/apl-html/lib/enums/EventType.d.ts b/apl-client-js/@types/apl-html/lib/enums/EventType.d.ts index 350214d..cbfa1cd 100644 --- a/apl-client-js/@types/apl-html/lib/enums/EventType.d.ts +++ b/apl-client-js/@types/apl-html/lib/enums/EventType.d.ts @@ -16,20 +16,24 @@ export declare enum EventType { kEventTypePreroll = 4, /** * Requests the bounds information for a text component * * The component is a TextComponent that needs the first line bounds measured */ kEventTypeRequestFirstLineBounds = 5, + /** * Requests the bounds information for a text component * * kEventPropertyRangeStart byte range start * kEventPropertyRangeEnd byte range end * * The component is a TextComponent that needs the line bounds measured */ + kEventTypeRequestLineBounds = 6, + /** * Requests the karaoke line to be highlighted * * kEventPropertyRangeStart byte range start * kEventPropertyRangeEnd byte range end * * The component is a TextComponent that needs the line highlighted. If range is empty (0,0) * clear any highlights. * * Does not have an ActionRef */ + kEventTypeLineHighlight = 7, /** * Send an event to the server * * kEventPropertySource: The rich source object describing who raised this event. * kEventPropertyArguments: The argument array provided by the APL author * kEventPropertyComponents: The values of the components requested by the APL author * * Does not have an ActionRef */ - kEventTypeSendEvent = 6, + kEventTypeSendEvent = 8, /** * Speak a single component. * * kEventPropertyHighlightMode: Highlight mode. kEventHighlightModeLine or kEventHighlightModeBlock * kEventPropertySource: The speech URI. * * The server must resolve the ActionRef when the scroll is completed. */ - kEventTypeSpeak = 7, + kEventTypeSpeak = 9, /** * Send a finish command. * * kEventPropertyReason: The reason for the finish command. kEventReasonExit or kEventReasonBack * * Does not have an ActionRef */ - kEventTypeFinish = 8, + kEventTypeFinish = 10, /** * A extension event registered with the core engine by the view host. */ - kEventTypeExtension = 9, + kEventTypeExtension = 11, /** * DataSourceProvider created event that could be used for data fetch requests. * * kEventPropertyName: name (type) of datasource that requests a fetch. * kEventPropertyValue: implementation specific fetch request. * * Does not have an ActionRef */ - kEventTypeDataSourceFetchRequest = 10, + kEventTypeDataSourceFetchRequest = 12, /** * The Document is asking to be reinflated. The server (view host) should do one of the following: * * 1. Leave the ActionRef unresolved and call RootContext::reinflate() to reinflate the document. * The ActionRef will be terminated and can be ignored. * 2. Resolve the ActionRef. The RootContext will resize() the document if the screen size has changed * and continue normal command processing. * * No properties * * Has an ActionRef. * * Note: It is not necessary to resolve the ActionRef if the server is calling RootContext::reinflate() * because all currently running command sequences will be terminated including the current ActionRef. */ - kEventTypeReinflate = 11, + kEventTypeReinflate = 13, /** * The Document is asking for external media to be loaded. Only issued when * @c ExperimentalFeature::kExperimentalFeatureManageMediaRequests is enabled. * * kEventPropertySource: the source URI of the requested media * kEventPropertyMediaType: the type of media being requested * * Does not have an ActionRef * * Note: Runtime supposed to answer with a call to RootContext::mediaLoaded when media loaded. */ - kEventTypeMediaRequest = 12, + kEventTypeMediaRequest = 14, /** * The document asking for virtual keyboard to be open. It's up to runtime to satisfy this request or not. * Only issued when @c ExperimentalFeature::kExperimentalFeatureRequestKeyboard is enabled. * * Does not have an ActionRef */ - kEventTypeOpenKeyboard = 13 + kEventTypeOpenKeyboard = 15 } diff --git a/apl-client-js/@types/apl-html/lib/enums/PropertyKey.d.ts b/apl-client-js/@types/apl-html/lib/enums/PropertyKey.d.ts index 381cf3d..f04801d 100644 --- a/apl-client-js/@types/apl-html/lib/enums/PropertyKey.d.ts +++ b/apl-client-js/@types/apl-html/lib/enums/PropertyKey.d.ts @@ -100,81 +100,83 @@ export declare enum PropertyKey { kPropertyOnLoad = 93, kPropertyOnMount = 94, kPropertyOnMove = 95, - kPropertyHandlePageMove = 96, - kPropertyOnPageChanged = 97, - kPropertyOnPause = 98, - kPropertyOnPlay = 99, - kPropertyOnPress = 100, - kPropertyOnScroll = 101, - kPropertyOnSubmit = 102, - kPropertyOnTextChange = 103, - kPropertyOnUp = 104, - kPropertyOnTimeUpdate = 105, - kPropertyOnTrackFail = 106, - kPropertyOnTrackReady = 107, - kPropertyOnTrackUpdate = 108, - kPropertyOpacity = 109, - kPropertyOverlayColor = 110, - kPropertyOverlayGradient = 111, - kPropertyPadding = 112, - kPropertyPaddingBottom = 113, - kPropertyPaddingEnd = 114, - kPropertyPaddingLeft = 115, - kPropertyPaddingRight = 116, - kPropertyPaddingTop = 117, - kPropertyPaddingStart = 118, - kPropertyPageDirection = 119, - kPropertyPageId = 120, - kPropertyPageIndex = 121, - kPropertyPlayingState = 122, - kPropertyPosition = 123, - kPropertyPreserve = 124, - kPropertyResourceId = 125, - kPropertyResourceOnFatalError = 126, - kPropertyResourceState = 127, - kPropertyResourceType = 128, - kPropertyRight = 129, - kPropertyRole = 130, - kPropertyScale = 131, - kPropertyScrollAnimation = 132, - kPropertyScrollOffset = 133, - kPropertyScrollPercent = 134, - kPropertyScrollPosition = 135, - kPropertySecureInput = 136, - kPropertySelectOnFocus = 137, - kPropertyShadowColor = 138, - kPropertyShadowHorizontalOffset = 139, - kPropertyShadowRadius = 140, - kPropertyShadowVerticalOffset = 141, - kPropertyShrink = 142, - kPropertySize = 143, - kPropertySnap = 144, - kPropertySource = 145, - kPropertySpacing = 146, - kPropertySpeech = 147, - kPropertyStart = 148, - kPropertySubmitKeyType = 149, - kPropertyText = 150, - kPropertyTextAlign = 151, - kPropertyTextAlignAssigned = 152, - kPropertyTextAlignVertical = 153, - kPropertyLang = 154, - kPropertyTrackCount = 155, - kPropertyTrackCurrentTime = 156, - kPropertyTrackDuration = 157, - kPropertyTrackEnded = 158, - kPropertyTrackIndex = 159, - kPropertyTrackPaused = 160, - kPropertyTrackState = 161, - kPropertyTransform = 162, - kPropertyTransformAssigned = 163, - kPropertyTop = 164, - kPropertyUser = 165, - kPropertyWidth = 166, - kPropertyOnCursorEnter = 167, - kPropertyOnCursorExit = 168, - kPropertyLaidOut = 169, - kPropertyValidCharacters = 170, - kPropertyVisualHash = 171, - kPropertyWrap = 172 + kPropertyOnSpeechMark = 96, + kPropertyHandlePageMove = 97, + kPropertyOnPageChanged = 98, + kPropertyOnPause = 99, + kPropertyOnPlay = 100, + kPropertyOnPress = 101, + kPropertyOnScroll = 102, + kPropertyOnSubmit = 103, + kPropertyOnTextChange = 104, + kPropertyOnUp = 105, + kPropertyOnTimeUpdate = 106, + kPropertyOnTrackFail = 107, + kPropertyOnTrackReady = 108, + kPropertyOnTrackUpdate = 109, + kPropertyOpacity = 110, + kPropertyOverlayColor = 111, + kPropertyOverlayGradient = 112, + kPropertyPadding = 113, + kPropertyPaddingBottom = 114, + kPropertyPaddingEnd = 115, + kPropertyPaddingLeft = 116, + kPropertyPaddingRight = 117, + kPropertyPaddingTop = 118, + kPropertyPaddingStart = 119, + kPropertyPageDirection = 120, + kPropertyPageId = 121, + kPropertyPageIndex = 122, + kPropertyPlayingState = 123, + kPropertyPosition = 124, + kPropertyPreserve = 125, + kPropertyRangeKaraokeTarget = 126, + kPropertyResourceId = 127, + kPropertyResourceOnFatalError = 128, + kPropertyResourceState = 129, + kPropertyResourceType = 130, + kPropertyRight = 131, + kPropertyRole = 132, + kPropertyScale = 133, + kPropertyScrollAnimation = 134, + kPropertyScrollOffset = 135, + kPropertyScrollPercent = 136, + kPropertyScrollPosition = 137, + kPropertySecureInput = 138, + kPropertySelectOnFocus = 139, + kPropertyShadowColor = 140, + kPropertyShadowHorizontalOffset = 141, + kPropertyShadowRadius = 142, + kPropertyShadowVerticalOffset = 143, + kPropertyShrink = 144, + kPropertySize = 145, + kPropertySnap = 146, + kPropertySource = 147, + kPropertySpacing = 148, + kPropertySpeech = 149, + kPropertyStart = 150, + kPropertySubmitKeyType = 151, + kPropertyText = 152, + kPropertyTextAlign = 153, + kPropertyTextAlignAssigned = 154, + kPropertyTextAlignVertical = 155, + kPropertyLang = 156, + kPropertyTrackCount = 157, + kPropertyTrackCurrentTime = 158, + kPropertyTrackDuration = 159, + kPropertyTrackEnded = 160, + kPropertyTrackIndex = 161, + kPropertyTrackPaused = 162, + kPropertyTrackState = 163, + kPropertyTransform = 164, + kPropertyTransformAssigned = 165, + kPropertyTop = 166, + kPropertyUser = 167, + kPropertyWidth = 168, + kPropertyOnCursorEnter = 169, + kPropertyOnCursorExit = 170, + kPropertyLaidOut = 171, + kPropertyValidCharacters = 172, + kPropertyVisualHash = 173, + kPropertyWrap = 174 } diff --git a/apl-client-js/@types/apl-html/lib/enums/TrackState.d.ts b/apl-client-js/@types/apl-html/lib/enums/TrackState.d.ts new file mode 100644 index 0000000..6550c5b --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/enums/TrackState.d.ts @@ -0,0 +1,10 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +export declare enum TrackState { + kTrackNotReady = 0, + kTrackReady = 1, + kTrackFailed = 2 +} diff --git a/apl-client-js/@types/apl-html/lib/index.d.ts b/apl-client-js/@types/apl-html/lib/index.d.ts index dd28c52..6a47910 100644 --- a/apl-client-js/@types/apl-html/lib/index.d.ts +++ b/apl-client-js/@types/apl-html/lib/index.d.ts @@ -11,8 +11,11 @@ export { Content } from './Content'; export { commandFactory } from './CommandFactory'; export { componentFactory } from './ComponentFactory'; export * from './media/audio/AudioPlayer'; +export * from './media/audio/AudioPlayerFactory'; export * from './media/audio/IAudioEventListener'; +export * from './media/audio/IAudioPlayer'; export * from './media/audio/DefaultAudioPlayer'; +export * from './media/audio/SpeechMarks'; export * from './media/audio/AudioContextProvider'; export * from './components/Component'; export * from './components/Container'; @@ -42,6 +45,7 @@ export * from './components/avg/Filter'; export * from './components/avg/VectorGraphic'; export * from './components/avg/VectorGraphicElementUpdater'; export * from './enums/AnimationQuality'; +export * from './enums/AudioPlayerEventType'; export * from './enums/AudioTrack'; export * from './enums/BlendMode'; export * from './enums/CommandAudioTrack'; @@ -72,6 +76,7 @@ export * from './enums/PropertyKey'; export * from './enums/ScrollDirection'; export * from './enums/TextAlign'; export * from './enums/TextAlignVertical'; +export * from './enums/TrackState'; export * from './enums/UpdateType'; export * from './enums/VideoScale'; export * from './enums/GraphicElementType'; @@ -83,6 +88,9 @@ export * from './extensions/CreateExtension'; export * from './extensions/IExtension'; export * from './extensions/LiveArray'; export * from './extensions/LiveMap'; +export * from './media/IMediaEventListener'; +export * from './media/IMediaPlayerHandle'; +export * from './media/MediaPlayerHandle'; export * from './media/PlaybackManager'; export * from './media/Resource'; export * from './utils/EventUtils'; diff --git a/apl-client-js/@types/apl-html/lib/media/IMediaEventListener.d.ts b/apl-client-js/@types/apl-html/lib/media/IMediaEventListener.d.ts index 704f894..2db6cb8 100644 --- a/apl-client-js/@types/apl-html/lib/media/IMediaEventListener.d.ts +++ b/apl-client-js/@types/apl-html/lib/media/IMediaEventListener.d.ts @@ -7,5 +7,6 @@ import { PlaybackState } from './Resource'; * @ignore */ export interface IMediaEventListener { + onPlayerReady(): void; onEvent(event: PlaybackState): void; } diff --git a/apl-client-js/@types/apl-html/lib/media/IMediaPlayerHandle.d.ts b/apl-client-js/@types/apl-html/lib/media/IMediaPlayerHandle.d.ts new file mode 100644 index 0000000..7e2b51c --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/media/IMediaPlayerHandle.d.ts @@ -0,0 +1,34 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + */ +import { Video } from '../components/video/Video'; +import { AudioTrack } from '../enums/AudioTrack'; +import { IMediaEventListener } from './IMediaEventListener'; +export interface IMediaPlayerHandle extends IMediaEventListener { + /** + * Called by C++ code + */ + setTrackList(trackArray: Array<{ + url: string; + offset: number; + duration: number; + repeatCount: number; + }>): void; + setTrackIndex(index: number): Promise; + seek(offset: number): Promise; + play(waitForFinish: boolean): Promise; + pause(): Promise; + stop(): Promise; + next(): Promise; + previous(): Promise; + rewind(): Promise; + setAudioTrack(audioTrack: AudioTrack): void; + setMute(mute: boolean): void; + /** + * Called by JS code + */ + setVideoComponent(video: Video): void; + getProcessor(): any; + getSequencer(): any; + destroy(): void; +} diff --git a/apl-client-js/@types/apl-html/lib/media/MediaPlayerHandle.d.ts b/apl-client-js/@types/apl-html/lib/media/MediaPlayerHandle.d.ts new file mode 100644 index 0000000..f28216a --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/media/MediaPlayerHandle.d.ts @@ -0,0 +1,46 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import { Video } from '../components/video/Video'; +import { AudioTrack } from '../enums/AudioTrack'; +import { IMediaEventListener } from './IMediaEventListener'; +import { IMediaPlayerHandle } from './IMediaPlayerHandle'; +import { PlaybackState } from './Resource'; +export declare class MediaPlayerHandle implements IMediaPlayerHandle, IMediaEventListener { + private readonly eventProcessor; + private readonly eventSequencer; + private readonly mediaPlayer; + private videoComponent; + private playWhenLoaded; + private waitForFinishOnInit; + private lastPlaybackState; + constructor(aplMediaPlayer: APL.MediaPlayer); + destroy(): void; + setVideoComponent(video: Video): void; + getProcessor(): any; + getSequencer(): any; + setTrackList(trackArray: Array<{ + url: string; + offset: number; + duration: number; + repeatCount: number; + }>): void; + setTrackIndex(index: number): Promise; + seek(offset: number): Promise; + play(waitForFinish: boolean): Promise; + pause(): Promise; + stop(): Promise; + next(): Promise; + previous(): Promise; + rewind(): Promise; + setAudioTrack(audioTrack: AudioTrack): void; + setMute(muted: boolean): void; + onEvent(event: PlaybackState): void; + onPlayerReady(): void; + protected readonly player: any; + protected readonly audioTrack: any; + protected readonly playbackManager: any; + protected readonly currentMediaResource: any; + protected readonly currentMediaState: any; +} diff --git a/apl-client-js/@types/apl-html/lib/media/PlaybackManager.d.ts b/apl-client-js/@types/apl-html/lib/media/PlaybackManager.d.ts index f8afa86..ca203ae 100644 --- a/apl-client-js/@types/apl-html/lib/media/PlaybackManager.d.ts +++ b/apl-client-js/@types/apl-html/lib/media/PlaybackManager.d.ts @@ -10,7 +10,6 @@ import { IMediaSource } from './IMediaSource'; */ export interface IMediaResource { toRepeat: number; - description: string; offset: number; repeatCount: number; trackIndex: number; diff --git a/apl-client-js/@types/apl-html/lib/media/audio/AudioPlayer.d.ts b/apl-client-js/@types/apl-html/lib/media/audio/AudioPlayer.d.ts index c5aea43..f46dfe5 100644 --- a/apl-client-js/@types/apl-html/lib/media/audio/AudioPlayer.d.ts +++ b/apl-client-js/@types/apl-html/lib/media/audio/AudioPlayer.d.ts @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ import { IAudioEventListener } from './IAudioEventListener'; -export declare type AudioPlayerFactory = (eventListener: IAudioEventListener) => AudioPlayer; +import { IAudioPlayer } from './IAudioPlayer'; export declare type IAudioNode = GainNode; -export declare abstract class AudioPlayer { +export declare abstract class AudioPlayer implements IAudioPlayer { private eventListener; private resourceMap; private currentSource; @@ -16,7 +16,7 @@ export declare abstract class AudioPlayer { prepare(url: string, decodeMarkers: boolean): string; protected onPlaybackFinished(id: string): void; protected onError(id: string, reason: string): void; - abstract play(id: string): any; + abstract play(id: string): void; protected playWithContext(id: string, audioContext: AudioContext): void; protected setCurrentAudioNode(node: IAudioNode): void; private getConnectedAudioNode(context); diff --git a/apl-client-js/@types/apl-html/lib/media/audio/AudioPlayerFactory.d.ts b/apl-client-js/@types/apl-html/lib/media/audio/AudioPlayerFactory.d.ts new file mode 100644 index 0000000..229cd2b --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/media/audio/AudioPlayerFactory.d.ts @@ -0,0 +1,10 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import { IAudioEventListener } from './IAudioEventListener'; +import { IAudioPlayer } from './IAudioPlayer'; +export declare abstract class IAudioPlayerFactory { + abstract tick(): void; +} +export declare type AudioPlayerFactory = (eventListener: IAudioEventListener) => IAudioPlayer; diff --git a/apl-client-js/@types/apl-html/lib/media/audio/IAudioPlayer.d.ts b/apl-client-js/@types/apl-html/lib/media/audio/IAudioPlayer.d.ts new file mode 100644 index 0000000..98faa1e --- /dev/null +++ b/apl-client-js/@types/apl-html/lib/media/audio/IAudioPlayer.d.ts @@ -0,0 +1,10 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +export interface IAudioPlayer { + prepare(url: string, decodeMarkers: boolean): string; + play(id: string): void; + releaseAudioContext(): void; + flush(): void; +} diff --git a/apl-client-js/@types/apl-html/lib/media/audio/SpeechMarks.d.ts b/apl-client-js/@types/apl-html/lib/media/audio/SpeechMarks.d.ts index bc94036..ff74b6f 100644 --- a/apl-client-js/@types/apl-html/lib/media/audio/SpeechMarks.d.ts +++ b/apl-client-js/@types/apl-html/lib/media/audio/SpeechMarks.d.ts @@ -7,7 +7,7 @@ * The type of speech mark * @ignore */ -export declare type SpeechMarkType = 'visime' | 'word' | 'sentence'; +export declare type SpeechMarkType = 'visime' | 'word' | 'sentence' | 'ssml'; /** * Base type * @ignore diff --git a/apl-client-js/APLAudioPlayer.d.ts b/apl-client-js/APLAudioPlayer.d.ts new file mode 100644 index 0000000..d34336e --- /dev/null +++ b/apl-client-js/APLAudioPlayer.d.ts @@ -0,0 +1,28 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import { AudioPlayerFactory, IAudioEventListener, IBaseMarker } from 'apl-html'; +import { APLClient, AudioPlayerSetTrackPayload } from './APLClient'; +/** + * Websocket transport for AudioPlayer. Allows controls for browser owned + * player to be invoked through websocket and events to get back. + */ +export declare class APLAudioPlayer implements APL.AudioPlayer, IAudioEventListener { + private client; + private playerId; + private player; + private audioId; + constructor(client: APLClient, id: string, playerFactory: AudioPlayerFactory); + play(): void; + release(): void; + setTrack(payload: AudioPlayerSetTrackPayload): void; + pause(): void; + private doPlayerCallback(id, eventType, paused, ended, trackState); + onPrepared(id: string): void; + onMarker(id: string, markers: IBaseMarker[]): void; + onPlaybackStarted(id: string): void; + onPlaybackFinished(id: string): void; + onError(id: string, reason: string): void; + delete(): void; +} diff --git a/apl-client-js/APLAudioPlayerFactory.d.ts b/apl-client-js/APLAudioPlayerFactory.d.ts new file mode 100644 index 0000000..8db9f39 --- /dev/null +++ b/apl-client-js/APLAudioPlayerFactory.d.ts @@ -0,0 +1,21 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import { AudioPlayerFactory } from 'apl-html'; +import { APLAudioPlayer } from './APLAudioPlayer'; +import { APLClient } from './APLClient'; +/** + * Websocket transport AudioPlayer factory. + */ +export declare class APLAudioPlayerFactory implements APL.AudioPlayerFactory { + private client; + private playerFactory; + private players; + static create(client: APLClient, playerFactory: AudioPlayerFactory): APLAudioPlayerFactory; + constructor(client: APLClient, playerFactory: AudioPlayerFactory); + createPlayer(id: string): APLAudioPlayer; + getPlayer(playerId: string): APLAudioPlayer; + tick(): void; + delete(): void; +} diff --git a/apl-client-js/APLClient.d.ts b/apl-client-js/APLClient.d.ts index 29b6ab4..815b4f2 100644 --- a/apl-client-js/APLClient.d.ts +++ b/apl-client-js/APLClient.d.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { APLMediaPlayerFactory, MediaPlayerFactoryFunc } from './APLMediaPlayerFactory'; import { ExtensionPayload } from './ExtensionMessageHandler'; export interface RenderingOptionsPayload { legacyKaraoke: boolean; @@ -89,6 +90,38 @@ export interface ContextPayload { messageId: string; result: string; } +export interface AudioPlayerPayload { + playerId: string; +} +export interface AudioPlayerSetTrackPayload extends AudioPlayerPayload { + url: string; +} +export interface MediaPlayerPayload { + playerId: string; +} +export interface MediaPlayerSetTrackListPayload extends MediaPlayerPayload { + trackArray: Array<{ + url: string; + offset: number; + duration: number; + repeatCount: number; + }>; +} +export interface MediaPlayerSetTrackIndexPayload extends MediaPlayerPayload { + index: number; +} +export interface MediaPlayerSeekPayload extends MediaPlayerPayload { + offset: number; +} +export interface MediaPlayerPlayPayload extends MediaPlayerPayload { + waitForFinish: boolean; +} +export interface MediaPlayerSetAudioTrackPayload extends MediaPlayerPayload { + audioTrack: number; +} +export interface MediaPlayerSetMutePayload extends MediaPlayerPayload { + mute: boolean; +} export interface PayloadTypeMap { 'renderingOptions': RenderingOptionsPayload; 'measure': MeasurePayload; @@ -114,6 +147,24 @@ export interface PayloadTypeMap { 'getDisplayedChildId': DisplayedChildIdPayload; 'supportsResizing': SupportsResizingPayload; 'extension': ExtensionPayload; + 'createAudioPlayer': AudioPlayerPayload; + 'audioPlayerPlay': AudioPlayerPayload; + 'audioPlayerSetTrack': AudioPlayerSetTrackPayload; + 'audioPlayerPause': AudioPlayerPayload; + 'audioPlayerRelease': AudioPlayerPayload; + 'mediaPlayerCreate': MediaPlayerPayload; + 'mediaPlayerDelete': MediaPlayerPayload; + 'mediaPlayerSetTrackList': MediaPlayerSetTrackListPayload; + 'mediaPlayerSetTrackIndex': MediaPlayerSetTrackIndexPayload; + 'mediaPlayerSeek': MediaPlayerSeekPayload; + 'mediaPlayerPlay': MediaPlayerPlayPayload; + 'mediaPlayerPause': MediaPlayerPayload; + 'mediaPlayerStop': MediaPlayerPayload; + 'mediaPlayerNext': MediaPlayerPayload; + 'mediaPlayerPrevious': MediaPlayerPayload; + 'mediaPlayerRewind': MediaPlayerPayload; + 'mediaPlayerSetAudioTrack': MediaPlayerSetAudioTrackPayload; + 'mediaPlayerSetMute': MediaPlayerSetMutePayload; } export interface Message { type: Type; @@ -155,6 +206,24 @@ export interface IAPLMessageListener { onGetDisplayedChildId?(message: Message<'getDisplayedChildId'>): void; onSupportsResizing?(message: Message<'supportsResizing'>): void; onExtensionEvent?(message: Message<'extension'>): void; + onCreateAudioPlayer?(message: Message<'createAudioPlayer'>): void; + onAudioPlayerPlay?(message: Message<'audioPlayerPlay'>): void; + onAudioPlayerSetTrack?(message: Message<'audioPlayerSetTrack'>): void; + onAudioPlayerPause?(message: Message<'audioPlayerPause'>): void; + onAudioPlayerRelease?(message: Message<'audioPlayerRelease'>): void; + onMediaPlayerCreate?(message: Message<'mediaPlayerCreate'>): void; + onMediaPlayerDelete?(message: Message<'mediaPlayerDelete'>): void; + onMediaPlayerSetTrackList?(message: Message<'mediaPlayerSetTrackList'>): void; + onMediaPlayerSetTrackIndex?(message: Message<'mediaPlayerSetTrackIndex'>): void; + onMediaPlayerSeek?(message: Message<'mediaPlayerSeek'>): void; + onMediaPlayerPlay?(message: Message<'mediaPlayerPlay'>): void; + onMediaPlayerPause?(message: Message<'mediaPlayerPause'>): void; + onMediaPlayerStop?(message: Message<'mediaPlayerStop'>): void; + onMediaPlayerNext?(message: Message<'mediaPlayerNext'>): void; + onMediaPlayerPrevious?(message: Message<'mediaPlayerPrevious'>): void; + onMediaPlayerRewind?(message: Message<'mediaPlayerRewind'>): void; + onMediaPlayerSetAudioTrack?(message: Message<'mediaPlayerSetAudioTrack'>): void; + onMediaPlayerSetMute?(message: Message<'mediaPlayerSetMute'>): void; } /** * Extend this class to implement a client. Must implement events described in @@ -162,7 +231,9 @@ export interface IAPLMessageListener { */ export declare abstract class APLClient { private logger; - constructor(); + private mediaPlayerFactory; + constructor(mediaPlayerFactoryFunc?: MediaPlayerFactoryFunc); + getMediaPlayerFactory(): APLMediaPlayerFactory; /** * Override this method to send a message * @param message diff --git a/apl-client-js/APLMediaPlayer.d.ts b/apl-client-js/APLMediaPlayer.d.ts new file mode 100644 index 0000000..7fb70b3 --- /dev/null +++ b/apl-client-js/APLMediaPlayer.d.ts @@ -0,0 +1,16 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import { IMediaPlayerHandle } from "./@types/apl-html/lib/index"; +import { APLClient } from './APLClient'; +export declare class APLMediaPlayer implements APL.MediaPlayer { + private client; + private playerId; + private mediaPlayerHandle; + constructor(client: APLClient, playerId: string, playerFactory: any); + delete(): void; + updateMediaState(mediaState: any): void; + doCallback(eventType: number): void; + getMediaPlayerHandle(): IMediaPlayerHandle; +} diff --git a/apl-client-js/APLMediaPlayerFactory.d.ts b/apl-client-js/APLMediaPlayerFactory.d.ts new file mode 100644 index 0000000..57d9c6b --- /dev/null +++ b/apl-client-js/APLMediaPlayerFactory.d.ts @@ -0,0 +1,22 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import { IMediaPlayerHandle } from "./@types/apl-html/lib/index"; +import { APLClient } from './APLClient'; +import { APLMediaPlayer } from './APLMediaPlayer'; +/** + * Websocket transport AudioPlayer factory. + */ +export declare class APLMediaPlayerFactory implements APL.MediaPlayerFactory { + private client; + private playerFactoryFunc; + private players; + constructor(client: APLClient, playerFactoryFunc: any); + static create(client: APLClient, playerFactoryFunc: any): APLMediaPlayerFactory; + createPlayer(id: string): APLMediaPlayer; + getMediaPlayer(playerId: string): APLMediaPlayer; + deleteMediaPlayer(playerId: string): void; + delete(): void; +} +export declare type MediaPlayerFactoryFunc = (aplMediaPlayer: APL.MediaPlayer) => IMediaPlayerHandle; diff --git a/apl-client-js/APLWSRenderer.d.ts b/apl-client-js/APLWSRenderer.d.ts index 84dbe1d..102877d 100644 --- a/apl-client-js/APLWSRenderer.d.ts +++ b/apl-client-js/APLWSRenderer.d.ts @@ -24,6 +24,7 @@ export declare class APLWSRenderer extends APLRenderer { componentMapping: { [id: string]: APLComponent; }; + private mediaPlayerFactory; /** * Creates a new renderer * @param options Options for this instance diff --git a/apl-client-js/index.d.ts b/apl-client-js/index.d.ts index aeab252..6196d5f 100644 --- a/apl-client-js/index.d.ts +++ b/apl-client-js/index.d.ts @@ -6,5 +6,6 @@ export * from './APLWSRenderer'; export * from './APLClient'; export * from './APLConfigurationChange'; export * from './WebSocketClient'; +export * from './APLMediaPlayerFactory'; export * from "./@types/apl-html/lib/index"; export { default as APLRenderer } from "./@types/apl-html/lib/index"; diff --git a/apl-client-js/index.js b/apl-client-js/index.js index 76417ac..9b08422 100644 --- a/apl-client-js/index.js +++ b/apl-client-js/index.js @@ -1,8 +1,8 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.APLClient=t():e.APLClient=t()}(window,(function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=9)}([function(e,t){e.exports=function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=34)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const n=r(147);class i{static initialize(e,t){this.rootLogger.setDefaultLevel(e),this.rootLogger.methodFactory=(e,r,n)=>{const o=i.originalFactory(e,r,n);return r=>{t?t(e,n,r):o(`${e[0].toUpperCase()} ${n}: ${r}`)}},this.rootLogger.setLevel(this.rootLogger.getLevel()),this.initialized=!0}static getLogger(e){return this.initialized||this.initialize("info"),this.rootLogger.getLogger(e)}}i.rootLogger=n,i.originalFactory=i.rootLogger.methodFactory,i.initialized=!1,t.LoggerFactory=i},function(e,t,r){"use strict";var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function a(e){try{d(n.next(e))}catch(e){o(e)}}function s(e){try{d(n.throw(e))}catch(e){o(e)}}function d(e){e.done?i(e.value):new r((function(t){t(e.value)})).then(a,s)}d((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const i=r(231),o=r(15),a=r(39),s=r(232),d=r(99),u=r(233),c=r(234),l=r(64),p=r(2),f=r(40),h=r(0),y=r(235),m=r(30),g=r(14),v=r(236),b=r(100),k=r(242),P=r(103),S={[a.ComponentType.kComponentTypeContainer]:"Container",[a.ComponentType.kComponentTypeEditText]:"EditText",[a.ComponentType.kComponentTypeFrame]:"Frame",[a.ComponentType.kComponentTypeImage]:"Image",[a.ComponentType.kComponentTypePager]:"Pager",[a.ComponentType.kComponentTypeScrollView]:"ScrollView",[a.ComponentType.kComponentTypeSequence]:"Sequence",[a.ComponentType.kComponentTypeGridSequence]:"GridSequence",[a.ComponentType.kComponentTypeText]:"Text",[a.ComponentType.kComponentTypeTouchWrapper]:"TouchWrapper",[a.ComponentType.kComponentTypeVideo]:"Video",[a.ComponentType.kComponentTypeVectorGraphic]:"VectorGraphic"},T={[l.LayoutDirection.kLayoutDirectionLTR]:"ltr",[l.LayoutDirection.kLayoutDirectionRTL]:"rtl"},E=new Set([a.ComponentType.kComponentTypeFrame,a.ComponentType.kComponentTypePager,a.ComponentType.kComponentTypeScrollView,a.ComponentType.kComponentTypeSequence,a.ComponentType.kComponentTypeGridSequence]),x=new Set([a.ComponentType.kComponentTypeEditText,a.ComponentType.kComponentTypeImage,a.ComponentType.kComponentTypeText,a.ComponentType.kComponentTypeTouchWrapper,a.ComponentType.kComponentTypeVideo]);t.SVG_NS="http://www.w3.org/2000/svg",t.uuidv4=r(45),t.IDENTITY_TRANSFORM="matrix(1.000000,0.000000,0.000000,1.000000,0.000000,0.000000)";class C extends i{constructor(e,t,r,n){if(super(),this.renderer=e,this.component=t,this.factory=r,this.parent=n,this.container=document.createElement("div"),this.$container=o(this.container),this.children=[],this.props={},this.isDestroyed=!1,this.doForceInvisible=!1,this.state={[f.UpdateType.kUpdatePagerPosition]:0,[f.UpdateType.kUpdatePressState]:0,[f.UpdateType.kUpdatePressed]:0,[f.UpdateType.kUpdateScrollPosition]:0,[f.UpdateType.kUpdateTakeFocus]:0},this.executors=new Map,this.propExecutor=(e,...t)=>{for(const r of t)this.executors.set(r,r=>{const n=Object.keys(t);for(const e of n)delete r[parseInt(e,10)];e()});return this.propExecutor},this.setTransform=()=>{if(this.renderer){const e=this.renderer.context.getScaleFactor(),t=v.getScaledTransform(this.props[p.PropertyKey.kPropertyTransform],e);this.$container.css({transform:t})}},this.setOpacity=()=>{this.$container.css("opacity",this.props[p.PropertyKey.kPropertyOpacity])},this.setLayoutDirection=()=>{this.layoutDirection=this.props[p.PropertyKey.kPropertyLayoutDirection],T.hasOwnProperty(this.layoutDirection)||(this.logger.warn(`Layout Direction ${this.layoutDirection} is not supported, defaulting to LTR`),this.layoutDirection=l.LayoutDirection.kLayoutDirectionLTR),this.parent&&this.parent.layoutDirection===this.layoutDirection||(this.container.dir=T[this.layoutDirection])},this.isRtl=()=>this.layoutDirection===l.LayoutDirection.kLayoutDirectionRTL,this.setDisplay=()=>{let e=this.props[p.PropertyKey.kPropertyDisplay];switch(this.hasValidBounds()&&!this.doForceInvisible||(e=s.Display.kDisplayInvisible),e){case s.Display.kDisplayInvisible:case s.Display.kDisplayNone:this.$container.css({display:"none"});break;case s.Display.kDisplayNormal:this.$container.css({display:this.getNormalDisplay()});break;default:this.logger.warn("Incorrect display type: "+e)}},this.setBoundsAndDisplay=()=>{if(this.bounds=this.props[p.PropertyKey.kPropertyBounds],!this.bounds)return;this.setDisplay();let e=0,t=0;if(this.parent&&this.parent.component.getType()===a.ComponentType.kComponentTypeFrame){const r=this.parent.component.getCalculatedByKey(p.PropertyKey.kPropertyBorderWidth);e-=r,t-=r}this.bounds={top:this.bounds.top+e,left:this.bounds.left+t,height:this.bounds.height,width:this.bounds.width};for(const e of this.children)e.setBoundsAndDisplay();P.applyAplRectToStyle({domElement:this.container,rectangle:this.bounds}),this.innerBounds=this.props[p.PropertyKey.kPropertyInnerBounds],P.applyPaddingToStyle({domElement:this.container,bounds:this.bounds,innerBounds:this.innerBounds}),this.boundsUpdated()},this.setUserProperties=()=>{if(!this.renderer)return;const e=this.renderer.getDeveloperToolOptions();if(!e)return;const t=this.props[p.PropertyKey.kPropertyUser],r=e.mappingKey;if(r&&t.hasOwnProperty(r)){const e=t[r]+this.id;this.renderer.componentByMappingKey.set(e,this)}const n=e.writeKeys;if(n&&Array.isArray(n))for(const e of n)t.hasOwnProperty(e)&&this.container.setAttribute(["data",e].join("-"),t[e])},this.handleComponentChildrenChange=()=>{for(const e of this.props[p.PropertyKey.kPropertyNotifyChildrenChanged])e.action===g.ChildAction.Insert||(e.action===g.ChildAction.Remove?void 0!==this.container.children[e.uid]&&this.container.children[e.uid].remove():this.logger.warn(`Invalid action type ${e.action} for child ${e.uid}`));this.ensureDisplayedChildren()},this.getCssShadow=()=>`${this.props[p.PropertyKey.kPropertyShadowHorizontalOffset]}px ${this.props[p.PropertyKey.kPropertyShadowVerticalOffset]}px ${this.props[p.PropertyKey.kPropertyShadowRadius]}px ${C.numberToColor(this.props[p.PropertyKey.kPropertyShadowColor])}`,this.setShadow=()=>{this.applyCssShadow(this.getCssShadow())},this.applyCssShadow=e=>{this.$container.css("box-shadow",e)},this.logger=h.LoggerFactory.getLogger(S[t.getType()]||"Component"),this.$container.css({position:"absolute","transform-origin":"0% 0%","-webkit-box-sizing":"border-box","-moz-box-sizing":"border-box","box-sizing":"border-box"}),this.checkComponentTypeAndEnableClipping(),this.id=t.getUniqueId(),this.$container.attr("id",this.id),this.assignedId=t.getId(),e){e.componentMap[this.id]=this,e.componentIdMap[this.assignedId]=this;const r=e.options;r&&r.developerToolOptions&&r.developerToolOptions.includeComponentId&&this.$container.attr("data-componentid",t.getId())}this.container.classList.add("apl-"+this.constructor.name.toLowerCase()),this.parent=n,this.propExecutor(this.setTransform,p.PropertyKey.kPropertyTransform)(this.setLayoutDirection,p.PropertyKey.kPropertyLayoutDirection)(this.setBoundsAndDisplay,p.PropertyKey.kPropertyBounds,p.PropertyKey.kPropertyInnerBounds,p.PropertyKey.kPropertyDisplay)(this.setOpacity,p.PropertyKey.kPropertyOpacity)(this.setUserProperties,p.PropertyKey.kPropertyUser)(this.handleComponentChildrenChange,p.PropertyKey.kPropertyNotifyChildrenChanged)(this.setShadow,p.PropertyKey.kPropertyShadowHorizontalOffset,p.PropertyKey.kPropertyShadowVerticalOffset,p.PropertyKey.kPropertyShadowRadius,p.PropertyKey.kPropertyShadowColor)}init(){const e=this.getDisplayedChildren();for(let t=0;te.id===n.getUniqueId()).shift();e[r]=void 0!==i?i:this.factory(this.renderer,n,this,!0,r)}this.children.forEach(t=>{e.some(e=>e.id===t.id)||t.destroy()}),this.children=e}getDisplayedChildCount(){return this.component.getDisplayedChildCount()}getDisplayedChildren(){const e=[],t=this.component.getDisplayedChildCount();for(let r=0;r{const r=parseInt(t,10);this.props[r]=e[r]}),Object.keys(e).forEach(t=>{const r=parseInt(t,10);if(r in e){const t=this.executors.get(r);t&&t(e)}}),this.onPropertiesUpdated()}updateDirtyProps(){const e=this.component.getDirtyProps();this.setProperties(e)}update(e,t){"string"==typeof t?(this.state[e]=t.toString(),this.component.updateEditText(e,t.toString())):(this.state[e]=t,this.component.update(e,t))}destroy(e=!1){this.container&&this.container.parentElement&&this.container.parentElement.removeChild(this.container),this.isDestroyed=!0,this.parent=void 0,delete this.renderer.componentMap[this.id],delete this.renderer.componentMap[this.assignedId],this.renderer=void 0;for(const t of this.children)t.destroy(e);this.children=void 0,e&&(this.component.delete(),this.component=void 0)}static numberToColor(e){return m.numberToColor(e)}static getGradientSpreadMethod(e){switch(e){case u.GradientSpreadMethod.REFLECT:return"reflect";case u.GradientSpreadMethod.REPEAT:return"repeat";case u.GradientSpreadMethod.PAD:default:return"pad"}}static getGradientUnits(e){switch(e){case c.GradientUnits.kGradientUnitsUserSpace:return"userSpaceOnUse";case c.GradientUnits.kGradientUnitsBoundingBox:default:return"objectBoundingBox"}}static fillAndStrokeConverter(e,t,r,n){return b.fillAndStrokeConverter({value:e,transform:t,parent:r,logger:n})}hasValidBounds(){return this.bounds.width>0&&this.bounds.width<1e6}static getClipPathElementId(e,r){if(!e||""===e)return"";const n=document.createElementNS(t.SVG_NS,"defs"),i=document.createElementNS(t.SVG_NS,"clipPath"),o=document.createElementNS(t.SVG_NS,"path"),a=t.uuidv4().toString();return i.setAttributeNS("","id",a),o.setAttributeNS("","d",e.toString()),i.appendChild(o),n.appendChild(i),r.appendChild(n),`url('#${a}')`}inflateAndAddChild(e,t){const r=this.component.inflateChild(t,e);let n;return r&&(n=this.factory(this.renderer,r,this,!0,e),this.children.splice(e,0,n)),n}remove(){return!!this.component.remove()&&(this.parent&&this.parent.children&&this.parent.children.splice(this.parent.children.indexOf(this),1),this.destroy(!0),!0)}boundsUpdated(){}isLayout(){return!1}sizeToFit(){if(this.renderer&&this.renderer.getLegacyClippingEnabled())return;const e=!!this.bounds,t=!!this.parent,r=this.layoutDirection===l.LayoutDirection.kLayoutDirectionLTR;if(!(e&&t&&r))return;const n=this.parent.component.getType()===a.ComponentType.kComponentTypeContainer,i=this.isLayout();if(!n||!i)return;const o=k.createBoundsFitter({containingBounds:this.parent.bounds,innerBounds:this.bounds,layoutDirection:this.layoutDirection}).fitBounds();if(o===this.bounds)return;const{width:s,height:d}=o,{width:u,height:c}=this.bounds;this.logger.warn(`Component ${this.id} has bounds that is bigger than parent bounds.\nCheck your template correctness.\nAdjusting ${this.id} to parent ${this.parent.id}\nWIDTH: ${u} => ${s}\nHEIGHT: ${c} => ${d}\n`);const p=y.getRectDifference(this.bounds,o);this.bounds=o,this.innerBounds&&((this.innerBounds.width>this.bounds.width||this.innerBounds.height>this.bounds.height)&&(this.innerBounds=y.getRectDifference(this.innerBounds,p)),P.applyAplRectToStyle({domElement:this.container,rectangle:this.bounds}),P.applyPaddingToStyle({domElement:this.container,bounds:this.bounds,innerBounds:this.innerBounds}),this.boundsUpdated())}alignSize(){return this.sizeToFit()}getProperties(){return this.component.getCalculated()}forceInvisible(e){this.doForceInvisible!==e&&(this.doForceInvisible=e,this.setDisplay())}getNormalDisplay(){return""}takeFocus(){return n(this,void 0,void 0,(function*(){const e=(yield this.renderer.context.getFocusableAreas())[this.id];e&&this.renderer.context.setFocus(d.FocusDirection.kFocusDirectionNone,e,this.id)}))}get lang(){return this.props[p.PropertyKey.kPropertyLang]||""}checkComponentTypeAndEnableClipping(){const e=this.component.getType();if(x.has(e))return;const t=this.parent&&E.has(this.parent.component.getType()),r=E.has(e),n=this.renderer&&this.renderer.getLegacyClippingEnabled();(r||t||!n)&&this.enableClipping()}enableClipping(){this.$container.css("overflow","hidden")}}t.Component=C},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e[e.kPropertyScrollDirection=0]="kPropertyScrollDirection",e[e.kPropertyAccessibilityActions=1]="kPropertyAccessibilityActions",e[e.kPropertyAccessibilityLabel=2]="kPropertyAccessibilityLabel",e[e.kPropertyAlign=3]="kPropertyAlign",e[e.kPropertyAlignItems=4]="kPropertyAlignItems",e[e.kPropertyAlignSelf=5]="kPropertyAlignSelf",e[e.kPropertyAudioTrack=6]="kPropertyAudioTrack",e[e.kPropertyAutoplay=7]="kPropertyAutoplay",e[e.kPropertyMuted=8]="kPropertyMuted",e[e.kPropertyBackgroundColor=9]="kPropertyBackgroundColor",e[e.kPropertyBorderBottomLeftRadius=10]="kPropertyBorderBottomLeftRadius",e[e.kPropertyBorderBottomRightRadius=11]="kPropertyBorderBottomRightRadius",e[e.kPropertyBorderColor=12]="kPropertyBorderColor",e[e.kPropertyBorderRadius=13]="kPropertyBorderRadius",e[e.kPropertyBorderRadii=14]="kPropertyBorderRadii",e[e.kPropertyBorderStrokeWidth=15]="kPropertyBorderStrokeWidth",e[e.kPropertyBorderTopLeftRadius=16]="kPropertyBorderTopLeftRadius",e[e.kPropertyBorderTopRightRadius=17]="kPropertyBorderTopRightRadius",e[e.kPropertyBorderWidth=18]="kPropertyBorderWidth",e[e.kPropertyBottom=19]="kPropertyBottom",e[e.kPropertyBounds=20]="kPropertyBounds",e[e.kPropertyCenterId=21]="kPropertyCenterId",e[e.kPropertyCenterIndex=22]="kPropertyCenterIndex",e[e.kPropertyChildHeight=23]="kPropertyChildHeight",e[e.kPropertyChildWidth=24]="kPropertyChildWidth",e[e.kPropertyChecked=25]="kPropertyChecked",e[e.kPropertyColor=26]="kPropertyColor",e[e.kPropertyColorKaraokeTarget=27]="kPropertyColorKaraokeTarget",e[e.kPropertyColorNonKaraoke=28]="kPropertyColorNonKaraoke",e[e.kPropertyCurrentPage=29]="kPropertyCurrentPage",e[e.kPropertyDescription=30]="kPropertyDescription",e[e.kPropertyDirection=31]="kPropertyDirection",e[e.kPropertyDisabled=32]="kPropertyDisabled",e[e.kPropertyDisplay=33]="kPropertyDisplay",e[e.kPropertyDrawnBorderWidth=34]="kPropertyDrawnBorderWidth",e[e.kPropertyEnd=35]="kPropertyEnd",e[e.kPropertyEntities=36]="kPropertyEntities",e[e.kPropertyFastScrollScale=37]="kPropertyFastScrollScale",e[e.kPropertyFilters=38]="kPropertyFilters",e[e.kPropertyFirstId=39]="kPropertyFirstId",e[e.kPropertyFirstIndex=40]="kPropertyFirstIndex",e[e.kPropertyFocusable=41]="kPropertyFocusable",e[e.kPropertyFontFamily=42]="kPropertyFontFamily",e[e.kPropertyFontSize=43]="kPropertyFontSize",e[e.kPropertyFontStyle=44]="kPropertyFontStyle",e[e.kPropertyFontWeight=45]="kPropertyFontWeight",e[e.kPropertyHandleTick=46]="kPropertyHandleTick",e[e.kPropertyHighlightColor=47]="kPropertyHighlightColor",e[e.kPropertyHint=48]="kPropertyHint",e[e.kPropertyHintColor=49]="kPropertyHintColor",e[e.kPropertyHintStyle=50]="kPropertyHintStyle",e[e.kPropertyHintWeight=51]="kPropertyHintWeight",e[e.kPropertyGestures=52]="kPropertyGestures",e[e.kPropertyGraphic=53]="kPropertyGraphic",e[e.kPropertyGrow=54]="kPropertyGrow",e[e.kPropertyHandleKeyDown=55]="kPropertyHandleKeyDown",e[e.kPropertyHandleKeyUp=56]="kPropertyHandleKeyUp",e[e.kPropertyHeight=57]="kPropertyHeight",e[e.kPropertyId=58]="kPropertyId",e[e.kPropertyInitialPage=59]="kPropertyInitialPage",e[e.kPropertyInnerBounds=60]="kPropertyInnerBounds",e[e.kPropertyItemsPerCourse=61]="kPropertyItemsPerCourse",e[e.kPropertyJustifyContent=62]="kPropertyJustifyContent",e[e.kPropertyKeyboardBehaviorOnFocus=63]="kPropertyKeyboardBehaviorOnFocus",e[e.kPropertyKeyboardType=64]="kPropertyKeyboardType",e[e.kPropertyLayoutDirection=65]="kPropertyLayoutDirection",e[e.kPropertyLayoutDirectionAssigned=66]="kPropertyLayoutDirectionAssigned",e[e.kPropertyLeft=67]="kPropertyLeft",e[e.kPropertyLetterSpacing=68]="kPropertyLetterSpacing",e[e.kPropertyLineHeight=69]="kPropertyLineHeight",e[e.kPropertyMaxHeight=70]="kPropertyMaxHeight",e[e.kPropertyMaxLength=71]="kPropertyMaxLength",e[e.kPropertyMaxLines=72]="kPropertyMaxLines",e[e.kPropertyMaxWidth=73]="kPropertyMaxWidth",e[e.kPropertyMediaBounds=74]="kPropertyMediaBounds",e[e.kPropertyMediaState=75]="kPropertyMediaState",e[e.kPropertyMinHeight=76]="kPropertyMinHeight",e[e.kPropertyMinWidth=77]="kPropertyMinWidth",e[e.kPropertyNavigation=78]="kPropertyNavigation",e[e.kPropertyNextFocusDown=79]="kPropertyNextFocusDown",e[e.kPropertyNextFocusForward=80]="kPropertyNextFocusForward",e[e.kPropertyNextFocusLeft=81]="kPropertyNextFocusLeft",e[e.kPropertyNextFocusRight=82]="kPropertyNextFocusRight",e[e.kPropertyNextFocusUp=83]="kPropertyNextFocusUp",e[e.kPropertyNotifyChildrenChanged=84]="kPropertyNotifyChildrenChanged",e[e.kPropertyNumbered=85]="kPropertyNumbered",e[e.kPropertyNumbering=86]="kPropertyNumbering",e[e.kPropertyOnBlur=87]="kPropertyOnBlur",e[e.kPropertyOnCancel=88]="kPropertyOnCancel",e[e.kPropertyOnDown=89]="kPropertyOnDown",e[e.kPropertyOnEnd=90]="kPropertyOnEnd",e[e.kPropertyOnFail=91]="kPropertyOnFail",e[e.kPropertyOnFocus=92]="kPropertyOnFocus",e[e.kPropertyOnLoad=93]="kPropertyOnLoad",e[e.kPropertyOnMount=94]="kPropertyOnMount",e[e.kPropertyOnMove=95]="kPropertyOnMove",e[e.kPropertyHandlePageMove=96]="kPropertyHandlePageMove",e[e.kPropertyOnPageChanged=97]="kPropertyOnPageChanged",e[e.kPropertyOnPause=98]="kPropertyOnPause",e[e.kPropertyOnPlay=99]="kPropertyOnPlay",e[e.kPropertyOnPress=100]="kPropertyOnPress",e[e.kPropertyOnScroll=101]="kPropertyOnScroll",e[e.kPropertyOnSubmit=102]="kPropertyOnSubmit",e[e.kPropertyOnTextChange=103]="kPropertyOnTextChange",e[e.kPropertyOnUp=104]="kPropertyOnUp",e[e.kPropertyOnTimeUpdate=105]="kPropertyOnTimeUpdate",e[e.kPropertyOnTrackFail=106]="kPropertyOnTrackFail",e[e.kPropertyOnTrackReady=107]="kPropertyOnTrackReady",e[e.kPropertyOnTrackUpdate=108]="kPropertyOnTrackUpdate",e[e.kPropertyOpacity=109]="kPropertyOpacity",e[e.kPropertyOverlayColor=110]="kPropertyOverlayColor",e[e.kPropertyOverlayGradient=111]="kPropertyOverlayGradient",e[e.kPropertyPadding=112]="kPropertyPadding",e[e.kPropertyPaddingBottom=113]="kPropertyPaddingBottom",e[e.kPropertyPaddingEnd=114]="kPropertyPaddingEnd",e[e.kPropertyPaddingLeft=115]="kPropertyPaddingLeft",e[e.kPropertyPaddingRight=116]="kPropertyPaddingRight",e[e.kPropertyPaddingTop=117]="kPropertyPaddingTop",e[e.kPropertyPaddingStart=118]="kPropertyPaddingStart",e[e.kPropertyPageDirection=119]="kPropertyPageDirection",e[e.kPropertyPageId=120]="kPropertyPageId",e[e.kPropertyPageIndex=121]="kPropertyPageIndex",e[e.kPropertyPlayingState=122]="kPropertyPlayingState",e[e.kPropertyPosition=123]="kPropertyPosition",e[e.kPropertyPreserve=124]="kPropertyPreserve",e[e.kPropertyResourceId=125]="kPropertyResourceId",e[e.kPropertyResourceOnFatalError=126]="kPropertyResourceOnFatalError",e[e.kPropertyResourceState=127]="kPropertyResourceState",e[e.kPropertyResourceType=128]="kPropertyResourceType",e[e.kPropertyRight=129]="kPropertyRight",e[e.kPropertyRole=130]="kPropertyRole",e[e.kPropertyScale=131]="kPropertyScale",e[e.kPropertyScrollAnimation=132]="kPropertyScrollAnimation",e[e.kPropertyScrollOffset=133]="kPropertyScrollOffset",e[e.kPropertyScrollPercent=134]="kPropertyScrollPercent",e[e.kPropertyScrollPosition=135]="kPropertyScrollPosition",e[e.kPropertySecureInput=136]="kPropertySecureInput",e[e.kPropertySelectOnFocus=137]="kPropertySelectOnFocus",e[e.kPropertyShadowColor=138]="kPropertyShadowColor",e[e.kPropertyShadowHorizontalOffset=139]="kPropertyShadowHorizontalOffset",e[e.kPropertyShadowRadius=140]="kPropertyShadowRadius",e[e.kPropertyShadowVerticalOffset=141]="kPropertyShadowVerticalOffset",e[e.kPropertyShrink=142]="kPropertyShrink",e[e.kPropertySize=143]="kPropertySize",e[e.kPropertySnap=144]="kPropertySnap",e[e.kPropertySource=145]="kPropertySource",e[e.kPropertySpacing=146]="kPropertySpacing",e[e.kPropertySpeech=147]="kPropertySpeech",e[e.kPropertyStart=148]="kPropertyStart",e[e.kPropertySubmitKeyType=149]="kPropertySubmitKeyType",e[e.kPropertyText=150]="kPropertyText",e[e.kPropertyTextAlign=151]="kPropertyTextAlign",e[e.kPropertyTextAlignAssigned=152]="kPropertyTextAlignAssigned",e[e.kPropertyTextAlignVertical=153]="kPropertyTextAlignVertical",e[e.kPropertyLang=154]="kPropertyLang",e[e.kPropertyTrackCount=155]="kPropertyTrackCount",e[e.kPropertyTrackCurrentTime=156]="kPropertyTrackCurrentTime",e[e.kPropertyTrackDuration=157]="kPropertyTrackDuration",e[e.kPropertyTrackEnded=158]="kPropertyTrackEnded",e[e.kPropertyTrackIndex=159]="kPropertyTrackIndex",e[e.kPropertyTrackPaused=160]="kPropertyTrackPaused",e[e.kPropertyTrackState=161]="kPropertyTrackState",e[e.kPropertyTransform=162]="kPropertyTransform",e[e.kPropertyTransformAssigned=163]="kPropertyTransformAssigned",e[e.kPropertyTop=164]="kPropertyTop",e[e.kPropertyUser=165]="kPropertyUser",e[e.kPropertyWidth=166]="kPropertyWidth",e[e.kPropertyOnCursorEnter=167]="kPropertyOnCursorEnter",e[e.kPropertyOnCursorExit=168]="kPropertyOnCursorExit",e[e.kPropertyLaidOut=169]="kPropertyLaidOut",e[e.kPropertyValidCharacters=170]="kPropertyValidCharacters",e[e.kPropertyVisualHash=171]="kPropertyVisualHash",e[e.kPropertyWrap=172]="kPropertyWrap"}(t.PropertyKey||(t.PropertyKey={}))},function(e,t,r){"use strict"; +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.APLClient=t():e.APLClient=t()}(window,(function(){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=10)}([function(e,t){e.exports=function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=44)}([function(e,t,r){"use strict";var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function a(e){try{d(n.next(e))}catch(e){o(e)}}function s(e){try{d(n.throw(e))}catch(e){o(e)}}function d(e){e.done?i(e.value):new r((function(t){t(e.value)})).then(a,s)}d((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const i=r(215),o=r(12),a=r(60),s=r(216),d=r(90),u=r(217),c=r(218),l=r(61),p=r(2),f=r(38),h=r(1),y=r(219),m=r(30),g=r(18),v=r(220),b=r(91),P=r(226),k=r(94),S={[a.ComponentType.kComponentTypeContainer]:"Container",[a.ComponentType.kComponentTypeEditText]:"EditText",[a.ComponentType.kComponentTypeFrame]:"Frame",[a.ComponentType.kComponentTypeImage]:"Image",[a.ComponentType.kComponentTypePager]:"Pager",[a.ComponentType.kComponentTypeScrollView]:"ScrollView",[a.ComponentType.kComponentTypeSequence]:"Sequence",[a.ComponentType.kComponentTypeGridSequence]:"GridSequence",[a.ComponentType.kComponentTypeText]:"Text",[a.ComponentType.kComponentTypeTouchWrapper]:"TouchWrapper",[a.ComponentType.kComponentTypeVideo]:"Video",[a.ComponentType.kComponentTypeVectorGraphic]:"VectorGraphic"},T={[l.LayoutDirection.kLayoutDirectionLTR]:"ltr",[l.LayoutDirection.kLayoutDirectionRTL]:"rtl"},E=new Set([a.ComponentType.kComponentTypeFrame,a.ComponentType.kComponentTypePager,a.ComponentType.kComponentTypeScrollView,a.ComponentType.kComponentTypeSequence,a.ComponentType.kComponentTypeGridSequence]),x=new Set([a.ComponentType.kComponentTypeEditText,a.ComponentType.kComponentTypeImage,a.ComponentType.kComponentTypeText,a.ComponentType.kComponentTypeTouchWrapper,a.ComponentType.kComponentTypeVideo]);t.SVG_NS="http://www.w3.org/2000/svg",t.uuidv4=r(63),t.IDENTITY_TRANSFORM="matrix(1.000000,0.000000,0.000000,1.000000,0.000000,0.000000)";class w extends i{constructor(e,t,r,n){if(super(),this.renderer=e,this.component=t,this.factory=r,this.parent=n,this.container=document.createElement("div"),this.$container=o(this.container),this.children=[],this.props={},this.isDestroyed=!1,this.doForceInvisible=!1,this.state={[f.UpdateType.kUpdatePagerPosition]:0,[f.UpdateType.kUpdatePressState]:0,[f.UpdateType.kUpdatePressed]:0,[f.UpdateType.kUpdateScrollPosition]:0,[f.UpdateType.kUpdateTakeFocus]:0},this.executors=new Map,this.propExecutor=(e,...t)=>{for(const r of t)this.executors.set(r,r=>{const n=Object.keys(t);for(const e of n)delete r[parseInt(e,10)];e()});return this.propExecutor},this.setTransform=()=>{if(this.renderer){const e=this.renderer.context.getScaleFactor(),t=v.getScaledTransform(this.props[p.PropertyKey.kPropertyTransform],e);this.$container.css({transform:t})}},this.setOpacity=()=>{this.$container.css("opacity",this.props[p.PropertyKey.kPropertyOpacity])},this.setLayoutDirection=()=>{this.layoutDirection=this.props[p.PropertyKey.kPropertyLayoutDirection],T.hasOwnProperty(this.layoutDirection)||(this.logger.warn(`Layout Direction ${this.layoutDirection} is not supported, defaulting to LTR`),this.layoutDirection=l.LayoutDirection.kLayoutDirectionLTR),this.parent&&this.parent.layoutDirection===this.layoutDirection||(this.container.dir=T[this.layoutDirection])},this.isRtl=()=>this.layoutDirection===l.LayoutDirection.kLayoutDirectionRTL,this.setDisplay=()=>{let e=this.props[p.PropertyKey.kPropertyDisplay];switch(this.hasValidBounds()&&!this.doForceInvisible||(e=s.Display.kDisplayInvisible),e){case s.Display.kDisplayInvisible:case s.Display.kDisplayNone:this.$container.css({display:"none"});break;case s.Display.kDisplayNormal:this.$container.css({display:this.getNormalDisplay()});break;default:this.logger.warn("Incorrect display type: "+e)}},this.setBoundsAndDisplay=()=>{if(this.bounds=this.props[p.PropertyKey.kPropertyBounds],!this.bounds)return;this.setDisplay();let e=0,t=0;if(this.parent&&this.parent.component.getType()===a.ComponentType.kComponentTypeFrame){const r=this.parent.component.getCalculatedByKey(p.PropertyKey.kPropertyBorderWidth);e-=r,t-=r}this.bounds={top:this.bounds.top+e,left:this.bounds.left+t,height:this.bounds.height,width:this.bounds.width};for(const e of this.children)e.setBoundsAndDisplay();k.applyAplRectToStyle({domElement:this.container,rectangle:this.bounds}),this.innerBounds=this.props[p.PropertyKey.kPropertyInnerBounds],k.applyPaddingToStyle({domElement:this.container,bounds:this.bounds,innerBounds:this.innerBounds}),this.boundsUpdated()},this.setUserProperties=()=>{if(!this.renderer)return;const e=this.renderer.getDeveloperToolOptions();if(!e)return;const t=this.props[p.PropertyKey.kPropertyUser],r=e.mappingKey;if(r&&t.hasOwnProperty(r)){const e=t[r]+this.id;this.renderer.componentByMappingKey.set(e,this)}const n=e.writeKeys;if(n&&Array.isArray(n))for(const e of n)t.hasOwnProperty(e)&&this.container.setAttribute(["data",e].join("-"),t[e])},this.handleComponentChildrenChange=()=>{for(const e of this.props[p.PropertyKey.kPropertyNotifyChildrenChanged])e.action===g.ChildAction.Insert||(e.action===g.ChildAction.Remove?void 0!==this.container.children[e.uid]&&this.container.children[e.uid].remove():this.logger.warn(`Invalid action type ${e.action} for child ${e.uid}`));this.ensureDisplayedChildren()},this.getCssShadow=()=>`${this.props[p.PropertyKey.kPropertyShadowHorizontalOffset]}px ${this.props[p.PropertyKey.kPropertyShadowVerticalOffset]}px ${this.props[p.PropertyKey.kPropertyShadowRadius]}px ${w.numberToColor(this.props[p.PropertyKey.kPropertyShadowColor])}`,this.setShadow=()=>{this.applyCssShadow(this.getCssShadow())},this.applyCssShadow=e=>{this.$container.css("box-shadow",e)},this.logger=h.LoggerFactory.getLogger(S[t.getType()]||"Component"),this.$container.css({position:"absolute","transform-origin":"0% 0%","-webkit-box-sizing":"border-box","-moz-box-sizing":"border-box","box-sizing":"border-box"}),this.checkComponentTypeAndEnableClipping(),this.id=t.getUniqueId(),this.$container.attr("id",this.id),this.assignedId=t.getId(),e){e.componentMap[this.id]=this,e.componentIdMap[this.assignedId]=this;const r=e.options;r&&r.developerToolOptions&&r.developerToolOptions.includeComponentId&&this.$container.attr("data-componentid",t.getId())}this.container.classList.add("apl-"+this.constructor.name.toLowerCase()),this.parent=n,this.propExecutor(this.setTransform,p.PropertyKey.kPropertyTransform)(this.setLayoutDirection,p.PropertyKey.kPropertyLayoutDirection)(this.setBoundsAndDisplay,p.PropertyKey.kPropertyBounds,p.PropertyKey.kPropertyInnerBounds,p.PropertyKey.kPropertyDisplay)(this.setOpacity,p.PropertyKey.kPropertyOpacity)(this.setUserProperties,p.PropertyKey.kPropertyUser)(this.handleComponentChildrenChange,p.PropertyKey.kPropertyNotifyChildrenChanged)(this.setShadow,p.PropertyKey.kPropertyShadowHorizontalOffset,p.PropertyKey.kPropertyShadowVerticalOffset,p.PropertyKey.kPropertyShadowRadius,p.PropertyKey.kPropertyShadowColor)}init(){const e=this.getDisplayedChildren();for(let t=0;te.id===n.getUniqueId()).shift();e[r]=void 0!==i?i:this.factory(this.renderer,n,this,!0,r)}this.children.forEach(t=>{e.some(e=>e.id===t.id)||t.destroy()}),this.children=e}getDisplayedChildCount(){return this.component.getDisplayedChildCount()}getDisplayedChildren(){const e=[],t=this.component.getDisplayedChildCount();for(let r=0;r{const r=parseInt(t,10);this.props[r]=e[r]}),Object.keys(e).forEach(t=>{const r=parseInt(t,10);if(r in e){const t=this.executors.get(r);t&&t(e)}}),this.onPropertiesUpdated()}updateDirtyProps(){const e=this.component.getDirtyProps();this.setProperties(e)}update(e,t){"string"==typeof t?(this.state[e]=t.toString(),this.component.updateEditText(e,t.toString())):(this.state[e]=t,this.component.update(e,t))}destroy(e=!1){this.container&&this.container.parentElement&&this.container.parentElement.removeChild(this.container),this.isDestroyed=!0,this.parent=void 0,delete this.renderer.componentMap[this.id],delete this.renderer.componentMap[this.assignedId],this.renderer=void 0;for(const t of this.children)t.destroy(e);this.children=void 0,e&&(this.component.delete(),this.component=void 0)}static numberToColor(e){return m.numberToColor(e)}static getGradientSpreadMethod(e){switch(e){case u.GradientSpreadMethod.REFLECT:return"reflect";case u.GradientSpreadMethod.REPEAT:return"repeat";case u.GradientSpreadMethod.PAD:default:return"pad"}}static getGradientUnits(e){switch(e){case c.GradientUnits.kGradientUnitsUserSpace:return"userSpaceOnUse";case c.GradientUnits.kGradientUnitsBoundingBox:default:return"objectBoundingBox"}}static fillAndStrokeConverter(e,t,r,n){return b.fillAndStrokeConverter({value:e,transform:t,parent:r,logger:n})}hasValidBounds(){return this.bounds.width>0&&this.bounds.width<1e6}static getClipPathElementId(e,r){if(!e||""===e)return"";const n=document.createElementNS(t.SVG_NS,"defs"),i=document.createElementNS(t.SVG_NS,"clipPath"),o=document.createElementNS(t.SVG_NS,"path"),a=t.uuidv4().toString();return i.setAttributeNS("","id",a),o.setAttributeNS("","d",e.toString()),i.appendChild(o),n.appendChild(i),r.appendChild(n),`url('#${a}')`}inflateAndAddChild(e,t){const r=this.component.inflateChild(t,e);let n;return r&&(n=this.factory(this.renderer,r,this,!0,e),this.children.splice(e,0,n)),n}remove(){return!!this.component.remove()&&(this.parent&&this.parent.children&&this.parent.children.splice(this.parent.children.indexOf(this),1),this.destroy(!0),!0)}boundsUpdated(){}isLayout(){return!1}sizeToFit(){if(this.renderer&&this.renderer.getLegacyClippingEnabled())return;const e=!!this.bounds,t=!!this.parent,r=this.layoutDirection===l.LayoutDirection.kLayoutDirectionLTR;if(!(e&&t&&r))return;const n=this.parent.component.getType()===a.ComponentType.kComponentTypeContainer,i=this.isLayout();if(!n||!i)return;const o=P.createBoundsFitter({containingBounds:this.parent.bounds,innerBounds:this.bounds,layoutDirection:this.layoutDirection}).fitBounds();if(o===this.bounds)return;const{width:s,height:d}=o,{width:u,height:c}=this.bounds;this.logger.warn(`Component ${this.id} has bounds that is bigger than parent bounds.\nCheck your template correctness.\nAdjusting ${this.id} to parent ${this.parent.id}\nWIDTH: ${u} => ${s}\nHEIGHT: ${c} => ${d}\n`);const p=y.getRectDifference(this.bounds,o);this.bounds=o,this.innerBounds&&((this.innerBounds.width>this.bounds.width||this.innerBounds.height>this.bounds.height)&&(this.innerBounds=y.getRectDifference(this.innerBounds,p)),k.applyAplRectToStyle({domElement:this.container,rectangle:this.bounds}),k.applyPaddingToStyle({domElement:this.container,bounds:this.bounds,innerBounds:this.innerBounds}),this.boundsUpdated())}alignSize(){return this.sizeToFit()}getProperties(){return this.component.getCalculated()}forceInvisible(e){this.doForceInvisible!==e&&(this.doForceInvisible=e,this.setDisplay())}getNormalDisplay(){return""}takeFocus(){return n(this,void 0,void 0,(function*(){const e=(yield this.renderer.context.getFocusableAreas())[this.id];e&&this.renderer.context.setFocus(d.FocusDirection.kFocusDirectionNone,e,this.id)}))}get lang(){return this.props[p.PropertyKey.kPropertyLang]||""}checkComponentTypeAndEnableClipping(){const e=this.component.getType();if(x.has(e))return;const t=this.parent&&E.has(this.parent.component.getType()),r=E.has(e),n=this.renderer&&this.renderer.getLegacyClippingEnabled();(r||t||!n)&&this.enableClipping()}enableClipping(){this.$container.css("overflow","hidden")}}t.Component=w},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const n=r(144);class i{static initialize(e,t){this.rootLogger.setDefaultLevel(e),this.rootLogger.methodFactory=(e,r,n)=>{const o=i.originalFactory(e,r,n);return r=>{t?t(e,n,r):o(`${e[0].toUpperCase()} ${n}: ${r}`)}},this.rootLogger.setLevel(this.rootLogger.getLevel()),this.initialized=!0}static getLogger(e){return this.initialized||this.initialize("info"),this.rootLogger.getLogger(e)}}i.rootLogger=n,i.originalFactory=i.rootLogger.methodFactory,i.initialized=!1,t.LoggerFactory=i},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e[e.kPropertyScrollDirection=0]="kPropertyScrollDirection",e[e.kPropertyAccessibilityActions=1]="kPropertyAccessibilityActions",e[e.kPropertyAccessibilityLabel=2]="kPropertyAccessibilityLabel",e[e.kPropertyAlign=3]="kPropertyAlign",e[e.kPropertyAlignItems=4]="kPropertyAlignItems",e[e.kPropertyAlignSelf=5]="kPropertyAlignSelf",e[e.kPropertyAudioTrack=6]="kPropertyAudioTrack",e[e.kPropertyAutoplay=7]="kPropertyAutoplay",e[e.kPropertyMuted=8]="kPropertyMuted",e[e.kPropertyBackgroundColor=9]="kPropertyBackgroundColor",e[e.kPropertyBorderBottomLeftRadius=10]="kPropertyBorderBottomLeftRadius",e[e.kPropertyBorderBottomRightRadius=11]="kPropertyBorderBottomRightRadius",e[e.kPropertyBorderColor=12]="kPropertyBorderColor",e[e.kPropertyBorderRadius=13]="kPropertyBorderRadius",e[e.kPropertyBorderRadii=14]="kPropertyBorderRadii",e[e.kPropertyBorderStrokeWidth=15]="kPropertyBorderStrokeWidth",e[e.kPropertyBorderTopLeftRadius=16]="kPropertyBorderTopLeftRadius",e[e.kPropertyBorderTopRightRadius=17]="kPropertyBorderTopRightRadius",e[e.kPropertyBorderWidth=18]="kPropertyBorderWidth",e[e.kPropertyBottom=19]="kPropertyBottom",e[e.kPropertyBounds=20]="kPropertyBounds",e[e.kPropertyCenterId=21]="kPropertyCenterId",e[e.kPropertyCenterIndex=22]="kPropertyCenterIndex",e[e.kPropertyChildHeight=23]="kPropertyChildHeight",e[e.kPropertyChildWidth=24]="kPropertyChildWidth",e[e.kPropertyChecked=25]="kPropertyChecked",e[e.kPropertyColor=26]="kPropertyColor",e[e.kPropertyColorKaraokeTarget=27]="kPropertyColorKaraokeTarget",e[e.kPropertyColorNonKaraoke=28]="kPropertyColorNonKaraoke",e[e.kPropertyCurrentPage=29]="kPropertyCurrentPage",e[e.kPropertyDescription=30]="kPropertyDescription",e[e.kPropertyDirection=31]="kPropertyDirection",e[e.kPropertyDisabled=32]="kPropertyDisabled",e[e.kPropertyDisplay=33]="kPropertyDisplay",e[e.kPropertyDrawnBorderWidth=34]="kPropertyDrawnBorderWidth",e[e.kPropertyEnd=35]="kPropertyEnd",e[e.kPropertyEntities=36]="kPropertyEntities",e[e.kPropertyFastScrollScale=37]="kPropertyFastScrollScale",e[e.kPropertyFilters=38]="kPropertyFilters",e[e.kPropertyFirstId=39]="kPropertyFirstId",e[e.kPropertyFirstIndex=40]="kPropertyFirstIndex",e[e.kPropertyFocusable=41]="kPropertyFocusable",e[e.kPropertyFontFamily=42]="kPropertyFontFamily",e[e.kPropertyFontSize=43]="kPropertyFontSize",e[e.kPropertyFontStyle=44]="kPropertyFontStyle",e[e.kPropertyFontWeight=45]="kPropertyFontWeight",e[e.kPropertyHandleTick=46]="kPropertyHandleTick",e[e.kPropertyHighlightColor=47]="kPropertyHighlightColor",e[e.kPropertyHint=48]="kPropertyHint",e[e.kPropertyHintColor=49]="kPropertyHintColor",e[e.kPropertyHintStyle=50]="kPropertyHintStyle",e[e.kPropertyHintWeight=51]="kPropertyHintWeight",e[e.kPropertyGestures=52]="kPropertyGestures",e[e.kPropertyGraphic=53]="kPropertyGraphic",e[e.kPropertyGrow=54]="kPropertyGrow",e[e.kPropertyHandleKeyDown=55]="kPropertyHandleKeyDown",e[e.kPropertyHandleKeyUp=56]="kPropertyHandleKeyUp",e[e.kPropertyHeight=57]="kPropertyHeight",e[e.kPropertyId=58]="kPropertyId",e[e.kPropertyInitialPage=59]="kPropertyInitialPage",e[e.kPropertyInnerBounds=60]="kPropertyInnerBounds",e[e.kPropertyItemsPerCourse=61]="kPropertyItemsPerCourse",e[e.kPropertyJustifyContent=62]="kPropertyJustifyContent",e[e.kPropertyKeyboardBehaviorOnFocus=63]="kPropertyKeyboardBehaviorOnFocus",e[e.kPropertyKeyboardType=64]="kPropertyKeyboardType",e[e.kPropertyLayoutDirection=65]="kPropertyLayoutDirection",e[e.kPropertyLayoutDirectionAssigned=66]="kPropertyLayoutDirectionAssigned",e[e.kPropertyLeft=67]="kPropertyLeft",e[e.kPropertyLetterSpacing=68]="kPropertyLetterSpacing",e[e.kPropertyLineHeight=69]="kPropertyLineHeight",e[e.kPropertyMaxHeight=70]="kPropertyMaxHeight",e[e.kPropertyMaxLength=71]="kPropertyMaxLength",e[e.kPropertyMaxLines=72]="kPropertyMaxLines",e[e.kPropertyMaxWidth=73]="kPropertyMaxWidth",e[e.kPropertyMediaBounds=74]="kPropertyMediaBounds",e[e.kPropertyMediaState=75]="kPropertyMediaState",e[e.kPropertyMinHeight=76]="kPropertyMinHeight",e[e.kPropertyMinWidth=77]="kPropertyMinWidth",e[e.kPropertyNavigation=78]="kPropertyNavigation",e[e.kPropertyNextFocusDown=79]="kPropertyNextFocusDown",e[e.kPropertyNextFocusForward=80]="kPropertyNextFocusForward",e[e.kPropertyNextFocusLeft=81]="kPropertyNextFocusLeft",e[e.kPropertyNextFocusRight=82]="kPropertyNextFocusRight",e[e.kPropertyNextFocusUp=83]="kPropertyNextFocusUp",e[e.kPropertyNotifyChildrenChanged=84]="kPropertyNotifyChildrenChanged",e[e.kPropertyNumbered=85]="kPropertyNumbered",e[e.kPropertyNumbering=86]="kPropertyNumbering",e[e.kPropertyOnBlur=87]="kPropertyOnBlur",e[e.kPropertyOnCancel=88]="kPropertyOnCancel",e[e.kPropertyOnDown=89]="kPropertyOnDown",e[e.kPropertyOnEnd=90]="kPropertyOnEnd",e[e.kPropertyOnFail=91]="kPropertyOnFail",e[e.kPropertyOnFocus=92]="kPropertyOnFocus",e[e.kPropertyOnLoad=93]="kPropertyOnLoad",e[e.kPropertyOnMount=94]="kPropertyOnMount",e[e.kPropertyOnMove=95]="kPropertyOnMove",e[e.kPropertyOnSpeechMark=96]="kPropertyOnSpeechMark",e[e.kPropertyHandlePageMove=97]="kPropertyHandlePageMove",e[e.kPropertyOnPageChanged=98]="kPropertyOnPageChanged",e[e.kPropertyOnPause=99]="kPropertyOnPause",e[e.kPropertyOnPlay=100]="kPropertyOnPlay",e[e.kPropertyOnPress=101]="kPropertyOnPress",e[e.kPropertyOnScroll=102]="kPropertyOnScroll",e[e.kPropertyOnSubmit=103]="kPropertyOnSubmit",e[e.kPropertyOnTextChange=104]="kPropertyOnTextChange",e[e.kPropertyOnUp=105]="kPropertyOnUp",e[e.kPropertyOnTimeUpdate=106]="kPropertyOnTimeUpdate",e[e.kPropertyOnTrackFail=107]="kPropertyOnTrackFail",e[e.kPropertyOnTrackReady=108]="kPropertyOnTrackReady",e[e.kPropertyOnTrackUpdate=109]="kPropertyOnTrackUpdate",e[e.kPropertyOpacity=110]="kPropertyOpacity",e[e.kPropertyOverlayColor=111]="kPropertyOverlayColor",e[e.kPropertyOverlayGradient=112]="kPropertyOverlayGradient",e[e.kPropertyPadding=113]="kPropertyPadding",e[e.kPropertyPaddingBottom=114]="kPropertyPaddingBottom",e[e.kPropertyPaddingEnd=115]="kPropertyPaddingEnd",e[e.kPropertyPaddingLeft=116]="kPropertyPaddingLeft",e[e.kPropertyPaddingRight=117]="kPropertyPaddingRight",e[e.kPropertyPaddingTop=118]="kPropertyPaddingTop",e[e.kPropertyPaddingStart=119]="kPropertyPaddingStart",e[e.kPropertyPageDirection=120]="kPropertyPageDirection",e[e.kPropertyPageId=121]="kPropertyPageId",e[e.kPropertyPageIndex=122]="kPropertyPageIndex",e[e.kPropertyPlayingState=123]="kPropertyPlayingState",e[e.kPropertyPosition=124]="kPropertyPosition",e[e.kPropertyPreserve=125]="kPropertyPreserve",e[e.kPropertyRangeKaraokeTarget=126]="kPropertyRangeKaraokeTarget",e[e.kPropertyResourceId=127]="kPropertyResourceId",e[e.kPropertyResourceOnFatalError=128]="kPropertyResourceOnFatalError",e[e.kPropertyResourceState=129]="kPropertyResourceState",e[e.kPropertyResourceType=130]="kPropertyResourceType",e[e.kPropertyRight=131]="kPropertyRight",e[e.kPropertyRole=132]="kPropertyRole",e[e.kPropertyScale=133]="kPropertyScale",e[e.kPropertyScrollAnimation=134]="kPropertyScrollAnimation",e[e.kPropertyScrollOffset=135]="kPropertyScrollOffset",e[e.kPropertyScrollPercent=136]="kPropertyScrollPercent",e[e.kPropertyScrollPosition=137]="kPropertyScrollPosition",e[e.kPropertySecureInput=138]="kPropertySecureInput",e[e.kPropertySelectOnFocus=139]="kPropertySelectOnFocus",e[e.kPropertyShadowColor=140]="kPropertyShadowColor",e[e.kPropertyShadowHorizontalOffset=141]="kPropertyShadowHorizontalOffset",e[e.kPropertyShadowRadius=142]="kPropertyShadowRadius",e[e.kPropertyShadowVerticalOffset=143]="kPropertyShadowVerticalOffset",e[e.kPropertyShrink=144]="kPropertyShrink",e[e.kPropertySize=145]="kPropertySize",e[e.kPropertySnap=146]="kPropertySnap",e[e.kPropertySource=147]="kPropertySource",e[e.kPropertySpacing=148]="kPropertySpacing",e[e.kPropertySpeech=149]="kPropertySpeech",e[e.kPropertyStart=150]="kPropertyStart",e[e.kPropertySubmitKeyType=151]="kPropertySubmitKeyType",e[e.kPropertyText=152]="kPropertyText",e[e.kPropertyTextAlign=153]="kPropertyTextAlign",e[e.kPropertyTextAlignAssigned=154]="kPropertyTextAlignAssigned",e[e.kPropertyTextAlignVertical=155]="kPropertyTextAlignVertical",e[e.kPropertyLang=156]="kPropertyLang",e[e.kPropertyTrackCount=157]="kPropertyTrackCount",e[e.kPropertyTrackCurrentTime=158]="kPropertyTrackCurrentTime",e[e.kPropertyTrackDuration=159]="kPropertyTrackDuration",e[e.kPropertyTrackEnded=160]="kPropertyTrackEnded",e[e.kPropertyTrackIndex=161]="kPropertyTrackIndex",e[e.kPropertyTrackPaused=162]="kPropertyTrackPaused",e[e.kPropertyTrackState=163]="kPropertyTrackState",e[e.kPropertyTransform=164]="kPropertyTransform",e[e.kPropertyTransformAssigned=165]="kPropertyTransformAssigned",e[e.kPropertyTop=166]="kPropertyTop",e[e.kPropertyUser=167]="kPropertyUser",e[e.kPropertyWidth=168]="kPropertyWidth",e[e.kPropertyOnCursorEnter=169]="kPropertyOnCursorEnter",e[e.kPropertyOnCursorExit=170]="kPropertyOnCursorExit",e[e.kPropertyLaidOut=171]="kPropertyLaidOut",e[e.kPropertyValidCharacters=172]="kPropertyValidCharacters",e[e.kPropertyVisualHash=173]="kPropertyVisualHash",e[e.kPropertyWrap=174]="kPropertyWrap"}(t.PropertyKey||(t.PropertyKey={}))},function(e,t){var r=e.exports={version:"2.6.11"};"number"==typeof __e&&(__e=r)},function(e,t,r){var n=r(52)("wks"),i=r(37),o=r(6).Symbol,a="function"==typeof o;(e.exports=function(e){return n[e]||(n[e]=a&&o[e]||(a?o:i)("Symbol."+e))}).store=n},function(e,t,r){"use strict"; /*! * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 - */var n=this&&this.__awaiter||function(e,t,r,n){return new(r||(r=Promise))((function(i,o){function a(e){try{d(n.next(e))}catch(e){o(e)}}function s(e){try{d(n.throw(e))}catch(e){o(e)}}function d(e){e.done?i(e.value):new r((function(t){t(e.value)})).then(a,s)}d((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const i=r(46),o=r(2),a=r(0),s={[i.EventType.kEventTypeSendEvent]:"SendEvent",[i.EventType.kEventTypeControlMedia]:"ControlMedia",[i.EventType.kEventTypePlayMedia]:"PlayMedia",[i.EventType.kEventTypeRequestFirstLineBounds]:"RequestFirstLineBounds",[i.EventType.kEventTypePreroll]:"Preroll",[i.EventType.kEventTypeSpeak]:"Speak",[i.EventType.kEventTypeFinish]:"Finish",[i.EventType.kEventTypeFocus]:"Focus",[i.EventType.kEventTypeOpenURL]:"OpenURL",[i.EventType.kEventTypeExtension]:"Extension",[i.EventType.kEventTypeDataSourceFetchRequest]:"DataSourceFetchRequest"};t.Event=class{constructor(e,t){this.event=e,this.renderer=t,this.isTerminated=!1,this.type=s[e.getType()]||"Event",this.logger=a.LoggerFactory.getLogger(this.type),e.addTerminateCallback(()=>{this.terminate()})}terminate(){this.isTerminated=!0}resolve(){this.event.resolve()}waitForValidLayout(e){return n(this,void 0,void 0,(function*(){for(;;){const t=e.getCalculatedByKey(o.PropertyKey.kPropertyBounds);if(t.width>0&&t.width<1e6)break;yield this.waitAFrame()}}))}wait(e){return new Promise(t=>{setTimeout(t,e)})}waitAFrame(){const e=Date.now();return new Promise(t=>{requestAnimationFrame(()=>{t(Date.now()-e)})})}destroy(){this.renderer=void 0,this.event=void 0}}},function(e,t){var r=e.exports={version:"2.6.11"};"number"==typeof __e&&(__e=r)},function(e,t,r){var n=r(56)("wks"),i=r(38),o=r(7).Symbol,a="function"==typeof o;(e.exports=function(e){return n[e]||(n[e]=a&&o[e]||(a?o:i)("Symbol."+e))}).store=n},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e[e.kEventPropertyAlign=0]="kEventPropertyAlign",e[e.kEventPropertyArguments=1]="kEventPropertyArguments",e[e.kEventPropertyAudioTrack=2]="kEventPropertyAudioTrack",e[e.kEventPropertyCommand=3]="kEventPropertyCommand",e[e.kEventPropertyComponent=4]="kEventPropertyComponent",e[e.kEventPropertyComponents=5]="kEventPropertyComponents",e[e.kEventPropertyDirection=6]="kEventPropertyDirection",e[e.kEventPropertyExtension=7]="kEventPropertyExtension",e[e.kEventPropertyExtensionURI=8]="kEventPropertyExtensionURI",e[e.kEventPropertyExtensionResourceId=9]="kEventPropertyExtensionResourceId",e[e.kEventPropertyFlags=10]="kEventPropertyFlags",e[e.kEventPropertyHeaders=11]="kEventPropertyHeaders",e[e.kEventPropertyHighlightMode=12]="kEventPropertyHighlightMode",e[e.kEventPropertyMediaType=13]="kEventPropertyMediaType",e[e.kEventPropertyName=14]="kEventPropertyName",e[e.kEventPropertyPosition=15]="kEventPropertyPosition",e[e.kEventPropertyReason=16]="kEventPropertyReason",e[e.kEventPropertySource=17]="kEventPropertySource",e[e.kEventPropertyValue=18]="kEventPropertyValue"}(t.EventProperty||(t.EventProperty={}))},function(e,t){var r=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(e,t){e.exports=function(e){return e&&e.__esModule?e:{default:e}}},function(e,t,r){var n=r(7),i=r(4),o=r(84),a=r(16),s=r(11),d=function(e,t,r){var u,c,l,p=e&d.F,f=e&d.G,h=e&d.S,y=e&d.P,m=e&d.B,g=e&d.W,v=f?i:i[t]||(i[t]={}),b=v.prototype,k=f?n:h?n[t]:(n[t]||{}).prototype;for(u in f&&(r=t),r)(c=!p&&k&&void 0!==k[u])&&s(v,u)||(l=c?k[u]:r[u],v[u]=f&&"function"!=typeof k[u]?r[u]:m&&c?o(l,n):g&&k[u]==l?function(e){var t=function(t,r,n){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,r)}return new e(t,r,n)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(l):y&&"function"==typeof l?o(Function.call,l):l,y&&((v.virtual||(v.virtual={}))[u]=l,e&d.R&&b&&!b[u]&&a(b,u,l)))};d.F=1,d.G=2,d.S=4,d.P=8,d.B=16,d.W=32,d.U=64,d.R=128,e.exports=d},function(e,t,r){var n=r(17),i=r(85),o=r(50),a=Object.defineProperty;t.f=r(18)?Object.defineProperty:function(e,t,r){if(n(e),t=o(t,!0),n(r),i)try{return a(e,t,r)}catch(e){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(e[t]=r.value),e}},function(e,t){var r={}.hasOwnProperty;e.exports=function(e,t){return r.call(e,t)}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Resource=class{constructor(){this.downloadState="pending"}setDownloadState(e){this.downloadState=e}getDownloadState(){return this.downloadState}getBuffer(){return this.buffer}setBuffer(e){this.buffer=e}},function(e){e.PENDING="pending",e.PREPARED="prepared",e.PLAYING="playing",e.PAUSED="paused"}(t.ResourceState||(t.ResourceState={})),function(e){e.PLAY="play",e.PAUSE="pause",e.NEXT="next",e.PREVIOUS="previous",e.REWIND="rewind",e.SEEK="seek",e.SETTRACK="setTrack"}(t.ControlMediaCommandName||(t.ControlMediaCommandName={})),function(e){e.IDLE="idling",e.LOADED="loaded",e.PLAYING="playing",e.ENDED="ended",e.PAUSED="paused",e.BUFFERING="buffering",e.ERROR="error"}(t.PlaybackState||(t.PlaybackState={}))},function(e,t,r){var n,i,o;!function(r,a){"use strict";i=[t],void 0!==(o="function"==typeof(n=function(e){var t,r=(t=[],function(e){return t[0]=128==(128&e)?"1":"0",t[1]=64==(64&e)?"1":"0",t[2]=32==(32&e)?"1":"0",t[3]=16==(16&e)?"1":"0",t[4]=8==(8&e)?"1":"0",t[5]=4==(4&e)?"1":"0",t[6]=2==(2&e)?"1":"0",t[7]=1==(1&e)?"1":"0",t.join("")});e.getFrameByteLength=function(t,r,n,i,o){var a=e.sampleLengthMap[i][o],s=n?"11"===o?4:1:0,d=1e3*t/8;return Math.floor(a*d/r+s)},e.getXingOffset=function(e,t){var r="11"===t;return"11"===e?r?21:36:r?13:21},e.v1l1Bitrates={"0000":"free","0001":32,"0010":64,"0011":96,"0100":128,"0101":160,"0110":192,"0111":224,1e3:256,1001:288,1010:320,1011:352,1100:384,1101:416,1110:448,1111:"bad"},e.v1l2Bitrates={"0000":"free","0001":32,"0010":48,"0011":56,"0100":64,"0101":80,"0110":96,"0111":112,1e3:128,1001:160,1010:192,1011:224,1100:256,1101:320,1110:384,1111:"bad"},e.v1l3Bitrates={"0000":"free","0001":32,"0010":40,"0011":48,"0100":56,"0101":64,"0110":80,"0111":96,1e3:112,1001:128,1010:160,1011:192,1100:224,1101:256,1110:320,1111:"bad"},e.v2l1Bitrates={"0000":"free","0001":32,"0010":48,"0011":56,"0100":64,"0101":80,"0110":96,"0111":112,1e3:128,1001:144,1010:160,1011:176,1100:192,1101:224,1110:256,1111:"bad"},e.v2l2Bitrates={"0000":"free","0001":8,"0010":16,"0011":24,"0100":32,"0101":40,"0110":48,"0111":56,1e3:64,1001:80,1010:96,1011:112,1100:128,1101:144,1110:160,1111:"bad"},e.v2l3Bitrates=e.v2l2Bitrates,e.v1SamplingRates={"00":44100,"01":48e3,10:32e3,11:"reserved"},e.v2SamplingRates={"00":22050,"01":24e3,10:16e3,11:"reserved"},e.v25SamplingRates={"00":11025,"01":12e3,10:8e3,11:"reserved"},e.channelModes={"00":"Stereo","01":"Joint stereo (Stereo)",10:"Dual channel (Stereo)",11:"Single channel (Mono)"},e.mpegVersionDescription={"00":"MPEG Version 2.5 (unofficial)","01":"reserved",10:"MPEG Version 2 (ISO/IEC 13818-3)",11:"MPEG Version 1 (ISO/IEC 11172-3)"},e.layerDescription={"00":"reserved","01":"Layer III",10:"Layer II",11:"Layer I"},e.bitrateMap={11:{"01":e.v1l3Bitrates,10:e.v1l2Bitrates,11:e.v1l1Bitrates},10:{"01":e.v2l3Bitrates,10:e.v2l2Bitrates,11:e.v2l1Bitrates}},e.samplingRateMap={"00":e.v25SamplingRates,10:e.v2SamplingRates,11:e.v1SamplingRates},e.v1SampleLengths={"01":1152,10:1152,11:384},e.v2SampleLengths={"01":576,10:1152,11:384},e.sampleLengthMap={"01":e.v2SampleLengths,10:e.v2SampleLengths,11:e.v1SampleLengths},e.wordSeqFromStr=function(e){for(var t=e.length-1,r=[];t>=0;--t)r[t]=e.charCodeAt(t);return r},e.seq={id3:e.wordSeqFromStr("ID3"),xing:e.wordSeqFromStr("Xing"),info:e.wordSeqFromStr("Info")},e.noOp=function(){},e.unsynchsafe=function(e){for(var t=0,r=2130706432;r;)t>>=1,t|=e&r,r>>=8;return t},e.isSeq=function(e,t,r){for(var n=e.length-1;n>=0;n--)if(e[n]!==t.getUint8(r+n))return!1;return!0},e.locateSeq=function(t,r,n,i){for(var o=0,a=i-t.length+1;o{this.terminate()})}terminate(){this.isTerminated=!0}resolve(){this.event.resolve()}waitForValidLayout(e){return n(this,void 0,void 0,(function*(){for(;;){const t=e.getCalculatedByKey(o.PropertyKey.kPropertyBounds);if(t.width>0&&t.width<1e6)break;yield this.waitAFrame()}}))}wait(e){return new Promise(t=>{setTimeout(t,e)})}waitAFrame(){const e=Date.now();return new Promise(t=>{requestAnimationFrame(()=>{t(Date.now()-e)})})}destroy(){this.renderer=void 0,this.event=void 0}}},function(e,t){var r=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e[e.kEventPropertyAlign=0]="kEventPropertyAlign",e[e.kEventPropertyArguments=1]="kEventPropertyArguments",e[e.kEventPropertyAudioTrack=2]="kEventPropertyAudioTrack",e[e.kEventPropertyCommand=3]="kEventPropertyCommand",e[e.kEventPropertyComponent=4]="kEventPropertyComponent",e[e.kEventPropertyComponents=5]="kEventPropertyComponents",e[e.kEventPropertyDirection=6]="kEventPropertyDirection",e[e.kEventPropertyExtension=7]="kEventPropertyExtension",e[e.kEventPropertyExtensionURI=8]="kEventPropertyExtensionURI",e[e.kEventPropertyExtensionResourceId=9]="kEventPropertyExtensionResourceId",e[e.kEventPropertyFlags=10]="kEventPropertyFlags",e[e.kEventPropertyHeaders=11]="kEventPropertyHeaders",e[e.kEventPropertyHighlightMode=12]="kEventPropertyHighlightMode",e[e.kEventPropertyMediaType=13]="kEventPropertyMediaType",e[e.kEventPropertyName=14]="kEventPropertyName",e[e.kEventPropertyPosition=15]="kEventPropertyPosition",e[e.kEventPropertyRangeStart=16]="kEventPropertyRangeStart",e[e.kEventPropertyRangeEnd=17]="kEventPropertyRangeEnd",e[e.kEventPropertyReason=18]="kEventPropertyReason",e[e.kEventPropertySource=19]="kEventPropertySource",e[e.kEventPropertyValue=20]="kEventPropertyValue"}(t.EventProperty||(t.EventProperty={}))},function(e,t){e.exports=function(e){return e&&e.__esModule?e:{default:e}}},function(e,t,r){var n=r(6),i=r(3),o=r(75),a=r(13),s=r(11),d=function(e,t,r){var u,c,l,p=e&d.F,f=e&d.G,h=e&d.S,y=e&d.P,m=e&d.B,g=e&d.W,v=f?i:i[t]||(i[t]={}),b=v.prototype,P=f?n:h?n[t]:(n[t]||{}).prototype;for(u in f&&(r=t),r)(c=!p&&P&&void 0!==P[u])&&s(v,u)||(l=c?P[u]:r[u],v[u]=f&&"function"!=typeof P[u]?r[u]:m&&c?o(l,n):g&&P[u]==l?function(e){var t=function(t,r,n){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,r)}return new e(t,r,n)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(l):y&&"function"==typeof l?o(Function.call,l):l,y&&((v.virtual||(v.virtual={}))[u]=l,e&d.R&&b&&!b[u]&&a(b,u,l)))};d.F=1,d.G=2,d.S=4,d.P=8,d.B=16,d.W=32,d.U=64,d.R=128,e.exports=d},function(e,t,r){var n=r(14),i=r(76),o=r(46),a=Object.defineProperty;t.f=r(15)?Object.defineProperty:function(e,t,r){if(n(e),t=o(t,!0),n(r),i)try{return a(e,t,r)}catch(e){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(e[t]=r.value),e}},function(e,t){var r={}.hasOwnProperty;e.exports=function(e,t){return r.call(e,t)}},function(e,t,r){var n; /*! * jQuery JavaScript Library v3.5.1 * https://jquery.com/ @@ -15,7 +15,7 @@ * https://jquery.org/license * * Date: 2020-05-04T22:49Z - */!function(t,r){"use strict";"object"==typeof e.exports?e.exports=t.document?r(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return r(e)}:r(t)}("undefined"!=typeof window?window:this,(function(r,i){"use strict";var o=[],a=Object.getPrototypeOf,s=o.slice,d=o.flat?function(e){return o.flat.call(e)}:function(e){return o.concat.apply([],e)},u=o.push,c=o.indexOf,l={},p=l.toString,f=l.hasOwnProperty,h=f.toString,y=h.call(Object),m={},g=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},v=function(e){return null!=e&&e===e.window},b=r.document,k={type:!0,src:!0,nonce:!0,noModule:!0};function P(e,t,r){var n,i,o=(r=r||b).createElement("script");if(o.text=e,t)for(n in k)(i=t[n]||t.getAttribute&&t.getAttribute(n))&&o.setAttribute(n,i);r.head.appendChild(o).parentNode.removeChild(o)}function S(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[p.call(e)]||"object":typeof e}var T=function(e,t){return new T.fn.init(e,t)};function E(e){var t=!!e&&"length"in e&&e.length,r=S(e);return!g(e)&&!v(e)&&("array"===r||0===t||"number"==typeof t&&t>0&&t-1 in e)}T.fn=T.prototype={jquery:"3.5.1",constructor:T,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=T.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return T.each(this,e)},map:function(e){return this.pushStack(T.map(this,(function(t,r){return e.call(t,r,t)})))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(T.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(T.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,r=+e+(e<0?t:0);return this.pushStack(r>=0&&r0&&t-1 in e)}T.fn=T.prototype={jquery:"3.5.1",constructor:T,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=T.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return T.each(this,e)},map:function(e){return this.pushStack(T.map(this,(function(t,r){return e.call(t,r,t)})))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(T.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(T.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,r=+e+(e<0?t:0);return this.pushStack(r>=0&&r+~]|"+N+")"+N+"*"),z=new RegExp(N+"|>"),q=new RegExp(U),W=new RegExp("^"+G+"$"),$={ID:new RegExp("^#("+G+")"),CLASS:new RegExp("^\\.("+G+")"),TAG:new RegExp("^("+G+"|[*])"),ATTR:new RegExp("^"+B),PSEUDO:new RegExp("^"+U),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+N+"*(even|odd|(([+-]|)(\\d*)n|)"+N+"*(?:([+-]|)"+N+"*(\\d+)|))"+N+"*\\)|)","i"),bool:new RegExp("^(?:"+F+")$","i"),needsContext:new RegExp("^"+N+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+N+"*((?:-\\d)?\\d*)"+N+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,X=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+N+"?|\\\\([^\\r\\n\\f])","g"),re=function(e,t){var r="0x"+e.slice(1)-65536;return t||(r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320))},ne=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){p()},ae=ke((function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{M.apply(L=D.call(P.childNodes),P.childNodes),L[P.childNodes.length].nodeType}catch(e){M={apply:L.length?function(e,t){R.apply(e,D.call(t))}:function(e,t){for(var r=e.length,n=0;e[r++]=t[n++];);e.length=r-1}}}function se(e,t,n,i){var o,s,u,c,l,h,g,v=t&&t.ownerDocument,P=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==P&&9!==P&&11!==P)return n;if(!i&&(p(t),t=t||f,y)){if(11!==P&&(l=Z.exec(e)))if(o=l[1]){if(9===P){if(!(u=t.getElementById(o)))return n;if(u.id===o)return n.push(u),n}else if(v&&(u=v.getElementById(o))&&b(t,u)&&u.id===o)return n.push(u),n}else{if(l[2])return M.apply(n,t.getElementsByTagName(e)),n;if((o=l[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(o)),n}if(r.qsa&&!w[e+" "]&&(!m||!m.test(e))&&(1!==P||"object"!==t.nodeName.toLowerCase())){if(g=e,v=t,1===P&&(z.test(e)||V.test(e))){for((v=ee.test(e)&&ge(t.parentNode)||t)===t&&r.scope||((c=t.getAttribute("id"))?c=c.replace(ne,ie):t.setAttribute("id",c=k)),s=(h=a(e)).length;s--;)h[s]=(c?"#"+c:":scope")+" "+be(h[s]);g=h.join(",")}try{return M.apply(n,v.querySelectorAll(g)),n}catch(t){w(e,!0)}finally{c===k&&t.removeAttribute("id")}}}return d(e.replace(j,"$1"),t,n,i)}function de(){var e=[];return function t(r,i){return e.push(r+" ")>n.cacheLength&&delete t[e.shift()],t[r+" "]=i}}function ue(e){return e[k]=!0,e}function ce(e){var t=f.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){for(var r=e.split("|"),i=r.length;i--;)n.attrHandle[r[i]]=t}function pe(e,t){var r=t&&e,n=r&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(n)return n;if(r)for(;r=r.nextSibling;)if(r===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function he(e){return function(t){var r=t.nodeName.toLowerCase();return("input"===r||"button"===r)&&t.type===e}}function ye(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ae(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function me(e){return ue((function(t){return t=+t,ue((function(r,n){for(var i,o=e([],r.length,t),a=o.length;a--;)r[i=o[a]]&&(r[i]=!(n[i]=r[i]))}))}))}function ge(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in r=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,r=(e.ownerDocument||e).documentElement;return!Y.test(t||r&&r.nodeName||"HTML")},p=se.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:P;return a!=f&&9===a.nodeType&&a.documentElement?(h=(f=a).documentElement,y=!o(f),P!=f&&(i=f.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",oe,!1):i.attachEvent&&i.attachEvent("onunload",oe)),r.scope=ce((function(e){return h.appendChild(e).appendChild(f.createElement("div")),void 0!==e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length})),r.attributes=ce((function(e){return e.className="i",!e.getAttribute("className")})),r.getElementsByTagName=ce((function(e){return e.appendChild(f.createComment("")),!e.getElementsByTagName("*").length})),r.getElementsByClassName=Q.test(f.getElementsByClassName),r.getById=ce((function(e){return h.appendChild(e).id=k,!f.getElementsByName||!f.getElementsByName(k).length})),r.getById?(n.filter.ID=function(e){var t=e.replace(te,re);return function(e){return e.getAttribute("id")===t}},n.find.ID=function(e,t){if(void 0!==t.getElementById&&y){var r=t.getElementById(e);return r?[r]:[]}}):(n.filter.ID=function(e){var t=e.replace(te,re);return function(e){var r=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return r&&r.value===t}},n.find.ID=function(e,t){if(void 0!==t.getElementById&&y){var r,n,i,o=t.getElementById(e);if(o){if((r=o.getAttributeNode("id"))&&r.value===e)return[o];for(i=t.getElementsByName(e),n=0;o=i[n++];)if((r=o.getAttributeNode("id"))&&r.value===e)return[o]}return[]}}),n.find.TAG=r.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):r.qsa?t.querySelectorAll(e):void 0}:function(e,t){var r,n=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;r=o[i++];)1===r.nodeType&&n.push(r);return n}return o},n.find.CLASS=r.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&y)return t.getElementsByClassName(e)},g=[],m=[],(r.qsa=Q.test(f.querySelectorAll))&&(ce((function(e){var t;h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&m.push("[*^$]="+N+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||m.push("\\["+N+"*(?:value|"+F+")"),e.querySelectorAll("[id~="+k+"-]").length||m.push("~="),(t=f.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||m.push("\\["+N+"*name"+N+"*="+N+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||m.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||m.push(".#.+[+~]"),e.querySelectorAll("\\\f"),m.push("[\\r\\n\\f]")})),ce((function(e){e.innerHTML="";var t=f.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&m.push("name"+N+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&m.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&m.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),m.push(",.*:")}))),(r.matchesSelector=Q.test(v=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ce((function(e){r.disconnectedMatch=v.call(e,"*"),v.call(e,"[s!='']:x"),g.push("!=",U)})),m=m.length&&new RegExp(m.join("|")),g=g.length&&new RegExp(g.join("|")),t=Q.test(h.compareDocumentPosition),b=t||Q.test(h.contains)?function(e,t){var r=9===e.nodeType?e.documentElement:e,n=t&&t.parentNode;return e===n||!(!n||1!==n.nodeType||!(r.contains?r.contains(n):e.compareDocumentPosition&&16&e.compareDocumentPosition(n)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},A=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!r.sortDetached&&t.compareDocumentPosition(e)===n?e==f||e.ownerDocument==P&&b(P,e)?-1:t==f||t.ownerDocument==P&&b(P,t)?1:c?O(c,e)-O(c,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var r,n=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==f?-1:t==f?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return pe(e,t);for(r=e;r=r.parentNode;)a.unshift(r);for(r=t;r=r.parentNode;)s.unshift(r);for(;a[n]===s[n];)n++;return n?pe(a[n],s[n]):a[n]==P?-1:s[n]==P?1:0},f):f},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(p(e),r.matchesSelector&&y&&!w[t+" "]&&(!g||!g.test(t))&&(!m||!m.test(t)))try{var n=v.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){w(t,!0)}return se(t,f,null,[e]).length>0},se.contains=function(e,t){return(e.ownerDocument||e)!=f&&p(e),b(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=f&&p(e);var i=n.attrHandle[t.toLowerCase()],o=i&&_.call(n.attrHandle,t.toLowerCase())?i(e,t,!y):void 0;return void 0!==o?o:r.attributes||!y?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},se.escape=function(e){return(e+"").replace(ne,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],i=0,o=0;if(l=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),l){for(;t=e[o++];)t===e[o]&&(i=n.push(o));for(;i--;)e.splice(n[i],1)}return c=null,e},i=se.getText=function(e){var t,r="",n=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)r+=i(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[n++];)r+=i(t);return r},(n=se.selectors={cacheLength:50,createPseudo:ue,match:$,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,re),e[3]=(e[3]||e[4]||e[5]||"").replace(te,re),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,r=!e[6]&&e[2];return $.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":r&&q.test(r)&&(t=a(r,!0))&&(t=r.indexOf(")",r.length-t)-r.length)&&(e[0]=e[0].slice(0,t),e[2]=r.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,re).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+N+")"+e+"("+N+"|$)"))&&E(e,(function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,r){return function(n){var i=se.attr(n,e);return null==i?"!="===t:!t||(i+="","="===t?i===r:"!="===t?i!==r:"^="===t?r&&0===i.indexOf(r):"*="===t?r&&i.indexOf(r)>-1:"$="===t?r&&i.slice(-r.length)===r:"~="===t?(" "+i.replace(K," ")+" ").indexOf(r)>-1:"|="===t&&(i===r||i.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,r,n,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===n&&0===i?function(e){return!!e.parentNode}:function(t,r,d){var u,c,l,p,f,h,y=o!==a?"nextSibling":"previousSibling",m=t.parentNode,g=s&&t.nodeName.toLowerCase(),v=!d&&!s,b=!1;if(m){if(o){for(;y;){for(p=t;p=p[y];)if(s?p.nodeName.toLowerCase()===g:1===p.nodeType)return!1;h=y="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(b=(f=(u=(c=(l=(p=m)[k]||(p[k]={}))[p.uniqueID]||(l[p.uniqueID]={}))[e]||[])[0]===S&&u[1])&&u[2],p=f&&m.childNodes[f];p=++f&&p&&p[y]||(b=f=0)||h.pop();)if(1===p.nodeType&&++b&&p===t){c[e]=[S,f,b];break}}else if(v&&(b=f=(u=(c=(l=(p=t)[k]||(p[k]={}))[p.uniqueID]||(l[p.uniqueID]={}))[e]||[])[0]===S&&u[1]),!1===b)for(;(p=++f&&p&&p[y]||(b=f=0)||h.pop())&&((s?p.nodeName.toLowerCase()!==g:1!==p.nodeType)||!++b||(v&&((c=(l=p[k]||(p[k]={}))[p.uniqueID]||(l[p.uniqueID]={}))[e]=[S,b]),p!==t)););return(b-=i)===n||b%n==0&&b/n>=0}}},PSEUDO:function(e,t){var r,i=n.pseudos[e]||n.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return i[k]?i(t):i.length>1?(r=[e,e,"",t],n.setFilters.hasOwnProperty(e.toLowerCase())?ue((function(e,r){for(var n,o=i(e,t),a=o.length;a--;)e[n=O(e,o[a])]=!(r[n]=o[a])})):function(e){return i(e,0,r)}):i}},pseudos:{not:ue((function(e){var t=[],r=[],n=s(e.replace(j,"$1"));return n[k]?ue((function(e,t,r,i){for(var o,a=n(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))})):function(e,i,o){return t[0]=e,n(t,null,o,r),t[0]=null,!r.pop()}})),has:ue((function(e){return function(t){return se(e,t).length>0}})),contains:ue((function(e){return e=e.replace(te,re),function(t){return(t.textContent||i(t)).indexOf(e)>-1}})),lang:ue((function(e){return W.test(e||"")||se.error("unsupported lang: "+e),e=e.replace(te,re).toLowerCase(),function(t){var r;do{if(r=y?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(r=r.toLowerCase())===e||0===r.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(t){var r=e.location&&e.location.hash;return r&&r.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ye(!1),disabled:ye(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!n.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return X.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:me((function(){return[0]})),last:me((function(e,t){return[t-1]})),eq:me((function(e,t,r){return[r<0?r+t:r]})),even:me((function(e,t){for(var r=0;rt?t:r;--n>=0;)e.push(n);return e})),gt:me((function(e,t,r){for(var n=r<0?r+t:r;++n1?function(t,r,n){for(var i=e.length;i--;)if(!e[i](t,r,n))return!1;return!0}:e[0]}function Se(e,t,r,n,i){for(var o,a=[],s=0,d=e.length,u=null!=t;s-1&&(o[u]=!(a[u]=l))}}else g=Se(g===a?g.splice(h,g.length):g),i?i(null,a,g,d):M.apply(a,g)}))}function Ee(e){for(var t,r,i,o=e.length,a=n.relative[e[0].type],s=a||n.relative[" "],d=a?1:0,c=ke((function(e){return e===t}),s,!0),l=ke((function(e){return O(t,e)>-1}),s,!0),p=[function(e,r,n){var i=!a&&(n||r!==u)||((t=r).nodeType?c(e,r,n):l(e,r,n));return t=null,i}];d1&&Pe(p),d>1&&be(e.slice(0,d-1).concat({value:" "===e[d-2].type?"*":""})).replace(j,"$1"),r,d0,i=e.length>0,o=function(o,a,s,d,c){var l,h,m,g=0,v="0",b=o&&[],k=[],P=u,T=o||i&&n.find.TAG("*",c),E=S+=null==P?1:Math.random()||.1,x=T.length;for(c&&(u=a==f||a||c);v!==x&&null!=(l=T[v]);v++){if(i&&l){for(h=0,a||l.ownerDocument==f||(p(l),s=!y);m=e[h++];)if(m(l,a||f,s)){d.push(l);break}c&&(S=E)}r&&((l=!m&&l)&&g--,o&&b.push(l))}if(g+=v,r&&v!==g){for(h=0;m=t[h++];)m(b,k,a,s);if(o){if(g>0)for(;v--;)b[v]||k[v]||(k[v]=I.call(d));k=Se(k)}M.apply(d,k),c&&!o&&k.length>0&&g+t.length>1&&se.uniqueSort(d)}return c&&(S=E,u=P),b};return r?ue(o):o}(o,i))).selector=e}return s},d=se.select=function(e,t,r,i){var o,d,u,c,l,p="function"==typeof e&&e,f=!i&&a(e=p.selector||e);if(r=r||[],1===f.length){if((d=f[0]=f[0].slice(0)).length>2&&"ID"===(u=d[0]).type&&9===t.nodeType&&y&&n.relative[d[1].type]){if(!(t=(n.find.ID(u.matches[0].replace(te,re),t)||[])[0]))return r;p&&(t=t.parentNode),e=e.slice(d.shift().value.length)}for(o=$.needsContext.test(e)?0:d.length;o--&&(u=d[o],!n.relative[c=u.type]);)if((l=n.find[c])&&(i=l(u.matches[0].replace(te,re),ee.test(d[0].type)&&ge(t.parentNode)||t))){if(d.splice(o,1),!(e=i.length&&be(d)))return M.apply(r,i),r;break}}return(p||s(e,f))(i,t,!y,r,!t||ee.test(e)&&ge(t.parentNode)||t),r},r.sortStable=k.split("").sort(A).join("")===k,r.detectDuplicates=!!l,p(),r.sortDetached=ce((function(e){return 1&e.compareDocumentPosition(f.createElement("fieldset"))})),ce((function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")}))||le("type|href|height|width",(function(e,t,r){if(!r)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)})),r.attributes&&ce((function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")}))||le("value",(function(e,t,r){if(!r&&"input"===e.nodeName.toLowerCase())return e.defaultValue})),ce((function(e){return null==e.getAttribute("disabled")}))||le(F,(function(e,t,r){var n;if(!r)return!0===e[t]?t.toLowerCase():(n=e.getAttributeNode(t))&&n.specified?n.value:null})),se}(r);T.find=x,T.expr=x.selectors,T.expr[":"]=T.expr.pseudos,T.uniqueSort=T.unique=x.uniqueSort,T.text=x.getText,T.isXMLDoc=x.isXML,T.contains=x.contains,T.escapeSelector=x.escape;var C=function(e,t,r){for(var n=[],i=void 0!==r;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&T(e).is(r))break;n.push(e)}return n},w=function(e,t){for(var r=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&r.push(e);return r},A=T.expr.match.needsContext;function _(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var L=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function I(e,t,r){return g(t)?T.grep(e,(function(e,n){return!!t.call(e,n,e)!==r})):t.nodeType?T.grep(e,(function(e){return e===t!==r})):"string"!=typeof t?T.grep(e,(function(e){return c.call(t,e)>-1!==r})):T.filter(t,e,r)}T.filter=function(e,t,r){var n=t[0];return r&&(e=":not("+e+")"),1===t.length&&1===n.nodeType?T.find.matchesSelector(n,e)?[n]:[]:T.find.matches(e,T.grep(t,(function(e){return 1===e.nodeType})))},T.fn.extend({find:function(e){var t,r,n=this.length,i=this;if("string"!=typeof e)return this.pushStack(T(e).filter((function(){for(t=0;t1?T.uniqueSort(r):r},filter:function(e){return this.pushStack(I(this,e||[],!1))},not:function(e){return this.pushStack(I(this,e||[],!0))},is:function(e){return!!I(this,"string"==typeof e&&A.test(e)?T(e):e||[],!1).length}});var R,M=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(T.fn.init=function(e,t,r){var n,i;if(!e)return this;if(r=r||R,"string"==typeof e){if(!(n="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:M.exec(e))||!n[1]&&t)return!t||t.jquery?(t||r).find(e):this.constructor(t).find(e);if(n[1]){if(t=t instanceof T?t[0]:t,T.merge(this,T.parseHTML(n[1],t&&t.nodeType?t.ownerDocument||t:b,!0)),L.test(n[1])&&T.isPlainObject(t))for(n in t)g(this[n])?this[n](t[n]):this.attr(n,t[n]);return this}return(i=b.getElementById(n[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==r.ready?r.ready(e):e(T):T.makeArray(e,this)}).prototype=T.fn,R=T(b);var D=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function F(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}T.fn.extend({has:function(e){var t=T(e,this),r=t.length;return this.filter((function(){for(var e=0;e-1:1===r.nodeType&&T.find.matchesSelector(r,e))){o.push(r);break}return this.pushStack(o.length>1?T.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?c.call(T(e),this[0]):c.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(T.uniqueSort(T.merge(this.get(),T(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),T.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return C(e,"parentNode")},parentsUntil:function(e,t,r){return C(e,"parentNode",r)},next:function(e){return F(e,"nextSibling")},prev:function(e){return F(e,"previousSibling")},nextAll:function(e){return C(e,"nextSibling")},prevAll:function(e){return C(e,"previousSibling")},nextUntil:function(e,t,r){return C(e,"nextSibling",r)},prevUntil:function(e,t,r){return C(e,"previousSibling",r)},siblings:function(e){return w((e.parentNode||{}).firstChild,e)},children:function(e){return w(e.firstChild)},contents:function(e){return null!=e.contentDocument&&a(e.contentDocument)?e.contentDocument:(_(e,"template")&&(e=e.content||e),T.merge([],e.childNodes))}},(function(e,t){T.fn[e]=function(r,n){var i=T.map(this,t,r);return"Until"!==e.slice(-5)&&(n=r),n&&"string"==typeof n&&(i=T.filter(n,i)),this.length>1&&(O[e]||T.uniqueSort(i),D.test(e)&&i.reverse()),this.pushStack(i)}}));var N=/[^\x20\t\r\n\f]+/g;function G(e){return e}function B(e){throw e}function U(e,t,r,n){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(r):e&&g(i=e.then)?i.call(e,t,r):t.apply(void 0,[e].slice(n))}catch(e){r.apply(void 0,[e])}}T.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return T.each(e.match(N)||[],(function(e,r){t[r]=!0})),t}(e):T.extend({},e);var t,r,n,i,o=[],a=[],s=-1,d=function(){for(i=i||e.once,n=t=!0;a.length;s=-1)for(r=a.shift();++s-1;)o.splice(r,1),r<=s&&s--})),this},has:function(e){return e?T.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=r="",this},disabled:function(){return!o},lock:function(){return i=a=[],r||t||(o=r=""),this},locked:function(){return!!i},fireWith:function(e,r){return i||(r=[e,(r=r||[]).slice?r.slice():r],a.push(r),t||d()),this},fire:function(){return u.fireWith(this,arguments),this},fired:function(){return!!n}};return u},T.extend({Deferred:function(e){var t=[["notify","progress",T.Callbacks("memory"),T.Callbacks("memory"),2],["resolve","done",T.Callbacks("once memory"),T.Callbacks("once memory"),0,"resolved"],["reject","fail",T.Callbacks("once memory"),T.Callbacks("once memory"),1,"rejected"]],n="pending",i={state:function(){return n},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return T.Deferred((function(r){T.each(t,(function(t,n){var i=g(e[n[4]])&&e[n[4]];o[n[1]]((function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[n[0]+"With"](this,i?[e]:arguments)}))})),e=null})).promise()},then:function(e,n,i){var o=0;function a(e,t,n,i){return function(){var s=this,d=arguments,u=function(){var r,u;if(!(e=o&&(n!==B&&(s=void 0,d=[r]),t.rejectWith(s,d))}};e?c():(T.Deferred.getStackHook&&(c.stackTrace=T.Deferred.getStackHook()),r.setTimeout(c))}}return T.Deferred((function(r){t[0][3].add(a(0,r,g(i)?i:G,r.notifyWith)),t[1][3].add(a(0,r,g(e)?e:G)),t[2][3].add(a(0,r,g(n)?n:B))})).promise()},promise:function(e){return null!=e?T.extend(e,i):i}},o={};return T.each(t,(function(e,r){var a=r[2],s=r[5];i[r[1]]=a.add,s&&a.add((function(){n=s}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),a.add(r[3].fire),o[r[0]]=function(){return o[r[0]+"With"](this===o?void 0:this,arguments),this},o[r[0]+"With"]=a.fireWith})),i.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,r=t,n=Array(r),i=s.call(arguments),o=T.Deferred(),a=function(e){return function(r){n[e]=this,i[e]=arguments.length>1?s.call(arguments):r,--t||o.resolveWith(n,i)}};if(t<=1&&(U(e,o.done(a(r)).resolve,o.reject,!t),"pending"===o.state()||g(i[r]&&i[r].then)))return o.then();for(;r--;)U(i[r],a(r),o.reject);return o.promise()}});var K=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;T.Deferred.exceptionHook=function(e,t){r.console&&r.console.warn&&e&&K.test(e.name)&&r.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},T.readyException=function(e){r.setTimeout((function(){throw e}))};var j=T.Deferred();function H(){b.removeEventListener("DOMContentLoaded",H),r.removeEventListener("load",H),T.ready()}T.fn.ready=function(e){return j.then(e).catch((function(e){T.readyException(e)})),this},T.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--T.readyWait:T.isReady)||(T.isReady=!0,!0!==e&&--T.readyWait>0||j.resolveWith(b,[T]))}}),T.ready.then=j.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?r.setTimeout(T.ready):(b.addEventListener("DOMContentLoaded",H),r.addEventListener("load",H));var V=function(e,t,r,n,i,o,a){var s=0,d=e.length,u=null==r;if("object"===S(r))for(s in i=!0,r)V(e,t,s,r[s],!0,o,a);else if(void 0!==n&&(i=!0,g(n)||(a=!0),u&&(a?(t.call(e,n),t=null):(u=t,t=function(e,t,r){return u.call(T(e),r)})),t))for(;s1,null,!0)},removeData:function(e){return this.each((function(){Q.remove(this,e)}))}}),T.extend({queue:function(e,t,r){var n;if(e)return t=(t||"fx")+"queue",n=J.get(e,t),r&&(!n||Array.isArray(r)?n=J.access(e,t,T.makeArray(r)):n.push(r)),n||[]},dequeue:function(e,t){t=t||"fx";var r=T.queue(e,t),n=r.length,i=r.shift(),o=T._queueHooks(e,t);"inprogress"===i&&(i=r.shift(),n--),i&&("fx"===t&&r.unshift("inprogress"),delete o.stop,i.call(e,(function(){T.dequeue(e,t)}),o)),!n&&o&&o.empty.fire()},_queueHooks:function(e,t){var r=t+"queueHooks";return J.get(e,r)||J.access(e,r,{empty:T.Callbacks("once memory").add((function(){J.remove(e,[t+"queue",r])}))})}}),T.fn.extend({queue:function(e,t){var r=2;return"string"!=typeof e&&(t=e,e="fx",r--),arguments.length\x20\t\r\n\f]*)/i,ge=/^$|^module$|\/(?:java|ecma)script/i;fe=b.createDocumentFragment().appendChild(b.createElement("div")),(he=b.createElement("input")).setAttribute("type","radio"),he.setAttribute("checked","checked"),he.setAttribute("name","t"),fe.appendChild(he),m.checkClone=fe.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.innerHTML="",m.noCloneChecked=!!fe.cloneNode(!0).lastChild.defaultValue,fe.innerHTML="",m.option=!!fe.lastChild;var ve={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function be(e,t){var r;return r=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&_(e,t)?T.merge([e],r):r}function ke(e,t){for(var r=0,n=e.length;r",""]);var Pe=/<|&#?\w+;/;function Se(e,t,r,n,i){for(var o,a,s,d,u,c,l=t.createDocumentFragment(),p=[],f=0,h=e.length;f-1)i&&i.push(o);else if(u=ae(o),a=be(l.appendChild(o),"script"),u&&ke(a),r)for(c=0;o=a[c++];)ge.test(o.type||"")&&r.push(o);return l}var Te=/^key/,Ee=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,xe=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function we(){return!1}function Ae(e,t){return e===function(){try{return b.activeElement}catch(e){}}()==("focus"===t)}function _e(e,t,r,n,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof r&&(n=n||r,r=void 0),t)_e(e,s,r,n,t[s],o);return e}if(null==n&&null==i?(i=r,n=r=void 0):null==i&&("string"==typeof r?(i=n,n=void 0):(i=n,n=r,r=void 0)),!1===i)i=we;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return T().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=T.guid++)),e.each((function(){T.event.add(this,t,i,n,r)}))}function Le(e,t,r){r?(J.set(e,t,!1),T.event.add(e,t,{namespace:!1,handler:function(e){var n,i,o=J.get(this,t);if(1&e.isTrigger&&this[t]){if(o.length)(T.event.special[t]||{}).delegateType&&e.stopPropagation();else if(o=s.call(arguments),J.set(this,t,o),n=r(this,t),this[t](),o!==(i=J.get(this,t))||n?J.set(this,t,!1):i={},o!==i)return e.stopImmediatePropagation(),e.preventDefault(),i.value}else o.length&&(J.set(this,t,{value:T.event.trigger(T.extend(o[0],T.Event.prototype),o.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===J.get(e,t)&&T.event.add(e,t,Ce)}T.event={global:{},add:function(e,t,r,n,i){var o,a,s,d,u,c,l,p,f,h,y,m=J.get(e);if(Y(e))for(r.handler&&(r=(o=r).handler,i=o.selector),i&&T.find.matchesSelector(oe,i),r.guid||(r.guid=T.guid++),(d=m.events)||(d=m.events=Object.create(null)),(a=m.handle)||(a=m.handle=function(t){return void 0!==T&&T.event.triggered!==t.type?T.event.dispatch.apply(e,arguments):void 0}),u=(t=(t||"").match(N)||[""]).length;u--;)f=y=(s=xe.exec(t[u])||[])[1],h=(s[2]||"").split(".").sort(),f&&(l=T.event.special[f]||{},f=(i?l.delegateType:l.bindType)||f,l=T.event.special[f]||{},c=T.extend({type:f,origType:y,data:n,handler:r,guid:r.guid,selector:i,needsContext:i&&T.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=d[f])||((p=d[f]=[]).delegateCount=0,l.setup&&!1!==l.setup.call(e,n,h,a)||e.addEventListener&&e.addEventListener(f,a)),l.add&&(l.add.call(e,c),c.handler.guid||(c.handler.guid=r.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),T.event.global[f]=!0)},remove:function(e,t,r,n,i){var o,a,s,d,u,c,l,p,f,h,y,m=J.hasData(e)&&J.get(e);if(m&&(d=m.events)){for(u=(t=(t||"").match(N)||[""]).length;u--;)if(f=y=(s=xe.exec(t[u])||[])[1],h=(s[2]||"").split(".").sort(),f){for(l=T.event.special[f]||{},p=d[f=(n?l.delegateType:l.bindType)||f]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;o--;)c=p[o],!i&&y!==c.origType||r&&r.guid!==c.guid||s&&!s.test(c.namespace)||n&&n!==c.selector&&("**"!==n||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,l.remove&&l.remove.call(e,c));a&&!p.length&&(l.teardown&&!1!==l.teardown.call(e,h,m.handle)||T.removeEvent(e,f,m.handle),delete d[f])}else for(f in d)T.event.remove(e,f+t[u],r,n,!0);T.isEmptyObject(d)&&J.remove(e,"handle events")}},dispatch:function(e){var t,r,n,i,o,a,s=new Array(arguments.length),d=T.event.fix(e),u=(J.get(this,"events")||Object.create(null))[d.type]||[],c=T.event.special[d.type]||{};for(s[0]=d,t=1;t=1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&("click"!==e.type||!0!==u.disabled)){for(o=[],a={},r=0;r-1:T.find(i,this,null,[u]).length),a[i]&&o.push(n);o.length&&s.push({elem:u,handlers:o})}return u=this,d\s*$/g;function De(e,t){return _(e,"table")&&_(11!==t.nodeType?t:t.firstChild,"tr")&&T(e).children("tbody")[0]||e}function Oe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Fe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Ne(e,t){var r,n,i,o,a,s;if(1===t.nodeType){if(J.hasData(e)&&(s=J.get(e).events))for(i in J.remove(t,"handle events"),s)for(r=0,n=s[i].length;r1&&"string"==typeof h&&!m.checkClone&&Re.test(h))return e.each((function(i){var o=e.eq(i);y&&(t[0]=h.call(this,i,o.html())),Be(o,t,r,n)}));if(p&&(o=(i=Se(t,e[0].ownerDocument,!1,e,n)).firstChild,1===i.childNodes.length&&(i=o),o||n)){for(s=(a=T.map(be(i,"script"),Oe)).length;l0&&ke(a,!d&&be(e,"script")),s},cleanData:function(e){for(var t,r,n,i=T.event.special,o=0;void 0!==(r=e[o]);o++)if(Y(r)){if(t=r[J.expando]){if(t.events)for(n in t.events)i[n]?T.event.remove(r,n):T.removeEvent(r,n,t.handle);r[J.expando]=void 0}r[Q.expando]&&(r[Q.expando]=void 0)}}}),T.fn.extend({detach:function(e){return Ue(this,e,!0)},remove:function(e){return Ue(this,e)},text:function(e){return V(this,(function(e){return void 0===e?T.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return Be(this,arguments,(function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||De(this,e).appendChild(e)}))},prepend:function(){return Be(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=De(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return Be(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return Be(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(T.cleanData(be(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return T.clone(this,e,t)}))},html:function(e){return V(this,(function(e){var t=this[0]||{},r=0,n=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ie.test(e)&&!ve[(me.exec(e)||["",""])[1].toLowerCase()]){e=T.htmlPrefilter(e);try{for(;r3,oe.removeChild(e)),s}}))}();var We=["Webkit","Moz","ms"],$e=b.createElement("div").style,Ye={};function Xe(e){return T.cssProps[e]||Ye[e]||(e in $e?e:Ye[e]=function(e){for(var t=e[0].toUpperCase()+e.slice(1),r=We.length;r--;)if((e=We[r]+t)in $e)return e}(e)||e)}var Je=/^(none|table(?!-c[ea]).+)/,Qe=/^--/,Ze={position:"absolute",visibility:"hidden",display:"block"},et={letterSpacing:"0",fontWeight:"400"};function tt(e,t,r){var n=ne.exec(t);return n?Math.max(0,n[2]-(r||0))+(n[3]||"px"):t}function rt(e,t,r,n,i,o){var a="width"===t?1:0,s=0,d=0;if(r===(n?"border":"content"))return 0;for(;a<4;a+=2)"margin"===r&&(d+=T.css(e,r+ie[a],!0,i)),n?("content"===r&&(d-=T.css(e,"padding"+ie[a],!0,i)),"margin"!==r&&(d-=T.css(e,"border"+ie[a]+"Width",!0,i))):(d+=T.css(e,"padding"+ie[a],!0,i),"padding"!==r?d+=T.css(e,"border"+ie[a]+"Width",!0,i):s+=T.css(e,"border"+ie[a]+"Width",!0,i));return!n&&o>=0&&(d+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-d-s-.5))||0),d}function nt(e,t,r){var n=je(e),i=(!m.boxSizingReliable()||r)&&"border-box"===T.css(e,"boxSizing",!1,n),o=i,a=ze(e,t,n),s="offset"+t[0].toUpperCase()+t.slice(1);if(Ke.test(a)){if(!r)return a;a="auto"}return(!m.boxSizingReliable()&&i||!m.reliableTrDimensions()&&_(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===T.css(e,"display",!1,n))&&e.getClientRects().length&&(i="border-box"===T.css(e,"boxSizing",!1,n),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+rt(e,t,r||(i?"border":"content"),o,n,a)+"px"}function it(e,t,r,n,i){return new it.prototype.init(e,t,r,n,i)}T.extend({cssHooks:{opacity:{get:function(e,t){if(t){var r=ze(e,"opacity");return""===r?"1":r}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,r,n){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=$(t),d=Qe.test(t),u=e.style;if(d||(t=Xe(s)),a=T.cssHooks[t]||T.cssHooks[s],void 0===r)return a&&"get"in a&&void 0!==(i=a.get(e,!1,n))?i:u[t];"string"==(o=typeof r)&&(i=ne.exec(r))&&i[1]&&(r=ue(e,t,i),o="number"),null!=r&&r==r&&("number"!==o||d||(r+=i&&i[3]||(T.cssNumber[s]?"":"px")),m.clearCloneStyle||""!==r||0!==t.indexOf("background")||(u[t]="inherit"),a&&"set"in a&&void 0===(r=a.set(e,r,n))||(d?u.setProperty(t,r):u[t]=r))}},css:function(e,t,r,n){var i,o,a,s=$(t);return Qe.test(t)||(t=Xe(s)),(a=T.cssHooks[t]||T.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,r)),void 0===i&&(i=ze(e,t,n)),"normal"===i&&t in et&&(i=et[t]),""===r||r?(o=parseFloat(i),!0===r||isFinite(o)?o||0:i):i}}),T.each(["height","width"],(function(e,t){T.cssHooks[t]={get:function(e,r,n){if(r)return!Je.test(T.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?nt(e,t,n):He(e,Ze,(function(){return nt(e,t,n)}))},set:function(e,r,n){var i,o=je(e),a=!m.scrollboxSize()&&"absolute"===o.position,s=(a||n)&&"border-box"===T.css(e,"boxSizing",!1,o),d=n?rt(e,t,n,s,o):0;return s&&a&&(d-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-rt(e,t,"border",!1,o)-.5)),d&&(i=ne.exec(r))&&"px"!==(i[3]||"px")&&(e.style[t]=r,r=T.css(e,t)),tt(0,r,d)}}})),T.cssHooks.marginLeft=qe(m.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(ze(e,"marginLeft"))||e.getBoundingClientRect().left-He(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),T.each({margin:"",padding:"",border:"Width"},(function(e,t){T.cssHooks[e+t]={expand:function(r){for(var n=0,i={},o="string"==typeof r?r.split(" "):[r];n<4;n++)i[e+ie[n]+t]=o[n]||o[n-2]||o[0];return i}},"margin"!==e&&(T.cssHooks[e+t].set=tt)})),T.fn.extend({css:function(e,t){return V(this,(function(e,t,r){var n,i,o={},a=0;if(Array.isArray(t)){for(n=je(e),i=t.length;a1)}}),T.Tween=it,it.prototype={constructor:it,init:function(e,t,r,n,i,o){this.elem=e,this.prop=r,this.easing=i||T.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=n,this.unit=o||(T.cssNumber[r]?"":"px")},cur:function(){var e=it.propHooks[this.prop];return e&&e.get?e.get(this):it.propHooks._default.get(this)},run:function(e){var t,r=it.propHooks[this.prop];return this.options.duration?this.pos=t=T.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),r&&r.set?r.set(this):it.propHooks._default.set(this),this}},it.prototype.init.prototype=it.prototype,it.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=T.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){T.fx.step[e.prop]?T.fx.step[e.prop](e):1!==e.elem.nodeType||!T.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:T.style(e.elem,e.prop,e.now+e.unit)}}},it.propHooks.scrollTop=it.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},T.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},T.fx=it.prototype.init,T.fx.step={};var ot,at,st=/^(?:toggle|show|hide)$/,dt=/queueHooks$/;function ut(){at&&(!1===b.hidden&&r.requestAnimationFrame?r.requestAnimationFrame(ut):r.setTimeout(ut,T.fx.interval),T.fx.tick())}function ct(){return r.setTimeout((function(){ot=void 0})),ot=Date.now()}function lt(e,t){var r,n=0,i={height:e};for(t=t?1:0;n<4;n+=2-t)i["margin"+(r=ie[n])]=i["padding"+r]=e;return t&&(i.opacity=i.width=e),i}function pt(e,t,r){for(var n,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each((function(){T.removeAttr(this,e)}))}}),T.extend({attr:function(e,t,r){var n,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?T.prop(e,t,r):(1===o&&T.isXMLDoc(e)||(i=T.attrHooks[t.toLowerCase()]||(T.expr.match.bool.test(t)?ht:void 0)),void 0!==r?null===r?void T.removeAttr(e,t):i&&"set"in i&&void 0!==(n=i.set(e,r,t))?n:(e.setAttribute(t,r+""),r):i&&"get"in i&&null!==(n=i.get(e,t))?n:null==(n=T.find.attr(e,t))?void 0:n)},attrHooks:{type:{set:function(e,t){if(!m.radioValue&&"radio"===t&&_(e,"input")){var r=e.value;return e.setAttribute("type",t),r&&(e.value=r),t}}}},removeAttr:function(e,t){var r,n=0,i=t&&t.match(N);if(i&&1===e.nodeType)for(;r=i[n++];)e.removeAttribute(r)}}),ht={set:function(e,t,r){return!1===t?T.removeAttr(e,r):e.setAttribute(r,r),r}},T.each(T.expr.match.bool.source.match(/\w+/g),(function(e,t){var r=yt[t]||T.find.attr;yt[t]=function(e,t,n){var i,o,a=t.toLowerCase();return n||(o=yt[a],yt[a]=i,i=null!=r(e,t,n)?a:null,yt[a]=o),i}}));var mt=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function vt(e){return(e.match(N)||[]).join(" ")}function bt(e){return e.getAttribute&&e.getAttribute("class")||""}function kt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(N)||[]}T.fn.extend({prop:function(e,t){return V(this,T.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[T.propFix[e]||e]}))}}),T.extend({prop:function(e,t,r){var n,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&T.isXMLDoc(e)||(t=T.propFix[t]||t,i=T.propHooks[t]),void 0!==r?i&&"set"in i&&void 0!==(n=i.set(e,r,t))?n:e[t]=r:i&&"get"in i&&null!==(n=i.get(e,t))?n:e[t]},propHooks:{tabIndex:{get:function(e){var t=T.find.attr(e,"tabindex");return t?parseInt(t,10):mt.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),m.optSelected||(T.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),T.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){T.propFix[this.toLowerCase()]=this})),T.fn.extend({addClass:function(e){var t,r,n,i,o,a,s,d=0;if(g(e))return this.each((function(t){T(this).addClass(e.call(this,t,bt(this)))}));if((t=kt(e)).length)for(;r=this[d++];)if(i=bt(r),n=1===r.nodeType&&" "+vt(i)+" "){for(a=0;o=t[a++];)n.indexOf(" "+o+" ")<0&&(n+=o+" ");i!==(s=vt(n))&&r.setAttribute("class",s)}return this},removeClass:function(e){var t,r,n,i,o,a,s,d=0;if(g(e))return this.each((function(t){T(this).removeClass(e.call(this,t,bt(this)))}));if(!arguments.length)return this.attr("class","");if((t=kt(e)).length)for(;r=this[d++];)if(i=bt(r),n=1===r.nodeType&&" "+vt(i)+" "){for(a=0;o=t[a++];)for(;n.indexOf(" "+o+" ")>-1;)n=n.replace(" "+o+" "," ");i!==(s=vt(n))&&r.setAttribute("class",s)}return this},toggleClass:function(e,t){var r=typeof e,n="string"===r||Array.isArray(e);return"boolean"==typeof t&&n?t?this.addClass(e):this.removeClass(e):g(e)?this.each((function(r){T(this).toggleClass(e.call(this,r,bt(this),t),t)})):this.each((function(){var t,i,o,a;if(n)for(i=0,o=T(this),a=kt(e);t=a[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==r||((t=bt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))}))},hasClass:function(e){var t,r,n=0;for(t=" "+e+" ";r=this[n++];)if(1===r.nodeType&&(" "+vt(bt(r))+" ").indexOf(t)>-1)return!0;return!1}});var Pt=/\r/g;T.fn.extend({val:function(e){var t,r,n,i=this[0];return arguments.length?(n=g(e),this.each((function(r){var i;1===this.nodeType&&(null==(i=n?e.call(this,r,T(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=T.map(i,(function(e){return null==e?"":e+""}))),(t=T.valHooks[this.type]||T.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))}))):i?(t=T.valHooks[i.type]||T.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(r=t.get(i,"value"))?r:"string"==typeof(r=i.value)?r.replace(Pt,""):null==r?"":r:void 0}}),T.extend({valHooks:{option:{get:function(e){var t=T.find.attr(e,"value");return null!=t?t:vt(T.text(e))}},select:{get:function(e){var t,r,n,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],d=a?o+1:i.length;for(n=o<0?d:a?o:0;n-1)&&(r=!0);return r||(e.selectedIndex=-1),o}}}}),T.each(["radio","checkbox"],(function(){T.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=T.inArray(T(e).val(),t)>-1}},m.checkOn||(T.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})})),m.focusin="onfocusin"in r;var St=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};T.extend(T.event,{trigger:function(e,t,n,i){var o,a,s,d,u,c,l,p,h=[n||b],y=f.call(e,"type")?e.type:e,m=f.call(e,"namespace")?e.namespace.split("."):[];if(a=p=s=n=n||b,3!==n.nodeType&&8!==n.nodeType&&!St.test(y+T.event.triggered)&&(y.indexOf(".")>-1&&(m=y.split("."),y=m.shift(),m.sort()),u=y.indexOf(":")<0&&"on"+y,(e=e[T.expando]?e:new T.Event(y,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=m.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:T.makeArray(t,[e]),l=T.event.special[y]||{},i||!l.trigger||!1!==l.trigger.apply(n,t))){if(!i&&!l.noBubble&&!v(n)){for(d=l.delegateType||y,St.test(d+y)||(a=a.parentNode);a;a=a.parentNode)h.push(a),s=a;s===(n.ownerDocument||b)&&h.push(s.defaultView||s.parentWindow||r)}for(o=0;(a=h[o++])&&!e.isPropagationStopped();)p=a,e.type=o>1?d:l.bindType||y,(c=(J.get(a,"events")||Object.create(null))[e.type]&&J.get(a,"handle"))&&c.apply(a,t),(c=u&&a[u])&&c.apply&&Y(a)&&(e.result=c.apply(a,t),!1===e.result&&e.preventDefault());return e.type=y,i||e.isDefaultPrevented()||l._default&&!1!==l._default.apply(h.pop(),t)||!Y(n)||u&&g(n[y])&&!v(n)&&((s=n[u])&&(n[u]=null),T.event.triggered=y,e.isPropagationStopped()&&p.addEventListener(y,Tt),n[y](),e.isPropagationStopped()&&p.removeEventListener(y,Tt),T.event.triggered=void 0,s&&(n[u]=s)),e.result}},simulate:function(e,t,r){var n=T.extend(new T.Event,r,{type:e,isSimulated:!0});T.event.trigger(n,null,t)}}),T.fn.extend({trigger:function(e,t){return this.each((function(){T.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var r=this[0];if(r)return T.event.trigger(e,t,r,!0)}}),m.focusin||T.each({focus:"focusin",blur:"focusout"},(function(e,t){var r=function(e){T.event.simulate(t,e.target,T.event.fix(e))};T.event.special[t]={setup:function(){var n=this.ownerDocument||this.document||this,i=J.access(n,t);i||n.addEventListener(e,r,!0),J.access(n,t,(i||0)+1)},teardown:function(){var n=this.ownerDocument||this.document||this,i=J.access(n,t)-1;i?J.access(n,t,i):(n.removeEventListener(e,r,!0),J.remove(n,t))}}}));var Et=r.location,xt={guid:Date.now()},Ct=/\?/;T.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new r.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||T.error("Invalid XML: "+e),t};var wt=/\[\]$/,At=/\r?\n/g,_t=/^(?:submit|button|image|reset|file)$/i,Lt=/^(?:input|select|textarea|keygen)/i;function It(e,t,r,n){var i;if(Array.isArray(t))T.each(t,(function(t,i){r||wt.test(e)?n(e,i):It(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,r,n)}));else if(r||"object"!==S(t))n(e,t);else for(i in t)It(e+"["+i+"]",t[i],r,n)}T.param=function(e,t){var r,n=[],i=function(e,t){var r=g(t)?t():t;n[n.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==r?"":r)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!T.isPlainObject(e))T.each(e,(function(){i(this.name,this.value)}));else for(r in e)It(r,e[r],t,i);return n.join("&")},T.fn.extend({serialize:function(){return T.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=T.prop(this,"elements");return e?T.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!T(this).is(":disabled")&&Lt.test(this.nodeName)&&!_t.test(e)&&(this.checked||!ye.test(e))})).map((function(e,t){var r=T(this).val();return null==r?null:Array.isArray(r)?T.map(r,(function(e){return{name:t.name,value:e.replace(At,"\r\n")}})):{name:t.name,value:r.replace(At,"\r\n")}})).get()}});var Rt=/%20/g,Mt=/#.*$/,Dt=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ft=/^(?:GET|HEAD)$/,Nt=/^\/\//,Gt={},Bt={},Ut="*/".concat("*"),Kt=b.createElement("a");function jt(e){return function(t,r){"string"!=typeof t&&(r=t,t="*");var n,i=0,o=t.toLowerCase().match(N)||[];if(g(r))for(;n=o[i++];)"+"===n[0]?(n=n.slice(1)||"*",(e[n]=e[n]||[]).unshift(r)):(e[n]=e[n]||[]).push(r)}}function Ht(e,t,r,n){var i={},o=e===Bt;function a(s){var d;return i[s]=!0,T.each(e[s]||[],(function(e,s){var u=s(t,r,n);return"string"!=typeof u||o||i[u]?o?!(d=u):void 0:(t.dataTypes.unshift(u),a(u),!1)})),d}return a(t.dataTypes[0])||!i["*"]&&a("*")}function Vt(e,t){var r,n,i=T.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n||(n={}))[r]=t[r]);return n&&T.extend(!0,e,n),e}Kt.href=Et.href,T.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Ut,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":T.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Vt(Vt(e,T.ajaxSettings),t):Vt(T.ajaxSettings,e)},ajaxPrefilter:jt(Gt),ajaxTransport:jt(Bt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var n,i,o,a,s,d,u,c,l,p,f=T.ajaxSetup({},t),h=f.context||f,y=f.context&&(h.nodeType||h.jquery)?T(h):T.event,m=T.Deferred(),g=T.Callbacks("once memory"),v=f.statusCode||{},k={},P={},S="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(u){if(!a)for(a={};t=Ot.exec(o);)a[t[1].toLowerCase()+" "]=(a[t[1].toLowerCase()+" "]||[]).concat(t[2]);t=a[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return u?o:null},setRequestHeader:function(e,t){return null==u&&(e=P[e.toLowerCase()]=P[e.toLowerCase()]||e,k[e]=t),this},overrideMimeType:function(e){return null==u&&(f.mimeType=e),this},statusCode:function(e){var t;if(e)if(u)E.always(e[E.status]);else for(t in e)v[t]=[v[t],e[t]];return this},abort:function(e){var t=e||S;return n&&n.abort(t),x(0,t),this}};if(m.promise(E),f.url=((e||f.url||Et.href)+"").replace(Nt,Et.protocol+"//"),f.type=t.method||t.type||f.method||f.type,f.dataTypes=(f.dataType||"*").toLowerCase().match(N)||[""],null==f.crossDomain){d=b.createElement("a");try{d.href=f.url,d.href=d.href,f.crossDomain=Kt.protocol+"//"+Kt.host!=d.protocol+"//"+d.host}catch(e){f.crossDomain=!0}}if(f.data&&f.processData&&"string"!=typeof f.data&&(f.data=T.param(f.data,f.traditional)),Ht(Gt,f,t,E),u)return E;for(l in(c=T.event&&f.global)&&0==T.active++&&T.event.trigger("ajaxStart"),f.type=f.type.toUpperCase(),f.hasContent=!Ft.test(f.type),i=f.url.replace(Mt,""),f.hasContent?f.data&&f.processData&&0===(f.contentType||"").indexOf("application/x-www-form-urlencoded")&&(f.data=f.data.replace(Rt,"+")):(p=f.url.slice(i.length),f.data&&(f.processData||"string"==typeof f.data)&&(i+=(Ct.test(i)?"&":"?")+f.data,delete f.data),!1===f.cache&&(i=i.replace(Dt,"$1"),p=(Ct.test(i)?"&":"?")+"_="+xt.guid+++p),f.url=i+p),f.ifModified&&(T.lastModified[i]&&E.setRequestHeader("If-Modified-Since",T.lastModified[i]),T.etag[i]&&E.setRequestHeader("If-None-Match",T.etag[i])),(f.data&&f.hasContent&&!1!==f.contentType||t.contentType)&&E.setRequestHeader("Content-Type",f.contentType),E.setRequestHeader("Accept",f.dataTypes[0]&&f.accepts[f.dataTypes[0]]?f.accepts[f.dataTypes[0]]+("*"!==f.dataTypes[0]?", "+Ut+"; q=0.01":""):f.accepts["*"]),f.headers)E.setRequestHeader(l,f.headers[l]);if(f.beforeSend&&(!1===f.beforeSend.call(h,E,f)||u))return E.abort();if(S="abort",g.add(f.complete),E.done(f.success),E.fail(f.error),n=Ht(Bt,f,t,E)){if(E.readyState=1,c&&y.trigger("ajaxSend",[E,f]),u)return E;f.async&&f.timeout>0&&(s=r.setTimeout((function(){E.abort("timeout")}),f.timeout));try{u=!1,n.send(k,x)}catch(e){if(u)throw e;x(-1,e)}}else x(-1,"No Transport");function x(e,t,a,d){var l,p,b,k,P,S=t;u||(u=!0,s&&r.clearTimeout(s),n=void 0,o=d||"",E.readyState=e>0?4:0,l=e>=200&&e<300||304===e,a&&(k=function(e,t,r){for(var n,i,o,a,s=e.contents,d=e.dataTypes;"*"===d[0];)d.shift(),void 0===n&&(n=e.mimeType||t.getResponseHeader("Content-Type"));if(n)for(i in s)if(s[i]&&s[i].test(n)){d.unshift(i);break}if(d[0]in r)o=d[0];else{for(i in r){if(!d[0]||e.converters[i+" "+d[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==d[0]&&d.unshift(o),r[o]}(f,E,a)),!l&&T.inArray("script",f.dataTypes)>-1&&(f.converters["text script"]=function(){}),k=function(e,t,r,n){var i,o,a,s,d,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(r[e.responseFields[o]]=t),!d&&n&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),d=o,o=c.shift())if("*"===o)o=d;else if("*"!==d&&d!==o){if(!(a=u[d+" "+o]||u["* "+o]))for(i in u)if((s=i.split(" "))[1]===o&&(a=u[d+" "+s[0]]||u["* "+s[0]])){!0===a?a=u[i]:!0!==u[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+d+" to "+o}}}return{state:"success",data:t}}(f,k,E,l),l?(f.ifModified&&((P=E.getResponseHeader("Last-Modified"))&&(T.lastModified[i]=P),(P=E.getResponseHeader("etag"))&&(T.etag[i]=P)),204===e||"HEAD"===f.type?S="nocontent":304===e?S="notmodified":(S=k.state,p=k.data,l=!(b=k.error))):(b=S,!e&&S||(S="error",e<0&&(e=0))),E.status=e,E.statusText=(t||S)+"",l?m.resolveWith(h,[p,S,E]):m.rejectWith(h,[E,S,b]),E.statusCode(v),v=void 0,c&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,f,l?p:b]),g.fireWith(h,[E,S]),c&&(y.trigger("ajaxComplete",[E,f]),--T.active||T.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,r){return T.get(e,t,r,"json")},getScript:function(e,t){return T.get(e,void 0,t,"script")}}),T.each(["get","post"],(function(e,t){T[t]=function(e,r,n,i){return g(r)&&(i=i||n,n=r,r=void 0),T.ajax(T.extend({url:e,type:t,dataType:i,data:r,success:n},T.isPlainObject(e)&&e))}})),T.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),T._evalUrl=function(e,t,r){return T.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){T.globalEval(e,t,r)}})},T.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=T(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return g(e)?this.each((function(t){T(this).wrapInner(e.call(this,t))})):this.each((function(){var t=T(this),r=t.contents();r.length?r.wrapAll(e):t.append(e)}))},wrap:function(e){var t=g(e);return this.each((function(r){T(this).wrapAll(t?e.call(this,r):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){T(this).replaceWith(this.childNodes)})),this}}),T.expr.pseudos.hidden=function(e){return!T.expr.pseudos.visible(e)},T.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},T.ajaxSettings.xhr=function(){try{return new r.XMLHttpRequest}catch(e){}};var zt={0:200,1223:204},qt=T.ajaxSettings.xhr();m.cors=!!qt&&"withCredentials"in qt,m.ajax=qt=!!qt,T.ajaxTransport((function(e){var t,n;if(m.cors||qt&&!e.crossDomain)return{send:function(i,o){var a,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(a in e.xhrFields)s[a]=e.xhrFields[a];for(a in e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)s.setRequestHeader(a,i[a]);t=function(e){return function(){t&&(t=n=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(zt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=t(),n=s.onerror=s.ontimeout=t("error"),void 0!==s.onabort?s.onabort=n:s.onreadystatechange=function(){4===s.readyState&&r.setTimeout((function(){t&&n()}))},t=t("abort");try{s.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}})),T.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),T.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return T.globalEval(e),e}}}),T.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),T.ajaxTransport("script",(function(e){var t,r;if(e.crossDomain||e.scriptAttrs)return{send:function(n,i){t=T("