diff options
Diffstat (limited to 'xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h')
| -rw-r--r-- | xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h | 128 |
1 files changed, 82 insertions, 46 deletions
diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h index 6c29693..4be785d 100644 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h +++ b/xbmc/addons/kodi-addon-dev-kit/include/kodi/addon-instance/Visualization.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include "../AddonBase.h" | 16 | #include "../AddonBase.h" |
| 17 | #include "../gui/renderHelper.h" | ||
| 17 | 18 | ||
| 18 | namespace kodi { namespace addon { class CInstanceVisualization; }} | 19 | namespace kodi { namespace addon { class CInstanceVisualization; }} |
| 19 | 20 | ||
| @@ -59,6 +60,7 @@ typedef struct AddonToKodiFuncTable_Visualization /* internal */ | |||
| 59 | { | 60 | { |
| 60 | KODI_HANDLE kodiInstance; | 61 | KODI_HANDLE kodiInstance; |
| 61 | void (__cdecl* transfer_preset) (void* kodiInstance, const char* preset); | 62 | void (__cdecl* transfer_preset) (void* kodiInstance, const char* preset); |
| 63 | void (__cdecl* clear_presets) (void* kodiInstance); | ||
| 62 | } AddonToKodiFuncTable_Visualization; | 64 | } AddonToKodiFuncTable_Visualization; |
| 63 | 65 | ||
| 64 | typedef struct KodiToAddonFuncTable_Visualization /* internal */ | 66 | typedef struct KodiToAddonFuncTable_Visualization /* internal */ |
| @@ -78,9 +80,9 @@ typedef struct KodiToAddonFuncTable_Visualization /* internal */ | |||
| 78 | 80 | ||
| 79 | typedef struct AddonInstance_Visualization /* internal */ | 81 | typedef struct AddonInstance_Visualization /* internal */ |
| 80 | { | 82 | { |
| 81 | AddonProps_Visualization props; | 83 | AddonProps_Visualization* props; |
| 82 | AddonToKodiFuncTable_Visualization toKodi; | 84 | AddonToKodiFuncTable_Visualization* toKodi; |
| 83 | KodiToAddonFuncTable_Visualization toAddon; | 85 | KodiToAddonFuncTable_Visualization* toAddon; |
| 84 | } AddonInstance_Visualization; | 86 | } AddonInstance_Visualization; |
| 85 | 87 | ||
| 86 | //============================================================================ | 88 | //============================================================================ |
| @@ -296,7 +298,7 @@ namespace addon | |||
| 296 | /// Kodi's header. Manually deleting the add-on instance is not required. | 298 | /// Kodi's header. Manually deleting the add-on instance is not required. |
| 297 | /// | 299 | /// |
| 298 | //---------------------------------------------------------------------------- | 300 | //---------------------------------------------------------------------------- |
| 299 | class CInstanceVisualization : public IAddonInstance | 301 | class ATTRIBUTE_HIDDEN CInstanceVisualization : public IAddonInstance |
| 300 | { | 302 | { |
| 301 | public: | 303 | public: |
| 302 | //========================================================================== | 304 | //========================================================================== |
| @@ -307,7 +309,8 @@ namespace addon | |||
| 307 | /// Used by an add-on that only supports visualizations. | 309 | /// Used by an add-on that only supports visualizations. |
| 308 | /// | 310 | /// |
| 309 | CInstanceVisualization() | 311 | CInstanceVisualization() |
| 310 | : IAddonInstance(ADDON_INSTANCE_VISUALIZATION) | 312 | : IAddonInstance(ADDON_INSTANCE_VISUALIZATION, |
| 313 | GetKodiTypeVersion(ADDON_INSTANCE_VISUALIZATION)) | ||
| 311 | { | 314 | { |
| 312 | if (CAddonBase::m_interface->globalSingleInstance != nullptr) | 315 | if (CAddonBase::m_interface->globalSingleInstance != nullptr) |
| 313 | throw std::logic_error("kodi::addon::CInstanceVisualization: Cannot create multiple instances of add-on."); | 316 | throw std::logic_error("kodi::addon::CInstanceVisualization: Cannot create multiple instances of add-on."); |
| @@ -325,11 +328,16 @@ namespace addon | |||
| 325 | /// | 328 | /// |
| 326 | /// @param[in] instance The instance value given to | 329 | /// @param[in] instance The instance value given to |
| 327 | /// <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>. | 330 | /// <b>`kodi::addon::CAddonBase::CreateInstance(...)`</b>. |
| 331 | /// @param[in] kodiVersion [opt] Version used in Kodi for this instance, to | ||
| 332 | /// allow compatibility to older Kodi versions. | ||
| 333 | /// @note Recommended to set. | ||
| 328 | /// | 334 | /// |
| 329 | /// @warning Only use `instance` from the CreateInstance call | 335 | /// @warning Only use `instance` from the CreateInstance call |
| 330 | /// | 336 | /// |
| 331 | explicit CInstanceVisualization(KODI_HANDLE instance) | 337 | explicit CInstanceVisualization(KODI_HANDLE instance, const std::string& kodiVersion = "") |
| 332 | : IAddonInstance(ADDON_INSTANCE_VISUALIZATION) | 338 | : IAddonInstance(ADDON_INSTANCE_VISUALIZATION, |
| 339 | !kodiVersion.empty() ? kodiVersion | ||
| 340 | : GetKodiTypeVersion(ADDON_INSTANCE_VISUALIZATION)) | ||
| 333 | { | 341 | { |
| 334 | if (CAddonBase::m_interface->globalSingleInstance != nullptr) | 342 | if (CAddonBase::m_interface->globalSingleInstance != nullptr) |
| 335 | throw std::logic_error("kodi::addon::CInstanceVisualization: Creation of multiple together with single instance way is not allowed!"); | 343 | throw std::logic_error("kodi::addon::CInstanceVisualization: Creation of multiple together with single instance way is not allowed!"); |
| @@ -548,6 +556,26 @@ namespace addon | |||
| 548 | //========================================================================== | 556 | //========================================================================== |
| 549 | /// | 557 | /// |
| 550 | /// @ingroup cpp_kodi_addon_visualization_CB | 558 | /// @ingroup cpp_kodi_addon_visualization_CB |
| 559 | /// @brief To transfer available presets on addon | ||
| 560 | /// | ||
| 561 | /// Used if @ref GetPresets not possible to use, e.g. where available presets | ||
| 562 | /// are only known during @ref Start call. | ||
| 563 | /// | ||
| 564 | /// @param[in] presets List to store available presets. | ||
| 565 | /// | ||
| 566 | /// @note The function should only be called once, if possible | ||
| 567 | /// | ||
| 568 | inline void TransferPresets(const std::vector<std::string>& presets) | ||
| 569 | { | ||
| 570 | m_instanceData->toKodi->clear_presets(m_instanceData->toKodi->kodiInstance); | ||
| 571 | for (auto it : presets) | ||
| 572 | m_instanceData->toKodi->transfer_preset(m_instanceData->toKodi->kodiInstance, it.c_str()); | ||
| 573 | } | ||
| 574 | //-------------------------------------------------------------------------- | ||
| 575 | |||
| 576 | //========================================================================== | ||
| 577 | /// | ||
| 578 | /// @ingroup cpp_kodi_addon_visualization_CB | ||
| 551 | /// @brief Device that represents the display adapter | 579 | /// @brief Device that represents the display adapter |
| 552 | /// | 580 | /// |
| 553 | /// @return A pointer to the used device | 581 | /// @return A pointer to the used device |
| @@ -555,7 +583,7 @@ namespace addon | |||
| 555 | /// @note This is only available on **DirectX**, It us unused (`nullptr`) on | 583 | /// @note This is only available on **DirectX**, It us unused (`nullptr`) on |
| 556 | /// **OpenGL** | 584 | /// **OpenGL** |
| 557 | /// | 585 | /// |
| 558 | inline void* Device() { return m_instanceData->props.device; } | 586 | inline void* Device() { return m_instanceData->props->device; } |
| 559 | //-------------------------------------------------------------------------- | 587 | //-------------------------------------------------------------------------- |
| 560 | 588 | ||
| 561 | //========================================================================== | 589 | //========================================================================== |
| @@ -565,7 +593,7 @@ namespace addon | |||
| 565 | /// | 593 | /// |
| 566 | /// @return The X position, in pixels | 594 | /// @return The X position, in pixels |
| 567 | /// | 595 | /// |
| 568 | inline int X() { return m_instanceData->props.x; } | 596 | inline int X() { return m_instanceData->props->x; } |
| 569 | //-------------------------------------------------------------------------- | 597 | //-------------------------------------------------------------------------- |
| 570 | 598 | ||
| 571 | //========================================================================== | 599 | //========================================================================== |
| @@ -575,7 +603,7 @@ namespace addon | |||
| 575 | /// | 603 | /// |
| 576 | /// @return The Y position, in pixels | 604 | /// @return The Y position, in pixels |
| 577 | /// | 605 | /// |
| 578 | inline int Y() { return m_instanceData->props.y; } | 606 | inline int Y() { return m_instanceData->props->y; } |
| 579 | //-------------------------------------------------------------------------- | 607 | //-------------------------------------------------------------------------- |
| 580 | 608 | ||
| 581 | //========================================================================== | 609 | //========================================================================== |
| @@ -585,7 +613,7 @@ namespace addon | |||
| 585 | /// | 613 | /// |
| 586 | /// @return The width, in pixels | 614 | /// @return The width, in pixels |
| 587 | /// | 615 | /// |
| 588 | inline int Width() { return m_instanceData->props.width; } | 616 | inline int Width() { return m_instanceData->props->width; } |
| 589 | //-------------------------------------------------------------------------- | 617 | //-------------------------------------------------------------------------- |
| 590 | 618 | ||
| 591 | //========================================================================== | 619 | //========================================================================== |
| @@ -595,7 +623,7 @@ namespace addon | |||
| 595 | /// | 623 | /// |
| 596 | /// @return The height, in pixels | 624 | /// @return The height, in pixels |
| 597 | /// | 625 | /// |
| 598 | inline int Height() { return m_instanceData->props.height; } | 626 | inline int Height() { return m_instanceData->props->height; } |
| 599 | //-------------------------------------------------------------------------- | 627 | //-------------------------------------------------------------------------- |
| 600 | 628 | ||
| 601 | //========================================================================== | 629 | //========================================================================== |
| @@ -606,7 +634,7 @@ namespace addon | |||
| 606 | /// | 634 | /// |
| 607 | /// @return The pixel aspect ratio used by the display | 635 | /// @return The pixel aspect ratio used by the display |
| 608 | /// | 636 | /// |
| 609 | inline float PixelRatio() { return m_instanceData->props.pixelRatio; } | 637 | inline float PixelRatio() { return m_instanceData->props->pixelRatio; } |
| 610 | //-------------------------------------------------------------------------- | 638 | //-------------------------------------------------------------------------- |
| 611 | 639 | ||
| 612 | //========================================================================== | 640 | //========================================================================== |
| @@ -616,7 +644,7 @@ namespace addon | |||
| 616 | /// | 644 | /// |
| 617 | /// @return The add-on name | 645 | /// @return The add-on name |
| 618 | /// | 646 | /// |
| 619 | inline std::string Name() { return m_instanceData->props.name; } | 647 | inline std::string Name() { return m_instanceData->props->name; } |
| 620 | //-------------------------------------------------------------------------- | 648 | //-------------------------------------------------------------------------- |
| 621 | 649 | ||
| 622 | //========================================================================== | 650 | //========================================================================== |
| @@ -626,7 +654,7 @@ namespace addon | |||
| 626 | /// | 654 | /// |
| 627 | /// @return The add-on installation path | 655 | /// @return The add-on installation path |
| 628 | /// | 656 | /// |
| 629 | inline std::string Presets() { return m_instanceData->props.presets; } | 657 | inline std::string Presets() { return m_instanceData->props->presets; } |
| 630 | //-------------------------------------------------------------------------- | 658 | //-------------------------------------------------------------------------- |
| 631 | 659 | ||
| 632 | //========================================================================== | 660 | //========================================================================== |
| @@ -640,7 +668,7 @@ namespace addon | |||
| 640 | /// | 668 | /// |
| 641 | /// @return Path to the user profile | 669 | /// @return Path to the user profile |
| 642 | /// | 670 | /// |
| 643 | inline std::string Profile() { return m_instanceData->props.profile; } | 671 | inline std::string Profile() { return m_instanceData->props->profile; } |
| 644 | //-------------------------------------------------------------------------- | 672 | //-------------------------------------------------------------------------- |
| 645 | //@} | 673 | //@} |
| 646 | 674 | ||
| @@ -651,46 +679,53 @@ namespace addon | |||
| 651 | throw std::logic_error("kodi::addon::CInstanceVisualization: Null pointer instance passed."); | 679 | throw std::logic_error("kodi::addon::CInstanceVisualization: Null pointer instance passed."); |
| 652 | 680 | ||
| 653 | m_instanceData = static_cast<AddonInstance_Visualization*>(instance); | 681 | m_instanceData = static_cast<AddonInstance_Visualization*>(instance); |
| 654 | m_instanceData->toAddon.addonInstance = this; | 682 | m_instanceData->toAddon->addonInstance = this; |
| 655 | m_instanceData->toAddon.start = ADDON_Start; | 683 | m_instanceData->toAddon->start = ADDON_Start; |
| 656 | m_instanceData->toAddon.stop = ADDON_Stop; | 684 | m_instanceData->toAddon->stop = ADDON_Stop; |
| 657 | m_instanceData->toAddon.audio_data = ADDON_AudioData; | 685 | m_instanceData->toAddon->audio_data = ADDON_AudioData; |
| 658 | m_instanceData->toAddon.render = ADDON_Render; | 686 | m_instanceData->toAddon->is_dirty = ADDON_IsDirty; |
| 659 | m_instanceData->toAddon.get_info = ADDON_GetInfo; | 687 | m_instanceData->toAddon->render = ADDON_Render; |
| 660 | m_instanceData->toAddon.on_action = ADDON_OnAction; | 688 | m_instanceData->toAddon->get_info = ADDON_GetInfo; |
| 661 | m_instanceData->toAddon.get_presets = ADDON_GetPresets; | 689 | m_instanceData->toAddon->on_action = ADDON_OnAction; |
| 662 | m_instanceData->toAddon.get_active_preset = ADDON_GetActivePreset; | 690 | m_instanceData->toAddon->get_presets = ADDON_GetPresets; |
| 663 | m_instanceData->toAddon.is_locked = ADDON_IsLocked; | 691 | m_instanceData->toAddon->get_active_preset = ADDON_GetActivePreset; |
| 692 | m_instanceData->toAddon->is_locked = ADDON_IsLocked; | ||
| 664 | } | 693 | } |
| 665 | 694 | ||
| 666 | inline static bool ADDON_Start(const AddonInstance_Visualization* addon, int channels, int samplesPerSec, int bitsPerSample, const char* songName) | 695 | inline static bool ADDON_Start(const AddonInstance_Visualization* addon, int channels, int samplesPerSec, int bitsPerSample, const char* songName) |
| 667 | { | 696 | { |
| 668 | return addon->toAddon.addonInstance->Start(channels, samplesPerSec, bitsPerSample, songName); | 697 | addon->toAddon->addonInstance->m_renderHelper = kodi::gui::GetRenderHelper(); |
| 698 | return addon->toAddon->addonInstance->Start(channels, samplesPerSec, bitsPerSample, songName); | ||
| 669 | } | 699 | } |
| 670 | 700 | ||
| 671 | inline static void ADDON_Stop(const AddonInstance_Visualization* addon) | 701 | inline static void ADDON_Stop(const AddonInstance_Visualization* addon) |
| 672 | { | 702 | { |
| 673 | addon->toAddon.addonInstance->Stop(); | 703 | addon->toAddon->addonInstance->Stop(); |
| 704 | addon->toAddon->addonInstance->m_renderHelper = nullptr; | ||
| 674 | } | 705 | } |
| 675 | 706 | ||
| 676 | inline static void ADDON_AudioData(const AddonInstance_Visualization* addon, const float* audioData, int audioDataLength, float *freqData, int freqDataLength) | 707 | inline static void ADDON_AudioData(const AddonInstance_Visualization* addon, const float* audioData, int audioDataLength, float *freqData, int freqDataLength) |
| 677 | { | 708 | { |
| 678 | addon->toAddon.addonInstance->AudioData(audioData, audioDataLength, freqData, freqDataLength); | 709 | addon->toAddon->addonInstance->AudioData(audioData, audioDataLength, freqData, freqDataLength); |
| 679 | } | 710 | } |
| 680 | 711 | ||
| 681 | inline static bool ADDON_IsDirty(const AddonInstance_Visualization* addon) | 712 | inline static bool ADDON_IsDirty(const AddonInstance_Visualization* addon) |
| 682 | { | 713 | { |
| 683 | return addon->toAddon.addonInstance->IsDirty(); | 714 | return addon->toAddon->addonInstance->IsDirty(); |
| 684 | } | 715 | } |
| 685 | 716 | ||
| 686 | inline static void ADDON_Render(const AddonInstance_Visualization* addon) | 717 | inline static void ADDON_Render(const AddonInstance_Visualization* addon) |
| 687 | { | 718 | { |
| 688 | addon->toAddon.addonInstance->Render(); | 719 | if (!addon->toAddon->addonInstance->m_renderHelper) |
| 720 | return; | ||
| 721 | addon->toAddon->addonInstance->m_renderHelper->Begin(); | ||
| 722 | addon->toAddon->addonInstance->Render(); | ||
| 723 | addon->toAddon->addonInstance->m_renderHelper->End(); | ||
| 689 | } | 724 | } |
| 690 | 725 | ||
| 691 | inline static void ADDON_GetInfo(const AddonInstance_Visualization* addon, VIS_INFO *info) | 726 | inline static void ADDON_GetInfo(const AddonInstance_Visualization* addon, VIS_INFO *info) |
| 692 | { | 727 | { |
| 693 | addon->toAddon.addonInstance->GetInfo(info->bWantsFreq, info->iSyncDelay); | 728 | addon->toAddon->addonInstance->GetInfo(info->bWantsFreq, info->iSyncDelay); |
| 694 | } | 729 | } |
| 695 | 730 | ||
| 696 | inline static bool ADDON_OnAction(const AddonInstance_Visualization* addon, VIS_ACTION action, const void *param) | 731 | inline static bool ADDON_OnAction(const AddonInstance_Visualization* addon, VIS_ACTION action, const void *param) |
| @@ -698,24 +733,24 @@ namespace addon | |||
| 698 | switch (action) | 733 | switch (action) |
| 699 | { | 734 | { |
| 700 | case VIS_ACTION_NEXT_PRESET: | 735 | case VIS_ACTION_NEXT_PRESET: |
| 701 | return addon->toAddon.addonInstance->NextPreset(); | 736 | return addon->toAddon->addonInstance->NextPreset(); |
| 702 | case VIS_ACTION_PREV_PRESET: | 737 | case VIS_ACTION_PREV_PRESET: |
| 703 | return addon->toAddon.addonInstance->PrevPreset(); | 738 | return addon->toAddon->addonInstance->PrevPreset(); |
| 704 | case VIS_ACTION_LOAD_PRESET: | 739 | case VIS_ACTION_LOAD_PRESET: |
| 705 | return addon->toAddon.addonInstance->LoadPreset(*static_cast<const int*>(param)); | 740 | return addon->toAddon->addonInstance->LoadPreset(*static_cast<const int*>(param)); |
| 706 | case VIS_ACTION_RANDOM_PRESET: | 741 | case VIS_ACTION_RANDOM_PRESET: |
| 707 | return addon->toAddon.addonInstance->RandomPreset(); | 742 | return addon->toAddon->addonInstance->RandomPreset(); |
| 708 | case VIS_ACTION_LOCK_PRESET: | 743 | case VIS_ACTION_LOCK_PRESET: |
| 709 | addon->toAddon.addonInstance->m_presetLockedByUser = !addon->toAddon.addonInstance->m_presetLockedByUser; | 744 | addon->toAddon->addonInstance->m_presetLockedByUser = !addon->toAddon->addonInstance->m_presetLockedByUser; |
| 710 | return addon->toAddon.addonInstance->LockPreset(addon->toAddon.addonInstance->m_presetLockedByUser); | 745 | return addon->toAddon->addonInstance->LockPreset(addon->toAddon->addonInstance->m_presetLockedByUser); |
| 711 | case VIS_ACTION_RATE_PRESET_PLUS: | 746 | case VIS_ACTION_RATE_PRESET_PLUS: |
| 712 | return addon->toAddon.addonInstance->RatePreset(true); | 747 | return addon->toAddon->addonInstance->RatePreset(true); |
| 713 | case VIS_ACTION_RATE_PRESET_MINUS: | 748 | case VIS_ACTION_RATE_PRESET_MINUS: |
| 714 | return addon->toAddon.addonInstance->RatePreset(false); | 749 | return addon->toAddon->addonInstance->RatePreset(false); |
| 715 | case VIS_ACTION_UPDATE_ALBUMART: | 750 | case VIS_ACTION_UPDATE_ALBUMART: |
| 716 | return addon->toAddon.addonInstance->UpdateAlbumart(static_cast<const char*>(param)); | 751 | return addon->toAddon->addonInstance->UpdateAlbumart(static_cast<const char*>(param)); |
| 717 | case VIS_ACTION_UPDATE_TRACK: | 752 | case VIS_ACTION_UPDATE_TRACK: |
| 718 | return addon->toAddon.addonInstance->UpdateTrack(*static_cast<const VisTrack*>(param)); | 753 | return addon->toAddon->addonInstance->UpdateTrack(*static_cast<const VisTrack*>(param)); |
| 719 | case VIS_ACTION_NONE: | 754 | case VIS_ACTION_NONE: |
| 720 | default: | 755 | default: |
| 721 | break; | 756 | break; |
| @@ -726,10 +761,10 @@ namespace addon | |||
| 726 | inline static unsigned int ADDON_GetPresets(const AddonInstance_Visualization* addon) | 761 | inline static unsigned int ADDON_GetPresets(const AddonInstance_Visualization* addon) |
| 727 | { | 762 | { |
| 728 | std::vector<std::string> presets; | 763 | std::vector<std::string> presets; |
| 729 | if (addon->toAddon.addonInstance->GetPresets(presets)) | 764 | if (addon->toAddon->addonInstance->GetPresets(presets)) |
| 730 | { | 765 | { |
| 731 | for (auto it : presets) | 766 | for (auto it : presets) |
| 732 | addon->toAddon.addonInstance->m_instanceData->toKodi.transfer_preset(addon->toKodi.kodiInstance, it.c_str()); | 767 | addon->toAddon->addonInstance->m_instanceData->toKodi->transfer_preset(addon->toKodi->kodiInstance, it.c_str()); |
| 733 | } | 768 | } |
| 734 | 769 | ||
| 735 | return static_cast<unsigned int>(presets.size()); | 770 | return static_cast<unsigned int>(presets.size()); |
| @@ -737,14 +772,15 @@ namespace addon | |||
| 737 | 772 | ||
| 738 | inline static int ADDON_GetActivePreset(const AddonInstance_Visualization* addon) | 773 | inline static int ADDON_GetActivePreset(const AddonInstance_Visualization* addon) |
| 739 | { | 774 | { |
| 740 | return addon->toAddon.addonInstance->GetActivePreset(); | 775 | return addon->toAddon->addonInstance->GetActivePreset(); |
| 741 | } | 776 | } |
| 742 | 777 | ||
| 743 | inline static bool ADDON_IsLocked(const AddonInstance_Visualization* addon) | 778 | inline static bool ADDON_IsLocked(const AddonInstance_Visualization* addon) |
| 744 | { | 779 | { |
| 745 | return addon->toAddon.addonInstance->IsLocked(); | 780 | return addon->toAddon->addonInstance->IsLocked(); |
| 746 | } | 781 | } |
| 747 | 782 | ||
| 783 | std::shared_ptr<kodi::gui::IRenderHelper> m_renderHelper; | ||
| 748 | bool m_presetLockedByUser = false; | 784 | bool m_presetLockedByUser = false; |
| 749 | AddonInstance_Visualization* m_instanceData; | 785 | AddonInstance_Visualization* m_instanceData; |
| 750 | }; | 786 | }; |
