@pkmn/engine 0.1.0-dev.a1fcc5d9 → 0.1.0-dev.a27b3ff3

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 (68) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +51 -5
  3. package/build/pkg/addon/browser.d.ts +1 -1
  4. package/build/pkg/addon/browser.js +6 -2
  5. package/build/pkg/addon/browser.js.map +1 -1
  6. package/build/pkg/addon/node.js +22 -8
  7. package/build/pkg/addon/node.js.map +1 -1
  8. package/build/pkg/addon/wasm.d.ts +2 -0
  9. package/build/pkg/addon/wasm.js +53 -0
  10. package/build/pkg/addon/wasm.js.map +1 -0
  11. package/build/pkg/addon.d.ts +24 -4
  12. package/build/pkg/addon.js +8 -17
  13. package/build/pkg/addon.js.map +1 -1
  14. package/build/pkg/data/layout.json +15 -2
  15. package/build/pkg/data/protocol.json +23 -9
  16. package/build/pkg/gen1.d.ts +15 -18
  17. package/build/pkg/gen1.js +28 -19
  18. package/build/pkg/gen1.js.map +1 -1
  19. package/build/pkg/index.d.ts +37 -100
  20. package/build/pkg/index.js +23 -75
  21. package/build/pkg/index.js.map +1 -1
  22. package/build/tools/debug.js +18 -9
  23. package/build/tools/debug.js.map +1 -1
  24. package/build/tools/display/debug.jsx +18 -7
  25. package/build/tools/display/debug.jsx.map +1 -1
  26. package/build/tools/display/index.js +35 -15
  27. package/build/tools/display/index.js.map +1 -1
  28. package/build/tools/display/ui.jsx +17 -7
  29. package/build/tools/display/ui.jsx.map +1 -1
  30. package/build/tools/display/util.js +16 -1
  31. package/build/tools/display/util.js.map +1 -1
  32. package/build.zig +198 -85
  33. package/package.json +29 -125
  34. package/src/bin/install-pkmn-engine +3 -2
  35. package/src/lib/bindings/c.zig +255 -0
  36. package/src/lib/bindings/node.zig +117 -0
  37. package/src/lib/bindings/wasm.zig +59 -0
  38. package/src/lib/common/array.zig +1 -1
  39. package/src/lib/common/js.zig +1 -5
  40. package/src/lib/common/napi.zig +4 -0
  41. package/src/lib/common/optional.zig +1 -1
  42. package/src/lib/common/options.zig +2 -0
  43. package/src/lib/common/protocol.zig +4 -8
  44. package/src/lib/common/rational.zig +281 -270
  45. package/src/lib/common/rng.zig +1 -3
  46. package/src/lib/common/util.zig +17 -2
  47. package/src/lib/gen1/calc.zig +52 -69
  48. package/src/lib/gen1/chance.zig +34 -18
  49. package/src/lib/gen1/data/moves.zig +2 -4
  50. package/src/lib/gen1/data/species.zig +1 -3
  51. package/src/lib/gen1/data/types.zig +2 -3
  52. package/src/lib/gen1/data.zig +7 -11
  53. package/src/lib/gen1/helpers.zig +4 -10
  54. package/src/lib/gen1/mechanics.zig +76 -51
  55. package/src/lib/gen2/calc.zig +10 -18
  56. package/src/lib/gen2/data/items.zig +1 -3
  57. package/src/lib/gen2/data/moves.zig +2 -4
  58. package/src/lib/gen2/data/species.zig +1 -3
  59. package/src/lib/gen2/data/types.zig +7 -5
  60. package/src/lib/gen2/data.zig +14 -17
  61. package/src/lib/gen2/generated.zig +18 -23
  62. package/src/lib/gen2/helpers.zig +5 -12
  63. package/src/lib/gen2/mechanics.zig +42 -39
  64. package/src/lib/node.zig +4 -121
  65. package/src/lib/pkmn.zig +7 -2
  66. package/src/lib/wasm.zig +13 -9
  67. package/src/tools/display/dom.ts +5 -8
  68. package/src/tools/display/ui.css +0 -5
@@ -1,44 +1,37 @@
1
- const std = @import("std");
2
-
3
- const pkmn = @import("../pkmn.zig");
4
-
5
- const common = @import("../common/data.zig");
6
1
  const DEBUG = @import("../common/debug.zig").print;
7
- const protocol = @import("../common/protocol.zig");
8
- const rng = @import("../common/rng.zig");
9
2
 
3
+ const builtin = @import("builtin");
4
+ const common = @import("../common/data.zig");
10
5
  const data = @import("data.zig");
11
6
  const generated = @import("generated.zig");
12
-
13
- const assert = std.debug.assert;
14
-
15
- const expectEqual = std.testing.expectEqual;
16
- const expectEqualSlices = std.testing.expectEqualSlices;
17
- const expectEqualStrings = std.testing.expectEqualStrings;
18
-
19
- const showdown = pkmn.options.showdown;
20
-
21
- const Choice = common.Choice;
22
- const ID = common.ID;
23
- const Player = common.Player;
24
- const Result = common.Result;
7
+ const pkmn = @import("../pkmn.zig");
8
+ const protocol = @import("../common/protocol.zig");
9
+ const rng = @import("../common/rng.zig");
10
+ const std = @import("std");
25
11
 
26
12
  const Activate = protocol.Activate;
13
+ const ActivePokemon = data.ActivePokemon;
14
+ const assert = std.debug.assert;
27
15
  const Boost = protocol.Boost;
16
+ const Boosts = data.Boosts;
17
+ const Choice = common.Choice;
28
18
  const Damage = protocol.Damage;
19
+ const Effectiveness = data.Effectiveness;
29
20
  const End = protocol.End;
21
+ const expectEqual = std.testing.expectEqual;
22
+ const expectEqualSlices = std.testing.expectEqualSlices;
23
+ const expectEqualStrings = std.testing.expectEqualStrings;
30
24
  const Fail = protocol.Fail;
31
- const Heal = protocol.Heal;
32
- const Start = protocol.Start;
33
-
34
25
  const Gen12 = rng.Gen12;
35
-
36
- const ActivePokemon = data.ActivePokemon;
37
- const Boosts = data.Boosts;
38
- const Effectiveness = data.Effectiveness;
26
+ const Heal = protocol.Heal;
27
+ const ID = common.ID;
39
28
  const Item = data.Item;
40
29
  const Move = data.Move;
30
+ const Player = common.Player;
31
+ const Result = common.Result;
32
+ const showdown = pkmn.options.showdown;
41
33
  const Side = data.Side;
34
+ const Start = protocol.Start;
42
35
  const Stats = data.Stats;
43
36
  const Status = data.Status;
44
37
  const TriAttack = data.TriAttack;
@@ -689,7 +682,7 @@ pub fn adjustDamage(battle: anytype, player: Player, state: *State, _: anytype)
689
682
 
690
683
  // Type effectiveness matchup precedence only matters with (NVE, SE)
691
684
  if (!showdown and (eff1 + eff2) == Effectiveness.mismatch and
692
- types.type1.precedence() > types.type2.precedence())
685
+ Type.precedence(state.type, types.type1) > Type.precedence(state.type, types.type2))
693
686
  {
694
687
  assert(eff2 != neutral);
695
688
  d = d *% eff2 / 10;
@@ -1200,7 +1193,7 @@ fn updateSideCondition(
1200
1193
  fn endTurn(battle: anytype, options: anytype) @TypeOf(options.log).Error!Result {
1201
1194
  battle.turn += 1;
1202
1195
 
1203
- if (showdown and battle.turn >= 1000) {
1196
+ if (pkmn.options.mod and battle.turn >= 1000) {
1204
1197
  try options.log.tie(.{});
1205
1198
  return Result.Tie;
1206
1199
  } else if (battle.turn >= 65535) {
@@ -1434,7 +1427,8 @@ pub const Effects = struct {
1434
1427
  if (move.type.special() != (last == .MirrorCoat)) return;
1435
1428
  if (state.damage == 0) return;
1436
1429
 
1437
- state.damage *|= 2;
1430
+ // NOTE: llvm/llvm-project#58557
1431
+ state.damage = smul(state.damage, 2);
1438
1432
  state.miss = false;
1439
1433
  }
1440
1434
 
@@ -1529,15 +1523,18 @@ pub const Effects = struct {
1529
1523
 
1530
1524
  pub const double = struct {
1531
1525
  pub fn flying(battle: anytype, player: Player, state: *State, _: anytype) !void {
1532
- if (battle.foe(player).active.volatiles.Flying) state.damage *|= 2;
1526
+ if (!battle.foe(player).active.volatiles.Flying) return;
1527
+ state.damage = smul(state.damage, 2);
1533
1528
  }
1534
1529
 
1535
1530
  pub fn underground(battle: anytype, player: Player, state: *State, _: anytype) !void {
1536
- if (battle.foe(player).active.volatiles.Underground) state.damage *|= 2;
1531
+ if (!battle.foe(player).active.volatiles.Underground) return;
1532
+ state.damage = smul(state.damage, 2);
1537
1533
  }
1538
1534
 
1539
1535
  pub fn minimize(battle: anytype, player: Player, state: *State, _: anytype) !void {
1540
- if (battle.foe(player).active.volatiles.minimized) state.damage *|= 2;
1536
+ if (!battle.foe(player).active.volatiles.minimized) return;
1537
+ state.damage = smul(state.damage, 2);
1541
1538
  }
1542
1539
  };
1543
1540
 
@@ -1706,7 +1703,7 @@ pub const Effects = struct {
1706
1703
  if (!state.proc) return;
1707
1704
  if (foe.conditions.Safeguard) return;
1708
1705
  // Freeze Clause Mod
1709
- if (showdown) for (foe.pokemon) |p| if (Status.is(p.status, .FRZ)) return;
1706
+ if (pkmn.options.mod) for (foe.pokemon) |p| if (Status.is(p.status, .FRZ)) return;
1710
1707
 
1711
1708
  foe_stored.status = Status.init(.FRZ);
1712
1709
  try options.log.status(.{ foe_ident, foe_stored.status, .None });
@@ -1735,7 +1732,7 @@ pub const Effects = struct {
1735
1732
  state.bp *= 2;
1736
1733
  assert(state.bp <= 160);
1737
1734
  } else {
1738
- state.damage *|= 2;
1735
+ state.damage = smul(state.damage, 2);
1739
1736
  }
1740
1737
  }
1741
1738
 
@@ -2206,7 +2203,7 @@ pub const Effects = struct {
2206
2203
 
2207
2204
  pub fn pursuit(battle: anytype, player: Player, state: *State, _: anytype) !void {
2208
2205
  // TODO: remove switching variable and just look at Choice saved in Battle struct?
2209
- if (battle.foe(player).active.volatiles.switching) state.damage *|= 2;
2206
+ if (battle.foe(player).active.volatiles.switching) state.damage = smul(state.damage, 2);
2210
2207
  }
2211
2208
 
2212
2209
  pub const rage = struct {
@@ -2219,7 +2216,7 @@ pub const Effects = struct {
2219
2216
  const side = battle.side(player);
2220
2217
 
2221
2218
  assert(side.active.volatiles.Rage);
2222
- state.damage *|= (side.active.volatiles.rage +| 1);
2219
+ state.damage = smul(state.damage, (side.active.volatiles.rage +| 1)); // TODO: |+
2223
2220
  }
2224
2221
  };
2225
2222
 
@@ -2314,7 +2311,7 @@ pub const Effects = struct {
2314
2311
  side.active.volatiles.attacks += 1;
2315
2312
  side.active.volatiles.Rollout = side.active.volatiles.attacks != 5;
2316
2313
 
2317
- if (side.active.volatiles.DefenseCurl) state.damage *|= 2;
2314
+ if (side.active.volatiles.DefenseCurl) state.damage = smul(state.damage, 2);
2318
2315
  }
2319
2316
  };
2320
2317
 
@@ -2384,7 +2381,7 @@ pub const Effects = struct {
2384
2381
  }
2385
2382
 
2386
2383
  // Sleep Clause Mod
2387
- if (showdown) {
2384
+ if (pkmn.options.mod) {
2388
2385
  for (foe.pokemon) |p| {
2389
2386
  if (Status.is(p.status, .SLP) and !Status.is(p.status, .EXT)) return;
2390
2387
  }
@@ -2842,6 +2839,12 @@ fn convertible(active: ActivePokemon, m: Move) bool {
2842
2839
  return t != .@"???" and !active.types.includes(t);
2843
2840
  }
2844
2841
 
2842
+ // NOTE: llvm/llvm-project#58557
2843
+ fn smul(a: anytype, b: @TypeOf(a)) @TypeOf(a) {
2844
+ if (!comptime builtin.target.cpu.arch.isWasm()) return a *| b;
2845
+ return @max(a *% b, std.math.maxInt(@TypeOf(a)));
2846
+ }
2847
+
2845
2848
  pub const Rolls = struct {
2846
2849
  fn speedTie(battle: anytype, options: anytype) !bool {
2847
2850
  const p1 = if (options.calc.overridden(.P1, 0, .speed_tie)) |player|
package/src/lib/node.zig CHANGED
@@ -1,131 +1,14 @@
1
- const std = @import("std");
2
-
3
- const pkmn = @import("pkmn.zig");
4
-
1
+ const c = @import("common/napi.zig");
5
2
  const js = @import("common/js.zig");
3
+ const node = @import("bindings/node.zig");
4
+ const std = @import("std");
6
5
 
7
6
  const assert = std.debug.assert;
8
7
 
9
- const c = @cImport({
10
- @cDefine("NAPI_VERSION", "8");
11
- @cInclude("node_api.h");
12
- });
13
-
14
8
  export fn napi_register_module_v1(env: c.napi_env, exports: c.napi_value) c.napi_value {
15
9
  const properties = [_]c.napi_property_descriptor{
16
- js.Property.init("engine", .{ .value = register(env) }),
10
+ js.Property.init("engine", .{ .value = node.register(env) }),
17
11
  };
18
12
  assert(c.napi_define_properties(env, exports, properties.len, &properties) == c.napi_ok);
19
13
  return exports;
20
14
  }
21
-
22
- pub fn register(env: c.napi_env) c.napi_value {
23
- const object = js.Object.init(env);
24
- const properties = [_]c.napi_property_descriptor{
25
- js.Property.init("options", .{ .value = options(env) }),
26
- js.Property.init("bindings", .{ .value = bindings(env) }),
27
- };
28
- assert(c.napi_define_properties(env, object, properties.len, &properties) == c.napi_ok);
29
- return object;
30
- }
31
-
32
- fn options(env: c.napi_env) c.napi_value {
33
- const object = js.Object.init(env);
34
- const properties = [_]c.napi_property_descriptor{
35
- js.Property.init("showdown", .{ .value = js.Boolean.init(env, pkmn.options.showdown) }),
36
- js.Property.init("log", .{ .value = js.Boolean.init(env, pkmn.options.log) }),
37
- js.Property.init("chance", .{ .value = js.Boolean.init(env, pkmn.options.chance) }),
38
- js.Property.init("calc", .{ .value = js.Boolean.init(env, pkmn.options.calc) }),
39
- };
40
- assert(c.napi_define_properties(env, object, properties.len, &properties) == c.napi_ok);
41
- return object;
42
- }
43
-
44
- fn bindings(env: c.napi_env) c.napi_value {
45
- const array = js.Array.init(env, .{ .length = 1 });
46
- js.Array.set(env, array, 0, bind(env, pkmn.gen1));
47
- return array;
48
- }
49
-
50
- fn bind(env: c.napi_env, gen: anytype) c.napi_value {
51
- const choices_size: u32 = @intCast(gen.CHOICES_SIZE);
52
- const logs_size: u32 = @intCast(gen.LOGS_SIZE);
53
- const object = js.Object.init(env);
54
- const properties = [_]c.napi_property_descriptor{
55
- js.Property.init("CHOICES_SIZE", .{ .value = js.Number.init(env, choices_size) }),
56
- js.Property.init("LOGS_SIZE", .{ .value = js.Number.init(env, logs_size) }),
57
- js.Property.init("update", .{ .method = update(gen) }),
58
- js.Property.init("choices", .{ .method = choices(gen) }),
59
- };
60
- assert(c.napi_define_properties(env, object, properties.len, &properties) == c.napi_ok);
61
- return object;
62
- }
63
-
64
- fn update(gen: anytype) c.napi_callback {
65
- return struct {
66
- fn call(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
67
- var argc: usize = 4;
68
- var argv: [4]c.napi_value = undefined;
69
- assert(c.napi_get_cb_info(env, info, &argc, &argv, null, null) == c.napi_ok);
70
- assert(argc == 4);
71
-
72
- var data: ?*anyopaque = undefined;
73
- var len: usize = 0;
74
- assert(c.napi_get_arraybuffer_info(env, argv[0], &data, &len) == c.napi_ok);
75
- assert(len == @sizeOf(gen.Battle(gen.PRNG)));
76
-
77
- var battle: *gen.Battle(gen.PRNG) = @alignCast(@ptrCast(data.?));
78
- const c1: pkmn.Choice = @bitCast(js.Number.get(env, argv[1], u8));
79
- const c2: pkmn.Choice = @bitCast(js.Number.get(env, argv[2], u8));
80
-
81
- var vtype: c.napi_valuetype = undefined;
82
- assert(c.napi_typeof(env, argv[3], &vtype) == c.napi_ok);
83
- const result = switch (vtype) {
84
- c.napi_undefined, c.napi_null => battle.update(c1, c2, &gen.NULL),
85
- else => result: {
86
- assert(c.napi_get_arraybuffer_info(env, argv[3], &data, &len) == c.napi_ok);
87
- assert(len == gen.LOGS_SIZE);
88
-
89
- const buf = @as([*]u8, @ptrCast(data.?))[0..gen.LOGS_SIZE];
90
- var stream: pkmn.protocol.ByteStream = .{ .buffer = buf };
91
- // TODO: extract out
92
- var opts = pkmn.battle.options(
93
- pkmn.protocol.FixedLog{ .writer = stream.writer() },
94
- gen.chance.NULL,
95
- gen.calc.NULL,
96
- );
97
- break :result battle.update(c1, c2, &opts);
98
- },
99
- } catch unreachable;
100
-
101
- return js.Number.init(env, @as(u8, @bitCast(result)));
102
- }
103
- }.call;
104
- }
105
-
106
- fn choices(gen: anytype) c.napi_callback {
107
- return struct {
108
- fn call(env: c.napi_env, info: c.napi_callback_info) callconv(.C) c.napi_value {
109
- var argc: usize = 4;
110
- var argv: [4]c.napi_value = undefined;
111
- assert(c.napi_get_cb_info(env, info, &argc, &argv, null, null) == c.napi_ok);
112
- assert(argc == 4);
113
-
114
- var data: ?*anyopaque = undefined;
115
- var len: usize = 0;
116
- assert(c.napi_get_arraybuffer_info(env, argv[0], &data, &len) == c.napi_ok);
117
- assert(len == @sizeOf(gen.Battle(gen.PRNG)));
118
-
119
- var battle: *gen.Battle(gen.PRNG) = @alignCast(@ptrCast(data.?));
120
- const player: pkmn.Player = @enumFromInt(js.Number.get(env, argv[1], u8));
121
- const request: pkmn.Choice.Type = @enumFromInt(js.Number.get(env, argv[2], u8));
122
-
123
- assert(c.napi_get_arraybuffer_info(env, argv[3], &data, &len) == c.napi_ok);
124
- assert(len == gen.CHOICES_SIZE);
125
-
126
- const out = @as([*]pkmn.Choice, @ptrCast(data.?))[0..gen.CHOICES_SIZE];
127
- const n = battle.choices(player, request, out);
128
- return js.Number.init(env, @as(u8, @bitCast(n)));
129
- }
130
- }.call;
131
- }
package/src/lib/pkmn.zig CHANGED
@@ -96,6 +96,10 @@ pub const gen1 = struct {
96
96
  /// though damage calculator support should additionally be turned off
97
97
  /// entirely via `options.calc`.
98
98
  pub const NULL = @import("gen1/calc.zig").NULL;
99
+ /// TODO
100
+ pub const MAX_FRONTIER = @import("gen1/calc.zig").MAX_FRONTIER;
101
+ /// TODO
102
+ pub const Rolls = @import("gen1/calc.zig").Rolls;
99
103
  };
100
104
  /// Provides helpers for initializing Generation I Pokémon battles.
101
105
  pub const helpers = @import("gen1/helpers.zig");
@@ -125,6 +129,7 @@ pub const gen2 = struct {
125
129
  // NOTE: `pub usingnamespace struct { ... }` here results in a (false?) dependency loop
126
130
  pub const js = if (options.internal) @import("common/js.zig") else {};
127
131
  pub const bindings = if (options.internal) struct {
128
- pub const node = @import("node.zig");
129
- pub const wasm = @import("wasm.zig");
132
+ pub const c = @import("bindings/c.zig");
133
+ pub const node = @import("bindings/node.zig");
134
+ pub const wasm = @import("bindings/wasm.zig");
130
135
  } else {};
package/src/lib/wasm.zig CHANGED
@@ -1,13 +1,17 @@
1
1
  const std = @import("std");
2
+ const wasm = @import("bindings/wasm.zig");
2
3
 
3
- const pkmn = @import("pkmn.zig");
4
+ export const SHOWDOWN = wasm.options.showdown;
5
+ export const LOG = wasm.options.log;
6
+ export const CHANCE = wasm.options.chance;
7
+ export const CALC = wasm.options.calc;
4
8
 
5
- export const SHOWDOWN = pkmn.options.showdown;
6
- export const LOG = pkmn.options.log;
7
- export const CHANCE = pkmn.options.chance;
8
- export const CALC = pkmn.options.calc;
9
+ export const GEN1_CHOICES_SIZE = wasm.gen(1).CHOICES_SIZE;
10
+ export const GEN1_LOGS_SIZE = wasm.gen(1).LOGS_SIZE;
9
11
 
10
- export const GEN1_CHOICES_SIZE =
11
- std.math.ceilPowerOfTwo(u32, @as(u32, @intCast(pkmn.gen1.CHOICES_SIZE))) catch unreachable;
12
- export const GEN1_LOGS_SIZE =
13
- std.math.ceilPowerOfTwo(u32, @as(u32, @intCast(pkmn.gen1.LOGS_SIZE))) catch unreachable;
12
+ const exportable = @hasDecl(std.zig, "Zir") and !@hasField(std.zig.Zir.Inst.Tag, "export_value");
13
+
14
+ usingnamespace if (exportable) struct {
15
+ export const GEN1_update = wasm.gen(1).update;
16
+ export const GEN1_choices = wasm.gen(1).choices;
17
+ } else wasm.exports();
@@ -1,6 +1,6 @@
1
1
  /** @license MIT modified from Vadim Demedes's https://github.com/vadimdemedes/dom-chef */
2
2
  type Attributes = JSX.IntrinsicElements['div'];
3
- type DocumentFragmentConstructor = typeof DocumentFragment;
3
+ type DocumentFragmentFunction = (props?: any) => DocumentFragment;
4
4
  type ElementFunction = (props?: any) => HTMLElement;
5
5
 
6
6
  declare global {
@@ -22,9 +22,6 @@ interface Fragment {
22
22
  // https://github.com/preactjs/preact/blob/1bbd687c/src/constants.js#L3
23
23
  const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
24
24
 
25
- const isFragment = (type: DocumentFragmentConstructor | ElementFunction):
26
- type is DocumentFragmentConstructor => type === DocumentFragment;
27
-
28
25
  const setCSSProps = (element: HTMLElement, style: CSSStyleDeclaration) => {
29
26
  for (const [name, value] of Object.entries(style)) {
30
27
  if (name.startsWith('-')) {
@@ -57,12 +54,12 @@ const addChildren = (parent: Element | DocumentFragment, children: Node[]) => {
57
54
  const FALSIFIABLE_ATTRIBUTES = ['contentEditable', 'draggable', 'spellCheck', 'value'];
58
55
 
59
56
  export const h = (
60
- type: DocumentFragmentConstructor | ElementFunction | string,
57
+ type: DocumentFragmentFunction | ElementFunction | string,
61
58
  attributes?: Attributes,
62
59
  ...children: Node[]
63
60
  ) => {
64
61
  if (typeof type !== 'string') {
65
- const element = isFragment(type) ? document.createDocumentFragment() : type(attributes);
62
+ const element = type(attributes);
66
63
  addChildren(element, children);
67
64
  return element;
68
65
  }
@@ -92,5 +89,5 @@ export const h = (
92
89
  return element;
93
90
  };
94
91
 
95
- export const Fragment =
96
- (typeof DocumentFragment === 'function' ? DocumentFragment : () => {}) as Fragment;
92
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
93
+ export const Fragment = (unused: any) => document.createDocumentFragment();
@@ -250,11 +250,6 @@ th, td {
250
250
  .disabled {
251
251
  color: #AAAAAA;
252
252
  }
253
- .log {
254
- display: flex;
255
- justify-content: center;
256
- padding-bottom: 2em;
257
- }
258
253
  .position {
259
254
  position: absolute;
260
255
  right: 10px;