コード例 #1
0
        /// <summary>
        /// Sets the content of the panel. Assumes the panel is already open.
        /// </summary>
        public virtual void SetContent(Subtitle subtitle)
        {
            if (subtitle == null)
            {
                return;
            }
            currentSubtitle = subtitle;
            if (!onlyShowNPCPortraits || subtitle.speakerInfo.isNPC)
            {
                if (portraitImage != null)
                {
                    var sprite = subtitle.GetSpeakerPortrait();
                    portraitImage.sprite = sprite;
                    Tools.SetGameObjectActive(portraitImage, sprite != null);
                }
                portraitName.text = subtitle.speakerInfo.Name;
                UITools.SendTextChangeMessage(portraitName);
            }
            TypewriterUtility.StopTyping(subtitleText);
            var previousText = accumulateText ? m_accumulatedText : string.Empty;

            SetFormattedText(subtitleText, previousText, subtitle.formattedText);
            if (accumulateText)
            {
                m_accumulatedText = subtitleText.text + "\n";
            }
            TypewriterUtility.StartTyping(subtitleText, subtitleText.text, previousText.Length);
        }
コード例 #2
0
        private IEnumerator WaitForAnimation(string triggerName, bool pauseAfterAnimation, bool panelActive, bool wait, System.Action callback)
        {
            if (panelActive)
            {
                if (panel != null && !panel.gameObject.activeSelf)
                {
                    panel.gameObject.SetActive(true);
                    yield return(null);
                }
            }
            if (CanTriggerAnimation(triggerName) && animator.gameObject.activeSelf)
            {
                CheckAnimatorModeAndTimescale(triggerName);
                animator.SetTrigger(triggerName);
                const float maxWaitDuration = 10;
                float       timeout         = Time.realtimeSinceStartup + maxWaitDuration;
                var         goalHashID      = Animator.StringToHash(triggerName);
                var         oldHashId       = UITools.GetAnimatorNameHash(animator.GetCurrentAnimatorStateInfo(0));
                var         currentHashID   = oldHashId;
                if (wait)
                {
                    while ((currentHashID != goalHashID) && (currentHashID == oldHashId) && (Time.realtimeSinceStartup < timeout))
                    {
                        yield return(null);

                        var isAnimatorValid = animator != null && animator.isActiveAndEnabled && animator.runtimeAnimatorController != null && animator.layerCount > 0;
                        currentHashID = isAnimatorValid ? UITools.GetAnimatorNameHash(animator.GetCurrentAnimatorStateInfo(0)) : currentHashID;
                    }
                    if (Time.realtimeSinceStartup < timeout)
                    {
                        var clipLength = animator.GetCurrentAnimatorStateInfo(0).length;
                        if (Mathf.Approximately(0, Time.timeScale))
                        {
                            timeout = Time.realtimeSinceStartup + clipLength;
                            while (Time.realtimeSinceStartup < timeout)
                            {
                                yield return(null);
                            }
                        }
                        else
                        {
                            yield return(new WaitForSeconds(clipLength));
                        }
                    }
                }
            }
            if (!panelActive)
            {
                Tools.SetGameObjectActive(panel, false);
            }
            if (pauseAfterAnimation)
            {
                Time.timeScale = 0;
            }
            animCoroutine = null;
            if (callback != null)
            {
                callback.Invoke();
            }
        }
コード例 #3
0
 private void ShowControls()
 {
     Tools.SetGameObjectActive(line, true);
     Tools.SetGameObjectActive(portraitImage, true);
     Tools.SetGameObjectActive(portraitName, true);
     Tools.SetGameObjectActive(continueButton, true);
 }
コード例 #4
0
 public override void SetActive(bool value)
 {
     try {
         Tools.SetGameObjectActive(line, value || alwaysVisible);
         Tools.SetGameObjectActive(portraitImage, value || alwaysVisible);
         Tools.SetGameObjectActive(portraitName, value || alwaysVisible);
         Tools.SetGameObjectActive(continueButton, value || alwaysVisible);
         if (value == true)
         {
             Tools.SetGameObjectActive(panel, true);
             if (!isVisible && CanTriggerAnimation(animationTransitions.showTrigger))
             {
                 animator.SetTrigger(animationTransitions.showTrigger);
             }
         }
         else
         {
             if (isVisible && !alwaysVisible && CanTriggerAnimation(animationTransitions.hideTrigger))
             {
                 animator.SetTrigger(animationTransitions.hideTrigger);
                 DialogueManager.Instance.StartCoroutine(DisableAfterAnimation(panel));
             }
             else if (!isHiding)
             {
                 if (panel != null)
                 {
                     Tools.SetGameObjectActive(panel, false || alwaysVisible);
                 }
             }
         }
     } finally {
         isVisible = value || alwaysVisible;
     }
 }
コード例 #5
0
 public override void SetActive(bool value)
 {
     try {
         if (value == true)
         {
             base.SetActive(true);
             if (panel != null)
             {
                 Tools.SetGameObjectActive(panel, true);
             }
             if (!isVisible && CanTriggerAnimation(animationTransitions.showTrigger))
             {
                 animator.SetTrigger(animationTransitions.showTrigger);
             }
         }
         else
         {
             if (isVisible && CanTriggerAnimation(animationTransitions.hideTrigger))
             {
                 animator.SetTrigger(animationTransitions.hideTrigger);
                 DialogueManager.Instance.StartCoroutine(DisableAfterAnimation(panel));
             }
             else
             {
                 base.SetActive(false);
                 if (panel != null)
                 {
                     Tools.SetGameObjectActive(panel, false);
                 }
             }
         }
     } finally {
         isVisible = value;
     }
 }
 /// <summary>
 /// Sets the alert controls active. If a hide animation is available, this method
 /// depends on the hide animation to hide the controls.
 /// </summary>
 /// <param name='value'>
 /// <c>true</c> for active.
 /// </param>
 public override void SetActive(bool value)
 {
     if (value == true)
     {
         Tools.SetGameObjectActive(panel, true);
         Tools.SetGameObjectActive(line, true);
         if (!isVisible && CanTriggerAnimations() && !string.IsNullOrEmpty(animationTransitions.showTrigger))
         {
             animator.SetTrigger(animationTransitions.showTrigger);
         }
     }
     else
     {
         if (isVisible && CanTriggerAnimations() && !string.IsNullOrEmpty(animationTransitions.hideTrigger))
         {
             animator.SetTrigger(animationTransitions.hideTrigger);
             DialogueManager.Instance.StartCoroutine(DisableAfterAnimation());
         }
         else
         {
             Tools.SetGameObjectActive(panel, false);
             Tools.SetGameObjectActive(line, false);
         }
     }
     isVisible = value;
 }
コード例 #7
0
 private void HideControls()
 {
     Tools.SetGameObjectActive(line, alwaysVisible);
     Tools.SetGameObjectActive(portraitImage, alwaysVisible);
     Tools.SetGameObjectActive(portraitName, alwaysVisible);
     Tools.SetGameObjectActive(continueButton, alwaysVisible);
 }
コード例 #8
0
 /// <summary>
 /// Hide the main panel and all of the templates on start.
 /// </summary>
 public virtual void Start()
 {
     UITools.RequireEventSystem();
     Tools.SetGameObjectActive(mainPanel, false);
     Tools.SetGameObjectActive(abandonPopup, false);
     Tools.SetGameObjectActive(questGroupTemplate, false);
     Tools.SetGameObjectActive(questTemplate, false);
     SetStateButtonListeners();
     SetStateToggleButtons();
     if (DialogueDebug.LogWarnings)
     {
         if (mainPanel == null)
         {
             Debug.LogWarning(string.Format("{0}: {1} Main Panel is unassigned", new object[] { DialogueDebug.Prefix, name }));
         }
         if (questTable == null)
         {
             Debug.LogWarning(string.Format("{0}: {1} Quest Table is unassigned", new object[] { DialogueDebug.Prefix, name }));
         }
         if (useGroups && ((questTemplate == null || !questTemplate.ArePropertiesAssigned)))
         {
             Debug.LogWarning(string.Format("{0}: {1} Quest Group Template or one of its properties is unassigned", new object[] { DialogueDebug.Prefix, name }));
         }
         if (questTemplate == null || !questTemplate.ArePropertiesAssigned)
         {
             Debug.LogWarning(string.Format("{0}: {1} Quest Template or one of its properties is unassigned", new object[] { DialogueDebug.Prefix, name }));
         }
     }
 }
コード例 #9
0
 protected virtual void ShowResponsesNow(Subtitle subtitle, Response[] responses, float timeout)
 {
     Tools.SetGameObjectActive(npcPreDelaySettings.preDelayIcon, false);
     Tools.SetGameObjectActive(pcPreDelaySettings.preDelayIcon, false);
     base.ShowResponses(subtitle, responses, timeout);
     ScrollToBottom(); //--- Now does smooth scroll: StartCoroutine(JumpToBottom());
 }
コード例 #10
0
 private void ShowControls()
 {
     if (panel != null)
     {
         Tools.SetGameObjectActive(panel, true);
     }
 }
コード例 #11
0
 /// <summary>
 /// Starts the timer.
 /// </summary>
 /// <param name='timeout'>
 /// Timeout duration in seconds.
 /// </param>
 public override void StartTimer(float timeout)
 {
     if (timer != null)
     {
         if (unityUITimer == null)
         {
             Tools.SetGameObjectActive(timer, true);
             unityUITimer = timer.GetComponent <UnityUITimer>();
             if (unityUITimer == null)
             {
                 unityUITimer = timer.gameObject.AddComponent <UnityUITimer>();
             }
             Tools.SetGameObjectActive(timer, false);
         }
         if (unityUITimer != null)
         {
             Tools.SetGameObjectActive(timer, true);
             unityUITimer.StartCountdown(timeout, OnTimeout);
         }
         else
         {
             if (DialogueDebug.LogWarnings)
             {
                 Debug.LogWarning(string.Format("{0}: No UnityUITimer component found on timer", DialogueDebug.Prefix));
             }
         }
     }
 }
コード例 #12
0
 /// <summary>
 /// Starts the timer.
 /// </summary>
 /// <param name='timeout'>Timeout duration in seconds.</param>
 /// <param name="timeoutHandler">Invoke this handler on timeout.</param>
 public virtual void StartTimer(float timeout, System.Action timeoutHandler)
 {
     if (m_timer == null)
     {
         if (timerSlider != null)
         {
             Tools.SetGameObjectActive(timerSlider, true);
             m_timer = timerSlider.GetComponent <StandardUITimer>();
             if (m_timer == null)
             {
                 m_timer = timerSlider.gameObject.AddComponent <StandardUITimer>();
             }
         }
         else
         {
             m_timer = GetComponentInChildren <StandardUITimer>();
             if (m_timer == null)
             {
                 m_timer = gameObject.AddComponent <StandardUITimer>();
             }
         }
     }
     Tools.SetGameObjectActive(m_timer, true);
     m_timer.StartCountdown(timeout, timeoutHandler);
 }
コード例 #13
0
 /// <summary>
 /// Sets the controls active/inactive, except this method never activates the timer. If the
 /// UI's display settings specify a timeout, then the UI will call StartTimer() to manually
 /// activate the timer.
 /// </summary>
 /// <param name='value'>
 /// Value (<c>true</c> for active; otherwise inactive).
 /// </param>
 public override void SetActive(bool value)
 {
     SubtitleReminder.SetActive(value && SubtitleReminder.HasText);
     Tools.SetGameObjectActive(buttonTemplate, false);
     foreach (var button in buttons)
     {
         if (button != null)
         {
             Tools.SetGameObjectActive(button, value && button.visible);
         }
     }
     Tools.SetGameObjectActive(timer, false);
     Tools.SetGameObjectActive(pcName, value);
     Tools.SetGameObjectActive(pcImage, value);
     Tools.SetGameObjectActive(panel, value);
     if (value == true)
     {
         if ((pcImage != null) && (pcPortraitTexture != null))
         {
             pcImage.sprite = UITools.CreateSprite(pcPortraitTexture);
         }
         if ((pcName != null) && (pcPortraitName != null))
         {
             pcName.text = pcPortraitName;
         }
     }
 }
コード例 #14
0
        /// <summary>
        /// Barks a subtitle. Does not observe formatting codes in the subtitle's FormattedText,
        /// instead using the formatting settings defined on this component.
        /// </summary>
        /// <param name='subtitle'>
        /// Subtitle to bark.
        /// </param>
        public override void Bark(Subtitle subtitle)
        {
            if (ShouldShowText(subtitle))
            {
                SetUIElementsActive(false);
                string subtitleText = subtitle.formattedText.text;
                if (includeName)
                {
                    if (nameText != null)
                    {
                        nameText.text = subtitle.speakerInfo.Name;
                    }
                    else
                    {
                        subtitleText = string.Format("{0}: {1}", subtitleText, subtitle.formattedText.text);
                    }
                }
                else
                {
                    if (nameText != null && nameText.gameObject != null)
                    {
                        nameText.gameObject.SetActive(false);
                    }
                }
                if (showPortraitImage && subtitle.speakerInfo.portrait != null)
                {
                    Tools.SetGameObjectActive(portraitImage, true);
                    portraitImage.sprite = subtitle.speakerInfo.portrait;
                }
                else
                {
                    Tools.SetGameObjectActive(portraitImage, false);
                }
                if (barkText != null)
                {
                    barkText.text = subtitleText;
                }

                SetUIElementsActive(true);
                if (CanTriggerAnimations() && !string.IsNullOrEmpty(animationTransitions.showTrigger))
                {
                    animator.SetTrigger(animationTransitions.showTrigger);
                }
                if (typewriter != null)
                {
                    typewriter.StartTyping(subtitleText);
                }

                //--- We now observe DialogueTime.time instead of using Invoke.
                //CancelInvoke("Hide");
                var barkDuration = Mathf.Approximately(0, duration) ? DialogueManager.GetBarkDuration(subtitleText) : duration;
                //if (!(waitUntilSequenceEnds || waitForContinueButton)) Invoke("Hide", barkDuration);
                if (waitUntilSequenceEnds)
                {
                    numSequencesActive++;
                }
                doneTime = waitForContinueButton ? Mathf.Infinity : (DialogueTime.time + barkDuration);
            }
        }
 private void DeactivateControls()
 {
     Tools.SetGameObjectActive(nameText, false);
     Tools.SetGameObjectActive(useMessageText, false);
     Tools.SetGameObjectActive(reticleInRange, false);
     Tools.SetGameObjectActive(reticleOutOfRange, false);
     Tools.SetGameObjectActive(mainGraphic, false);
 }
コード例 #16
0
 private void SetUIElementsActive(bool value)
 {
     Tools.SetGameObjectActive(panel, value);
     Tools.SetGameObjectActive(line, value);
     Tools.SetGameObjectActive(portraitImage, value);
     Tools.SetGameObjectActive(portraitName, value);
     Tools.SetGameObjectActive(continueButton, false); // Let ConversationView determine if continueButton should be shown.
 }
コード例 #17
0
 /// <summary>
 /// Sets the subtitle controls active or inactive.
 /// </summary>
 /// <param name='value'>
 /// <c>true</c> for active; <c>false</c> for inactive.
 /// </param>
 public override void SetActive(bool value)
 {
     Tools.SetGameObjectActive(line, value);
     Tools.SetGameObjectActive(portraitImage, value);
     Tools.SetGameObjectActive(portraitName, value);
     Tools.SetGameObjectActive(continueButton, value);
     Tools.SetGameObjectActive(panel, value);
 }
コード例 #18
0
 public virtual void StopTimer()
 {
     if (m_timer != null)
     {
         m_timer.StopCountdown();
         Tools.SetGameObjectActive(m_timer, false);
     }
 }
 private void DeactivateUIElements()
 {
     if (panel != null)
     {
         Tools.SetGameObjectActive(panel, false);
     }
     ClearResponseButtons();
 }
コード例 #20
0
 /// <summary>
 /// Hides the QTE indicator specified by the index.
 /// </summary>
 /// <param name='index'>Zero-based index of the indicator.</param>
 public override void HideIndicator(int index)
 {
     if (IsValidQTEIndex(index) && IsQTEIndicatorVisible(index))
     {
         Tools.SetGameObjectActive(QTEIndicators[index], false);
         m_numVisibleQTEIndicators--;
     }
 }
コード例 #21
0
 public void HideImmediate()
 {
     m_numVisibleQTEIndicators = 0;
     foreach (var qteIndicator in QTEIndicators)
     {
         Tools.SetGameObjectActive(qteIndicator, false);
     }
 }
コード例 #22
0
 /// <summary>
 /// Shows the QTE indicator specified by the index.
 /// </summary>
 /// <param name='index'>Zero-based index of the indicator.</param>
 public override void ShowIndicator(int index)
 {
     if (!IsQTEIndicatorVisible(index))
     {
         Tools.SetGameObjectActive(QTEIndicators[index], true);
         m_numVisibleQTEIndicators++;
     }
 }
コード例 #23
0
 /// <summary>
 /// Shows the QTE indicator specified by the index.
 /// </summary>
 /// <param name='index'>
 /// Zero-based index of the indicator.
 /// </param>
 public override void ShowIndicator(int index)
 {
     if (IsValidQTEIndex(index) && !IsQTEIndicatorVisible(index))
     {
         Tools.SetGameObjectActive(qteIndicators[index], true);
         numVisibleQTEIndicators++;
     }
 }
コード例 #24
0
 protected virtual void SetUIElementsActive(bool value)
 {
     Tools.SetGameObjectActive(panel, value);
     Tools.SetGameObjectActive(portraitImage, value);
     portraitName.SetActive(value);
     subtitleText.SetActive(value);
     Tools.SetGameObjectActive(continueButton, false); // Let ConversationView determine if continueButton should be shown.
 }
コード例 #25
0
 public virtual void SetPCPortrait(Sprite portraitSprite, string portraitName)
 {
     if (pcImage != null)
     {
         pcImage.sprite = portraitSprite;
         Tools.SetGameObjectActive(pcImage, portraitSprite != null);
     }
     pcName.text = portraitName;
 }
コード例 #26
0
 protected virtual void InitializeTemplates()
 {
     if (DialogueDebug.logWarnings)
     {
         if (mainPanel == null)
         {
             Debug.LogWarning("Dialogue System: Main Panel is unassigned.", this);
         }
         if (questSelectionContentContainer == null)
         {
             Debug.LogWarning("Dialogue System: Quest Selection Content Container is unassigned.", this);
         }
         if (questGroupTemplate == null)
         {
             Debug.LogWarning("Dialogue System: Quest Group Template is unassigned.", this);
         }
         if (activeQuestHeadingTemplate == null)
         {
             Debug.LogWarning("Dialogue System: Active Quest Title Template is unassigned.", this);
         }
         if (completedQuestHeadingTemplate == null)
         {
             Debug.LogWarning("Dialogue System: Completed Quest Title Template is unassigned.", this);
         }
         if (questDetailsContentContainer == null)
         {
             Debug.LogWarning("Dialogue System: Quest Details Content Container is unassigned.", this);
         }
         if (questHeadingTextTemplate == null)
         {
             Debug.LogWarning("Dialogue System: Quest Heading Text Template is unassigned.", this);
         }
         if (questDescriptionTextTemplate == null)
         {
             Debug.LogWarning("Dialogue System: Quest Body Text Template is unassigned.", this);
         }
         if (abandonQuestPanel == null)
         {
             Debug.LogWarning("Dialogue System: Abandon Quest Panel is unassigned.", this);
         }
         if (abandonQuestTitleText == null)
         {
             Debug.LogWarning("Dialogue System: Abandon Quest Title Text is unassigned.", this);
         }
     }
     Tools.SetGameObjectActive(questGroupTemplate, false);
     Tools.SetGameObjectActive(activeQuestHeadingTemplate, false);
     Tools.SetGameObjectActive(completedQuestHeadingTemplate, false);
     Tools.SetGameObjectActive(selectedActiveQuestHeadingTemplate, false);
     Tools.SetGameObjectActive(selectedCompletedQuestHeadingTemplate, false);
     Tools.SetGameObjectActive(questHeadingTextTemplate, false);
     Tools.SetGameObjectActive(questDescriptionTextTemplate, false);
     Tools.SetGameObjectActive(questEntryActiveTextTemplate, false);
     Tools.SetGameObjectActive(questEntrySuccessTextTemplate, false);
     Tools.SetGameObjectActive(questEntryFailureTextTemplate, false);
     Tools.SetGameObjectActive(abandonButtonTemplate, false);
 }
コード例 #27
0
 private void UpdateReticle(bool inRange)
 {
     if (elements == null)
     {
         return;
     }
     Tools.SetGameObjectActive(elements.reticleInRange, inRange);
     Tools.SetGameObjectActive(elements.reticleOutOfRange, !inRange);
 }
コード例 #28
0
 /// <summary>
 /// Sets the controls active/inactive, except this method never activates the timer. If the
 /// UI's display settings specify a timeout, then the UI will call StartTimer() to manually
 /// activate the timer.
 /// </summary>
 /// <param name='value'>
 /// Value (<c>true</c> for active; otherwise inactive).
 /// </param>
 public override void SetActive(bool value)
 {
     try
     {
         SubtitleReminder.SetActive(value && SubtitleReminder.HasText);
         Tools.SetGameObjectActive(buttonTemplate, false);
         foreach (var button in buttons)
         {
             if (button != null)
             {
                 Tools.SetGameObjectActive(button, value && button.visible);
             }
         }
         Tools.SetGameObjectActive(timer, false);
         Tools.SetGameObjectActive(pcName, value);
         Tools.SetGameObjectActive(pcImage, value);
         if (value == true)
         {
             if ((pcImage != null) && (pcPortraitTexture != null))
             {
                 pcImage.sprite = UITools.CreateSprite(pcPortraitTexture);
             }
             if ((pcName != null) && (pcPortraitName != null))
             {
                 pcName.text = pcPortraitName;
             }
             Tools.SetGameObjectActive(panel, true);
             if (!isVisible && CanTriggerAnimation(animationTransitions.showTrigger))
             {
                 animator.SetTrigger(animationTransitions.showTrigger);
             }
             if (explicitNavigationForTemplateButtons)
             {
                 SetupTemplateButtonNavigation();
             }
         }
         else
         {
             if (isVisible && CanTriggerAnimation(animationTransitions.hideTrigger))
             {
                 animator.SetTrigger(animationTransitions.hideTrigger);
                 DialogueManager.Instance.StartCoroutine(DisableAfterAnimation(panel));
             }
             else if (!isHiding)
             {
                 if (panel != null)
                 {
                     Tools.SetGameObjectActive(panel, false);
                 }
             }
         }
     }
     finally
     {
         isVisible = value;
     }
 }
        /// <summary>
        /// Sets the controls active/inactive, except this method never activates the timer. If the
        /// UI's display settings specify a timeout, then the UI will call StartTimer() to manually
        /// activate the timer.
        /// </summary>
        /// <param name='value'>
        /// Value (<c>true</c> for active; otherwise inactive).
        /// </param>
        public override void SetActive(bool value)
        {
            subtitleReminder.SetActive(value && subtitleReminder.HasText);
            Tools.SetGameObjectActive(buttonTemplate, false);
            foreach (var button in buttons)
            {
                if (button != null)
                {
                    if (value == true)
                    {
                        Tools.SetGameObjectActive(button, button.visible);
                    }
                    else
                    {
                        button.clickable = false;
                    }
                }
            }
            Tools.SetGameObjectActive(timer, false);
            Tools.SetGameObjectActive(pcName, value);
            Tools.SetGameObjectActive(pcImage, value);
            if (value == true)
            {
                if ((pcImage != null) && (pcPortraitSprite != null))
                {
                    pcImage.sprite = pcPortraitSprite;
                }
                if ((pcName != null) && (pcPortraitName != null))
                {
                    pcName.text = pcPortraitName;
                }
                Tools.SetGameObjectActive(panel, true);

                animationTransitions.ClearTriggers(showHideController);
                showHideController.Show(animationTransitions.showTrigger, false, null);
                if (explicitNavigationForTemplateButtons)
                {
                    SetupTemplateButtonNavigation();
                }
            }
            else
            {
                if (isVisible && CanTriggerAnimation(animationTransitions.hideTrigger))
                {
                    animationTransitions.ClearTriggers(showHideController);
                    showHideController.Hide(animationTransitions.hideTrigger, DeactivateUIElements);
                }
                else
                {
                    if (panel != null)
                    {
                        Tools.SetGameObjectActive(panel, false);
                    }
                }
            }
        }
コード例 #30
0
 /// <summary>
 /// Sets the QTE controls active/inactive.
 /// </summary>
 /// <param name='value'>
 /// <c>true</c> for active; <c>false</c> for inactive.
 /// </param>
 public override void SetActive(bool value)
 {
     if (value == false)
     {
         numVisibleQTEIndicators = 0;
         foreach (var qteIndicator in qteIndicators)
         {
             Tools.SetGameObjectActive(qteIndicator, false);
         }
     }
 }