com.wallstop-studios.unity-helpers 2.0.0-rc73.14 → 2.0.0-rc73.16
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/Editor/AnimationEventEditor.cs +4 -5
- package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs +1 -1
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs +590 -0
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs.meta +3 -0
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs +303 -0
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs.meta +3 -0
- package/Editor/FitTextureSizeWindow.cs +5 -44
- package/Editor/PersistentDirectorySettings.cs +248 -0
- package/Editor/PersistentDirectorySettings.cs.meta +3 -0
- package/Editor/PrefabChecker.cs +1 -2
- package/Editor/{AnimationCopier.cs → Sprites/AnimationCopier.cs} +33 -166
- package/Editor/{AnimationCreator.cs → Sprites/AnimationCreator.cs} +9 -80
- package/Editor/Sprites/ScriptableSpriteAtlas.cs +95 -0
- package/Editor/Sprites/ScriptableSpriteAtlas.cs.meta +3 -0
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs +938 -0
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs.meta +3 -0
- package/Editor/{SpriteCropper.cs → Sprites/SpriteCropper.cs} +66 -64
- package/Editor/{SpriteSettingsApplier.cs → Sprites/SpriteSettingsApplier.cs} +9 -76
- package/Editor/{TextureResizerWizard.cs → Sprites/TextureResizerWizard.cs} +1 -1
- package/Editor/{TextureSettingsApplier.cs → Sprites/TextureSettingsApplier.cs} +1 -1
- package/Editor/Sprites.meta +3 -0
- package/Editor/Utils/DxReadOnlyPropertyDrawer.cs +1 -1
- package/Runtime/Core/Helper/DirectoryHelper.cs +64 -0
- package/package.json +3 -1
- package/Editor/SpriteAtlasGenerator.cs +0 -895
- package/Editor/SpriteAtlasGenerator.cs.meta +0 -3
- package/Editor/Utils/GUIHorizontalScope.cs +0 -20
- package/Editor/Utils/GUIHorizontalScope.cs.meta +0 -3
- package/Editor/Utils/GUIIndentScope.cs +0 -20
- package/Editor/Utils/GUIIndentScope.cs.meta +0 -3
- /package/Editor/{AnimationCopier.cs.meta → Sprites/AnimationCopier.cs.meta} +0 -0
- /package/Editor/{AnimationCreator.cs.meta → Sprites/AnimationCreator.cs.meta} +0 -0
- /package/Editor/{SpriteCropper.cs.meta → Sprites/SpriteCropper.cs.meta} +0 -0
- /package/Editor/{SpriteSettingsApplier.cs.meta → Sprites/SpriteSettingsApplier.cs.meta} +0 -0
- /package/Editor/{TextureResizerWizard.cs.meta → Sprites/TextureResizerWizard.cs.meta} +0 -0
- /package/Editor/{TextureSettingsApplier.cs.meta → Sprites/TextureSettingsApplier.cs.meta} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
namespace WallstopStudios.UnityHelpers.Editor
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
2
2
|
{
|
|
3
3
|
#if UNITY_EDITOR
|
|
4
4
|
using System;
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
using System.IO;
|
|
7
7
|
using System.Linq;
|
|
8
8
|
using System.Threading.Tasks;
|
|
9
|
-
using Core.Extension;
|
|
10
9
|
using UnityEditor;
|
|
11
10
|
using UnityEngine;
|
|
11
|
+
using Core.Extension;
|
|
12
|
+
using CustomEditors;
|
|
12
13
|
using Object = UnityEngine.Object;
|
|
13
14
|
|
|
14
15
|
public sealed class SpriteCropper : EditorWindow
|
|
@@ -35,64 +36,55 @@
|
|
|
35
36
|
[SerializeField]
|
|
36
37
|
private bool _onlyNecessary;
|
|
37
38
|
|
|
39
|
+
[SerializeField]
|
|
40
|
+
private int _leftPadding;
|
|
41
|
+
|
|
42
|
+
[SerializeField]
|
|
43
|
+
private int _rightPadding;
|
|
44
|
+
|
|
45
|
+
[SerializeField]
|
|
46
|
+
private int _topPadding;
|
|
47
|
+
|
|
48
|
+
[SerializeField]
|
|
49
|
+
private int _bottomPadding;
|
|
50
|
+
|
|
38
51
|
private List<string> _filesToProcess;
|
|
52
|
+
private SerializedObject _serializedObject;
|
|
53
|
+
private SerializedProperty _inputDirectoriesProperty;
|
|
54
|
+
private SerializedProperty _onlyNecessaryProperty;
|
|
55
|
+
private SerializedProperty _leftPaddingProperty;
|
|
56
|
+
private SerializedProperty _rightPaddingProperty;
|
|
57
|
+
private SerializedProperty _topPaddingProperty;
|
|
58
|
+
private SerializedProperty _bottomPaddingProperty;
|
|
39
59
|
|
|
40
60
|
[MenuItem("Tools/Wallstop Studios/Unity Helpers/" + Name)]
|
|
41
61
|
private static void ShowWindow() => GetWindow<SpriteCropper>(Name);
|
|
42
62
|
|
|
63
|
+
private void OnEnable()
|
|
64
|
+
{
|
|
65
|
+
_serializedObject = new SerializedObject(this);
|
|
66
|
+
_inputDirectoriesProperty = _serializedObject.FindProperty(nameof(_inputDirectories));
|
|
67
|
+
_onlyNecessaryProperty = _serializedObject.FindProperty(nameof(_onlyNecessary));
|
|
68
|
+
_leftPaddingProperty = _serializedObject.FindProperty(nameof(_leftPadding));
|
|
69
|
+
_rightPaddingProperty = _serializedObject.FindProperty(nameof(_rightPadding));
|
|
70
|
+
_topPaddingProperty = _serializedObject.FindProperty(nameof(_topPadding));
|
|
71
|
+
_bottomPaddingProperty = _serializedObject.FindProperty(nameof(_bottomPadding));
|
|
72
|
+
}
|
|
73
|
+
|
|
43
74
|
private void OnGUI()
|
|
44
75
|
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
EditorGUILayout.PropertyField(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"Select Sprite Input Folder",
|
|
58
|
-
Application.dataPath,
|
|
59
|
-
""
|
|
60
|
-
);
|
|
61
|
-
if (!string.IsNullOrWhiteSpace(path))
|
|
62
|
-
{
|
|
63
|
-
if (path.StartsWith(Application.dataPath, StringComparison.Ordinal))
|
|
64
|
-
{
|
|
65
|
-
path = "Assets" + path.Substring(Application.dataPath.Length);
|
|
66
|
-
if (
|
|
67
|
-
!_inputDirectories
|
|
68
|
-
.Select(AssetDatabase.GetAssetPath)
|
|
69
|
-
.Any(directory =>
|
|
70
|
-
string.Equals(
|
|
71
|
-
directory,
|
|
72
|
-
path,
|
|
73
|
-
StringComparison.OrdinalIgnoreCase
|
|
74
|
-
)
|
|
75
|
-
)
|
|
76
|
-
)
|
|
77
|
-
{
|
|
78
|
-
Object folder = AssetDatabase.LoadAssetAtPath<Object>(path);
|
|
79
|
-
if (folder == null)
|
|
80
|
-
{
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
_inputDirectories.Add(folder);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
else
|
|
87
|
-
{
|
|
88
|
-
EditorUtility.DisplayDialog(
|
|
89
|
-
"Invalid Folder",
|
|
90
|
-
"Please select a folder inside the project's Assets directory.",
|
|
91
|
-
"OK"
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
76
|
+
EditorGUILayout.LabelField("Input directories", EditorStyles.boldLabel);
|
|
77
|
+
_serializedObject.Update();
|
|
78
|
+
PersistentDirectoryGUI.PathSelectorObjectArray(
|
|
79
|
+
_inputDirectoriesProperty,
|
|
80
|
+
nameof(SpriteCropper)
|
|
81
|
+
);
|
|
82
|
+
EditorGUILayout.PropertyField(_onlyNecessaryProperty, true);
|
|
83
|
+
EditorGUILayout.PropertyField(_leftPaddingProperty, true);
|
|
84
|
+
EditorGUILayout.PropertyField(_rightPaddingProperty, true);
|
|
85
|
+
EditorGUILayout.PropertyField(_topPaddingProperty, true);
|
|
86
|
+
EditorGUILayout.PropertyField(_bottomPaddingProperty, true);
|
|
87
|
+
_serializedObject.ApplyModifiedProperties();
|
|
96
88
|
|
|
97
89
|
if (GUILayout.Button("Find Sprites To Process"))
|
|
98
90
|
{
|
|
@@ -229,9 +221,6 @@
|
|
|
229
221
|
$"An error occurred during processing. Last processed: {lastProcessed}.",
|
|
230
222
|
e
|
|
231
223
|
);
|
|
232
|
-
AssetDatabase.StopAssetEditing();
|
|
233
|
-
AssetDatabase.SaveAssets();
|
|
234
|
-
AssetDatabase.Refresh();
|
|
235
224
|
}
|
|
236
225
|
finally
|
|
237
226
|
{
|
|
@@ -339,14 +328,8 @@
|
|
|
339
328
|
}
|
|
340
329
|
);
|
|
341
330
|
|
|
342
|
-
int cropWidth
|
|
343
|
-
int cropHeight
|
|
344
|
-
|
|
345
|
-
if (_onlyNecessary && (!hasVisible || (cropWidth == width && cropHeight == height)))
|
|
346
|
-
{
|
|
347
|
-
return null;
|
|
348
|
-
}
|
|
349
|
-
|
|
331
|
+
int cropWidth;
|
|
332
|
+
int cropHeight;
|
|
350
333
|
if (!hasVisible)
|
|
351
334
|
{
|
|
352
335
|
cropWidth = 1;
|
|
@@ -354,6 +337,20 @@
|
|
|
354
337
|
minX = 0;
|
|
355
338
|
minY = 0;
|
|
356
339
|
}
|
|
340
|
+
else
|
|
341
|
+
{
|
|
342
|
+
minX = Mathf.Max(0, minX - _leftPadding);
|
|
343
|
+
minY = Mathf.Max(0, minY - _bottomPadding);
|
|
344
|
+
maxX = Mathf.Min(width, maxX + _rightPadding);
|
|
345
|
+
maxY = Mathf.Min(height, maxY + _topPadding);
|
|
346
|
+
cropWidth = maxX - minX + 1;
|
|
347
|
+
cropHeight = maxY - minY + 1;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (_onlyNecessary && (!hasVisible || (cropWidth == width && cropHeight == height)))
|
|
351
|
+
{
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
357
354
|
|
|
358
355
|
Texture2D cropped = new(cropWidth, cropHeight, TextureFormat.RGBA32, false);
|
|
359
356
|
Color32[] croppedPixels = new Color32[cropWidth * cropHeight];
|
|
@@ -407,6 +404,11 @@
|
|
|
407
404
|
cropHeight > 0 ? newPivotPixels.y / cropHeight : 0.5f
|
|
408
405
|
);
|
|
409
406
|
|
|
407
|
+
if (!hasVisible)
|
|
408
|
+
{
|
|
409
|
+
newPivotNorm = new Vector2(0.5f, 0.5f);
|
|
410
|
+
}
|
|
411
|
+
|
|
410
412
|
newImporter.spriteImportMode = SpriteImportMode.Single;
|
|
411
413
|
newImporter.spritePivot = newPivotNorm;
|
|
412
414
|
newSettings.spritePivot = newPivotNorm;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// ReSharper disable CompareOfFloatsByEqualityOperator
|
|
2
|
-
namespace WallstopStudios.UnityHelpers.Editor
|
|
2
|
+
namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
3
3
|
{
|
|
4
4
|
#if UNITY_EDITOR
|
|
5
|
-
using Core.Attributes;
|
|
6
|
-
using Core.Extension;
|
|
7
5
|
using System;
|
|
8
6
|
using System.Collections.Generic;
|
|
9
7
|
using System.IO;
|
|
10
8
|
using System.Linq;
|
|
11
9
|
using UnityEditor;
|
|
12
10
|
using UnityEngine;
|
|
13
|
-
using
|
|
11
|
+
using Core.Attributes;
|
|
12
|
+
using Core.Extension;
|
|
13
|
+
using CustomEditors;
|
|
14
14
|
using Object = UnityEngine.Object;
|
|
15
15
|
|
|
16
16
|
[Serializable]
|
|
@@ -77,7 +77,7 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
[CustomPropertyDrawer(typeof(SpriteSettings))]
|
|
80
|
-
public class SpriteSettingsDrawer : PropertyDrawer
|
|
80
|
+
public sealed class SpriteSettingsDrawer : PropertyDrawer
|
|
81
81
|
{
|
|
82
82
|
private const float CheckboxWidth = 18f;
|
|
83
83
|
private const float HorizontalSpacing = 5f;
|
|
@@ -204,7 +204,7 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
204
204
|
valuePropHeight
|
|
205
205
|
);
|
|
206
206
|
|
|
207
|
-
using (new
|
|
207
|
+
using (new EditorGUI.IndentLevelScope())
|
|
208
208
|
{
|
|
209
209
|
EditorGUI.PropertyField(valueRect, valueProp, GUIContent.none, true);
|
|
210
210
|
}
|
|
@@ -301,25 +301,16 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
301
301
|
private void OnGUI()
|
|
302
302
|
{
|
|
303
303
|
_serializedObject.Update();
|
|
304
|
-
|
|
305
304
|
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
|
|
306
305
|
|
|
307
306
|
EditorGUILayout.LabelField("Sprite Sources", EditorStyles.boldLabel);
|
|
308
307
|
EditorGUILayout.PropertyField(_spritesProp, new GUIContent("Specific Sprites"), true);
|
|
309
|
-
|
|
310
308
|
EditorGUILayout.Space();
|
|
311
|
-
|
|
312
309
|
EditorGUILayout.LabelField("Directory Sources", EditorStyles.boldLabel);
|
|
313
|
-
|
|
310
|
+
PersistentDirectoryGUI.PathSelectorObjectArray(
|
|
314
311
|
_directoriesProp,
|
|
315
|
-
|
|
316
|
-
true
|
|
312
|
+
nameof(SpriteSettingsApplierWindow)
|
|
317
313
|
);
|
|
318
|
-
if (GUILayout.Button("Add Directory via Browser"))
|
|
319
|
-
{
|
|
320
|
-
AddDirectory();
|
|
321
|
-
}
|
|
322
|
-
|
|
323
314
|
EditorGUILayout.Space();
|
|
324
315
|
EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
|
|
325
316
|
EditorGUILayout.PropertyField(
|
|
@@ -332,7 +323,6 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
332
323
|
new GUIContent("Sprite Settings Profiles"),
|
|
333
324
|
true
|
|
334
325
|
);
|
|
335
|
-
|
|
336
326
|
EditorGUILayout.Space();
|
|
337
327
|
EditorGUILayout.LabelField("Actions", EditorStyles.boldLabel);
|
|
338
328
|
|
|
@@ -363,67 +353,10 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
363
353
|
_serializedObject.ApplyModifiedProperties();
|
|
364
354
|
}
|
|
365
355
|
|
|
366
|
-
private void AddDirectory()
|
|
367
|
-
{
|
|
368
|
-
string path = EditorUtility.OpenFolderPanel("Select Directory", "Assets", "");
|
|
369
|
-
if (string.IsNullOrWhiteSpace(path))
|
|
370
|
-
{
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
if (path.StartsWith(Application.dataPath, StringComparison.Ordinal))
|
|
375
|
-
{
|
|
376
|
-
string relativePath = "Assets" + path.Substring(Application.dataPath.Length);
|
|
377
|
-
Object folderAsset = AssetDatabase.LoadAssetAtPath<Object>(relativePath);
|
|
378
|
-
if (folderAsset != null)
|
|
379
|
-
{
|
|
380
|
-
_directoriesProp.serializedObject.Update();
|
|
381
|
-
bool alreadyExists = false;
|
|
382
|
-
for (int i = 0; i < _directoriesProp.arraySize; i++)
|
|
383
|
-
{
|
|
384
|
-
if (
|
|
385
|
-
_directoriesProp.GetArrayElementAtIndex(i).objectReferenceValue
|
|
386
|
-
== folderAsset
|
|
387
|
-
)
|
|
388
|
-
{
|
|
389
|
-
alreadyExists = true;
|
|
390
|
-
break;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (!alreadyExists)
|
|
395
|
-
{
|
|
396
|
-
int newIndex = _directoriesProp.arraySize;
|
|
397
|
-
_directoriesProp.InsertArrayElementAtIndex(newIndex);
|
|
398
|
-
_directoriesProp.GetArrayElementAtIndex(newIndex).objectReferenceValue =
|
|
399
|
-
folderAsset;
|
|
400
|
-
this.Log($"Added directory: {relativePath}");
|
|
401
|
-
}
|
|
402
|
-
else
|
|
403
|
-
{
|
|
404
|
-
this.LogWarn($"Directory already in list: {relativePath}");
|
|
405
|
-
}
|
|
406
|
-
_directoriesProp.serializedObject.ApplyModifiedProperties();
|
|
407
|
-
}
|
|
408
|
-
else
|
|
409
|
-
{
|
|
410
|
-
this.LogError(
|
|
411
|
-
$"Could not load asset at path: {relativePath}. Is it a valid folder within Assets?"
|
|
412
|
-
);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
else
|
|
416
|
-
{
|
|
417
|
-
this.LogError(
|
|
418
|
-
$"Selected folder must be inside the project's Assets folder. Path selected: {path}"
|
|
419
|
-
);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
356
|
private List<(string fullFilePath, string relativePath)> GetTargetSpritePaths()
|
|
424
357
|
{
|
|
425
358
|
HashSet<string> uniqueRelativePaths = new(StringComparer.OrdinalIgnoreCase);
|
|
426
|
-
|
|
359
|
+
HashSet<Object> validDirectories = new();
|
|
427
360
|
|
|
428
361
|
for (int i = 0; i < _directoriesProp.arraySize; i++)
|
|
429
362
|
{
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#if UNITY_EDITOR
|
|
4
4
|
using UnityEditor;
|
|
5
5
|
using UnityEngine;
|
|
6
|
-
using
|
|
6
|
+
using Core.Attributes;
|
|
7
7
|
|
|
8
8
|
// https://www.patrykgalach.com/2020/01/20/readonly-attribute-in-unity-editor/
|
|
9
9
|
[CustomPropertyDrawer(typeof(DxReadOnlyAttribute))]
|
|
@@ -4,9 +4,73 @@
|
|
|
4
4
|
using System.IO;
|
|
5
5
|
using System.Runtime.CompilerServices;
|
|
6
6
|
using UnityEngine;
|
|
7
|
+
#if UNITY_EDITOR
|
|
8
|
+
using UnityEditor;
|
|
9
|
+
#endif
|
|
7
10
|
|
|
8
11
|
public static class DirectoryHelper
|
|
9
12
|
{
|
|
13
|
+
public static void EnsureDirectoryExists(string relativeDirectoryPath)
|
|
14
|
+
{
|
|
15
|
+
if (string.IsNullOrWhiteSpace(relativeDirectoryPath))
|
|
16
|
+
{
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
#if UNITY_EDITOR
|
|
21
|
+
if (!relativeDirectoryPath.StartsWith("Assets/"))
|
|
22
|
+
{
|
|
23
|
+
if (relativeDirectoryPath.Equals("Assets", StringComparison.OrdinalIgnoreCase))
|
|
24
|
+
{
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Debug.LogError(
|
|
29
|
+
$"Attempted to create directory outside of Assets: '{relativeDirectoryPath}'"
|
|
30
|
+
);
|
|
31
|
+
throw new ArgumentException(
|
|
32
|
+
"Cannot create directories outside the Assets folder using AssetDatabase.",
|
|
33
|
+
nameof(relativeDirectoryPath)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (AssetDatabase.IsValidFolder(relativeDirectoryPath))
|
|
38
|
+
{
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
string parentPath = Path.GetDirectoryName(relativeDirectoryPath).SanitizePath();
|
|
43
|
+
if (
|
|
44
|
+
string.IsNullOrWhiteSpace(parentPath)
|
|
45
|
+
|| parentPath.Equals("Assets", StringComparison.OrdinalIgnoreCase)
|
|
46
|
+
)
|
|
47
|
+
{
|
|
48
|
+
string folderNameToCreate = Path.GetFileName(relativeDirectoryPath);
|
|
49
|
+
if (
|
|
50
|
+
!string.IsNullOrWhiteSpace(folderNameToCreate)
|
|
51
|
+
&& !AssetDatabase.IsValidFolder(relativeDirectoryPath)
|
|
52
|
+
)
|
|
53
|
+
{
|
|
54
|
+
AssetDatabase.CreateFolder("Assets", folderNameToCreate);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
EnsureDirectoryExists(parentPath);
|
|
60
|
+
string currentFolderName = Path.GetFileName(relativeDirectoryPath);
|
|
61
|
+
if (
|
|
62
|
+
!string.IsNullOrWhiteSpace(currentFolderName)
|
|
63
|
+
&& !AssetDatabase.IsValidFolder(relativeDirectoryPath)
|
|
64
|
+
)
|
|
65
|
+
{
|
|
66
|
+
AssetDatabase.CreateFolder(parentPath, currentFolderName);
|
|
67
|
+
Debug.Log($"Created folder: {relativeDirectoryPath}");
|
|
68
|
+
}
|
|
69
|
+
#else
|
|
70
|
+
Directory.CreateDirectory(relativeDirectoryPath);
|
|
71
|
+
#endif
|
|
72
|
+
}
|
|
73
|
+
|
|
10
74
|
public static string GetCallerScriptDirectory([CallerFilePath] string sourceFilePath = "")
|
|
11
75
|
{
|
|
12
76
|
return string.IsNullOrWhiteSpace(sourceFilePath)
|
package/package.json
CHANGED