maidraw 0.9.1 → 0.9.3

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.
Files changed (76) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/assets/themes/chunithm/{jp → best}/verseLandscape/new/manifest.json +23 -23
  3. package/assets/themes/chunithm/{jp → best}/verseLandscape/recents/manifest.json +23 -23
  4. package/assets/themes/chunithm/chart/common/verse/jp/background.png +0 -0
  5. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/100.png +0 -0
  6. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/105.png +0 -0
  7. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/110.png +0 -0
  8. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/115.png +0 -0
  9. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/120.png +0 -0
  10. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/125.png +0 -0
  11. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/130.png +0 -0
  12. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/135.png +0 -0
  13. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/140.png +0 -0
  14. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/145.png +0 -0
  15. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/150.png +0 -0
  16. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/155.png +0 -0
  17. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/200.png +0 -0
  18. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/205.png +0 -0
  19. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/210.png +0 -0
  20. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/215.png +0 -0
  21. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/220.png +0 -0
  22. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/225.png +0 -0
  23. package/assets/themes/chunithm/chart/common/versionless/logo/jpn/230.png +0 -0
  24. package/assets/themes/chunithm/chart/jp/verse/manifest.json +143 -0
  25. package/dist/chu/bests/best50.js +110 -93
  26. package/dist/chu/bests/best50.js.map +1 -1
  27. package/dist/chu/chart/database.d.ts +94 -0
  28. package/dist/chu/chart/database.js +44 -0
  29. package/dist/chu/chart/database.js.map +1 -1
  30. package/dist/chu/chart/index.d.ts +208 -0
  31. package/dist/chu/chart/index.js +1033 -1
  32. package/dist/chu/chart/index.js.map +1 -1
  33. package/dist/chu/lib/index.d.ts +8 -0
  34. package/dist/chu/lib/index.js.map +1 -1
  35. package/dist/chu/lib/kamaiTachi/index.d.ts +9 -0
  36. package/dist/chu/lib/kamaiTachi/index.js +108 -28
  37. package/dist/chu/lib/kamaiTachi/index.js.map +1 -1
  38. package/dist/chu/lib/lxns/index.d.ts +9 -0
  39. package/dist/chu/lib/lxns/index.js +75 -22
  40. package/dist/chu/lib/lxns/index.js.map +1 -1
  41. package/dist/lib/util.d.ts +182 -4
  42. package/dist/lib/util.js +390 -0
  43. package/dist/lib/util.js.map +1 -1
  44. package/dist/mai/best50/index.js +2 -26
  45. package/dist/mai/best50/index.js.map +1 -1
  46. package/dist/mai/chart/index.js +10 -3
  47. package/dist/mai/chart/index.js.map +1 -1
  48. package/dist/mai/level50/index.js +1 -1
  49. package/dist/mai/level50/index.js.map +1 -1
  50. package/dist/mai/lib/kamaiTachi/index.d.ts +6 -5
  51. package/dist/mai/lib/kamaiTachi/index.js +37 -41
  52. package/dist/mai/lib/kamaiTachi/index.js.map +1 -1
  53. package/package.json +1 -1
  54. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/A.png +0 -0
  55. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/AA.png +0 -0
  56. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/AAA.png +0 -0
  57. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/B.png +0 -0
  58. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/BB.png +0 -0
  59. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/BBB.png +0 -0
  60. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/C.png +0 -0
  61. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/D.png +0 -0
  62. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/S.png +0 -0
  63. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/SP.png +0 -0
  64. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/SS.png +0 -0
  65. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/SSP.png +0 -0
  66. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/SSS.png +0 -0
  67. /package/assets/themes/chunithm/{common → best/common}/verse/achievement/SSSP.png +0 -0
  68. /package/assets/themes/chunithm/{common → best/common}/verse/jp/background.png +0 -0
  69. /package/assets/themes/chunithm/{common → best/common}/verse/jp/logo.png +0 -0
  70. /package/assets/themes/chunithm/{common → best/common}/versionless/icon.png +0 -0
  71. /package/assets/themes/chunithm/{common → best/common}/versionless/milestone/aj.png +0 -0
  72. /package/assets/themes/chunithm/{common → best/common}/versionless/milestone/ajc.png +0 -0
  73. /package/assets/themes/chunithm/{common → best/common}/versionless/milestone/fc.png +0 -0
  74. /package/assets/themes/chunithm/{common → best/common}/versionless/nameplate.png +0 -0
  75. /package/assets/themes/chunithm/{common → best/common}/versionless/numberMap.png +0 -0
  76. /package/assets/themes/chunithm/{common → best/common}/versionless/void.png +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ "typescript.tsdk": "node_modules/typescript/lib"
3
+ }
@@ -5,31 +5,31 @@
5
5
  "height": 1340,
6
6
  "sprites": {
7
7
  "achievement": {
8
- "d": "../../../common/verse/achievement/D.png",
9
- "c": "../../../common/verse/achievement/C.png",
10
- "b": "../../../common/verse/achievement/B.png",
11
- "bb": "../../../common/verse/achievement/BB.png",
12
- "bbb": "../../../common/verse/achievement/BBB.png",
13
- "a": "../../../common/verse/achievement/A.png",
14
- "aa": "../../../common/verse/achievement/AA.png",
15
- "aaa": "../../../common/verse/achievement/AAA.png",
16
- "s": "../../../common/verse/achievement/S.png",
17
- "sp": "../../../common/verse/achievement/SP.png",
18
- "ss": "../../../common/verse/achievement/SS.png",
19
- "ssp": "../../../common/verse/achievement/SSP.png",
20
- "sss": "../../../common/verse/achievement/SSS.png",
21
- "sssp": "../../../common/verse/achievement/SSSP.png"
8
+ "d": "../../common/verse/achievement/D.png",
9
+ "c": "../../common/verse/achievement/C.png",
10
+ "b": "../../common/verse/achievement/B.png",
11
+ "bb": "../../common/verse/achievement/BB.png",
12
+ "bbb": "../../common/verse/achievement/BBB.png",
13
+ "a": "../../common/verse/achievement/A.png",
14
+ "aa": "../../common/verse/achievement/AA.png",
15
+ "aaa": "../../common/verse/achievement/AAA.png",
16
+ "s": "../../common/verse/achievement/S.png",
17
+ "sp": "../../common/verse/achievement/SP.png",
18
+ "ss": "../../common/verse/achievement/SS.png",
19
+ "ssp": "../../common/verse/achievement/SSP.png",
20
+ "sss": "../../common/verse/achievement/SSS.png",
21
+ "sssp": "../../common/verse/achievement/SSSP.png"
22
22
  },
23
23
  "milestone": {
24
- "aj": "../../../common/versionless/milestone/aj.png",
25
- "ajc": "../../../common/versionless/milestone/ajc.png",
26
- "fc": "../../../common/versionless/milestone/fc.png",
27
- "none": "../../../common/versionless/void.png"
24
+ "aj": "../../common/versionless/milestone/aj.png",
25
+ "ajc": "../../common/versionless/milestone/ajc.png",
26
+ "fc": "../../common/versionless/milestone/fc.png",
27
+ "none": "../../common/versionless/void.png"
28
28
  },
29
- "ratingNumberMap": "../../../common/versionless/numberMap.png",
29
+ "ratingNumberMap": "../../common/versionless/numberMap.png",
30
30
  "profile": {
31
- "nameplate": "../../../common/versionless/nameplate.png",
32
- "icon": "../../../common/versionless/icon.png"
31
+ "nameplate": "../../common/versionless/nameplate.png",
32
+ "icon": "../../common/versionless/icon.png"
33
33
  }
34
34
  },
35
35
  "elements": [
@@ -39,7 +39,7 @@
39
39
  "y": -151,
40
40
  "width": 2920,
41
41
  "height": 1642,
42
- "path": "../../../common/verse/jp/background.png"
42
+ "path": "../../common/verse/jp/background.png"
43
43
  },
44
44
  {
45
45
  "type": "image",
@@ -47,7 +47,7 @@
47
47
  "y": -20,
48
48
  "width": 450,
49
49
  "height": 350,
50
- "path": "../../../common/verse/jp/logo.png"
50
+ "path": "../../common/verse/jp/logo.png"
51
51
  },
52
52
  {
53
53
  "type": "score-grid",
@@ -5,31 +5,31 @@
5
5
  "height": 1440,
6
6
  "sprites": {
7
7
  "achievement": {
8
- "d": "../../../common/verse/achievement/D.png",
9
- "c": "../../../common/verse/achievement/C.png",
10
- "b": "../../../common/verse/achievement/B.png",
11
- "bb": "../../../common/verse/achievement/BB.png",
12
- "bbb": "../../../common/verse/achievement/BBB.png",
13
- "a": "../../../common/verse/achievement/A.png",
14
- "aa": "../../../common/verse/achievement/AA.png",
15
- "aaa": "../../../common/verse/achievement/AAA.png",
16
- "s": "../../../common/verse/achievement/S.png",
17
- "sp": "../../../common/verse/achievement/SP.png",
18
- "ss": "../../../common/verse/achievement/SS.png",
19
- "ssp": "../../../common/verse/achievement/SSP.png",
20
- "sss": "../../../common/verse/achievement/SSS.png",
21
- "sssp": "../../../common/verse/achievement/SSSP.png"
8
+ "d": "../../common/verse/achievement/D.png",
9
+ "c": "../../common/verse/achievement/C.png",
10
+ "b": "../../common/verse/achievement/B.png",
11
+ "bb": "../../common/verse/achievement/BB.png",
12
+ "bbb": "../../common/verse/achievement/BBB.png",
13
+ "a": "../../common/verse/achievement/A.png",
14
+ "aa": "../../common/verse/achievement/AA.png",
15
+ "aaa": "../../common/verse/achievement/AAA.png",
16
+ "s": "../../common/verse/achievement/S.png",
17
+ "sp": "../../common/verse/achievement/SP.png",
18
+ "ss": "../../common/verse/achievement/SS.png",
19
+ "ssp": "../../common/verse/achievement/SSP.png",
20
+ "sss": "../../common/verse/achievement/SSS.png",
21
+ "sssp": "../../common/verse/achievement/SSSP.png"
22
22
  },
23
23
  "milestone": {
24
- "aj": "../../../common/versionless/milestone/aj.png",
25
- "ajc": "../../../common/versionless/milestone/ajc.png",
26
- "fc": "../../../common/versionless/milestone/fc.png",
27
- "none": "../../../common/versionless/void.png"
24
+ "aj": "../../common/versionless/milestone/aj.png",
25
+ "ajc": "../../common/versionless/milestone/ajc.png",
26
+ "fc": "../../common/versionless/milestone/fc.png",
27
+ "none": "../../common/versionless/void.png"
28
28
  },
29
- "ratingNumberMap": "../../../common/versionless/numberMap.png",
29
+ "ratingNumberMap": "../../common/versionless/numberMap.png",
30
30
  "profile": {
31
- "nameplate": "../../../common/versionless/nameplate.png",
32
- "icon": "../../../common/versionless/icon.png"
31
+ "nameplate": "../../common/versionless/nameplate.png",
32
+ "icon": "../../common/versionless/icon.png"
33
33
  }
34
34
  },
35
35
  "elements": [
@@ -39,7 +39,7 @@
39
39
  "y": 0,
40
40
  "width": 2560,
41
41
  "height": 1440,
42
- "path": "../../../common/verse/jp/background.png"
42
+ "path": "../../common/verse/jp/background.png"
43
43
  },
44
44
  {
45
45
  "type": "image",
@@ -47,7 +47,7 @@
47
47
  "y": -20,
48
48
  "width": 450,
49
49
  "height": 350,
50
- "path": "../../../common/verse/jp/logo.png"
50
+ "path": "../../common/verse/jp/logo.png"
51
51
  },
52
52
  {
53
53
  "type": "score-grid",
@@ -0,0 +1,143 @@
1
+ {
2
+ "displayName": "CHUNITHM VERSE",
3
+ "name": "jp-verse",
4
+ "width": 2560,
5
+ "height": 1440,
6
+ "sprites": {
7
+ "achievement": {
8
+ "d": "../../../best/common/verse/achievement/D.png",
9
+ "c": "../../../best/common/verse/achievement/C.png",
10
+ "b": "../../../best/common/verse/achievement/B.png",
11
+ "bb": "../../../best/common/verse/achievement/BB.png",
12
+ "bbb": "../../../best/common/verse/achievement/BBB.png",
13
+ "a": "../../../best/common/verse/achievement/A.png",
14
+ "aa": "../../../best/common/verse/achievement/AA.png",
15
+ "aaa": "../../../best/common/verse/achievement/AAA.png",
16
+ "s": "../../../best/common/verse/achievement/S.png",
17
+ "sp": "../../../best/common/verse/achievement/SP.png",
18
+ "ss": "../../../best/common/verse/achievement/SS.png",
19
+ "ssp": "../../../best/common/verse/achievement/SSP.png",
20
+ "sss": "../../../best/common/verse/achievement/SS.png",
21
+ "sssp": "../../../best/common/verse/achievement/SSSP.png"
22
+ },
23
+ "milestone": {
24
+ "aj": "../../../best/common/versionless/milestone/aj.png",
25
+ "ajc": "../../../best/common/versionless/milestone/ajc.png",
26
+ "fc": "../../../best/common/versionless/milestone/fc.png",
27
+ "none": "../../../best/common/versionless/void.png"
28
+ },
29
+ "ratingNumberMap": "../../../best/common/versionless/numberMap.png",
30
+ "profile": {
31
+ "nameplate": "../../../best/common/versionless/nameplate.png",
32
+ "icon": "../../../best/common/versionless/icon.png"
33
+ },
34
+ "versions": {
35
+ "JPN": {
36
+ "100": "../../common/versionless/logo/jpn/100.png",
37
+ "105": "../../common/versionless/logo/jpn/105.png",
38
+ "110": "../../common/versionless/logo/jpn/110.png",
39
+ "115": "../../common/versionless/logo/jpn/115.png",
40
+ "120": "../../common/versionless/logo/jpn/120.png",
41
+ "125": "../../common/versionless/logo/jpn/125.png",
42
+ "130": "../../common/versionless/logo/jpn/130.png",
43
+ "135": "../../common/versionless/logo/jpn/135.png",
44
+ "140": "../../common/versionless/logo/jpn/140.png",
45
+ "145": "../../common/versionless/logo/jpn/145.png",
46
+ "150": "../../common/versionless/logo/jpn/150.png",
47
+ "155": "../../common/versionless/logo/jpn/155.png",
48
+ "200": "../../common/versionless/logo/jpn/200.png",
49
+ "205": "../../common/versionless/logo/jpn/205.png",
50
+ "210": "../../common/versionless/logo/jpn/210.png",
51
+ "215": "../../common/versionless/logo/jpn/215.png",
52
+ "220": "../../common/versionless/logo/jpn/220.png",
53
+ "225": "../../common/versionless/logo/jpn/225.png",
54
+ "230": "../../common/versionless/logo/jpn/230.png",
55
+ "240": "../../../best/common/versionless/void.png"
56
+ },
57
+ "INT": {
58
+ "100": "../../../best/common/versionless/void.png",
59
+ "105": "../../../best/common/versionless/void.png",
60
+ "110": "../../common/versionless/logo/jpn/200.png",
61
+ "115": "../../common/versionless/logo/jpn/205.png",
62
+ "120": "../../common/versionless/logo/jpn/210.png",
63
+ "125": "../../common/versionless/logo/jpn/215.png",
64
+ "130": "../../common/versionless/logo/jpn/220.png",
65
+ "135": "../../common/versionless/logo/jpn/225.png",
66
+ "140": "../../common/versionless/logo/jpn/230.png"
67
+ },
68
+ "CHN": {
69
+ "100": "../../../best/common/versionless/void.png",
70
+ "110": "../../../best/common/versionless/void.png",
71
+ "120": "../../../best/common/versionless/void.png",
72
+ "130": "../../../best/common/versionless/void.png"
73
+ }
74
+ }
75
+ },
76
+ "elements": [
77
+ {
78
+ "type": "image",
79
+ "x": 0,
80
+ "y": 0,
81
+ "width": 2560,
82
+ "height": 1440,
83
+ "path": "../../common/verse/jp/background.png"
84
+ },
85
+ {
86
+ "type": "image",
87
+ "x": 1957,
88
+ "y": 262,
89
+ "width": 391,
90
+ "height": 305,
91
+ "path": "../../../best/common/verse/jp/logo.png"
92
+ },
93
+ {
94
+ "type": "chart-grid",
95
+ "x": 100,
96
+ "y": 262,
97
+ "width": 1645,
98
+ "height": 1045,
99
+ "margin": 70,
100
+ "gap": 40,
101
+ "bubble": {
102
+ "margin": 20,
103
+ "color": {
104
+ "basic": "#70E262",
105
+ "advanced": "#FFBB00",
106
+ "expert": "#FF4A5A",
107
+ "master": "#A04FDA",
108
+ "ultima": "#591C28",
109
+ "worldsEnd": "#70E262"
110
+ }
111
+ },
112
+ "color": {
113
+ "card": "#b9eae5"
114
+ }
115
+ },
116
+ {
117
+ "type": "detail-info",
118
+ "x": 1845,
119
+ "y": 562,
120
+ "width": 615,
121
+ "height": 745,
122
+ "margin": 40,
123
+ "color": {
124
+ "card": "#b9eae5"
125
+ }
126
+ },
127
+ {
128
+ "type": "profile",
129
+ "x": 150,
130
+ "y": 10,
131
+ "height": 293
132
+ },
133
+ {
134
+ "type": "text",
135
+ "size": 32,
136
+ "x": 2480,
137
+ "y": 1407,
138
+ "borderColor": "#226180",
139
+ "align": "right",
140
+ "content": "Generated by saltbot | chunithm.cab/discord | chunithm.cab/invite"
141
+ }
142
+ ]
143
+ }
@@ -59,7 +59,7 @@ class Best50 {
59
59
  return !!this.themes[name];
60
60
  }
61
61
  static {
62
- const manifests = (0, glob_1.globSync)(upath_1.default.join(this.assetsPath, "themes", "chunithm", "**", "manifest.json"));
62
+ const manifests = (0, glob_1.globSync)(upath_1.default.join(this.assetsPath, "themes", "chunithm", "best", "**", "manifest.json"));
63
63
  for (const manifestPath of manifests) {
64
64
  const manifest = JSON.parse(fs_1.default.readFileSync(manifestPath, "utf-8"));
65
65
  if (this.validateManifest(manifest, upath_1.default.dirname(manifestPath))) {
@@ -83,134 +83,151 @@ class Best50 {
83
83
  });
84
84
  }
85
85
  static validateManifest(payload, path) {
86
- function isFileExist(p) {
87
- if (isString(p))
88
- return fs_1.default.existsSync(upath_1.default.join(path, p));
89
- else
90
- return false;
86
+ function assert(obj, path, condition) {
87
+ const deepValue = (o, p) => p.split(".").reduce((a, v) => a[v], o);
88
+ const payload = deepValue(obj, path);
89
+ const result = condition(payload);
90
+ if (result === true)
91
+ return true;
92
+ throw `Manifest validation failed at ${path}.${result == false ? "" : ` ${result}`}`;
91
93
  }
92
- function isOneOf(p, ...args) {
93
- return args.includes(p);
94
+ function isFileExist(object, objectPath) {
95
+ return assert(object, objectPath, (p) => {
96
+ const filePath = upath_1.default.join(path, p);
97
+ if (typeof p == "string") {
98
+ if (fs_1.default.existsSync(filePath)) {
99
+ return true;
100
+ }
101
+ else {
102
+ return `${filePath} does not exist.`;
103
+ }
104
+ }
105
+ else
106
+ return false;
107
+ });
94
108
  }
95
- function isString(p) {
96
- return typeof p == "string";
109
+ function isOneOf(object, path, optional = false, args) {
110
+ return assert(object, path, (p) => args.includes(p) || (optional && p === undefined));
97
111
  }
98
- function isNumber(p) {
99
- return typeof p == "number";
112
+ function isString(object, path, optional = false) {
113
+ return assert(object, path, (p) => typeof p == "string" || (optional && p === undefined));
100
114
  }
101
- function isArray(p) {
102
- return Array.isArray(p);
115
+ function isNumber(object, path, optional = false) {
116
+ return assert(object, path, (p) => typeof p == "number" || (optional && p === undefined));
103
117
  }
104
- function isObject(p) {
105
- return typeof p == "object";
118
+ function isArray(object, path, optional = false) {
119
+ return assert(object, path, (p) => Array.isArray(p) || (optional && p === undefined));
106
120
  }
107
- function isHexColor(p) {
108
- if (isString(p))
109
- return /^(?:#[0-9A-F]{6}|#[0-9A-F]{8})$/i.test(p);
110
- else
111
- return false;
121
+ function isObject(object, path, optional = false) {
122
+ return assert(object, path, (p) => typeof p == "object" || (optional && p === undefined));
112
123
  }
113
- function isUndefined(p) {
114
- return typeof p == "undefined";
124
+ function isHexColor(object, path, optional = false) {
125
+ return assert(object, path, (p) => {
126
+ if (typeof p == "string")
127
+ return (/^(?:#[0-9A-F]{6}|#[0-9A-F]{8})$/i.test(p) ||
128
+ (optional && p === undefined));
129
+ else
130
+ return optional && p === undefined;
131
+ });
115
132
  }
116
- function isBoolean(p) {
117
- return typeof p == "boolean";
133
+ function isBoolean(object, path, optional = false) {
134
+ return assert(object, path, (p) => typeof p == "boolean" || (optional && p === undefined));
118
135
  }
119
- if (isString(payload.displayName) &&
120
- isString(payload.name) &&
121
- isNumber(payload.width) &&
122
- isNumber(payload.height) &&
123
- isObject(payload.sprites) &&
124
- isObject(payload.sprites.achievement) &&
125
- isFileExist(payload.sprites.achievement.d) &&
126
- isFileExist(payload.sprites.achievement.c) &&
127
- isFileExist(payload.sprites.achievement.b) &&
128
- isFileExist(payload.sprites.achievement.bb) &&
129
- isFileExist(payload.sprites.achievement.bbb) &&
130
- isFileExist(payload.sprites.achievement.a) &&
131
- isFileExist(payload.sprites.achievement.aa) &&
132
- isFileExist(payload.sprites.achievement.aaa) &&
133
- isFileExist(payload.sprites.achievement.s) &&
134
- isFileExist(payload.sprites.achievement.sp) &&
135
- isFileExist(payload.sprites.achievement.ss) &&
136
- isFileExist(payload.sprites.achievement.ssp) &&
137
- isFileExist(payload.sprites.achievement.sss) &&
138
- isFileExist(payload.sprites.achievement.sssp) &&
139
- isObject(payload.sprites.milestone) &&
140
- isFileExist(payload.sprites.milestone.aj) &&
141
- isFileExist(payload.sprites.milestone.ajc) &&
142
- isFileExist(payload.sprites.milestone.fc) &&
143
- isFileExist(payload.sprites.milestone.none) &&
144
- isObject(payload.sprites.profile) &&
145
- isFileExist(payload.sprites.profile.icon) &&
146
- isFileExist(payload.sprites.profile.nameplate) &&
147
- isFileExist(payload.sprites.ratingNumberMap) &&
148
- isArray(payload.elements)) {
136
+ if (isString(payload, "displayName") &&
137
+ isString(payload, "name") &&
138
+ isNumber(payload, "width") &&
139
+ isNumber(payload, "height") &&
140
+ isObject(payload, "sprites") &&
141
+ isObject(payload, "sprites.achievement") &&
142
+ isFileExist(payload, "sprites.achievement.d") &&
143
+ isFileExist(payload, "sprites.achievement.c") &&
144
+ isFileExist(payload, "sprites.achievement.b") &&
145
+ isFileExist(payload, "sprites.achievement.bb") &&
146
+ isFileExist(payload, "sprites.achievement.bbb") &&
147
+ isFileExist(payload, "sprites.achievement.a") &&
148
+ isFileExist(payload, "sprites.achievement.aa") &&
149
+ isFileExist(payload, "sprites.achievement.aaa") &&
150
+ isFileExist(payload, "sprites.achievement.s") &&
151
+ isFileExist(payload, "sprites.achievement.sp") &&
152
+ isFileExist(payload, "sprites.achievement.ss") &&
153
+ isFileExist(payload, "sprites.achievement.ssp") &&
154
+ isFileExist(payload, "sprites.achievement.sss") &&
155
+ isFileExist(payload, "sprites.achievement.sssp") &&
156
+ isObject(payload, "sprites.milestone") &&
157
+ isFileExist(payload, "sprites.milestone.aj") &&
158
+ isFileExist(payload, "sprites.milestone.ajc") &&
159
+ isFileExist(payload, "sprites.milestone.fc") &&
160
+ isFileExist(payload, "sprites.milestone.none") &&
161
+ isObject(payload, "sprites.profile") &&
162
+ isFileExist(payload, "sprites.profile.icon") &&
163
+ isFileExist(payload, "sprites.profile.nameplate") &&
164
+ isFileExist(payload, "sprites.ratingNumberMap") &&
165
+ isArray(payload, "elements")) {
149
166
  for (const element of payload.elements) {
150
- if (isNumber(element.x) && isNumber(element.y)) {
167
+ if (isNumber(element, "x") && isNumber(element, "y")) {
151
168
  switch (element.type) {
152
169
  case "image": {
153
- if (isNumber(element.width) &&
154
- isNumber(element.height) &&
155
- isFileExist(element.path)) {
170
+ if (isNumber(element, "width") &&
171
+ isNumber(element, "height") &&
172
+ isFileExist(element, "path")) {
156
173
  continue;
157
174
  }
158
175
  else
159
176
  return false;
160
177
  }
161
178
  case "score-grid": {
162
- if (isOneOf(element.region, "old", "new") &&
163
- isNumber(element.horizontalSize) &&
164
- isNumber(element.verticalSize) &&
165
- isNumber(element.index) &&
166
- isObject(element.scoreBubble) &&
167
- isNumber(element.scoreBubble.width) &&
168
- isNumber(element.scoreBubble.height) &&
169
- isNumber(element.scoreBubble.margin) &&
170
- isNumber(element.scoreBubble.gap) &&
171
- isObject(element.scoreBubble.color) &&
172
- isHexColor(element.scoreBubble.color.basic) &&
173
- isHexColor(element.scoreBubble.color.advanced) &&
174
- isHexColor(element.scoreBubble.color.expert) &&
175
- isHexColor(element.scoreBubble.color.master) &&
176
- isHexColor(element.scoreBubble.color.ultima) &&
177
- isHexColor(element.scoreBubble.color.worldsEnd)) {
179
+ if (isOneOf(element, "region", false, [
180
+ "old",
181
+ "new",
182
+ ]) &&
183
+ isNumber(element, "horizontalSize") &&
184
+ isNumber(element, "verticalSize") &&
185
+ isNumber(element, "index") &&
186
+ isObject(element, "scoreBubble") &&
187
+ isNumber(element, "scoreBubble.width") &&
188
+ isNumber(element, "scoreBubble.height") &&
189
+ isNumber(element, "scoreBubble.margin") &&
190
+ isNumber(element, "scoreBubble.gap") &&
191
+ isObject(element, "scoreBubble.color") &&
192
+ isHexColor(element, "scoreBubble.color.basic") &&
193
+ isHexColor(element, "scoreBubble.color.advanced") &&
194
+ isHexColor(element, "scoreBubble.color.expert") &&
195
+ isHexColor(element, "scoreBubble.color.master") &&
196
+ isHexColor(element, "scoreBubble.color.ultima") &&
197
+ isHexColor(element, "scoreBubble.color.worldsEnd")) {
178
198
  continue;
179
199
  }
180
200
  else
181
201
  return false;
182
202
  }
183
203
  case "profile": {
184
- if (isNumber(element.height)) {
204
+ if (isNumber(element, "height")) {
185
205
  continue;
186
206
  }
187
207
  else
188
208
  return false;
189
209
  }
190
210
  case "text": {
191
- if (isNumber(element.size) &&
192
- isString(element.content) &&
193
- (isUndefined(element.width) ||
194
- isNumber(element.width)) &&
195
- (isUndefined(element.height) ||
196
- isNumber(element.height)) &&
197
- (isUndefined(element.linebreak) ||
198
- isBoolean(element.linebreak)) &&
199
- (isUndefined(element.align) ||
200
- isOneOf(element.align, "left", "center", "right")) &&
201
- (isUndefined(element.color) ||
202
- isString(element.color)) &&
203
- (isUndefined(element.borderColor) ||
204
- isString(element.borderColor)) &&
205
- (isUndefined(element.font) ||
206
- isString(element.font))) {
211
+ if (isNumber(element, "size") &&
212
+ isString(element, "content") &&
213
+ isNumber(element, "width", true) &&
214
+ isNumber(element, "height", true) &&
215
+ isBoolean(element, "linebreak", true) &&
216
+ isOneOf(element, "align", true, [
217
+ "left",
218
+ "center",
219
+ "right",
220
+ ]) &&
221
+ isString(element, "color", true) &&
222
+ isString(element, "borderColor", true) &&
223
+ isString(element, "font", true)) {
207
224
  continue;
208
225
  }
209
226
  else
210
227
  return false;
211
228
  }
212
229
  default:
213
- return false;
230
+ throw `Manifest validation failed at elements.type. Unsupported element type ${element.type}.`;
214
231
  }
215
232
  }
216
233
  }