com.taptap.sdk.compliance 4.3.0-aplha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Mobile/Editor/NativeDependencies.xml +18 -0
- package/Mobile/Editor/NativeDependencies.xml.meta +7 -0
- package/Mobile/Editor/TapComplianceMobileProcessBuild.cs +21 -0
- package/Mobile/Editor/TapComplianceMobileProcessBuild.cs.meta +3 -0
- package/Mobile/Editor/TapSDK.Compliance.Mobile.Editor.asmdef +17 -0
- package/Mobile/Editor/TapSDK.Compliance.Mobile.Editor.asmdef.meta +7 -0
- package/Mobile/Editor/iOS/BuidPostProcessor.cs +45 -0
- package/Mobile/Editor/iOS/BuidPostProcessor.cs.meta +11 -0
- package/Mobile/Editor/iOS.meta +8 -0
- package/Mobile/Editor.meta +8 -0
- package/Mobile/Runtime/ComplianceMobileBridge.cs +319 -0
- package/Mobile/Runtime/ComplianceMobileBridge.cs.meta +11 -0
- package/Mobile/Runtime/ComplianceMobileOldJob.cs +81 -0
- package/Mobile/Runtime/ComplianceMobileOldJob.cs.meta +11 -0
- package/Mobile/Runtime/TapSDK.Compliance.Mobile.Runtime.asmdef +19 -0
- package/Mobile/Runtime/TapSDK.Compliance.Mobile.Runtime.asmdef.meta +7 -0
- package/Mobile/Runtime.meta +3 -0
- package/Mobile.meta +8 -0
- package/Resources/BillingMode.json +1 -0
- package/Resources/BillingMode.json.meta +7 -0
- package/Resources/Config/ComplianceLocalization.json +116 -0
- package/Resources/Config/ComplianceLocalization.json.meta +7 -0
- package/Resources/Config.meta +8 -0
- package/Resources/Prefabs/Mobile/TapTapAntiAddictionRetryAlert.prefab +803 -0
- package/Resources/Prefabs/Mobile/TapTapAntiAddictionRetryAlert.prefab.meta +7 -0
- package/Resources/Prefabs/Mobile/TapTapHealthPaymentPanel.prefab +820 -0
- package/Resources/Prefabs/Mobile/TapTapHealthPaymentPanel.prefab.meta +7 -0
- package/Resources/Prefabs/Mobile/TapTapHealthReminderPanel.prefab +988 -0
- package/Resources/Prefabs/Mobile/TapTapHealthReminderPanel.prefab.meta +7 -0
- package/Resources/Prefabs/Mobile/TapTapVietnamTimeSelectorPanel.prefab +3176 -0
- package/Resources/Prefabs/Mobile/TapTapVietnamTimeSelectorPanel.prefab.meta +7 -0
- package/Resources/Prefabs/Mobile.meta +8 -0
- package/Resources/Prefabs.meta +8 -0
- package/Resources/Textures/Background.png +0 -0
- package/Resources/Textures/Background.png.meta +128 -0
- package/Resources/Textures/Button.png +0 -0
- package/Resources/Textures/Button.png.meta +128 -0
- package/Resources/Textures/Checkmark.png +0 -0
- package/Resources/Textures/Checkmark.png.meta +128 -0
- package/Resources/Textures/Dropdown.png +0 -0
- package/Resources/Textures/Dropdown.png.meta +128 -0
- package/Resources/Textures/DropdownH.png +0 -0
- package/Resources/Textures/DropdownH.png.meta +128 -0
- package/Resources/Textures/Loading.png +0 -0
- package/Resources/Textures/Loading.png.meta +128 -0
- package/Resources/Textures/On.png +0 -0
- package/Resources/Textures/On.png.meta +128 -0
- package/Resources/Textures/Scrollview.png +0 -0
- package/Resources/Textures/Scrollview.png.meta +128 -0
- package/Resources/Textures/WhiteButton.png +0 -0
- package/Resources/Textures/WhiteButton.png.meta +128 -0
- package/Resources/Textures/error_tip.png +0 -0
- package/Resources/Textures/error_tip.png.meta +128 -0
- package/Resources/Textures/off.png +0 -0
- package/Resources/Textures/off.png.meta +128 -0
- package/Resources/Textures/taptap-antiaddiction-input.png +0 -0
- package/Resources/Textures/taptap-antiaddiction-input.png.meta +128 -0
- package/Resources/Textures/taptap-antiaddiction-largebutton.png +0 -0
- package/Resources/Textures/taptap-antiaddiction-largebutton.png.meta +128 -0
- package/Resources/Textures/taptap-antiaddiction-mobile-button.png +0 -0
- package/Resources/Textures/taptap-antiaddiction-mobile-button.png.meta +128 -0
- package/Resources/Textures.meta +8 -0
- package/Resources.meta +8 -0
- package/Runtime/Internal/ComplianceJobManager.cs +85 -0
- package/Runtime/Internal/ComplianceJobManager.cs.meta +11 -0
- package/Runtime/Internal/ComplianceResult.cs +89 -0
- package/Runtime/Internal/ComplianceResult.cs.meta +3 -0
- package/Runtime/Internal/IComplianceJob.cs +51 -0
- package/Runtime/Internal/IComplianceJob.cs.meta +11 -0
- package/Runtime/Internal/Init/ComplianceInitTask.cs +46 -0
- package/Runtime/Internal/Init/ComplianceInitTask.cs.meta +3 -0
- package/Runtime/Internal/Init.meta +3 -0
- package/Runtime/Internal/Model/StartUpResult.cs +28 -0
- package/Runtime/Internal/Model/StartUpResult.cs.meta +11 -0
- package/Runtime/Internal/Model.meta +8 -0
- package/Runtime/Internal.meta +8 -0
- package/Runtime/Public/TapTapCompliance.cs +119 -0
- package/Runtime/Public/TapTapCompliance.cs.meta +11 -0
- package/Runtime/Public/TapTapComplianceOption.cs +52 -0
- package/Runtime/Public/TapTapComplianceOption.cs.meta +3 -0
- package/Runtime/Public.meta +3 -0
- package/Runtime/TapSDK.Compliance.Runtime.asmdef +16 -0
- package/Runtime/TapSDK.Compliance.Runtime.asmdef.meta +7 -0
- package/Runtime.meta +3 -0
- package/Standalone/Editor/TapComplianceStandaloneProcessBuild.cs +20 -0
- package/Standalone/Editor/TapComplianceStandaloneProcessBuild.cs.meta +3 -0
- package/Standalone/Editor/TapSDK.Compliance.Standalone.Editor.asmdef +17 -0
- package/Standalone/Editor/TapSDK.Compliance.Standalone.Editor.asmdef.meta +7 -0
- package/Standalone/Editor.meta +3 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapAntiAddictionRetryAlert.prefab +835 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapAntiAddictionRetryAlert.prefab.meta +7 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapChinaIDInputPanel.prefab +1646 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapChinaIDInputPanel.prefab.meta +7 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapChinaQuickVerifyTipPanel.prefab +1591 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapChinaQuickVerifyTipPanel.prefab.meta +7 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapHealthPaymentPanel.prefab +897 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapHealthPaymentPanel.prefab.meta +7 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapHealthReminderPanel.prefab +1065 -0
- package/Standalone/Resources/Prefabs/Standalone/TapTapHealthReminderPanel.prefab.meta +7 -0
- package/Standalone/Resources/Prefabs/Standalone.meta +8 -0
- package/Standalone/Resources/Prefabs.meta +8 -0
- package/Standalone/Resources/Textures/QuickVerifyTip.png +0 -0
- package/Standalone/Resources/Textures/QuickVerifyTip.png.meta +128 -0
- package/Standalone/Resources/Textures/taptap-antiaddiction-largebutton.png +0 -0
- package/Standalone/Resources/Textures/taptap-antiaddiction-largebutton.png.meta +128 -0
- package/Standalone/Resources/Textures.meta +8 -0
- package/Standalone/Resources.meta +8 -0
- package/Standalone/Runtime/ComplianceWorker.cs +524 -0
- package/Standalone/Runtime/ComplianceWorker.cs.meta +11 -0
- package/Standalone/Runtime/Internal/AccessTokenJsonConverter.cs +58 -0
- package/Standalone/Runtime/Internal/AccessTokenJsonConverter.cs.meta +3 -0
- package/Standalone/Runtime/Internal/ComplianceConst.cs +73 -0
- package/Standalone/Runtime/Internal/ComplianceConst.cs.meta +11 -0
- package/Standalone/Runtime/Internal/ComplianceException.cs +24 -0
- package/Standalone/Runtime/Internal/ComplianceException.cs.meta +11 -0
- package/Standalone/Runtime/Internal/ComplianceNewJob.cs +174 -0
- package/Standalone/Runtime/Internal/ComplianceNewJob.cs.meta +11 -0
- package/Standalone/Runtime/Internal/CompliancePoll.cs +136 -0
- package/Standalone/Runtime/Internal/CompliancePoll.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Config.cs +137 -0
- package/Standalone/Runtime/Internal/Config.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http/ComplianceHttpClient.cs +215 -0
- package/Standalone/Runtime/Internal/Http/ComplianceHttpClient.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Http.meta +8 -0
- package/Standalone/Runtime/Internal/Model/BaseResponse.cs +14 -0
- package/Standalone/Runtime/Internal/Model/BaseResponse.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/ErrorResponse.cs +27 -0
- package/Standalone/Runtime/Internal/Model/ErrorResponse.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/Payable.cs +23 -0
- package/Standalone/Runtime/Internal/Model/Payable.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/Playable.cs +48 -0
- package/Standalone/Runtime/Internal/Model/Playable.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/RealNameConfig.cs +73 -0
- package/Standalone/Runtime/Internal/Model/RealNameConfig.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/ServerTime.cs +19 -0
- package/Standalone/Runtime/Internal/Model/ServerTime.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/StandaloneResponse.cs +12 -0
- package/Standalone/Runtime/Internal/Model/StandaloneResponse.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/SubmitPayment.cs +8 -0
- package/Standalone/Runtime/Internal/Model/SubmitPayment.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/UserComplianceConfig.cs +109 -0
- package/Standalone/Runtime/Internal/Model/UserComplianceConfig.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model/Verification.cs +88 -0
- package/Standalone/Runtime/Internal/Model/Verification.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Model.meta +8 -0
- package/Standalone/Runtime/Internal/Network.cs +296 -0
- package/Standalone/Runtime/Internal/Network.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Persistence.cs +91 -0
- package/Standalone/Runtime/Internal/Persistence.cs.meta +11 -0
- package/Standalone/Runtime/Internal/TapComplianceUI.cs +68 -0
- package/Standalone/Runtime/Internal/TapComplianceUI.cs.meta +11 -0
- package/Standalone/Runtime/Internal/TapLoginPermissionProvider.cs +24 -0
- package/Standalone/Runtime/Internal/TapLoginPermissionProvider.cs.meta +11 -0
- package/Standalone/Runtime/Internal/TapTapComplianceManager.cs +253 -0
- package/Standalone/Runtime/Internal/TapTapComplianceManager.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Tool.cs +211 -0
- package/Standalone/Runtime/Internal/Tool.cs.meta +11 -0
- package/Standalone/Runtime/Internal/UI/Controller/TapTapChinaVerifyFinishPanelController.cs +81 -0
- package/Standalone/Runtime/Internal/UI/Controller/TapTapChinaVerifyFinishPanelController.cs.meta +11 -0
- package/Standalone/Runtime/Internal/UI/Controller/TapTapComplianceQuickVerifyTipController.cs +119 -0
- package/Standalone/Runtime/Internal/UI/Controller/TapTapComplianceQuickVerifyTipController.cs.meta +3 -0
- package/Standalone/Runtime/Internal/UI/Controller/TaptapComplianceHealthPaymentController.cs +105 -0
- package/Standalone/Runtime/Internal/UI/Controller/TaptapComplianceHealthPaymentController.cs.meta +11 -0
- package/Standalone/Runtime/Internal/UI/Controller/TaptapComplianceHealthReminderController.cs +129 -0
- package/Standalone/Runtime/Internal/UI/Controller/TaptapComplianceHealthReminderController.cs.meta +11 -0
- package/Standalone/Runtime/Internal/UI/Controller/TaptapComplianceIDInputController.cs +218 -0
- package/Standalone/Runtime/Internal/UI/Controller/TaptapComplianceIDInputController.cs.meta +11 -0
- package/Standalone/Runtime/Internal/UI/Controller/TaptapComplianceRetryAlertController.cs +46 -0
- package/Standalone/Runtime/Internal/UI/Controller/TaptapComplianceRetryAlertController.cs.meta +11 -0
- package/Standalone/Runtime/Internal/UI/Controller.meta +8 -0
- package/Standalone/Runtime/Internal/UI.meta +8 -0
- package/Standalone/Runtime/Internal/Verification.cs +315 -0
- package/Standalone/Runtime/Internal/Verification.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Worker/BaseComplianceWorker.cs +489 -0
- package/Standalone/Runtime/Internal/Worker/BaseComplianceWorker.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Worker.meta +8 -0
- package/Standalone/Runtime/Internal.meta +3 -0
- package/Standalone/Runtime/TapTap.AntiAddiction.Standalone.Runtime.asmdef +26 -0
- package/Standalone/Runtime/TapTap.AntiAddiction.Standalone.Runtime.asmdef.meta +3 -0
- package/Standalone/Runtime/gen/ComplianceLocalizationItems.cs +121 -0
- package/Standalone/Runtime/gen/ComplianceLocalizationItems.cs.meta +11 -0
- package/Standalone/Runtime/gen.meta +8 -0
- package/Standalone/Runtime.meta +3 -0
- package/Standalone.meta +3 -0
- package/package.json +12 -0
- package/package.json.meta +7 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine.UI;
|
|
3
|
+
using TapSDK.UI;
|
|
4
|
+
using UnityEngine;
|
|
5
|
+
|
|
6
|
+
namespace TapSDK.Compliance.Internal {
|
|
7
|
+
public class TapTapComplianceQuickVerifyTipController : BasePanelController {
|
|
8
|
+
public class OpenParams : AbstractOpenPanelParameter {
|
|
9
|
+
public Action<bool> onClicked;
|
|
10
|
+
public bool justShowConfirmBtn;
|
|
11
|
+
public Action onClose;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public Text titleText;
|
|
15
|
+
public Text mainIntroText;
|
|
16
|
+
public Text confirmBtn1Text;
|
|
17
|
+
public Text confirmBtn2Text;
|
|
18
|
+
public Text denyBtnText;
|
|
19
|
+
|
|
20
|
+
public Button confirmBtn1;
|
|
21
|
+
public Button confirmBtn2;
|
|
22
|
+
public Button denyBtn;
|
|
23
|
+
public Button closeBtn;
|
|
24
|
+
|
|
25
|
+
private OpenParams param;
|
|
26
|
+
|
|
27
|
+
public ScrollRect scrollRect;
|
|
28
|
+
/// <summary>
|
|
29
|
+
/// bind ugui components for every panel
|
|
30
|
+
/// </summary>
|
|
31
|
+
protected override void BindComponents()
|
|
32
|
+
{
|
|
33
|
+
titleText = transform.Find("Root/TitleText").GetComponent<Text>();
|
|
34
|
+
scrollRect = transform.Find("Root/Scroll View").GetComponent<ScrollRect>();
|
|
35
|
+
mainIntroText = scrollRect.transform.Find("Viewport/Content/GameIntro").GetComponent<Text>();
|
|
36
|
+
confirmBtn1Text = transform.Find("Root/Button1/ConfirmBtn/Text").GetComponent<Text>();
|
|
37
|
+
confirmBtn2Text = transform.Find("Root/Button2/ConfirmBtn/Text").GetComponent<Text>();
|
|
38
|
+
denyBtnText = transform.Find("Root/Button2/DenyBtn/Text").GetComponent<Text>();
|
|
39
|
+
|
|
40
|
+
confirmBtn1 = transform.Find("Root/Button1/ConfirmBtn").GetComponent<Button>();
|
|
41
|
+
confirmBtn2 = transform.Find("Root/Button2/ConfirmBtn").GetComponent<Button>();
|
|
42
|
+
denyBtn = transform.Find("Root/Button2/DenyBtn").GetComponent<Button>();
|
|
43
|
+
closeBtn = transform.Find("Root/CloseButton").GetComponent<Button>();
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected override void OnLoadSuccess()
|
|
48
|
+
{
|
|
49
|
+
base.OnLoadSuccess();
|
|
50
|
+
param = openParam as OpenParams;
|
|
51
|
+
|
|
52
|
+
closeBtn.onClick.AddListener(() => {
|
|
53
|
+
Close();
|
|
54
|
+
param.onClose?.Invoke();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
confirmBtn1.onClick.RemoveAllListeners();
|
|
58
|
+
confirmBtn1.gameObject.SetActive(false);
|
|
59
|
+
confirmBtn2.onClick.RemoveAllListeners();
|
|
60
|
+
confirmBtn2.gameObject.SetActive(false);
|
|
61
|
+
denyBtn.onClick.RemoveAllListeners();
|
|
62
|
+
denyBtn.gameObject.SetActive(false);
|
|
63
|
+
if (param.justShowConfirmBtn) {
|
|
64
|
+
confirmBtn1.onClick.AddListener(() => {
|
|
65
|
+
this.Close();
|
|
66
|
+
param.onClicked?.Invoke(true);
|
|
67
|
+
});
|
|
68
|
+
confirmBtn1.gameObject.SetActive(true);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
confirmBtn2.onClick.AddListener(() => {
|
|
72
|
+
this.Close();
|
|
73
|
+
param.onClicked?.Invoke(true);
|
|
74
|
+
});
|
|
75
|
+
confirmBtn2.gameObject.SetActive(true);
|
|
76
|
+
denyBtn.onClick.AddListener(() => {
|
|
77
|
+
this.Close();
|
|
78
|
+
param.onClicked?.Invoke(false);
|
|
79
|
+
});
|
|
80
|
+
denyBtn.gameObject.SetActive(true);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
var config = Config.GetQuickVerifyTipPanelTip();
|
|
84
|
+
if (config != null) {
|
|
85
|
+
titleText.text = config.Title;
|
|
86
|
+
mainIntroText.text = config.Content.Replace(" ","\u00A0");//.Substring(0, index + + splitter.Length);
|
|
87
|
+
Debug.Log("set mainIntro text = " + config.Content);
|
|
88
|
+
int lineCount;
|
|
89
|
+
float lineHeight;
|
|
90
|
+
if (IsTextOverflowing(mainIntroText, out lineCount, out lineHeight)) {
|
|
91
|
+
scrollRect.enabled = true;
|
|
92
|
+
mainIntroText.rectTransform.sizeDelta = new Vector2(mainIntroText.rectTransform.sizeDelta.x,
|
|
93
|
+
40 + (lineCount - 4) * lineHeight);
|
|
94
|
+
|
|
95
|
+
var contentRect = scrollRect.transform.Find("Viewport/Content").GetComponent<RectTransform>();
|
|
96
|
+
contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x,
|
|
97
|
+
40 + (lineCount - 4) * lineHeight);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
scrollRect.enabled = false;
|
|
101
|
+
}
|
|
102
|
+
confirmBtn1Text.text = config.PositiveButtonText;
|
|
103
|
+
confirmBtn2Text.text = config.PositiveButtonText;
|
|
104
|
+
denyBtnText.text = config.NegativeButtonText;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
bool IsTextOverflowing(Text text, out int lineCount, out float lineHeight)
|
|
109
|
+
{
|
|
110
|
+
var textGenerator = text.cachedTextGenerator;
|
|
111
|
+
var settings = text.GetGenerationSettings(text.rectTransform.rect.size);
|
|
112
|
+
textGenerator.Populate(text.text, settings);
|
|
113
|
+
lineCount = textGenerator.lineCount;
|
|
114
|
+
lineHeight = 15 + (text.lineSpacing - 1) * 15;
|
|
115
|
+
return textGenerator.lineCount > 6;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
|
|
2
|
+
using TapSDK.UI;
|
|
3
|
+
using TapSDK.Compliance.Model;
|
|
4
|
+
using UnityEngine.UI;
|
|
5
|
+
using System;
|
|
6
|
+
using UnityEngine;
|
|
7
|
+
|
|
8
|
+
namespace TapSDK.Compliance.Internal
|
|
9
|
+
{
|
|
10
|
+
public class TaptapComplianceHealthPaymentController : BasePanelController
|
|
11
|
+
{
|
|
12
|
+
public Text titleText;
|
|
13
|
+
public Text contentText;
|
|
14
|
+
public Text buttonText;
|
|
15
|
+
public Button okButton;
|
|
16
|
+
public ScrollRect scrollRect;
|
|
17
|
+
private Action _onOk;
|
|
18
|
+
|
|
19
|
+
/// <summary>
|
|
20
|
+
/// bind ugui components for every panel
|
|
21
|
+
/// </summary>
|
|
22
|
+
protected override void BindComponents()
|
|
23
|
+
{
|
|
24
|
+
titleText = transform.Find("Root/TitleText").GetComponent<Text>();
|
|
25
|
+
scrollRect = transform.Find("Root/Scroll View").GetComponent<ScrollRect>();
|
|
26
|
+
contentText = transform.Find("Root/Scroll View/Viewport/Content/ContentText").GetComponent<Text>();
|
|
27
|
+
okButton = transform.Find("Root/OKButton").GetComponent<Button>();
|
|
28
|
+
buttonText = okButton.transform.Find("Text").GetComponent<Text>();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
protected override void OnLoadSuccess()
|
|
32
|
+
{
|
|
33
|
+
base.OnLoadSuccess();
|
|
34
|
+
|
|
35
|
+
okButton.onClick.AddListener(OnOKButtonClicked);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
internal void Show(PayableResult payable)
|
|
39
|
+
{
|
|
40
|
+
titleText.text = payable.Title;
|
|
41
|
+
contentText.text = ProcessContent(payable.Content);
|
|
42
|
+
if (IsTextOverflowing(contentText, out int lineCount, out float lineHeight)) {
|
|
43
|
+
scrollRect.enabled = true;
|
|
44
|
+
contentText.rectTransform.sizeDelta = new Vector2(contentText.rectTransform.sizeDelta.x,
|
|
45
|
+
80 + lineCount * lineHeight);
|
|
46
|
+
|
|
47
|
+
var contentRect = scrollRect.transform.Find("Viewport/Content").GetComponent<RectTransform>();
|
|
48
|
+
contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x,
|
|
49
|
+
80 + lineCount * lineHeight);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
scrollRect.enabled = false;
|
|
53
|
+
}
|
|
54
|
+
// var buttonText = Config.GetHealthTip();
|
|
55
|
+
// if (!string.IsNullOrEmpty(buttonText))
|
|
56
|
+
// this.buttonText.text = buttonText;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
internal void Show(string title, string content, string buttonText, Action onOk = null)
|
|
60
|
+
{
|
|
61
|
+
titleText.text = title;
|
|
62
|
+
contentText.text = ProcessContent(content);
|
|
63
|
+
if (IsTextOverflowing(contentText, out int lineCount, out float lineHeight)) {
|
|
64
|
+
scrollRect.enabled = true;
|
|
65
|
+
contentText.rectTransform.sizeDelta = new Vector2(contentText.rectTransform.sizeDelta.x,
|
|
66
|
+
80 + lineCount * lineHeight);
|
|
67
|
+
|
|
68
|
+
var contentRect = scrollRect.transform.Find("Viewport/Content").GetComponent<RectTransform>();
|
|
69
|
+
contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x,
|
|
70
|
+
80 + lineCount * lineHeight);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
scrollRect.enabled = false;
|
|
74
|
+
}
|
|
75
|
+
if (!string.IsNullOrEmpty(buttonText))
|
|
76
|
+
this.buttonText.text = buttonText;
|
|
77
|
+
_onOk = onOk;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private string ProcessContent(string content)
|
|
81
|
+
{
|
|
82
|
+
return content
|
|
83
|
+
?.Replace(" ", "\u00A0");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private void OnOKButtonClicked()
|
|
87
|
+
{
|
|
88
|
+
Close();
|
|
89
|
+
_onOk?.Invoke();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
bool IsTextOverflowing(Text text, out int lineCount, out float lineHeight)
|
|
93
|
+
{
|
|
94
|
+
var textGenerator = text.cachedTextGenerator;
|
|
95
|
+
var settings = text.GetGenerationSettings(text.rectTransform.rect.size);
|
|
96
|
+
textGenerator.Populate(text.text, settings);
|
|
97
|
+
lineCount = textGenerator.lineCount;
|
|
98
|
+
if (TapTapComplianceManager.IsUseMobileUI()) {
|
|
99
|
+
lineCount += 3;
|
|
100
|
+
}
|
|
101
|
+
lineHeight = 25 + (text.lineSpacing - 1) * 25;
|
|
102
|
+
return lineCount > 4;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine.UI;
|
|
3
|
+
using TapSDK.UI;
|
|
4
|
+
using UnityEngine;
|
|
5
|
+
using TapSDK.Compliance.Model;
|
|
6
|
+
using TapSDK.Core;
|
|
7
|
+
|
|
8
|
+
namespace TapSDK.Compliance.Internal {
|
|
9
|
+
public class TaptapComplianceHealthReminderController : BasePanelController
|
|
10
|
+
{
|
|
11
|
+
public Text titleText;
|
|
12
|
+
public Text contentText;
|
|
13
|
+
public Button switchAccountButton;
|
|
14
|
+
public Button okButton;
|
|
15
|
+
public ScrollRect scrollRect;
|
|
16
|
+
|
|
17
|
+
private Action OnOk { get; set; }
|
|
18
|
+
private Action OnSwitchAccount { get; set; }
|
|
19
|
+
|
|
20
|
+
/// <summary>
|
|
21
|
+
/// bind ugui components for every panel
|
|
22
|
+
/// </summary>
|
|
23
|
+
protected override void BindComponents()
|
|
24
|
+
{
|
|
25
|
+
titleText = transform.Find("Root/TitleText").GetComponent<Text>();
|
|
26
|
+
scrollRect = transform.Find("Root/Scroll View").GetComponent<ScrollRect>();
|
|
27
|
+
contentText = transform.Find("Root/Scroll View/Viewport/Content/ContentText").GetComponent<Text>();
|
|
28
|
+
switchAccountButton = transform.Find("Root/SwitchAccountButton").GetComponent<Button>();
|
|
29
|
+
okButton = transform.Find("Root/OKButton").GetComponent<Button>();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
protected override void OnLoadSuccess()
|
|
33
|
+
{
|
|
34
|
+
base.OnLoadSuccess();
|
|
35
|
+
|
|
36
|
+
switchAccountButton.onClick.AddListener(OnSwitchAccountButtonClicked);
|
|
37
|
+
okButton.onClick.AddListener(OnOKButtonClicked);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
internal void Show(PlayableResult playable, Action onOk, Action onSwitchAccount)
|
|
41
|
+
{
|
|
42
|
+
OnOk = onOk;
|
|
43
|
+
OnSwitchAccount = onSwitchAccount;
|
|
44
|
+
string title = playable.Title;
|
|
45
|
+
string content = playable.Content;
|
|
46
|
+
//服务端异常,返回了无效的提示文案,为避免异常闪退,使用保底文案
|
|
47
|
+
if(title == null || title.Length == 0 || content == null || content.Length == 0){
|
|
48
|
+
HealthReminderDesc healthReminderDesc;
|
|
49
|
+
if(playable.RemainTime > 0){
|
|
50
|
+
healthReminderDesc = TapTapComplianceManager.CurrentUserAntiResult.localConfig.timeRangeConfig.uITipText.allow;
|
|
51
|
+
}else{
|
|
52
|
+
healthReminderDesc = TapTapComplianceManager.CurrentUserAntiResult.localConfig.timeRangeConfig.uITipText.reject;
|
|
53
|
+
}
|
|
54
|
+
title = healthReminderDesc.tipTitle;
|
|
55
|
+
content = healthReminderDesc.tipDescription;
|
|
56
|
+
}
|
|
57
|
+
titleText.text = title;
|
|
58
|
+
// 替换富文本标签
|
|
59
|
+
//周六、周日和法定节假日每日 20 时至 21 时向未成年人提供 60 分钟网络游戏服务
|
|
60
|
+
TapLogger.Debug("remain tip = " + content);
|
|
61
|
+
if(content.Contains("# ${remaining} #")){
|
|
62
|
+
string timeDesc;
|
|
63
|
+
if(playable.RemainTime >= 60){
|
|
64
|
+
int remainTime = (int)Math.Ceiling(playable.RemainTime * 1d / 60);
|
|
65
|
+
timeDesc = remainTime.ToString();
|
|
66
|
+
content = content.Replace("# ${remaining} #", timeDesc);
|
|
67
|
+
TapLogger.Debug("remain tip = " + content);
|
|
68
|
+
}else{
|
|
69
|
+
int index = content.IndexOf("# ${remaining} #");
|
|
70
|
+
string substring1 = content.Substring(0,index);
|
|
71
|
+
string substring2 = content.Substring(index)
|
|
72
|
+
.Replace("# ${remaining} #", playable.RemainTime.ToString())
|
|
73
|
+
.Replace("分钟","秒");
|
|
74
|
+
TapLogger.Debug("remain tip sub1 = " + substring1 + " sub2 = " + substring2);
|
|
75
|
+
content = substring1 + substring2;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
contentText.text = content.Replace(" ", "\u00A0");
|
|
80
|
+
if (IsTextOverflowing(contentText, out int lineCount, out float lineHeight)) {
|
|
81
|
+
scrollRect.enabled = true;
|
|
82
|
+
contentText.rectTransform.sizeDelta = new Vector2(contentText.rectTransform.sizeDelta.x,
|
|
83
|
+
lineCount * lineHeight);
|
|
84
|
+
|
|
85
|
+
var contentRect = scrollRect.transform.Find("Viewport/Content").GetComponent<RectTransform>();
|
|
86
|
+
contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x,
|
|
87
|
+
lineCount * lineHeight);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
scrollRect.enabled = false;
|
|
91
|
+
}
|
|
92
|
+
switchAccountButton.gameObject.SetActive(onSwitchAccount != null);
|
|
93
|
+
|
|
94
|
+
var buttonText = okButton.transform.Find("Text").GetComponent<Text>();
|
|
95
|
+
var switchButtonText = switchAccountButton.transform.Find("Text").GetComponent<Text>();
|
|
96
|
+
|
|
97
|
+
buttonText.text = playable.RemainTime > 0
|
|
98
|
+
? TapTapComplianceManager.LocalizationItems.Current.EnterGame
|
|
99
|
+
: TapTapComplianceManager.LocalizationItems.Current.ExitGame;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
private void OnOKButtonClicked()
|
|
105
|
+
{
|
|
106
|
+
Close();
|
|
107
|
+
OnOk?.Invoke();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private void OnSwitchAccountButtonClicked()
|
|
111
|
+
{
|
|
112
|
+
Close();
|
|
113
|
+
OnSwitchAccount?.Invoke();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
bool IsTextOverflowing(Text text, out int lineCount, out float lineHeight)
|
|
117
|
+
{
|
|
118
|
+
var textGenerator = text.cachedTextGenerator;
|
|
119
|
+
var settings = text.GetGenerationSettings(text.rectTransform.rect.size);
|
|
120
|
+
textGenerator.Populate(text.text, settings);
|
|
121
|
+
lineCount = textGenerator.lineCount;
|
|
122
|
+
if (TapTapComplianceManager.IsUseMobileUI()) {
|
|
123
|
+
lineCount += 3;
|
|
124
|
+
}
|
|
125
|
+
lineHeight = 25 + (text.lineSpacing - 1) * 25;
|
|
126
|
+
return lineCount > 5;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Text.RegularExpressions;
|
|
3
|
+
using Newtonsoft.Json;
|
|
4
|
+
using UnityEngine;
|
|
5
|
+
using UnityEngine.UI;
|
|
6
|
+
using TapSDK.UI;
|
|
7
|
+
using TapSDK.Compliance.Model;
|
|
8
|
+
|
|
9
|
+
namespace TapSDK.Compliance.Internal {
|
|
10
|
+
public class TaptapComplianceIDInputController : BasePanelController
|
|
11
|
+
{
|
|
12
|
+
public Button closeButton;
|
|
13
|
+
public Button submitButton;
|
|
14
|
+
|
|
15
|
+
public InputField nameInputField;
|
|
16
|
+
public InputField idNumberInputField;
|
|
17
|
+
|
|
18
|
+
public Text titleText;
|
|
19
|
+
public Text descriptionText;
|
|
20
|
+
public Text buttonText;
|
|
21
|
+
|
|
22
|
+
public ScrollRect scrollRect;
|
|
23
|
+
|
|
24
|
+
public Action<VerificationResult> OnVerified;
|
|
25
|
+
public Action<Exception> OnException;
|
|
26
|
+
public Action OnClosed;
|
|
27
|
+
|
|
28
|
+
public bool activeManualVerification;
|
|
29
|
+
private bool _isSending;
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
private bool isSending
|
|
33
|
+
{
|
|
34
|
+
get => _isSending;
|
|
35
|
+
set
|
|
36
|
+
{
|
|
37
|
+
if (value != _isSending)
|
|
38
|
+
{
|
|
39
|
+
_isSending = value;
|
|
40
|
+
if (_isSending)
|
|
41
|
+
UIManager.Instance.OpenLoading();
|
|
42
|
+
else
|
|
43
|
+
UIManager.Instance.CloseLoading();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// <summary>
|
|
49
|
+
/// bind ugui components for every panel
|
|
50
|
+
/// </summary>
|
|
51
|
+
protected override void BindComponents()
|
|
52
|
+
{
|
|
53
|
+
closeButton = transform.Find("Root/CloseButton").GetComponent<Button>();
|
|
54
|
+
submitButton = transform.Find("Root/SubmitButton").GetComponent<Button>();
|
|
55
|
+
scrollRect = transform.Find("Root/Scroll View").GetComponent<ScrollRect>();
|
|
56
|
+
titleText = transform.Find("Root/TitleText").GetComponent<Text>();
|
|
57
|
+
descriptionText = scrollRect.transform.Find("Viewport/Content/ContentText").GetComponent<Text>();
|
|
58
|
+
buttonText = submitButton.transform.Find("Text").GetComponent<Text>();
|
|
59
|
+
|
|
60
|
+
nameInputField = transform.Find("Root/NameInput").GetComponent<InputField>();
|
|
61
|
+
idNumberInputField = transform.Find("Root/IDNumInput").GetComponent<InputField>();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
protected override void OnLoadSuccess()
|
|
65
|
+
{
|
|
66
|
+
base.OnLoadSuccess();
|
|
67
|
+
|
|
68
|
+
closeButton.onClick.AddListener(OnCloseButtonClicked);
|
|
69
|
+
submitButton.onClick.AddListener(OnConfirmButtonClicked);
|
|
70
|
+
|
|
71
|
+
var config = Config.GetInputIdentifyTip();
|
|
72
|
+
if (config != null)
|
|
73
|
+
{
|
|
74
|
+
titleText.text = config.Title;
|
|
75
|
+
descriptionText.text = config.Content.Replace(" ","\u00A0");
|
|
76
|
+
if (IsTextOverflowing(descriptionText, out int lineCount, out float lineHeight)) {
|
|
77
|
+
scrollRect.enabled = true;
|
|
78
|
+
descriptionText.rectTransform.sizeDelta = new Vector2(descriptionText.rectTransform.sizeDelta.x,
|
|
79
|
+
40 + (lineCount - 3) * lineHeight);
|
|
80
|
+
|
|
81
|
+
var contentRect = scrollRect.transform.Find("Viewport/Content").GetComponent<RectTransform>();
|
|
82
|
+
contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x,
|
|
83
|
+
40 + (lineCount - 3) * lineHeight);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
scrollRect.enabled = false;
|
|
87
|
+
}
|
|
88
|
+
buttonText.text = config.PositiveButtonText;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
isSending = false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private bool Validate(out string name, out string idNumber, out string errorTip)
|
|
95
|
+
{
|
|
96
|
+
errorTip = null;
|
|
97
|
+
name = nameInputField.text;
|
|
98
|
+
idNumber = idNumberInputField.text;
|
|
99
|
+
if (string.IsNullOrWhiteSpace(name))
|
|
100
|
+
{
|
|
101
|
+
errorTip = "姓名不能为空";
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!IsIdNum(idNumber))
|
|
106
|
+
{
|
|
107
|
+
errorTip = "身份信息不能为空";
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private async void OnConfirmButtonClicked()
|
|
115
|
+
{
|
|
116
|
+
if (isSending) return;
|
|
117
|
+
string errorTip;
|
|
118
|
+
string name;
|
|
119
|
+
string idNumber;
|
|
120
|
+
var validation = Validate(out name, out idNumber, out errorTip);
|
|
121
|
+
if (validation)
|
|
122
|
+
{
|
|
123
|
+
try
|
|
124
|
+
{
|
|
125
|
+
isSending = true;
|
|
126
|
+
var verificationResult = await Verification.FetchVerificationManual(TapTapComplianceManager.UserId, name, idNumber);
|
|
127
|
+
isSending = false;
|
|
128
|
+
if (verificationResult.Status.Equals("pass")) {
|
|
129
|
+
// TODO@luran:本地化
|
|
130
|
+
Close();
|
|
131
|
+
UIManager.Instance.OpenToast("提交成功", UIManager.GeneralToastLevel.Success);
|
|
132
|
+
}
|
|
133
|
+
OnVerified?.Invoke(verificationResult);
|
|
134
|
+
}
|
|
135
|
+
catch (Exception e)
|
|
136
|
+
{
|
|
137
|
+
isSending = false;
|
|
138
|
+
OnException?.Invoke(e);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else
|
|
142
|
+
{
|
|
143
|
+
UIManager.Instance.OpenToast(errorTip, UIManager.GeneralToastLevel.Error);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
private void OnCloseButtonClicked()
|
|
149
|
+
{
|
|
150
|
+
Close();
|
|
151
|
+
OnClosed?.Invoke();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/// <summary>
|
|
155
|
+
/// 验证身份证号(https://cloud.tencent.com/developer/article/1860685)
|
|
156
|
+
/// </summary>
|
|
157
|
+
/// <param name="input"></param>
|
|
158
|
+
/// <returns></returns>
|
|
159
|
+
private static bool IsIdNum(string input)
|
|
160
|
+
{
|
|
161
|
+
return !string.IsNullOrWhiteSpace(input);
|
|
162
|
+
// double iSum = 0;
|
|
163
|
+
// // 18位验证
|
|
164
|
+
// Regex rg = new Regex(@"^\d{17}(\d|x)$");
|
|
165
|
+
// Match mc = rg.Match(input);
|
|
166
|
+
// if (!mc.Success)
|
|
167
|
+
// {
|
|
168
|
+
// return false;
|
|
169
|
+
// }
|
|
170
|
+
//
|
|
171
|
+
// // 生日验证
|
|
172
|
+
// input = input.ToLower();
|
|
173
|
+
// input = input.Replace("x", "a");
|
|
174
|
+
// try
|
|
175
|
+
// {
|
|
176
|
+
// var year = input.Substring(6, 4);
|
|
177
|
+
// var month = input.Substring(10, 2);
|
|
178
|
+
// var day = input.Substring(12, 2);
|
|
179
|
+
// DateTime.Parse(year + "-" + month + "-" + day);
|
|
180
|
+
// }
|
|
181
|
+
// catch
|
|
182
|
+
// {
|
|
183
|
+
// #if UNITY_EDITOR
|
|
184
|
+
// TapLogger.Error("国内-防沉迷 身份证号非法出生日期");
|
|
185
|
+
// #endif
|
|
186
|
+
// return false;
|
|
187
|
+
// }
|
|
188
|
+
//
|
|
189
|
+
// // 最后一位验证
|
|
190
|
+
// for (int i = 17; i >= 0; i--)
|
|
191
|
+
// {
|
|
192
|
+
// iSum += (Math.Pow(2, i) % 11) *
|
|
193
|
+
// int.Parse(input[17 - i].ToString(), System.Globalization.NumberStyles.HexNumber);
|
|
194
|
+
// }
|
|
195
|
+
//
|
|
196
|
+
// if (iSum % 11 != 1)
|
|
197
|
+
// {
|
|
198
|
+
// #if UNITY_EDITOR
|
|
199
|
+
// TapLogger.Error("国内-防沉迷 身份证号非法尾号");
|
|
200
|
+
// #endif
|
|
201
|
+
// return false;
|
|
202
|
+
// }
|
|
203
|
+
//
|
|
204
|
+
// return true;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
bool IsTextOverflowing(Text text, out int lineCount, out float lineHeight)
|
|
208
|
+
{
|
|
209
|
+
var textGenerator = text.cachedTextGenerator;
|
|
210
|
+
var settings = text.GetGenerationSettings(text.rectTransform.rect.size);
|
|
211
|
+
textGenerator.Populate(text.text, settings);
|
|
212
|
+
lineCount = textGenerator.lineCount + 3;
|
|
213
|
+
lineHeight = 15 + (text.lineSpacing - 1) * 15;
|
|
214
|
+
return lineCount > 3;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
}
|
|
218
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine.UI;
|
|
3
|
+
using TapSDK.UI;
|
|
4
|
+
using TapSDK.Compliance;
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
namespace TapSDK.Compliance.Internal {
|
|
8
|
+
public class TaptapComplianceRetryAlertController : BasePanelController
|
|
9
|
+
{
|
|
10
|
+
public Text messageText;
|
|
11
|
+
public Text buttonText;
|
|
12
|
+
public Button retryButton;
|
|
13
|
+
|
|
14
|
+
private Action _onRetry;
|
|
15
|
+
|
|
16
|
+
/// <summary>
|
|
17
|
+
/// bind ugui components for every panel
|
|
18
|
+
/// </summary>
|
|
19
|
+
protected override void BindComponents()
|
|
20
|
+
{
|
|
21
|
+
messageText = transform.Find("Root/BackgroundImage/MessageText").GetComponent<Text>();
|
|
22
|
+
retryButton = transform.Find("Root/BackgroundImage/RetryButton").GetComponent<Button>();
|
|
23
|
+
buttonText = retryButton.transform.Find("Text").GetComponent<Text>();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
protected override void OnLoadSuccess()
|
|
27
|
+
{
|
|
28
|
+
base.OnLoadSuccess();
|
|
29
|
+
buttonText.text = TapTapComplianceManager.LocalizationItems.Current.Retry;
|
|
30
|
+
retryButton.onClick.AddListener(OnRetryClicked);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private void OnRetryClicked()
|
|
34
|
+
{
|
|
35
|
+
Close();
|
|
36
|
+
_onRetry?.Invoke();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
internal void Show(string message, Action onRetry, string confirmButtonText = null)
|
|
40
|
+
{
|
|
41
|
+
messageText.text = message;
|
|
42
|
+
_onRetry = onRetry;
|
|
43
|
+
buttonText.text = string.IsNullOrEmpty(confirmButtonText) ? TapTapComplianceManager.LocalizationItems.Current.Retry : confirmButtonText;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|