zig_example 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/mkmf.rb +2734 -0
- data/ext/openssl/openssl_missing.c +40 -0
- data/ext/openssl/openssl_missing.h +238 -0
- data/ext/openssl/ossl.c +1295 -0
- data/ext/openssl/ossl.h +201 -0
- data/ext/openssl/ossl_asn1.c +1891 -0
- data/ext/openssl/ossl_asn1.h +62 -0
- data/ext/openssl/ossl_bio.c +42 -0
- data/ext/openssl/ossl_bio.h +16 -0
- data/ext/openssl/ossl_bn.c +1344 -0
- data/ext/openssl/ossl_bn.h +26 -0
- data/ext/openssl/ossl_cipher.c +1074 -0
- data/ext/openssl/ossl_cipher.h +20 -0
- data/ext/openssl/ossl_config.c +460 -0
- data/ext/openssl/ossl_config.h +16 -0
- data/ext/openssl/ossl_digest.c +425 -0
- data/ext/openssl/ossl_digest.h +20 -0
- data/ext/openssl/ossl_engine.c +568 -0
- data/ext/openssl/ossl_engine.h +19 -0
- data/ext/openssl/ossl_hmac.c +310 -0
- data/ext/openssl/ossl_hmac.h +18 -0
- data/ext/openssl/ossl_kdf.c +311 -0
- data/ext/openssl/ossl_kdf.h +6 -0
- data/ext/openssl/ossl_ns_spki.c +405 -0
- data/ext/openssl/ossl_ns_spki.h +19 -0
- data/ext/openssl/ossl_ocsp.c +1965 -0
- data/ext/openssl/ossl_ocsp.h +23 -0
- data/ext/openssl/ossl_pkcs12.c +275 -0
- data/ext/openssl/ossl_pkcs12.h +13 -0
- data/ext/openssl/ossl_pkcs7.c +1081 -0
- data/ext/openssl/ossl_pkcs7.h +36 -0
- data/ext/openssl/ossl_pkey.c +1624 -0
- data/ext/openssl/ossl_pkey.h +204 -0
- data/ext/openssl/ossl_pkey_dh.c +440 -0
- data/ext/openssl/ossl_pkey_dsa.c +359 -0
- data/ext/openssl/ossl_pkey_ec.c +1655 -0
- data/ext/openssl/ossl_pkey_rsa.c +579 -0
- data/ext/openssl/ossl_rand.c +200 -0
- data/ext/openssl/ossl_rand.h +18 -0
- data/ext/openssl/ossl_ssl.c +3142 -0
- data/ext/openssl/ossl_ssl.h +36 -0
- data/ext/openssl/ossl_ssl_session.c +331 -0
- data/ext/openssl/ossl_ts.c +1539 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +256 -0
- data/ext/openssl/ossl_x509.h +115 -0
- data/ext/openssl/ossl_x509attr.c +324 -0
- data/ext/openssl/ossl_x509cert.c +1002 -0
- data/ext/openssl/ossl_x509crl.c +545 -0
- data/ext/openssl/ossl_x509ext.c +490 -0
- data/ext/openssl/ossl_x509name.c +597 -0
- data/ext/openssl/ossl_x509req.c +444 -0
- data/ext/openssl/ossl_x509revoked.c +300 -0
- data/ext/openssl/ossl_x509store.c +986 -0
- data/ext/zigrb_100doors/build.zig +0 -12
- data/ext/zigrb_100doors/extconf.rb +2 -19
- data/ext/zigrb_ackermann/build.zig +0 -12
- data/ext/zigrb_ackermann/extconf.rb +2 -19
- data/ext/zigrb_lucas_lehmer/build.zig +53 -0
- data/ext/zigrb_lucas_lehmer/extconf.rb +3 -0
- data/ext/zigrb_lucas_lehmer/src/lucas_lehmer.c +60 -0
- data/ext/zigrb_lucas_lehmer/src/lucas_lehmer.h +1 -0
- data/ext/zigrb_lucas_lehmer/src/wrapper.zig +42 -0
- data/lib/zig_example/version.rb +1 -1
- data/lib/zig_example.rb +1 -0
- metadata +63 -3
@@ -4,10 +4,6 @@ pub fn build(b: *std.Build) void {
|
|
4
4
|
const optimize = b.standardOptimizeOption(.{});
|
5
5
|
const target = b.standardTargetOptions(.{});
|
6
6
|
|
7
|
-
var rubylibdir = std.os.getenv("RUBYLIBDIR") orelse "";
|
8
|
-
var rubyhdrdir = std.os.getenv("RUBYHDRDIR") orelse "";
|
9
|
-
var rubyarchhdrdir = std.os.getenv("RUBYARCHHDRDIR") orelse "";
|
10
|
-
|
11
7
|
////////////////////////////////////////////////////////////////
|
12
8
|
// lib
|
13
9
|
|
@@ -18,10 +14,6 @@ pub fn build(b: *std.Build) void {
|
|
18
14
|
.optimize = optimize,
|
19
15
|
});
|
20
16
|
|
21
|
-
lib.addLibraryPath(rubylibdir);
|
22
|
-
lib.addIncludePath(rubyhdrdir);
|
23
|
-
lib.addIncludePath(rubyarchhdrdir);
|
24
|
-
|
25
17
|
lib.linkSystemLibrary("ruby");
|
26
18
|
lib.linkSystemLibrary("c");
|
27
19
|
|
@@ -36,10 +28,6 @@ pub fn build(b: *std.Build) void {
|
|
36
28
|
.optimize = optimize,
|
37
29
|
});
|
38
30
|
|
39
|
-
unit_tests.addLibraryPath(rubylibdir);
|
40
|
-
unit_tests.addIncludePath(rubyhdrdir);
|
41
|
-
unit_tests.addIncludePath(rubyarchhdrdir);
|
42
|
-
|
43
31
|
unit_tests.linkSystemLibrary("ruby");
|
44
32
|
unit_tests.linkSystemLibrary("c");
|
45
33
|
|
@@ -1,20 +1,3 @@
|
|
1
|
-
|
1
|
+
require_relative '../mkmf'
|
2
2
|
|
3
|
-
|
4
|
-
$srcs = ['']
|
5
|
-
TARGET = 'libzigrb_100doors'
|
6
|
-
|
7
|
-
create_makefile TARGET
|
8
|
-
File.open('Makefile', 'a') do |f|
|
9
|
-
f.puts <<~MFILE
|
10
|
-
|
11
|
-
clean: clean-zig
|
12
|
-
clean-zig:
|
13
|
-
\t-$(Q)$(RM) -rf zig-cache zig-out
|
14
|
-
|
15
|
-
#{TARGET}.so: Makefile build.zig src/main.zig
|
16
|
-
\tenv -u DESTDIR RUBYLIBDIR=$(rubylibdir) RUBYHDRDIR=$(rubyhdrdir) RUBYARCHHDRDIR=$(rubyarchhdrdir) zig build test install
|
17
|
-
\tcp -v zig-out/lib/#{TARGET}.so .
|
18
|
-
|
19
|
-
MFILE
|
20
|
-
end
|
3
|
+
create_makefile 'libzigrb_100doors'
|
@@ -4,10 +4,6 @@ pub fn build(b: *std.Build) void {
|
|
4
4
|
const optimize = b.standardOptimizeOption(.{});
|
5
5
|
const target = b.standardTargetOptions(.{});
|
6
6
|
|
7
|
-
var rubylibdir = std.os.getenv("RUBYLIBDIR") orelse "";
|
8
|
-
var rubyhdrdir = std.os.getenv("RUBYHDRDIR") orelse "";
|
9
|
-
var rubyarchhdrdir = std.os.getenv("RUBYARCHHDRDIR") orelse "";
|
10
|
-
|
11
7
|
////////////////////////////////////////////////////////////////
|
12
8
|
// lib
|
13
9
|
|
@@ -18,10 +14,6 @@ pub fn build(b: *std.Build) void {
|
|
18
14
|
.optimize = optimize,
|
19
15
|
});
|
20
16
|
|
21
|
-
lib.addLibraryPath(rubylibdir);
|
22
|
-
lib.addIncludePath(rubyhdrdir);
|
23
|
-
lib.addIncludePath(rubyarchhdrdir);
|
24
|
-
|
25
17
|
lib.linkSystemLibrary("ruby");
|
26
18
|
lib.linkSystemLibrary("c");
|
27
19
|
|
@@ -36,10 +28,6 @@ pub fn build(b: *std.Build) void {
|
|
36
28
|
.optimize = optimize,
|
37
29
|
});
|
38
30
|
|
39
|
-
unit_tests.addLibraryPath(rubylibdir);
|
40
|
-
unit_tests.addIncludePath(rubyhdrdir);
|
41
|
-
unit_tests.addIncludePath(rubyarchhdrdir);
|
42
|
-
|
43
31
|
unit_tests.linkSystemLibrary("ruby");
|
44
32
|
unit_tests.linkSystemLibrary("c");
|
45
33
|
|
@@ -1,20 +1,3 @@
|
|
1
|
-
|
1
|
+
require_relative '../mkmf'
|
2
2
|
|
3
|
-
|
4
|
-
$srcs = ['']
|
5
|
-
TARGET = 'libzigrb_ackermann'
|
6
|
-
|
7
|
-
create_makefile TARGET
|
8
|
-
File.open('Makefile', 'a') do |f|
|
9
|
-
f.puts <<~MFILE
|
10
|
-
|
11
|
-
clean: clean-zig
|
12
|
-
clean-zig:
|
13
|
-
\t-$(Q)$(RM) -rf zig-cache zig-out
|
14
|
-
|
15
|
-
#{TARGET}.so: Makefile build.zig src/main.zig
|
16
|
-
\tenv -u DESTDIR RUBYLIBDIR=$(rubylibdir) RUBYHDRDIR=$(rubyhdrdir) RUBYARCHHDRDIR=$(rubyarchhdrdir) zig build test install
|
17
|
-
\tcp -v zig-out/lib/#{TARGET}.so .
|
18
|
-
|
19
|
-
MFILE
|
20
|
-
end
|
3
|
+
create_makefile 'libzigrb_ackermann'
|
@@ -0,0 +1,53 @@
|
|
1
|
+
const std = @import("std");
|
2
|
+
|
3
|
+
pub fn build(b: *std.Build) void {
|
4
|
+
const optimize = b.standardOptimizeOption(.{});
|
5
|
+
const target = b.standardTargetOptions(.{});
|
6
|
+
|
7
|
+
////////////////////////////////////////////////////////////////
|
8
|
+
// lib
|
9
|
+
|
10
|
+
const clib = b.addStaticLibrary(.{
|
11
|
+
.name = "zigrb_lucas_lehmer",
|
12
|
+
.root_source_file = .{ .path = "src/lucas_lehmer.c" },
|
13
|
+
.target = target,
|
14
|
+
.optimize = optimize,
|
15
|
+
});
|
16
|
+
clib.force_pic = true;
|
17
|
+
|
18
|
+
clib.linkSystemLibrary("gmp");
|
19
|
+
|
20
|
+
const lib = b.addSharedLibrary(.{
|
21
|
+
.name = "zigrb_lucas_lehmer",
|
22
|
+
.root_source_file = .{ .path = "src/wrapper.zig" },
|
23
|
+
.target = target,
|
24
|
+
.optimize = optimize,
|
25
|
+
});
|
26
|
+
|
27
|
+
lib.linkSystemLibrary("ruby");
|
28
|
+
lib.linkSystemLibrary("c");
|
29
|
+
|
30
|
+
lib.addIncludePath("src");
|
31
|
+
lib.linkLibrary(clib);
|
32
|
+
|
33
|
+
b.installArtifact(lib);
|
34
|
+
|
35
|
+
////////////////////////////////////////////////////////////////
|
36
|
+
// test
|
37
|
+
|
38
|
+
const unit_tests = b.addTest(.{
|
39
|
+
.root_source_file = .{ .path = "src/wrapper.zig" },
|
40
|
+
.target = target,
|
41
|
+
.optimize = optimize,
|
42
|
+
});
|
43
|
+
|
44
|
+
unit_tests.linkSystemLibrary("ruby");
|
45
|
+
unit_tests.linkSystemLibrary("c");
|
46
|
+
|
47
|
+
unit_tests.addIncludePath("src");
|
48
|
+
unit_tests.linkLibrary(clib);
|
49
|
+
|
50
|
+
const run_unit_tests = b.addRunArtifact(unit_tests);
|
51
|
+
const test_step = b.step("test", "Run unit tests");
|
52
|
+
test_step.dependOn(&run_unit_tests.step);
|
53
|
+
}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#include <gmp.h>
|
2
|
+
|
3
|
+
int lucas_lehmer(unsigned long p)
|
4
|
+
{
|
5
|
+
mpz_t V, mp, t;
|
6
|
+
unsigned long k, tlim;
|
7
|
+
int res;
|
8
|
+
|
9
|
+
if (p == 2) return 1;
|
10
|
+
if (!(p&1)) return 0;
|
11
|
+
|
12
|
+
mpz_init_set_ui(t, p);
|
13
|
+
if (!mpz_probab_prime_p(t, 25)) /* if p is composite, 2^p-1 is not prime */
|
14
|
+
{ mpz_clear(t); return 0; }
|
15
|
+
|
16
|
+
if (p < 23) /* trust the PRP test for these values */
|
17
|
+
{ mpz_clear(t); return (p != 11); }
|
18
|
+
|
19
|
+
mpz_init(mp);
|
20
|
+
mpz_setbit(mp, p);
|
21
|
+
mpz_sub_ui(mp, mp, 1);
|
22
|
+
|
23
|
+
/* If p=3 mod 4 and p,2p+1 both prime, then 2p+1 | 2^p-1. Cheap test. */
|
24
|
+
if (p > 3 && p % 4 == 3) {
|
25
|
+
mpz_mul_ui(t, t, 2);
|
26
|
+
mpz_add_ui(t, t, 1);
|
27
|
+
if (mpz_probab_prime_p(t,25) && mpz_divisible_p(mp, t))
|
28
|
+
{ mpz_clear(mp); mpz_clear(t); return 0; }
|
29
|
+
}
|
30
|
+
|
31
|
+
/* Do a little trial division first. Saves quite a bit of time. */
|
32
|
+
tlim = p/2;
|
33
|
+
if (tlim > (ULONG_MAX/(2*p)))
|
34
|
+
tlim = ULONG_MAX/(2*p);
|
35
|
+
for (k = 1; k < tlim; k++) {
|
36
|
+
unsigned long q = 2*p*k+1;
|
37
|
+
/* factor must be 1 or 7 mod 8 and a prime */
|
38
|
+
if ( (q%8==1 || q%8==7) &&
|
39
|
+
q % 3 && q % 5 && q % 7 &&
|
40
|
+
mpz_divisible_ui_p(mp, q) )
|
41
|
+
{ mpz_clear(mp); mpz_clear(t); return 0; }
|
42
|
+
}
|
43
|
+
|
44
|
+
mpz_init_set_ui(V, 4);
|
45
|
+
for (k = 3; k <= p; k++) {
|
46
|
+
mpz_mul(V, V, V);
|
47
|
+
mpz_sub_ui(V, V, 2);
|
48
|
+
/* mpz_mod(V, V, mp) but more efficiently done given mod 2^p-1 */
|
49
|
+
if (mpz_sgn(V) < 0) mpz_add(V, V, mp);
|
50
|
+
/* while (n > mp) { n = (n >> p) + (n & mp) } if (n==mp) n=0 */
|
51
|
+
/* but in this case we can have at most one loop plus a carry */
|
52
|
+
mpz_tdiv_r_2exp(t, V, p);
|
53
|
+
mpz_tdiv_q_2exp(V, V, p);
|
54
|
+
mpz_add(V, V, t);
|
55
|
+
while (mpz_cmp(V, mp) >= 0) mpz_sub(V, V, mp);
|
56
|
+
}
|
57
|
+
res = !mpz_sgn(V);
|
58
|
+
mpz_clear(t); mpz_clear(mp); mpz_clear(V);
|
59
|
+
return res;
|
60
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
int lucas_lehmer(unsigned long p);
|
@@ -0,0 +1,42 @@
|
|
1
|
+
const std = @import("std");
|
2
|
+
const testing = std.testing;
|
3
|
+
|
4
|
+
const ruby = @cImport(@cInclude("ruby/ruby.h"));
|
5
|
+
const clib = @cImport(@cInclude("lucas_lehmer.h"));
|
6
|
+
|
7
|
+
fn rb_lucas_lehmer(...) callconv(.C) ruby.VALUE {
|
8
|
+
var ap = @cVaStart();
|
9
|
+
defer @cVaEnd(&ap);
|
10
|
+
|
11
|
+
// first argument is `self` in ruby; discard it
|
12
|
+
var self = @cVaArg(&ap, ruby.VALUE); _ = self;
|
13
|
+
|
14
|
+
// back and forth type conversions + delegation
|
15
|
+
var p = ruby.NUM2ULONG(@cVaArg(&ap, ruby.VALUE));
|
16
|
+
return if (clib.lucas_lehmer(p) == 1) ruby.Qtrue else ruby.Qfalse;
|
17
|
+
}
|
18
|
+
|
19
|
+
export fn Init_libzigrb_lucas_lehmer() void {
|
20
|
+
ruby.ruby_init();
|
21
|
+
var zig_rb_class: ruby.VALUE = ruby.rb_define_class("ZigExample", ruby.rb_cObject);
|
22
|
+
_ = ruby.rb_define_method(zig_rb_class, "lucas_lehmer", rb_lucas_lehmer, 1);
|
23
|
+
}
|
24
|
+
|
25
|
+
test "lucas_lehmer 1 passes" {
|
26
|
+
try testing.expect(clib.lucas_lehmer(1) == 0);
|
27
|
+
}
|
28
|
+
test "lucas_lehmer 2 passes" {
|
29
|
+
try testing.expect(clib.lucas_lehmer(2) == 1);
|
30
|
+
}
|
31
|
+
test "lucas_lehmer 3 passes" {
|
32
|
+
try testing.expect(clib.lucas_lehmer(3) == 1);
|
33
|
+
}
|
34
|
+
test "lucas_lehmer 4 passes" {
|
35
|
+
try testing.expect(clib.lucas_lehmer(4) == 0);
|
36
|
+
}
|
37
|
+
test "lucas_lehmer 5 passes" {
|
38
|
+
try testing.expect(clib.lucas_lehmer(5) == 1);
|
39
|
+
}
|
40
|
+
test "lucas_lehmer 11 passes" {
|
41
|
+
try testing.expect(clib.lucas_lehmer(11) == 0);
|
42
|
+
}
|
data/lib/zig_example/version.rb
CHANGED
data/lib/zig_example.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zig_example
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank J. Cameron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -17,14 +17,74 @@ executables: []
|
|
17
17
|
extensions:
|
18
18
|
- ext/zigrb_100doors/extconf.rb
|
19
19
|
- ext/zigrb_ackermann/extconf.rb
|
20
|
+
- ext/zigrb_lucas_lehmer/extconf.rb
|
20
21
|
extra_rdoc_files: []
|
21
22
|
files:
|
23
|
+
- ext/mkmf.rb
|
24
|
+
- ext/openssl/openssl_missing.c
|
25
|
+
- ext/openssl/openssl_missing.h
|
26
|
+
- ext/openssl/ossl.c
|
27
|
+
- ext/openssl/ossl.h
|
28
|
+
- ext/openssl/ossl_asn1.c
|
29
|
+
- ext/openssl/ossl_asn1.h
|
30
|
+
- ext/openssl/ossl_bio.c
|
31
|
+
- ext/openssl/ossl_bio.h
|
32
|
+
- ext/openssl/ossl_bn.c
|
33
|
+
- ext/openssl/ossl_bn.h
|
34
|
+
- ext/openssl/ossl_cipher.c
|
35
|
+
- ext/openssl/ossl_cipher.h
|
36
|
+
- ext/openssl/ossl_config.c
|
37
|
+
- ext/openssl/ossl_config.h
|
38
|
+
- ext/openssl/ossl_digest.c
|
39
|
+
- ext/openssl/ossl_digest.h
|
40
|
+
- ext/openssl/ossl_engine.c
|
41
|
+
- ext/openssl/ossl_engine.h
|
42
|
+
- ext/openssl/ossl_hmac.c
|
43
|
+
- ext/openssl/ossl_hmac.h
|
44
|
+
- ext/openssl/ossl_kdf.c
|
45
|
+
- ext/openssl/ossl_kdf.h
|
46
|
+
- ext/openssl/ossl_ns_spki.c
|
47
|
+
- ext/openssl/ossl_ns_spki.h
|
48
|
+
- ext/openssl/ossl_ocsp.c
|
49
|
+
- ext/openssl/ossl_ocsp.h
|
50
|
+
- ext/openssl/ossl_pkcs12.c
|
51
|
+
- ext/openssl/ossl_pkcs12.h
|
52
|
+
- ext/openssl/ossl_pkcs7.c
|
53
|
+
- ext/openssl/ossl_pkcs7.h
|
54
|
+
- ext/openssl/ossl_pkey.c
|
55
|
+
- ext/openssl/ossl_pkey.h
|
56
|
+
- ext/openssl/ossl_pkey_dh.c
|
57
|
+
- ext/openssl/ossl_pkey_dsa.c
|
58
|
+
- ext/openssl/ossl_pkey_ec.c
|
59
|
+
- ext/openssl/ossl_pkey_rsa.c
|
60
|
+
- ext/openssl/ossl_rand.c
|
61
|
+
- ext/openssl/ossl_rand.h
|
62
|
+
- ext/openssl/ossl_ssl.c
|
63
|
+
- ext/openssl/ossl_ssl.h
|
64
|
+
- ext/openssl/ossl_ssl_session.c
|
65
|
+
- ext/openssl/ossl_ts.c
|
66
|
+
- ext/openssl/ossl_ts.h
|
67
|
+
- ext/openssl/ossl_x509.c
|
68
|
+
- ext/openssl/ossl_x509.h
|
69
|
+
- ext/openssl/ossl_x509attr.c
|
70
|
+
- ext/openssl/ossl_x509cert.c
|
71
|
+
- ext/openssl/ossl_x509crl.c
|
72
|
+
- ext/openssl/ossl_x509ext.c
|
73
|
+
- ext/openssl/ossl_x509name.c
|
74
|
+
- ext/openssl/ossl_x509req.c
|
75
|
+
- ext/openssl/ossl_x509revoked.c
|
76
|
+
- ext/openssl/ossl_x509store.c
|
22
77
|
- ext/zigrb_100doors/build.zig
|
23
78
|
- ext/zigrb_100doors/extconf.rb
|
24
79
|
- ext/zigrb_100doors/src/main.zig
|
25
80
|
- ext/zigrb_ackermann/build.zig
|
26
81
|
- ext/zigrb_ackermann/extconf.rb
|
27
82
|
- ext/zigrb_ackermann/src/main.zig
|
83
|
+
- ext/zigrb_lucas_lehmer/build.zig
|
84
|
+
- ext/zigrb_lucas_lehmer/extconf.rb
|
85
|
+
- ext/zigrb_lucas_lehmer/src/lucas_lehmer.c
|
86
|
+
- ext/zigrb_lucas_lehmer/src/lucas_lehmer.h
|
87
|
+
- ext/zigrb_lucas_lehmer/src/wrapper.zig
|
28
88
|
- lib/zig_example.rb
|
29
89
|
- lib/zig_example/version.rb
|
30
90
|
homepage: https://gitlab.com/fjc/ruby-zig_example
|
@@ -51,5 +111,5 @@ requirements: []
|
|
51
111
|
rubygems_version: 3.2.5
|
52
112
|
signing_key:
|
53
113
|
specification_version: 4
|
54
|
-
summary: An example gem for ruby with
|
114
|
+
summary: An example gem for ruby with native zig extensions.
|
55
115
|
test_files: []
|