com.amanotes.gdk 0.2.85 → 0.2.86
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/CHANGELOG.md +8 -0
- package/Editor/Extra/SDKVersionTracking.cs +9 -1
- package/Editor/Utils/AmaGDKEditor.ExtractVersion.Max.cs +113 -0
- package/Editor/Utils/AmaGDKEditor.ExtractVersion.Max.cs.meta +3 -0
- package/Editor/Utils/AmaGDKEditor.ExtractVersion.cs +8 -10
- package/Extra/AmaGDKInstaller.unitypackage +0 -0
- package/Extra/AutoEventQC.unitypackage +0 -0
- package/Extra/CheckDiskSpace.unitypackage +0 -0
- package/Extra/Consent.unitypackage +0 -0
- package/Extra/CrashlyticHook.unitypackage +0 -0
- package/Extra/ForceUpdate.unitypackage +0 -0
- package/Extra/LegacyGDKUpdateHelper.unitypackage +0 -0
- package/Extra/PostProcessor.unitypackage +0 -0
- package/Packages/AmaGDKConfig.unitypackage +0 -0
- package/Packages/AmaGDKExample.unitypackage +0 -0
- package/Packages/AmaGDKTest.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.PurchaseConnector.unitypackage +0 -0
- package/Packages/AppsFlyerAdapter.unitypackage +0 -0
- package/Packages/FirebaseAnalyticsAdapter.unitypackage +0 -0
- package/Packages/FirebaseRemoteConfigAdapter.unitypackage +0 -0
- package/Packages/IronSourceAdapter.AdQuality.unitypackage +0 -0
- package/Packages/IronSourceAdapter.unitypackage +0 -0
- package/Packages/MaxAdNetworkAdapter.unitypackage +0 -0
- package/Packages/RevenueCatAdapter.unitypackage +0 -0
- package/Packages/SqliteAnalyticsAdapter.unitypackage +0 -0
- package/Runtime/Ad/AdLogic.cs +10 -3
- package/Runtime/AmaGDK.Adapters.cs +2 -0
- package/Runtime/AmaGDK.Analytics.cs +36 -14
- package/Runtime/AmaGDK.Singleton.cs +2 -0
- package/Runtime/AmaGDK.cs +3 -1
- package/Runtime/Core/GDKDispatcher.cs +4 -2
- package/Runtime/Utils/GDKFileUtils.cs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [0.2.86] - 2025-05-22
|
|
2
|
+
- [Dev] Track max adapters
|
|
3
|
+
- [Fix] Do not override config when Adapter id is not available
|
|
4
|
+
- [Fix] Bypass file utils unit test
|
|
5
|
+
- [Dev] Improve verbose logging
|
|
6
|
+
- [BugFix]: Fix sentry issue : Null exception issue
|
|
7
|
+
- [Fix] Missing User Mapping in MaxAdapter
|
|
8
|
+
|
|
1
9
|
## [0.2.85] - 2025-03-18
|
|
2
10
|
- [Fix] Manage ad activity killed routine
|
|
3
11
|
|
|
@@ -252,6 +252,11 @@ namespace Amanotes.Editor
|
|
|
252
252
|
|
|
253
253
|
public int callbackOrder { get; }
|
|
254
254
|
public void OnPreprocessBuild(BuildReport report)
|
|
255
|
+
{
|
|
256
|
+
OnPreprocessBuild();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
public void OnPreprocessBuild()
|
|
255
260
|
{
|
|
256
261
|
_dicThirdPartyVersion = AmaGDKExtra.GetThirdPartyVersions();
|
|
257
262
|
_dicImportedGDKAdapter = GetImportedGDKAdapter();
|
|
@@ -283,10 +288,13 @@ namespace Amanotes.Editor
|
|
|
283
288
|
return;
|
|
284
289
|
}
|
|
285
290
|
|
|
291
|
+
var maxAdapters = MaxEditorUtils.GetMaxAdapters().ToDictionary(kvp => $"{kvp.Key}-MaxAdapter", kvp => (object)kvp.Value);
|
|
292
|
+
var ironSourceAdapters = _dicIronSourceAdapterVersion.ToDictionary(kvp => $"{kvp.Key}-ISAdapter", kvp => kvp.Value);
|
|
286
293
|
var rawData = _dicThirdPartyVersion
|
|
287
294
|
.Concat(_dicExtraVersion)
|
|
288
|
-
.Concat(_dicIronSourceAdapterVersion.ToDictionary(kvp => kvp.Key, kvp => (object)("IS_" + kvp.Value)))
|
|
289
295
|
.ToDictionary(x => x.Key, x => x.Value);
|
|
296
|
+
rawData["MaxAdapters"] = maxAdapters;
|
|
297
|
+
rawData["IronSourceAdapters"] = ironSourceAdapters;
|
|
290
298
|
rawData["UnityVersion"] = Application.unityVersion;
|
|
291
299
|
string platform = "";
|
|
292
300
|
#if UNITY_ANDROID
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
using System.Collections.Generic;
|
|
2
|
+
using System.IO;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Xml.Linq;
|
|
5
|
+
|
|
6
|
+
namespace Amanotes.Editor
|
|
7
|
+
{
|
|
8
|
+
public class Versions
|
|
9
|
+
{
|
|
10
|
+
public string Unity;
|
|
11
|
+
public string Android;
|
|
12
|
+
public string Ios;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public class MaxEditorUtils
|
|
16
|
+
{
|
|
17
|
+
public static Dictionary<string, string> GetMaxAdapters()
|
|
18
|
+
{
|
|
19
|
+
var result = new Dictionary<string, string>();
|
|
20
|
+
string mediationPath = "Assets/MaxSdk/Mediation";
|
|
21
|
+
string[] adapterFolders = Directory.GetDirectories(mediationPath);
|
|
22
|
+
|
|
23
|
+
foreach (string adapterFolder in adapterFolders)
|
|
24
|
+
{
|
|
25
|
+
string adapterName = new DirectoryInfo(adapterFolder).Name;
|
|
26
|
+
string dependencyPath = Path.Combine(adapterFolder, "Editor/Dependencies.xml");
|
|
27
|
+
Versions version = GetCurrentVersions(dependencyPath);
|
|
28
|
+
result.Add(adapterName, $"android_{version.Android}_ios_{version.Ios}");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public static Versions GetCurrentVersions(string dependencyPath)
|
|
35
|
+
{
|
|
36
|
+
XDocument dependency;
|
|
37
|
+
try
|
|
38
|
+
{
|
|
39
|
+
dependency = XDocument.Load(dependencyPath);
|
|
40
|
+
}
|
|
41
|
+
#pragma warning disable 0168
|
|
42
|
+
catch (IOException exception)
|
|
43
|
+
#pragma warning restore 0168
|
|
44
|
+
{
|
|
45
|
+
// Couldn't find the dependencies file. The plugin is not installed.
|
|
46
|
+
return new Versions();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// <dependencies>
|
|
50
|
+
// <androidPackages>
|
|
51
|
+
// <androidPackage spec="com.applovin.mediation:network_name-adapter:1.2.3.4" />
|
|
52
|
+
// </androidPackages>
|
|
53
|
+
// <iosPods>
|
|
54
|
+
// <iosPod name="AppLovinMediationNetworkNameAdapter" version="2.3.4.5" />
|
|
55
|
+
// </iosPods>
|
|
56
|
+
// </dependencies>
|
|
57
|
+
string androidVersion = null;
|
|
58
|
+
string iosVersion = null;
|
|
59
|
+
var dependenciesElement = dependency.Element("dependencies");
|
|
60
|
+
if (dependenciesElement != null)
|
|
61
|
+
{
|
|
62
|
+
var androidPackages = dependenciesElement.Element("androidPackages");
|
|
63
|
+
if (androidPackages != null)
|
|
64
|
+
{
|
|
65
|
+
var adapterPackage = androidPackages.Descendants().FirstOrDefault(element => element.Name.LocalName.Equals("androidPackage")
|
|
66
|
+
&& element.FirstAttribute.Name.LocalName.Equals("spec")
|
|
67
|
+
&& element.FirstAttribute.Value.StartsWith("com.applovin"));
|
|
68
|
+
if (adapterPackage != null)
|
|
69
|
+
{
|
|
70
|
+
androidVersion = adapterPackage.FirstAttribute.Value.Split(':').Last();
|
|
71
|
+
// Hack alert: Some Android versions might have square brackets to force a specific version. Remove them if they are detected.
|
|
72
|
+
if (androidVersion.StartsWith("["))
|
|
73
|
+
{
|
|
74
|
+
androidVersion = androidVersion.Trim('[', ']');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var iosPods = dependenciesElement.Element("iosPods");
|
|
80
|
+
if (iosPods != null)
|
|
81
|
+
{
|
|
82
|
+
var adapterPod = iosPods.Descendants().FirstOrDefault(element => element.Name.LocalName.Equals("iosPod")
|
|
83
|
+
&& element.FirstAttribute.Name.LocalName.Equals("name")
|
|
84
|
+
&& element.FirstAttribute.Value.StartsWith("AppLovin"));
|
|
85
|
+
if (adapterPod != null)
|
|
86
|
+
{
|
|
87
|
+
iosVersion = adapterPod.Attributes().First(attribute => attribute.Name.LocalName.Equals("version")).Value;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
var currentVersions = new Versions();
|
|
93
|
+
if (androidVersion != null && iosVersion != null)
|
|
94
|
+
{
|
|
95
|
+
currentVersions.Unity = string.Format("android_{0}_ios_{1}", androidVersion, iosVersion);
|
|
96
|
+
currentVersions.Android = androidVersion;
|
|
97
|
+
currentVersions.Ios = iosVersion;
|
|
98
|
+
}
|
|
99
|
+
else if (androidVersion != null)
|
|
100
|
+
{
|
|
101
|
+
currentVersions.Unity = string.Format("android_{0}", androidVersion);
|
|
102
|
+
currentVersions.Android = androidVersion;
|
|
103
|
+
}
|
|
104
|
+
else if (iosVersion != null)
|
|
105
|
+
{
|
|
106
|
+
currentVersions.Unity = string.Format("ios_{0}", iosVersion);
|
|
107
|
+
currentVersions.Ios = iosVersion;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return currentVersions;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -361,20 +361,18 @@ namespace Amanotes.Editor
|
|
|
361
361
|
internal static List<IronSourceSDKAdapter> IronSourceAdapter()
|
|
362
362
|
{
|
|
363
363
|
var listAdapter = new List<IronSourceSDKAdapter>();
|
|
364
|
-
const string
|
|
364
|
+
const string IRON_SOURCE_PATH = "Assets/IronSource";
|
|
365
|
+
const string LEVEL_PLAY_PATH = "Assets/LevelPlay";
|
|
365
366
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
string[] filesIRadapter = Directory.GetFiles(IRONSOURCE_PATH, "IS*AdapterDependencies.xml", SearchOption.AllDirectories);
|
|
367
|
+
var irsFiles = Directory.Exists(IRON_SOURCE_PATH) ? Directory.GetFiles(IRON_SOURCE_PATH, "IS*AdapterDependencies.xml", SearchOption.AllDirectories).ToList() : new List<string>();
|
|
368
|
+
var levelPlayFiles = Directory.Exists(LEVEL_PLAY_PATH) ? Directory.GetFiles(LEVEL_PLAY_PATH, "IS*AdapterDependencies.xml", SearchOption.AllDirectories).ToList() : new List<string>();
|
|
369
|
+
|
|
370
|
+
var adapterFiles = irsFiles.Concat(levelPlayFiles).ToList();
|
|
372
371
|
|
|
373
|
-
if (
|
|
374
|
-
|
|
372
|
+
if (adapterFiles.Count <= 0) return listAdapter;
|
|
373
|
+
foreach (string filePath in adapterFiles)
|
|
375
374
|
{
|
|
376
375
|
var Xdoc = new XmlDocument();
|
|
377
|
-
string filePath = filesIRadapter[i];
|
|
378
376
|
|
|
379
377
|
Xdoc.Load(filePath);
|
|
380
378
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/Runtime/Ad/AdLogic.cs
CHANGED
|
@@ -347,11 +347,18 @@ namespace Amanotes.Core.Internal
|
|
|
347
347
|
localData.Save();
|
|
348
348
|
TriggerOnAfterAdShow();
|
|
349
349
|
|
|
350
|
-
|
|
350
|
+
// Fix: https://amanotes.sentry.io/issues/6366233489/events/0f3f58d81f0848b9bdbf1fd3e4a8161f/
|
|
351
|
+
var currentContext = Ads.context;
|
|
352
|
+
Log($"[Ad] {adType} ShowAdRoutineCompleted: {isSuccess}\n{(currentContext != null ? JsonUtility.ToJson(currentContext) : "Context is null")}");
|
|
351
353
|
|
|
354
|
+
Action<bool> resultCallback = null;
|
|
355
|
+
if (currentContext != null)
|
|
356
|
+
{
|
|
357
|
+
currentContext.showFinishAt = Time.realtimeSinceStartup;
|
|
358
|
+
resultCallback = currentContext.onAdResult;
|
|
359
|
+
}
|
|
360
|
+
|
|
352
361
|
// Extra callback
|
|
353
|
-
context.showFinishAt = Time.realtimeSinceStartup;
|
|
354
|
-
var resultCallback = context.onAdResult;
|
|
355
362
|
Ads.context = null;
|
|
356
363
|
_showState = ShowAdsState.None;
|
|
357
364
|
resultCallback?.Invoke(isSuccess);
|
|
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
|
|
3
3
|
using System.Collections.Generic;
|
|
4
4
|
using System.Text;
|
|
5
5
|
using Amanotes.Core.Internal;
|
|
6
|
+
using System.Linq;
|
|
6
7
|
using UnityEngine;
|
|
7
8
|
using UnityEngine.Profiling;
|
|
8
9
|
using static Amanotes.Core.AmaGDK.Analytics;
|
|
@@ -90,7 +91,7 @@ namespace Amanotes.Core
|
|
|
90
91
|
return !allowAdapterIds.Contains(adapterId);
|
|
91
92
|
}
|
|
92
93
|
|
|
93
|
-
|
|
94
|
+
LogWarning("[AmaGDK] Should never be here: overrideConfig == true but no id in listAdapterIds!");
|
|
94
95
|
return false;
|
|
95
96
|
}
|
|
96
97
|
|
|
@@ -106,8 +107,14 @@ namespace Amanotes.Core
|
|
|
106
107
|
|
|
107
108
|
public static IEventParamsBuilder LogEvent(string eventName)
|
|
108
109
|
{
|
|
110
|
+
if (listAdapters.Count == 0)
|
|
111
|
+
{
|
|
112
|
+
InitModule();
|
|
113
|
+
}
|
|
114
|
+
|
|
109
115
|
var result = PrepareEvent(eventName);
|
|
110
116
|
eventQueue.Enqueue(result);
|
|
117
|
+
Log($"Queued Event <{result.eventName}>");
|
|
111
118
|
return result;
|
|
112
119
|
}
|
|
113
120
|
|
|
@@ -364,6 +371,7 @@ namespace Amanotes.Core
|
|
|
364
371
|
{
|
|
365
372
|
sessionStat = new SessionStat();
|
|
366
373
|
}
|
|
374
|
+
|
|
367
375
|
listAdapters.Clear();
|
|
368
376
|
listAdapters.AddRange(Adapter2.GetAllAdapter<AnalyticsAdapter>());
|
|
369
377
|
}
|
|
@@ -448,15 +456,10 @@ namespace Amanotes.Core
|
|
|
448
456
|
string eventNameToSend = GetEventNameToSend(eventParams.eventName, countInSession, totalCount);
|
|
449
457
|
AnalyticsConfig config = Config.analytics;
|
|
450
458
|
if (config.normalizeEventName) NormalizeEventName(ref eventNameToSend);
|
|
451
|
-
|
|
452
|
-
if (config.showAnalyticsLog)
|
|
453
|
-
{
|
|
454
|
-
ForceLog($"[Analytics] Event <{eventNameToSend}> (in session: {countInSession}, total: {totalCount})\n{JsonUtils.DictionaryToJson(eventParams.parameters, true)}");
|
|
455
|
-
}
|
|
456
|
-
|
|
457
459
|
config.quality.CheckEventQuality(eventParams.eventName, eventParams.parameters);
|
|
458
460
|
|
|
459
461
|
var inUseAdapterIDs = config.enableEventStat ? new List<string>(listAdapters.Count) : null;
|
|
462
|
+
var effective = false;
|
|
460
463
|
foreach (AnalyticsAdapter m in listAdapters)
|
|
461
464
|
{
|
|
462
465
|
if (eventParams.overrideConfig)
|
|
@@ -471,9 +474,23 @@ namespace Amanotes.Core
|
|
|
471
474
|
{
|
|
472
475
|
if (m.IsForbidden(eventParams.eventName)) continue;
|
|
473
476
|
}
|
|
477
|
+
|
|
478
|
+
effective = true;
|
|
474
479
|
m.LogEvent(eventNameToSend, eventParams.parameters);
|
|
475
480
|
inUseAdapterIDs?.Add(m.adapterId);
|
|
476
481
|
}
|
|
482
|
+
|
|
483
|
+
if (effective)
|
|
484
|
+
{
|
|
485
|
+
if (config.showAnalyticsLog)
|
|
486
|
+
{
|
|
487
|
+
ForceLog($"[Analytics] Event <{eventNameToSend}> (in session: {countInSession}, total: {totalCount})\n{JsonUtils.DictionaryToJson(eventParams.parameters, true)}");
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
else
|
|
491
|
+
{
|
|
492
|
+
LogError($"Event <{eventParams}> has been skipped (no matching Adapter)\n{JsonUtility.ToJson(eventParams)}");
|
|
493
|
+
}
|
|
477
494
|
|
|
478
495
|
GDKUtils.SafeInvoke(OnEventSent, eventNameToSend, eventParams.parameters);
|
|
479
496
|
sessionStat?.OnEventSent(eventNameToSend, eventParams.parameters, inUseAdapterIDs);
|
|
@@ -777,7 +794,7 @@ namespace Amanotes.Core
|
|
|
777
794
|
{
|
|
778
795
|
if (cachedEventDetails.ContainsKey(ed.eventName))
|
|
779
796
|
{
|
|
780
|
-
|
|
797
|
+
LogWarning($"EventName <{ed.eventName}> existed!");
|
|
781
798
|
return false;
|
|
782
799
|
}
|
|
783
800
|
|
|
@@ -1039,18 +1056,23 @@ namespace Amanotes.Core
|
|
|
1039
1056
|
LogWarning("OnlyTo() can only be set once!");
|
|
1040
1057
|
return ap;
|
|
1041
1058
|
}
|
|
1042
|
-
|
|
1043
|
-
eventData.overrideConfig = true;
|
|
1044
|
-
eventData.allowAdapterIds ??= GDKPool.GetHashSet();
|
|
1045
1059
|
|
|
1060
|
+
var h = GDKPool.GetHashSet();
|
|
1046
1061
|
foreach (string mId in analyticIds)
|
|
1047
1062
|
{
|
|
1048
|
-
if (!listAdapters.Exists(a => a.adapterId == mId))
|
|
1063
|
+
if (listAdapters.Count > 0 && !listAdapters.Exists(a => a.adapterId == mId))
|
|
1049
1064
|
{
|
|
1050
|
-
LogError($"Cannot send event <{eventData.eventName}> to <{mId}>. Analytics adapter for <{mId}> is not available
|
|
1065
|
+
LogError($"Cannot send event <{eventData.eventName}> to <{mId}>. Analytics adapter for <{mId}> is not available.\n" +
|
|
1066
|
+
$"listAdapters ({listAdapters.Count}): [{string.Join(",", listAdapters.Select(item=>item.adapterId).ToArray())}]");
|
|
1051
1067
|
continue;
|
|
1052
1068
|
}
|
|
1053
|
-
|
|
1069
|
+
h.Add(mId);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
if (h.Count > 0)
|
|
1073
|
+
{
|
|
1074
|
+
eventData.overrideConfig = true;
|
|
1075
|
+
eventData.allowAdapterIds ??= h;
|
|
1054
1076
|
}
|
|
1055
1077
|
|
|
1056
1078
|
return ap;
|
package/Runtime/AmaGDK.cs
CHANGED
|
@@ -27,7 +27,7 @@ namespace Amanotes.Core
|
|
|
27
27
|
{
|
|
28
28
|
public partial class AmaGDK : MonoBehaviour
|
|
29
29
|
{
|
|
30
|
-
public const string VERSION = "0.2.
|
|
30
|
+
public const string VERSION = "0.2.86";
|
|
31
31
|
|
|
32
32
|
internal static Status _status = Status.None;
|
|
33
33
|
internal static ConfigAsset _config = null;
|
|
@@ -200,6 +200,8 @@ namespace Amanotes.Core
|
|
|
200
200
|
|
|
201
201
|
IEnumerator InitRoutine()
|
|
202
202
|
{
|
|
203
|
+
Log("InitRoutine!");
|
|
204
|
+
|
|
203
205
|
_allowInit = _allowInit || autoInit;
|
|
204
206
|
|
|
205
207
|
if (Config == null)
|
|
@@ -44,9 +44,11 @@ namespace Amanotes.Core.Internal
|
|
|
44
44
|
return false;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
// Fix: https://amanotes.sentry.io/issues/6366288384/events/d45dd8fb736f43d0a8e2aec0df0f173d/
|
|
48
|
+
int argsLength = args != null ? args.Length : 0;
|
|
49
|
+
if (argsLength != nParams)
|
|
48
50
|
{
|
|
49
|
-
GDKUtils.ThrowExceptionInEditor($"Dispatch <{eventName}> with incorrect number of params, expecting {nParams}, got {
|
|
51
|
+
GDKUtils.ThrowExceptionInEditor($"Dispatch <{eventName}> with incorrect number of params, expecting {nParams}, got {argsLength}!",
|
|
50
52
|
(m) => new TargetParameterCountException(m));
|
|
51
53
|
return false;
|
|
52
54
|
}
|
|
@@ -70,7 +70,7 @@ namespace Amanotes.Core.Internal
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
internal static int writePendingCount => _pendingWrites.Count;
|
|
73
|
-
internal static bool HasAnyWritePending => _pendingWrites.Count > 0;
|
|
73
|
+
internal static bool HasAnyWritePending => _pendingWrites.Count > 0 || _isProcessing != 0;
|
|
74
74
|
internal static bool IsWritePending(string fileName)
|
|
75
75
|
{
|
|
76
76
|
return !string.IsNullOrEmpty(fileName) && _pendingWrites.ContainsKey(fileName);
|