@zigc/lib 0.17.0-dev.314 → 0.17.0-dev.329

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.
@@ -45,11 +45,11 @@ const IfContext = struct {
45
45
  level: u8,
46
46
 
47
47
  fn get(self: *const IfContext) Nesting {
48
- return @enumFromInt(std.mem.readPackedIntNative(Backing, &self.kind, @as(usize, self.level) * 2));
48
+ return @enumFromInt(std.mem.readPackedInt(Backing, &self.kind, @as(usize, self.level) * 2, .native));
49
49
  }
50
50
 
51
51
  fn set(self: *IfContext, context: Nesting) void {
52
- std.mem.writePackedIntNative(Backing, &self.kind, @as(usize, self.level) * 2, @intFromEnum(context));
52
+ std.mem.writePackedInt(Backing, &self.kind, @as(usize, self.level) * 2, @intFromEnum(context), .native);
53
53
  }
54
54
 
55
55
  fn increment(self: *IfContext) bool {
@@ -21,17 +21,17 @@ const RegisterManager = zig.RegisterManager(Renderer, Register, Ir.Ref, abi.allo
21
21
  const RegisterBitSet = RegisterManager.RegisterBitSet;
22
22
  const RegisterClass = struct {
23
23
  const gp: RegisterBitSet = blk: {
24
- var set = RegisterBitSet.initEmpty();
24
+ var set: RegisterBitSet = .empty;
25
25
  for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index);
26
26
  break :blk set;
27
27
  };
28
28
  const x87: RegisterBitSet = blk: {
29
- var set = RegisterBitSet.initEmpty();
29
+ var set: RegisterBitSet = .empty;
30
30
  for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index);
31
31
  break :blk set;
32
32
  };
33
33
  const sse: RegisterBitSet = blk: {
34
- var set = RegisterBitSet.initEmpty();
34
+ var set: RegisterBitSet = .empty;
35
35
  for (abi.allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index);
36
36
  break :blk set;
37
37
  };
@@ -97,7 +97,7 @@ pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin
97
97
  if (limb(x, limb_index) != 0) break true;
98
98
  } else limb(x, exponent_limb) & ((@as(u32, 1) << @truncate(exponent)) - 1) != 0;
99
99
  return math.ldexp(@as(T, @floatFromInt(
100
- std.mem.readPackedIntNative(I, std.mem.sliceAsBytes(x), exponent) | @intFromBool(sticky),
100
+ std.mem.readPackedInt(I, std.mem.sliceAsBytes(x), exponent, .native) | @intFromBool(sticky),
101
101
  )), @intCast(exponent));
102
102
  }
103
103
 
@@ -141,7 +141,7 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul
141
141
  },
142
142
  .unsigned => @memset(result, 0),
143
143
  }
144
- std.mem.writePackedIntNative(I, std.mem.sliceAsBytes(result), exponent, int);
144
+ std.mem.writePackedInt(I, std.mem.sliceAsBytes(result), exponent, int, .native);
145
145
  }
146
146
 
147
147
  test {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zigc/lib",
3
- "version": "0.17.0-dev.314",
3
+ "version": "0.17.0-dev.329",
4
4
  "description": "Zig standard library and libc headers (shared across all platforms)",
5
5
  "repository": {
6
6
  "type": "git",
package/std/Io/Dir.zig CHANGED
@@ -1124,9 +1124,6 @@ pub const RenamePreserveError = error{
1124
1124
  ///
1125
1125
  /// If `new_sub_path` already exists, `error.PathAlreadyExists` will be returned.
1126
1126
  ///
1127
- /// Renaming a file over an existing directory or a directory over an existing
1128
- /// file will fail with `error.IsDir` or `error.NotDir`
1129
- ///
1130
1127
  /// * On Windows, both paths should be encoded as [WTF-8](https://wtf-8.codeberg.page/).
1131
1128
  /// * On WASI, both paths should be encoded as valid UTF-8.
1132
1129
  /// * On other platforms, both paths are an opaque sequence of bytes with no particular encoding.
package/std/Io/RwLock.zig CHANGED
@@ -284,6 +284,8 @@ test "concurrent access" {
284
284
  }
285
285
 
286
286
  test "lock canceling" {
287
+ if (builtin.cpu.arch.isSPARC() and builtin.os.tag == .linux) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35347
288
+
287
289
  const io = testing.io;
288
290
 
289
291
  var rl: Io.RwLock = .init;
@@ -14401,7 +14401,7 @@ pub fn setTimestampToPosix(set_ts: File.SetTimestamp) posix.timespec {
14401
14401
  }
14402
14402
 
14403
14403
  pub fn pathToPosix(file_path: []const u8, buffer: *[posix.PATH_MAX]u8) Dir.PathNameError![:0]u8 {
14404
- if (std.mem.containsAtLeastScalar2(u8, file_path, 0, 1)) return error.BadPathName;
14404
+ if (std.mem.containsAtLeastScalar(u8, file_path, 0, 1)) return error.BadPathName;
14405
14405
  // >= rather than > to make room for the null byte
14406
14406
  if (file_path.len >= buffer.len) return error.NameTooLong;
14407
14407
  @memcpy(buffer[0..file_path.len], file_path);
package/std/Io/Writer.zig CHANGED
@@ -802,12 +802,14 @@ pub fn splatBytePreserve(w: *Writer, preserve: usize, byte: u8, n: usize) Error!
802
802
  return;
803
803
  }
804
804
  }
805
- // All the next bytes received must be preserved.
806
- if (preserve < w.end) {
807
- @memmove(w.buffer[0..preserve], w.buffer[w.end - preserve ..][0..preserve]);
808
- w.end = preserve;
809
- }
810
- while (remaining > 0) remaining -= try w.splatByte(byte, remaining);
805
+ // Ensure the contract of `rebase` is upheld.
806
+ assert(w.end + remaining > w.buffer.len);
807
+ // Offset the amount preserved by the amount we have left to splat
808
+ // since the remaining splat is always going to be part of that
809
+ // preservation.
810
+ try w.vtable.rebase(w, preserve -| remaining, remaining);
811
+ @memset(w.buffer[w.end..][0..remaining], byte);
812
+ w.end += remaining;
811
813
  }
812
814
 
813
815
  /// Writes the same byte many times, allowing short writes.
@@ -2887,3 +2889,46 @@ test "writableSlice with fixed writer" {
2887
2889
  try w.writeByte(1);
2888
2890
  try std.testing.expectError(error.WriteFailed, w.writableSlice(2));
2889
2891
  }
2892
+
2893
+ test splatBytePreserve {
2894
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .splat_len = 5 });
2895
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 9, .preserve = 5, .splat_len = 2 });
2896
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .splat_len = 6 });
2897
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 6 });
2898
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 5, .splat_len = 10 });
2899
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 10 });
2900
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 11 });
2901
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 80 });
2902
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 6, .splat_len = 85 });
2903
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .splat_len = 6 });
2904
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .splat_len = 11 });
2905
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .splat_len = 80 });
2906
+ try testSplatBytePreserve(.{ .buf_len = 10, .fill_len = 5, .preserve = 10, .splat_len = 85 });
2907
+ }
2908
+
2909
+ fn testSplatBytePreserve(options: struct { buf_len: u4, fill_len: u4, preserve: u4, splat_len: u8 }) !void {
2910
+ assert(options.fill_len <= options.buf_len);
2911
+ assert(options.preserve <= options.buf_len);
2912
+
2913
+ const fill_buf = "abcdefghijklmno";
2914
+ const fill = fill_buf[0..options.fill_len];
2915
+ var expected_out_buf: [256]u8 = @splat('X');
2916
+ @memcpy(expected_out_buf[0..options.fill_len], fill);
2917
+ const expected_out = expected_out_buf[0 .. options.fill_len + options.splat_len];
2918
+ const expected_preserved = expected_out[expected_out.len -| options.preserve..];
2919
+
2920
+ var out_buf: [256]u8 = undefined;
2921
+ var fw: Writer = .fixed(&out_buf);
2922
+ var indirect_buffer: [16]u8 = undefined;
2923
+ var twi: std.testing.WriterIndirect = .init(&fw, indirect_buffer[0..options.buf_len]);
2924
+ const w = &twi.interface;
2925
+
2926
+ try w.writeAll(fill);
2927
+ try w.splatBytePreserve(options.preserve, 'X', options.splat_len);
2928
+
2929
+ try std.testing.expectEqualStrings(expected_preserved, w.buffer[w.end -| options.preserve..w.end]);
2930
+
2931
+ try w.flush();
2932
+
2933
+ try std.testing.expectEqualStrings(expected_out, fw.buffer[0..fw.end]);
2934
+ }
package/std/ascii.zig CHANGED
@@ -378,17 +378,11 @@ test endsWithIgnoreCase {
378
378
  try std.testing.expect(!endsWithIgnoreCase("BoB", "Bo"));
379
379
  }
380
380
 
381
- /// Deprecated in favor of `findIgnoreCase`.
382
- pub const indexOfIgnoreCase = findIgnoreCase;
383
-
384
381
  /// Finds `needle` in `haystack`, ignoring case, starting at index 0.
385
382
  pub fn findIgnoreCase(haystack: []const u8, needle: []const u8) ?usize {
386
383
  return findIgnoreCasePos(haystack, 0, needle);
387
384
  }
388
385
 
389
- /// Deprecated in favor of `findIgnoreCasePos`.
390
- pub const indexOfIgnoreCasePos = findIgnoreCasePos;
391
-
392
386
  /// Finds `needle` in `haystack`, ignoring case, starting at `start_index`.
393
387
  /// Uses Boyer-Moore-Horspool algorithm on large inputs; `findIgnoreCasePosLinear` on small inputs.
394
388
  pub fn findIgnoreCasePos(haystack: []const u8, start_index: usize, needle: []const u8) ?usize {
@@ -410,9 +404,6 @@ pub fn findIgnoreCasePos(haystack: []const u8, start_index: usize, needle: []con
410
404
  return null;
411
405
  }
412
406
 
413
- /// Deprecated in favor of `findIgnoreCaseLinear`.
414
- pub const indexOfIgnoreCasePosLinear = findIgnoreCasePosLinear;
415
-
416
407
  /// Consider using `findIgnoreCasePos` instead of this, which will automatically use a
417
408
  /// more sophisticated algorithm on larger inputs.
418
409
  pub fn findIgnoreCasePosLinear(haystack: []const u8, start_index: usize, needle: []const u8) ?usize {
package/std/bit_set.zig CHANGED
@@ -73,18 +73,6 @@ pub fn Integer(comptime size: u16) type {
73
73
  /// The bit mask, as a single integer
74
74
  mask: MaskInt,
75
75
 
76
- /// Deprecated: use `.empty`.
77
- /// Creates a bit set with no elements present.
78
- pub fn initEmpty() Self {
79
- return .{ .mask = 0 };
80
- }
81
-
82
- /// Deprecated: use `.full`.
83
- /// Creates a bit set with all elements present.
84
- pub fn initFull() Self {
85
- return .{ .mask = ~@as(MaskInt, 0) };
86
- }
87
-
88
76
  /// A bit set with no elements present.
89
77
  pub const empty: Self = .{ .mask = 0 };
90
78
 
@@ -403,18 +391,6 @@ pub fn Array(comptime MaskIntType: type, comptime size: usize) type {
403
391
  /// Padding bits at the end are undefined.
404
392
  masks: [num_masks]MaskInt,
405
393
 
406
- /// Deprecated: use `.empty`.
407
- /// Creates a bit set with no elements present.
408
- pub fn initEmpty() Self {
409
- return .empty;
410
- }
411
-
412
- /// Deprecated: use `.full`.
413
- /// Creates a bit set with all elements present.
414
- pub fn initFull() Self {
415
- return .full;
416
- }
417
-
418
394
  /// A bit set with no elements present.
419
395
  pub const empty: Self = .{ .masks = @splat(0) };
420
396
 
package/std/enums.zig CHANGED
@@ -284,18 +284,6 @@ pub fn EnumSet(comptime E: type) type {
284
284
  /// A set containing all possible keys.
285
285
  pub const full: Self = .{ .bits = .full };
286
286
 
287
- /// Deprecated: use `.empty`.
288
- /// Returns a set containing no keys.
289
- pub fn initEmpty() Self {
290
- return .empty;
291
- }
292
-
293
- /// Deprecated: use `.full`.
294
- /// Returns a set containing all possible keys.
295
- pub fn initFull() Self {
296
- return .full;
297
- }
298
-
299
287
  /// Returns a set containing multiple keys.
300
288
  pub fn initMany(keys: []const Key) Self {
301
289
  var set: Self = .empty;
package/std/math/acos.zig CHANGED
@@ -448,6 +448,8 @@ test "acosBinary128.special" {
448
448
  }
449
449
 
450
450
  test "acosBinary128" {
451
+ if (builtin.cpu.arch.isSPARC()) return error.SkipZigTest;
452
+
451
453
  try testing.expectApproxEqAbs(0x1.250e9a58f049eeafa99db4360c88p1, acosBinary128(-0x1.511bdb99a3c4373bedf834ef4f68p-1), math.floatEpsAt(f128, 0x1.250e9a58f049eeafa99db4360c88p1));
452
454
  try testing.expectApproxEqAbs(0x1.2786664b1c676c99437b68590004p1, acosBinary128(-0x1.5879cc3ad6dfd2a52e9891c69808p-1), math.floatEpsAt(f128, 0x1.2786664b1c676c99437b68590004p1));
453
455
  try testing.expectApproxEqAbs(0x1.cb190cd361c7c03a09c470b4caebp-1, acosBinary128(0x1.3f988ba64a7eb97a751c5f0b3077p-1), math.floatEpsAt(f128, 0x1.cb190cd361c7c03a09c470b4caebp-1));
package/std/math/asin.zig CHANGED
@@ -442,6 +442,8 @@ test "asinBinary128.special" {
442
442
  }
443
443
 
444
444
  test "asinBinary128" {
445
+ if (builtin.cpu.arch.isSPARC()) return error.SkipZigTest;
446
+
445
447
  try testing.expectApproxEqAbs(0x1.87e9c740d7837f8e8fa667988fbep-3, asinBinary128(0x1.85868ce287ca0196b01c25fec5ffp-3), math.floatEpsAt(f128, 0x1.87e9c740d7837f8e8fa667988fbep-3));
446
448
  try testing.expectApproxEqAbs(0x1.bd11a474e864213b48e0f005f1f4p-1, asinBinary128(0x1.8718d6d30b4daed08d04ef59f478p-1), math.floatEpsAt(f128, 0x1.bd11a474e864213b48e0f005f1f4p-1));
447
449
  try testing.expectApproxEqAbs(0x1.20b56f8b42649fe72d1f8d68a378p-1, asinBinary128(0x1.11a67640cd7f0ba5d5e362f3abfap-1), math.floatEpsAt(f128, 0x1.20b56f8b42649fe72d1f8d68a378p-1));
package/std/mem.zig CHANGED
@@ -1691,7 +1691,7 @@ test countScalar {
1691
1691
  //
1692
1692
  /// See also: `containsAtLeastScalar`
1693
1693
  pub fn containsAtLeast(comptime T: type, haystack: []const T, expected_count: usize, needle: []const T) bool {
1694
- if (needle.len == 1) return containsAtLeastScalar(T, haystack, expected_count, needle[0]);
1694
+ if (needle.len == 1) return containsAtLeastScalar(T, haystack, needle[0], expected_count);
1695
1695
  assert(needle.len > 0);
1696
1696
  if (expected_count == 0) return true;
1697
1697
 
@@ -1722,17 +1722,12 @@ test containsAtLeast {
1722
1722
  try testing.expect(!containsAtLeast(u8, " radar radar ", 3, "radar"));
1723
1723
  }
1724
1724
 
1725
- /// Deprecated in favor of `containsAtLeastScalar2`.
1726
- pub fn containsAtLeastScalar(comptime T: type, list: []const T, minimum: usize, element: T) bool {
1727
- return containsAtLeastScalar2(T, list, element, minimum);
1728
- }
1729
-
1730
1725
  /// Returns true if `element` appears at least `minimum` number of times in `list`.
1731
1726
  //
1732
1727
  /// Related:
1733
1728
  /// * `containsAtLeast`
1734
1729
  /// * `countScalar`
1735
- pub fn containsAtLeastScalar2(comptime T: type, list: []const T, element: T, minimum: usize) bool {
1730
+ pub fn containsAtLeastScalar(comptime T: type, list: []const T, element: T, minimum: usize) bool {
1736
1731
  const n = list.len;
1737
1732
  var i: usize = 0;
1738
1733
  var found: usize = 0;
@@ -1760,14 +1755,14 @@ pub fn containsAtLeastScalar2(comptime T: type, list: []const T, element: T, min
1760
1755
  return false;
1761
1756
  }
1762
1757
 
1763
- test containsAtLeastScalar2 {
1764
- try testing.expect(containsAtLeastScalar2(u8, "aa", 'a', 0));
1765
- try testing.expect(containsAtLeastScalar2(u8, "aa", 'a', 1));
1766
- try testing.expect(containsAtLeastScalar2(u8, "aa", 'a', 2));
1767
- try testing.expect(!containsAtLeastScalar2(u8, "aa", 'a', 3));
1758
+ test containsAtLeastScalar {
1759
+ try testing.expect(containsAtLeastScalar(u8, "aa", 'a', 0));
1760
+ try testing.expect(containsAtLeastScalar(u8, "aa", 'a', 1));
1761
+ try testing.expect(containsAtLeastScalar(u8, "aa", 'a', 2));
1762
+ try testing.expect(!containsAtLeastScalar(u8, "aa", 'a', 3));
1768
1763
 
1769
- try testing.expect(containsAtLeastScalar2(u8, "adadda", 'd', 3));
1770
- try testing.expect(!containsAtLeastScalar2(u8, "adadda", 'd', 4));
1764
+ try testing.expect(containsAtLeastScalar(u8, "adadda", 'd', 3));
1765
+ try testing.expect(!containsAtLeastScalar(u8, "adadda", 'd', 4));
1771
1766
  }
1772
1767
 
1773
1768
  /// Reads an integer from memory with size equal to bytes.len.
@@ -1973,18 +1968,6 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T {
1973
1968
  } else return @as(T, @bitCast(val));
1974
1969
  }
1975
1970
 
1976
- /// Deprecated: use readPackedInt(T, bytes, bit_offset, value, .native)
1977
- pub const readPackedIntNative = switch (native_endian) {
1978
- .little => readPackedIntLittle,
1979
- .big => readPackedIntBig,
1980
- };
1981
-
1982
- /// Deprecated: use readPackedInt(T, bytes, bit_offset, value, .foreign)
1983
- pub const readPackedIntForeign = switch (native_endian) {
1984
- .little => readPackedIntBig,
1985
- .big => readPackedIntLittle,
1986
- };
1987
-
1988
1971
  /// Loads an integer from packed memory.
1989
1972
  /// Asserts that buffer contains at least bit_offset + @bitSizeOf(T) bits.
1990
1973
  pub fn readPackedInt(comptime T: type, bytes: []const u8, bit_offset: usize, endian: Endian) T {
@@ -2128,18 +2111,6 @@ fn writePackedIntBig(comptime T: type, bytes: []u8, bit_offset: usize, value: T)
2128
2111
  writeInt(StoreInt, write_bytes[(byte_count - store_size)..][0..store_size], write_value, .big);
2129
2112
  }
2130
2113
 
2131
- /// Deprecated: use writePackedInt(T, bytes, bit_offset, value, .native)
2132
- pub const writePackedIntNative = switch (native_endian) {
2133
- .little => writePackedIntLittle,
2134
- .big => writePackedIntBig,
2135
- };
2136
-
2137
- /// Deprecated: use writePackedInt(T, bytes, bit_offset, value, .foreign)
2138
- pub const writePackedIntForeign = switch (native_endian) {
2139
- .little => writePackedIntBig,
2140
- .big => writePackedIntLittle,
2141
- };
2142
-
2143
2114
  /// Stores an integer to packed memory.
2144
2115
  /// Asserts that buffer contains at least bit_offset + @bitSizeOf(T) bits.
2145
2116
  pub fn writePackedInt(comptime T: type, bytes: []u8, bit_offset: usize, value: T, endian: Endian) void {
package/std/testing.zig CHANGED
@@ -1334,6 +1334,67 @@ pub const ReaderIndirect = struct {
1334
1334
  }
1335
1335
  };
1336
1336
 
1337
+ /// A `Io.Writer` that writes its data to another `Io.Writer`, and only
1338
+ /// writes new data to its own buffer during `drain`.
1339
+ pub const WriterIndirect = struct {
1340
+ out: *Io.Writer,
1341
+ interface: Io.Writer,
1342
+
1343
+ pub fn init(out: *Io.Writer, buffer: []u8) WriterIndirect {
1344
+ return .{
1345
+ .out = out,
1346
+ .interface = .{
1347
+ .vtable = &.{
1348
+ .drain = drain,
1349
+ },
1350
+ .buffer = buffer,
1351
+ .end = 0,
1352
+ },
1353
+ };
1354
+ }
1355
+
1356
+ fn drain(w: *Io.Writer, data: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
1357
+ const w_indirect: *WriterIndirect = @alignCast(@fieldParentPtr("interface", w));
1358
+
1359
+ // Write all data in the buffer to `out`
1360
+ try w_indirect.out.writeAll(w.buffer[0..w.end]);
1361
+ w.end = 0;
1362
+
1363
+ // Refill buffer using data
1364
+ {
1365
+ const end_before_fill = w.end;
1366
+ for (data[0 .. data.len - 1]) |bytes| {
1367
+ const dest = w.buffer[w.end..];
1368
+ const len = @min(bytes.len, dest.len);
1369
+ @memcpy(dest[0..len], bytes[0..len]);
1370
+ w.end += len;
1371
+ }
1372
+ const pattern = data[data.len - 1];
1373
+ switch (pattern.len) {
1374
+ 0 => {},
1375
+ 1 => {
1376
+ const len = @min(w.buffer[w.end..].len, splat);
1377
+ @memset(w.buffer[w.end..][0..len], pattern[0]);
1378
+ w.end += len;
1379
+ },
1380
+ else => {
1381
+ const dest = w.buffer[w.end..];
1382
+ for (0..splat) |i| {
1383
+ const start_i = i * pattern.len;
1384
+ if (start_i >= dest.len) break;
1385
+ const remaining = dest[start_i..];
1386
+ const len = @min(pattern.len, remaining.len);
1387
+ @memcpy(remaining[0..len], pattern[0..len]);
1388
+ w.end += len;
1389
+ }
1390
+ },
1391
+ }
1392
+
1393
+ return w.end - end_before_fill;
1394
+ }
1395
+ }
1396
+ };
1397
+
1337
1398
  test {
1338
1399
  _ = &Smith;
1339
1400
  }