@andresclua/perlindom 0.0.3 → 0.0.5
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/CHANGELOG.md +16 -0
- package/dist/PerlinDOM.es.js +61 -55
- package/dist/PerlinDOM.umd.js +1 -1
- package/package.json +5 -5
- package/readme.md +1 -0
- package/src/js/PerlinDom.js +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.0.5] - 2025-01-07
|
|
9
|
+
|
|
10
|
+
- **Remove logs** : remove logs
|
|
11
|
+
|
|
12
|
+
## [0.0.4] - 2025-01-07
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **Package Configuration**: Updated package to be public (removed `"private": true`)
|
|
16
|
+
- **NPM Publishing**: Package is now available for public installation via npm
|
|
17
|
+
- **Module Exports**: Enhanced module exports configuration for better compatibility
|
|
18
|
+
- **Package Metadata**: Updated package name to `@andresclua/perlindom` with proper scoping
|
|
19
|
+
|
|
20
|
+
### Improved
|
|
21
|
+
- **Distribution**: Better UMD and ES module support through improved exports configuration
|
|
22
|
+
- **Accessibility**: Package now publicly available on npm registry
|
|
23
|
+
|
|
8
24
|
## [0.0.3] - 2025-01-07
|
|
9
25
|
|
|
10
26
|
### Fixed
|
package/dist/PerlinDOM.es.js
CHANGED
|
@@ -1,59 +1,65 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
1
|
+
var j = Object.defineProperty;
|
|
2
|
+
var S = (c) => {
|
|
3
3
|
throw TypeError(c);
|
|
4
4
|
};
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var a = (c, t, i) => (
|
|
9
|
-
var n, W, H,
|
|
5
|
+
var C = (c, t, i) => t in c ? j(c, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : c[t] = i;
|
|
6
|
+
var q = (c, t, i) => C(c, typeof t != "symbol" ? t + "" : t, i), k = (c, t, i) => t.has(c) || S("Cannot " + i);
|
|
7
|
+
var Y = (c, t, i) => t.has(c) ? S("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(c) : t.set(c, i);
|
|
8
|
+
var a = (c, t, i) => (k(c, t, "access private method"), i);
|
|
9
|
+
var n, W, H, R, v, p, T, $, L;
|
|
10
10
|
const o = class o {
|
|
11
11
|
constructor({
|
|
12
12
|
element: t,
|
|
13
13
|
x: i = null,
|
|
14
|
-
y:
|
|
15
|
-
speed:
|
|
14
|
+
y: r = null,
|
|
15
|
+
speed: h = 0.01,
|
|
16
16
|
seed: l = 0,
|
|
17
17
|
lerpSpeed: s = 0.1
|
|
18
18
|
}) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var t, i,
|
|
22
|
-
if (this.lerpFactor !== this.targetLerpFactor && (this.lerpFactor = a(this, p,
|
|
19
|
+
Y(this, p);
|
|
20
|
+
q(this, "animate", () => {
|
|
21
|
+
var t, i, r, h, l, s, e, m, g, f, u, d;
|
|
22
|
+
if (this.lerpFactor !== this.targetLerpFactor && (this.lerpFactor = a(this, p, $).call(this, this.lerpFactor, this.targetLerpFactor, this.lerpSpeed), Math.abs(this.lerpFactor - this.targetLerpFactor) < 1e-3 && (this.lerpFactor = this.targetLerpFactor)), this.lerpFactor > 0) {
|
|
23
23
|
this.time += this.speed * this.lerpFactor;
|
|
24
|
-
const
|
|
24
|
+
const x = this.noise.perlin2(this.time, 0), A = this.noise.perlin2(this.time, 100);
|
|
25
25
|
if (this.el) {
|
|
26
|
-
let
|
|
26
|
+
let F, y, P, X;
|
|
27
27
|
if (this.hasPercentages) {
|
|
28
|
-
const
|
|
29
|
-
this.xRange && (
|
|
28
|
+
const w = this.el.parentElement || document.body, M = w.clientWidth, B = w.clientHeight;
|
|
29
|
+
this.xRange && (F = a(t = o, n, R).call(t, this.xRange.min) ? a(i = o, n, v).call(i, this.xRange.min, M) : this.xRange.min, y = a(r = o, n, R).call(r, this.xRange.max) ? a(h = o, n, v).call(h, this.xRange.max, M) : this.xRange.max), this.yRange && (P = a(l = o, n, R).call(l, this.yRange.min) ? a(s = o, n, v).call(s, this.yRange.min, B) : this.yRange.min, X = a(e = o, n, R).call(e, this.yRange.max) ? a(m = o, n, v).call(m, this.yRange.max, B) : this.yRange.max);
|
|
30
30
|
} else
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
this.lastX =
|
|
31
|
+
F = (g = this.xRange) == null ? void 0 : g.min, y = (f = this.xRange) == null ? void 0 : f.max, P = (u = this.yRange) == null ? void 0 : u.min, X = (d = this.yRange) == null ? void 0 : d.max;
|
|
32
|
+
const z = this.xRange ? a(this, p, L).call(this, x, -1, 1, F, y) : 0, b = this.yRange ? a(this, p, L).call(this, A, -1, 1, P, X) : 0;
|
|
33
|
+
this.lastX = z, this.lastY = b, this.el.style.transform = `translate3d(${z}px, ${b}px, 0)`;
|
|
34
34
|
} else {
|
|
35
|
-
const
|
|
36
|
-
this.lastX =
|
|
35
|
+
const F = this.xRange ? a(this, p, L).call(this, x, -1, 1, this.xRange.min, this.xRange.max) : 0, y = this.yRange ? a(this, p, L).call(this, A, -1, 1, this.yRange.min, this.yRange.max) : 0;
|
|
36
|
+
this.lastX = F, this.lastY = y;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
(this.lerpFactor > 0 || this.targetLerpFactor > 0) && (this.raf = requestAnimationFrame(this.animate));
|
|
40
40
|
});
|
|
41
|
-
var e,
|
|
42
|
-
this.el = t, this.xRange = i, this.yRange =
|
|
41
|
+
var e, m, g, f;
|
|
42
|
+
if (this.el = t, this.xRange = i, this.yRange = r, this.speed = h, this.time = l, this.isPlaying = !0, this.lerpFactor = 1, this.lerpSpeed = s, this.targetLerpFactor = 1, this.lastX = 0, this.lastY = 0, this.hasPercentages = !1, (i && (a(e = o, n, R).call(e, i.min) || a(m = o, n, R).call(m, i.max)) || r && (a(g = o, n, R).call(g, r.min) || a(f = o, n, R).call(f, r.max))) && (this.hasPercentages = !0), t) {
|
|
43
|
+
const u = window.getComputedStyle(t);
|
|
44
|
+
u.position === "static" && (t.style.position = "relative");
|
|
45
|
+
const d = u.transform;
|
|
46
|
+
(!d || d === "none") && (t.style.transform = "translate3d(0px, 0px, 0px)"), this.hasPercentages && (this.handleResize = this.handleResize.bind(this), window.addEventListener("resize", this.handleResize));
|
|
47
|
+
}
|
|
48
|
+
this.animate = this.animate.bind(this), this.init(l);
|
|
43
49
|
}
|
|
44
50
|
init(t) {
|
|
45
51
|
var i;
|
|
46
|
-
this.noise = a(this, p,
|
|
52
|
+
this.noise = a(this, p, T).call(this, a(i = o, n, H).call(i, t)), this.isPlaying = !0, this.lerpFactor = 1, this.targetLerpFactor = 1, this.raf = requestAnimationFrame(this.animate);
|
|
47
53
|
}
|
|
48
54
|
// Handle window resize for percentage-based values
|
|
49
55
|
handleResize() {
|
|
50
56
|
this.hasPercentages && this.el && (this.needsRecalculation = !0);
|
|
51
57
|
}
|
|
52
58
|
pause() {
|
|
53
|
-
this.isPlaying && (this.targetLerpFactor = 0, this.isPlaying = !1
|
|
59
|
+
this.isPlaying && (this.targetLerpFactor = 0, this.isPlaying = !1);
|
|
54
60
|
}
|
|
55
61
|
play() {
|
|
56
|
-
this.isPlaying || (this.targetLerpFactor = 1, this.isPlaying = !0, this.lerpFactor === 0 && (this.raf = requestAnimationFrame(this.animate))
|
|
62
|
+
this.isPlaying || (this.targetLerpFactor = 1, this.isPlaying = !0, this.lerpFactor === 0 && (this.raf = requestAnimationFrame(this.animate)));
|
|
57
63
|
}
|
|
58
64
|
destroy() {
|
|
59
65
|
cancelAnimationFrame(this.raf), this.hasPercentages && window.removeEventListener("resize", this.handleResize);
|
|
@@ -65,56 +71,56 @@ n = new WeakSet(), W = function(t) {
|
|
|
65
71
|
return i = Math.imul(i ^ i >>> 15, i | 1), i ^= i + Math.imul(i ^ i >>> 7, i | 61), ((i ^ i >>> 14) >>> 0) / 4294967296;
|
|
66
72
|
};
|
|
67
73
|
}, H = function(t = 0) {
|
|
68
|
-
var
|
|
69
|
-
const i = Array.from({ length: 256 }, (l, s) => s),
|
|
74
|
+
var h;
|
|
75
|
+
const i = Array.from({ length: 256 }, (l, s) => s), r = a(h = o, n, W).call(h, t);
|
|
70
76
|
for (let l = 255; l > 0; l--) {
|
|
71
|
-
const s = Math.floor(
|
|
77
|
+
const s = Math.floor(r() * (l + 1));
|
|
72
78
|
[i[l], i[s]] = [i[s], i[l]];
|
|
73
79
|
}
|
|
74
80
|
return i.concat(i);
|
|
75
|
-
},
|
|
81
|
+
}, R = function(t) {
|
|
76
82
|
return typeof t == "string" && t.endsWith("%");
|
|
77
|
-
},
|
|
78
|
-
var
|
|
79
|
-
return a(
|
|
80
|
-
}, p = new WeakSet(),
|
|
81
|
-
const i = (s) => s * s * s * (s * (s * 6 - 15) + 10),
|
|
82
|
-
const
|
|
83
|
-
return (
|
|
83
|
+
}, v = function(t, i) {
|
|
84
|
+
var h;
|
|
85
|
+
return a(h = o, n, R).call(h, t) ? parseFloat(t) / 100 * i : t;
|
|
86
|
+
}, p = new WeakSet(), T = function(t) {
|
|
87
|
+
const i = (s) => s * s * s * (s * (s * 6 - 15) + 10), r = (s, e, m) => e + s * (m - e), h = (s, e, m) => {
|
|
88
|
+
const g = s & 15, f = g < 8 ? e : m, u = g < 4 ? m : g === 12 || g === 14 ? e : 0;
|
|
89
|
+
return (g & 1 ? -f : f) + (g & 2 ? -u : u);
|
|
84
90
|
}, l = (s, e) => s & 1 ? -e : e;
|
|
85
91
|
return {
|
|
86
92
|
// Original 1D Perlin noise function
|
|
87
93
|
perlin1(s) {
|
|
88
94
|
const e = Math.floor(s) & 255;
|
|
89
95
|
s -= Math.floor(s);
|
|
90
|
-
const
|
|
91
|
-
return
|
|
96
|
+
const m = i(s);
|
|
97
|
+
return r(m, l(t[e], s), l(t[e + 1], s - 1));
|
|
92
98
|
},
|
|
93
99
|
// New 2D Perlin noise function
|
|
94
100
|
perlin2(s, e) {
|
|
95
|
-
const
|
|
101
|
+
const m = Math.floor(s) & 255, g = Math.floor(e) & 255;
|
|
96
102
|
s -= Math.floor(s), e -= Math.floor(e);
|
|
97
|
-
const f = i(s),
|
|
98
|
-
return
|
|
99
|
-
|
|
100
|
-
|
|
103
|
+
const f = i(s), u = i(e), d = t[m] + g, x = t[m + 1] + g, A = t[d], F = t[d + 1], y = t[x], P = t[x + 1];
|
|
104
|
+
return r(
|
|
105
|
+
u,
|
|
106
|
+
r(
|
|
101
107
|
f,
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
h(t[A], s, e),
|
|
109
|
+
h(t[y], s - 1, e)
|
|
104
110
|
),
|
|
105
|
-
|
|
111
|
+
r(
|
|
106
112
|
f,
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
h(t[F], s, e - 1),
|
|
114
|
+
h(t[P], s - 1, e - 1)
|
|
109
115
|
)
|
|
110
116
|
);
|
|
111
117
|
}
|
|
112
118
|
};
|
|
113
|
-
},
|
|
114
|
-
return t +
|
|
115
|
-
}, L = function(t, i,
|
|
116
|
-
return (t - i) * (l -
|
|
117
|
-
},
|
|
119
|
+
}, $ = function(t, i, r) {
|
|
120
|
+
return t + r * (i - t);
|
|
121
|
+
}, L = function(t, i, r, h, l) {
|
|
122
|
+
return (t - i) * (l - h) / (r - i) + h;
|
|
123
|
+
}, Y(o, n);
|
|
118
124
|
let E = o;
|
|
119
125
|
export {
|
|
120
126
|
E as default
|
package/dist/PerlinDOM.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(a,t){typeof exports=="object"&&typeof module<"u"?module.exports=t():typeof define=="function"&&define.amd?define(t):(a=typeof globalThis<"u"?globalThis:a||self,a.PerlinDOM=t())})(this,function(){"use strict";var
|
|
1
|
+
(function(a,t){typeof exports=="object"&&typeof module<"u"?module.exports=t():typeof define=="function"&&define.amd?define(t):(a=typeof globalThis<"u"?globalThis:a||self,a.PerlinDOM=t())})(this,function(){"use strict";var $=Object.defineProperty;var T=a=>{throw TypeError(a)};var C=(a,t,p)=>t in a?$(a,t,{enumerable:!0,configurable:!0,writable:!0,value:p}):a[t]=p;var q=(a,t,p)=>C(a,typeof t!="symbol"?t+"":t,p),D=(a,t,p)=>t.has(a)||T("Cannot "+p);var b=(a,t,p)=>t.has(a)?T("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(a):t.set(a,p);var r=(a,t,p)=>(D(a,t,"access private method"),p);var t,E,W,R,L,f,j,H,A;const o=class o{constructor({element:e,x:i=null,y:h=null,speed:l=.01,seed:c=0,lerpSpeed:s=.1}){b(this,f);q(this,"animate",()=>{var e,i,h,l,c,s,n,m,g,u,d,F;if(this.lerpFactor!==this.targetLerpFactor&&(this.lerpFactor=r(this,f,H).call(this,this.lerpFactor,this.targetLerpFactor,this.lerpSpeed),Math.abs(this.lerpFactor-this.targetLerpFactor)<.001&&(this.lerpFactor=this.targetLerpFactor)),this.lerpFactor>0){this.time+=this.speed*this.lerpFactor;const P=this.noise.perlin2(this.time,0),X=this.noise.perlin2(this.time,100);if(this.el){let y,x,v,Y;if(this.hasPercentages){const w=this.el.parentElement||document.body,B=w.clientWidth,S=w.clientHeight;this.xRange&&(y=r(e=o,t,R).call(e,this.xRange.min)?r(i=o,t,L).call(i,this.xRange.min,B):this.xRange.min,x=r(h=o,t,R).call(h,this.xRange.max)?r(l=o,t,L).call(l,this.xRange.max,B):this.xRange.max),this.yRange&&(v=r(c=o,t,R).call(c,this.yRange.min)?r(s=o,t,L).call(s,this.yRange.min,S):this.yRange.min,Y=r(n=o,t,R).call(n,this.yRange.max)?r(m=o,t,L).call(m,this.yRange.max,S):this.yRange.max)}else y=(g=this.xRange)==null?void 0:g.min,x=(u=this.xRange)==null?void 0:u.max,v=(d=this.yRange)==null?void 0:d.min,Y=(F=this.yRange)==null?void 0:F.max;const z=this.xRange?r(this,f,A).call(this,P,-1,1,y,x):0,M=this.yRange?r(this,f,A).call(this,X,-1,1,v,Y):0;this.lastX=z,this.lastY=M,this.el.style.transform=`translate3d(${z}px, ${M}px, 0)`}else{const y=this.xRange?r(this,f,A).call(this,P,-1,1,this.xRange.min,this.xRange.max):0,x=this.yRange?r(this,f,A).call(this,X,-1,1,this.yRange.min,this.yRange.max):0;this.lastX=y,this.lastY=x}}(this.lerpFactor>0||this.targetLerpFactor>0)&&(this.raf=requestAnimationFrame(this.animate))});var n,m,g,u;if(this.el=e,this.xRange=i,this.yRange=h,this.speed=l,this.time=c,this.isPlaying=!0,this.lerpFactor=1,this.lerpSpeed=s,this.targetLerpFactor=1,this.lastX=0,this.lastY=0,this.hasPercentages=!1,(i&&(r(n=o,t,R).call(n,i.min)||r(m=o,t,R).call(m,i.max))||h&&(r(g=o,t,R).call(g,h.min)||r(u=o,t,R).call(u,h.max)))&&(this.hasPercentages=!0),e){const d=window.getComputedStyle(e);d.position==="static"&&(e.style.position="relative");const F=d.transform;(!F||F==="none")&&(e.style.transform="translate3d(0px, 0px, 0px)"),this.hasPercentages&&(this.handleResize=this.handleResize.bind(this),window.addEventListener("resize",this.handleResize))}this.animate=this.animate.bind(this),this.init(c)}init(e){var i;this.noise=r(this,f,j).call(this,r(i=o,t,W).call(i,e)),this.isPlaying=!0,this.lerpFactor=1,this.targetLerpFactor=1,this.raf=requestAnimationFrame(this.animate)}handleResize(){this.hasPercentages&&this.el&&(this.needsRecalculation=!0)}pause(){this.isPlaying&&(this.targetLerpFactor=0,this.isPlaying=!1)}play(){this.isPlaying||(this.targetLerpFactor=1,this.isPlaying=!0,this.lerpFactor===0&&(this.raf=requestAnimationFrame(this.animate)))}destroy(){cancelAnimationFrame(this.raf),this.hasPercentages&&window.removeEventListener("resize",this.handleResize)}};t=new WeakSet,E=function(e){return function(){let i=e+=1831565813;return i=Math.imul(i^i>>>15,i|1),i^=i+Math.imul(i^i>>>7,i|61),((i^i>>>14)>>>0)/4294967296}},W=function(e=0){var l;const i=Array.from({length:256},(c,s)=>s),h=r(l=o,t,E).call(l,e);for(let c=255;c>0;c--){const s=Math.floor(h()*(c+1));[i[c],i[s]]=[i[s],i[c]]}return i.concat(i)},R=function(e){return typeof e=="string"&&e.endsWith("%")},L=function(e,i){var l;return r(l=o,t,R).call(l,e)?parseFloat(e)/100*i:e},f=new WeakSet,j=function(e){const i=s=>s*s*s*(s*(s*6-15)+10),h=(s,n,m)=>n+s*(m-n),l=(s,n,m)=>{const g=s&15,u=g<8?n:m,d=g<4?m:g===12||g===14?n:0;return(g&1?-u:u)+(g&2?-d:d)},c=(s,n)=>s&1?-n:n;return{perlin1(s){const n=Math.floor(s)&255;s-=Math.floor(s);const m=i(s);return h(m,c(e[n],s),c(e[n+1],s-1))},perlin2(s,n){const m=Math.floor(s)&255,g=Math.floor(n)&255;s-=Math.floor(s),n-=Math.floor(n);const u=i(s),d=i(n),F=e[m]+g,P=e[m+1]+g,X=e[F],y=e[F+1],x=e[P],v=e[P+1];return h(d,h(u,l(e[X],s,n),l(e[x],s-1,n)),h(u,l(e[y],s,n-1),l(e[v],s-1,n-1)))}}},H=function(e,i,h){return e+h*(i-e)},A=function(e,i,h,l,c){return(e-i)*(c-l)/(h-i)+l},b(o,t);let a=o;return a});
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andresclua/perlindom",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"description": "A lightweight JavaScript library for creating smooth, organic animations for DOM elements using Perlin noise",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"main": "./dist/
|
|
8
|
-
"module": "./dist/
|
|
7
|
+
"main": "./dist/PerlinDOM.umd.js",
|
|
8
|
+
"module": "./dist/PerlinDOM.es.js",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"import": "./dist/
|
|
12
|
-
"require": "./dist/
|
|
11
|
+
"import": "./dist/PerlinDOM.es.js",
|
|
12
|
+
"require": "./dist/PerlinDOM.umd.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
package/readme.md
CHANGED
|
@@ -336,6 +336,7 @@ See [CHANGELOG.md](./CHANGELOG.md) for detailed version history.
|
|
|
336
336
|
|
|
337
337
|
### Recent Updates
|
|
338
338
|
|
|
339
|
+
- **v0.0.4**: Package now public on npm, enhanced module exports configuration
|
|
339
340
|
- **v0.0.3**: Fixed positioning conflicts, improved automatic position detection
|
|
340
341
|
- **v0.0.2**: Added percentage support and responsive animations
|
|
341
342
|
- **v0.0.1**: Initial release with core Perlin noise animations
|
package/src/js/PerlinDom.js
CHANGED
|
@@ -77,6 +77,7 @@ class PerlinDOM {
|
|
|
77
77
|
this.handleResize = this.handleResize.bind(this);
|
|
78
78
|
window.addEventListener('resize', this.handleResize);
|
|
79
79
|
}
|
|
80
|
+
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
this.animate = this.animate.bind(this);
|
|
@@ -90,7 +91,6 @@ class PerlinDOM {
|
|
|
90
91
|
this.lerpFactor = 1;
|
|
91
92
|
this.targetLerpFactor = 1;
|
|
92
93
|
this.raf = requestAnimationFrame(this.animate);
|
|
93
|
-
console.log('PerlinDOM initialized');
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
// Handle window resize for percentage-based values
|
|
@@ -106,7 +106,6 @@ class PerlinDOM {
|
|
|
106
106
|
if (this.isPlaying) {
|
|
107
107
|
this.targetLerpFactor = 0; // Target paused state
|
|
108
108
|
this.isPlaying = false;
|
|
109
|
-
console.log('PerlinDOM pausing...');
|
|
110
109
|
}
|
|
111
110
|
}
|
|
112
111
|
|
|
@@ -120,7 +119,6 @@ class PerlinDOM {
|
|
|
120
119
|
this.raf = requestAnimationFrame(this.animate);
|
|
121
120
|
}
|
|
122
121
|
|
|
123
|
-
console.log('PerlinDOM playing...');
|
|
124
122
|
}
|
|
125
123
|
}
|
|
126
124
|
|