diff options
| author | polwex <polwex@sortug.com> | 2025-11-23 13:29:28 +0700 |
|---|---|---|
| committer | polwex <polwex@sortug.com> | 2025-11-23 13:29:28 +0700 |
| commit | ba2dbc660c229d3e86662d35513dfa7c904d9870 (patch) | |
| tree | afdc039ac31587be0a3d089d024222fb2023fbe9 /packages/sortug/src | |
| parent | cb1b56f5a0eddbf77446f415f2beda57c8305f85 (diff) | |
Diffstat (limited to 'packages/sortug/src')
| -rw-r--r-- | packages/sortug/src/styles.css | 247 | ||||
| -rw-r--r-- | packages/sortug/src/utils.ts | 50 |
2 files changed, 282 insertions, 15 deletions
diff --git a/packages/sortug/src/styles.css b/packages/sortug/src/styles.css new file mode 100644 index 0000000..375e620 --- /dev/null +++ b/packages/sortug/src/styles.css @@ -0,0 +1,247 @@ +/* SORTUG CSS */ +/* variables */ +:root { + --bai: rgba(255, 255, 255, 1); + --baizi: rgba(230, 230, 230); + --hui: rgba(130, 130, 130, 1); + --hei: rgba(0, 0, 0, 1); + --hong: rgb(141, 15, 15, 1); + --huang: rgb(230, 180, 60, 1); + --lan: rgb(30, 60, 80, 1); +} + +[data-theme="dark"] { + --bg: hei; + --fg: baizi; +} + +[data-theme="light"] { + --bg: white; + --fg: black; +} + +* { + box-sizing: border-box; +} + +html, +body, +#root { + height: 100%; + min-height: 100%; + overscroll-behavior: none; + color: var(--fg); + -webkit-font-smoothing: antialiased; + margin: 0; +} + +/* tailwindy classes */ +.card { + padding: 1rem; + max-width: max-content; +} + +button, +.button { + max-width: max-content; + padding: 0.5rem; + border: 1px solid var(--fg); +} + +/* borders */ +.nb { + border: none; +} + +/* widths */ +.hw { + width: 50%; +} + +.qw { + width: 25%; +} + +.tqw { + width: 75%; +} + +/* flex */ +.row { + display: flex; + align-items: center; +} + +.sy { + overflow-y: scroll; +} + +.fsy { + overflow-y: scroll; + height: 100%; +} + +.fxc { + display: flex; + justify-content: center; + align-items: baseline; +} + +/* flex spread */ +.fs { + display: flex; + justify-content: space-between; +} + +.fsc { + display: flex; + justify-content: space-between; + align-items: center; +} + +.g1 { + gap: 0.5rem; +} + +.g2 { + gap: 1rem; +} + +.address { + font-family: "Courier New", Courier, monospace; +} + +.spread { + justify-content: space-between; +} + +.even { + justify-content: space-evenly; +} + +.flexc { + justify-content: center; +} + +.cp { + cursor: pointer; +} + +/* centering */ +.gc { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.agc { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.ac { + position: absolute; + left: 50%; + transform: translateX(-50%); +} + +.xc { + position: fixed; + left: 50%; + transform: translateX(-50%); + z-index: 20; +} + +.tc { + text-align: center; +} + +.bc { + display: block; + margin-left: auto; + margin-right: auto; +} + +.blocks { + & * { + display: block; + } +} + +.bold { + font-weight: 700; +} + +.weak { + opacity: 0.7; +} + +.all-c { + & * { + margin-left: auto; + margin-right: auto; + } +} + +.mb-1 { + margin-bottom: 1rem; +} + +.error { + color: red; + text-align: center; +} + +.tabs { + display: flex; + justify-content: space-evenly; + align-items: center; + + & .tab { + cursor: pointer; + opacity: 0.5; + } + + & .tab.active { + opacity: 1; + } +} + +.disabled { + opacity: 0.5; +} + +.smol { + font-size: 0.9rem; +} + +/* The Modal (background) */ +#modal-bg { + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgba(0, 0, 0, 0.4); + z-index: 998; +} + +/* Modal Content */ +#modal-fg { + background-color: var(--modal-bg); + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: 20px; + z-index: 999; + max-height: 90vh; + min-height: 20vh; + max-width: 90vw; + overflow: auto; +}
\ No newline at end of file diff --git a/packages/sortug/src/utils.ts b/packages/sortug/src/utils.ts index 687b8db..43fac8a 100644 --- a/packages/sortug/src/utils.ts +++ b/packages/sortug/src/utils.ts @@ -1,25 +1,45 @@ +export function cycleNext(current: number, max: number) { + if (current + 1 === max) return 0; + else return current + 1; +} +export function cyclePrev(current: number, max: number) { + if (current === 0) return max; + else return current - 1; +} + export function randomFromArray<T>(a: Array<T>): T { const l = a.length; - const ind = Math.floor(Math.random() * l); - if (ind === l) return a[ind - 1]; - else return a[ind]; + if (l === 0) throw new Error("Empty array!"); + const randomIdx = Math.floor(Math.random() * l); + const idx = randomIdx === l ? randomIdx - 1 : randomIdx; + const el = a[idx]!; + return el; } -export function randomFromArrayAcc<T>(a: Array<T>, s?: Set<T>): T { - const st = s ? s : new Set(a); - const l = a.length; - const ind = Math.floor(Math.random() * l); - const res = ind === l ? a[ind - 1] : a[ind]; - if (st.has(res)) return randomFromArrayAcc(a, st); - else { - st.add(res); - // TODO have to return this too? - return res; - } +export function randomFromArrayMany<T>( + a: Array<T>, + count: number, + canRepeat = false, +): Array<T> { + if (canRepeat) return [...new Array(count)].map((s) => randomFromArray(a)); + else return randomFromArrayNoRepeat(a, count); +} +export function randomFromArrayNoRepeat<T>( + a: Array<T>, + count: number, + acc?: Set<T>, +): T[] { + const all = new Set(a); + const st = acc ? acc : new Set<T>(); + if (all.size === st.size || st.size === count) return [...st]; + const el = randomFromArray(a); + if (!st.has(el)) st.add(el); + return randomFromArrayNoRepeat(a, count, st); } + export function notRandomFromArray<T>(data: string, a: Array<T>): T { const l = a.length; const ind = hashTextToNumber(data, l - 1); - return a[ind]; + return a[ind]!; } function hashTextToNumber(text: string, max: number): number { |
