billy-herrington-utils 1.4.4 → 1.4.6

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.
@@ -1,46 +1,6 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- function stringToWords(s) {
5
- return s.split(",").map((s2) => s2.trim().toLowerCase()).filter((_) => _);
6
- }
7
- function sanitizeStr(s) {
8
- return s?.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase() || "";
9
- }
10
- function formatTimeToHHMMSS(timeString) {
11
- const regex = /(?:(\d+)\s*h\s*)?(?:(\d+)\s*mi?n?\s*)?(?:(\d+)\s*sec)?/;
12
- const match = timeString.match(regex);
13
- const h = parseInt(match?.[1] || "0");
14
- const m = parseInt(match?.[2] || "0");
15
- const s = parseInt(match?.[3] || "0");
16
- const pad = (num) => String(num).padStart(2, "0");
17
- return `${pad(h)}:${pad(m)}:${pad(s)}`;
18
- }
19
- function timeToSeconds(t) {
20
- const r = /sec|min|h|m/.test(t) ? formatTimeToHHMMSS(t) : t;
21
- return (r?.match(/\d+/gm) || [0]).reverse().map((s, i) => parseInt(s) * 60 ** i).reduce((a, b) => a + b);
22
- }
23
- function parseIntegerOr(n, or) {
24
- return ((num) => Number.isNaN(num) ? or : num)(parseInt(n));
25
- }
26
- function parseDataParams(str) {
27
- const paramsStr = decodeURI(str.trim()).split(";");
28
- return paramsStr.reduce((acc, s) => {
29
- const parsed = s.match(/([\+\w]+):([\w\-\ ]+)?/);
30
- if (parsed) {
31
- const [, key, value] = parsed;
32
- if (value) {
33
- key.split("+").forEach((p) => {
34
- acc[p] = value;
35
- });
36
- }
37
- }
38
- return acc;
39
- }, {});
40
- }
41
- function parseCSSUrl(s) {
42
- return s.replace(/url\("|\"\).*/g, "");
43
- }
44
4
  class Observer {
45
5
  constructor(callback) {
46
6
  __publicField(this, "observer");
@@ -92,215 +52,11 @@ class LazyImgLoader {
92
52
  this.lazyImgObserver.observe(img);
93
53
  }
94
54
  }
95
- function circularShift(n, c = 6, s = 1) {
96
- return (n + s) % c || c;
97
- }
98
- function parseDom(html) {
99
- const parsed = new DOMParser().parseFromString(html, "text/html").body;
100
- return parsed.children.length > 1 ? parsed : parsed.firstElementChild;
101
- }
102
- function copyAttributes(target, source) {
103
- for (const attr of source.attributes) {
104
- attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);
105
- }
106
- }
107
- function replaceElementTag(e, tagName) {
108
- const newTagElement = document.createElement(tagName);
109
- copyAttributes(newTagElement, e);
110
- newTagElement.innerHTML = e.innerHTML;
111
- e.parentNode?.replaceChild(newTagElement, e);
112
- return newTagElement;
113
- }
114
- function getAllUniqueParents(elements) {
115
- return Array.from(elements).reduce((acc, v) => {
116
- if (v.parentElement && !acc.includes(v.parentElement)) {
117
- acc.push(v.parentElement);
118
- }
119
- return acc;
120
- }, []);
121
- }
122
- function findNextSibling(el) {
123
- if (el.nextElementSibling) return el.nextElementSibling;
124
- if (el.parentElement) return findNextSibling(el.parentElement);
125
- return null;
126
- }
127
- function waitForElementExists(parent, selector, callback) {
128
- const observer = new MutationObserver((_mutations) => {
129
- const el = parent.querySelector(selector);
130
- if (el) {
131
- observer.disconnect();
132
- callback(el);
133
- }
134
- });
135
- observer.observe(document.body, { childList: true, subtree: true });
136
- }
137
- function watchElementChildrenCount(element, callback) {
138
- let count = element.children.length;
139
- const observer = new MutationObserver((mutationList, observer2) => {
140
- for (const mutation of mutationList) {
141
- if (mutation.type === "childList") {
142
- if (count !== element.children.length) {
143
- count = element.children.length;
144
- callback(observer2, count);
145
- }
146
- }
147
- }
148
- });
149
- observer.observe(element, { childList: true });
150
- }
151
- function watchDomChangesWithThrottle(element, callback, throttle = 1e3, times = Infinity, options = { childList: true, subtree: true, attributes: true }) {
152
- let lastMutationTime;
153
- let timeout;
154
- let times_ = times;
155
- const observer = new MutationObserver((_mutationList, _observer) => {
156
- if (times_ !== Infinity && times_ < 1) {
157
- observer.disconnect();
158
- return;
159
- }
160
- times_--;
161
- const now = Date.now();
162
- if (lastMutationTime && now - lastMutationTime < throttle) {
163
- timeout && clearTimeout(timeout);
164
- }
165
- timeout = setTimeout(callback, throttle);
166
- lastMutationTime = now;
167
- });
168
- observer.observe(element, options);
169
- return observer;
170
- }
171
- function downloader(options = { append: "", after: "", button: "", cbBefore: () => {
172
- } }) {
173
- const btn = parseDom(options.button);
174
- if (options.append) document.querySelector(options.append)?.append(btn);
175
- if (options.after) document.querySelector(options.after)?.after(btn);
176
- btn.addEventListener("click", (e) => {
177
- e.preventDefault();
178
- if (options.cbBefore) options.cbBefore();
179
- waitForElementExists(document.body, "video", (video) => {
180
- window.location.href = video.getAttribute("src");
181
- });
182
- });
183
- }
184
- function exterminateVideo(video) {
185
- video.removeAttribute("src");
186
- video.load();
187
- video.remove();
188
- }
189
- const MOBILE_UA = [
190
- "Mozilla/5.0 (Linux; Android 10; K)",
191
- "AppleWebKit/537.36 (KHTML, like Gecko)",
192
- "Chrome/114.0.0.0 Mobile Safari/537.36"
193
- ].join(" ");
194
- function fetchWith(url, options = { html: false, mobile: false }) {
195
- const reqOpts = {};
196
- if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ "User-Agent": MOBILE_UA }) });
197
- return fetch(url, reqOpts).then((r) => r.text()).then((r) => options.html ? parseDom(r) : r);
198
- }
199
- const fetchHtml = (url) => fetchWith(url, { html: true });
200
- const fetchText = (url) => fetchWith(url);
201
- function objectToFormData(object) {
202
- const formData = new FormData();
203
- Object.entries(object).forEach(([k, v]) => formData.append(k, v));
204
- return formData;
205
- }
206
- function listenEvents(dom, events, callback) {
207
- for (const e of events) {
208
- dom.addEventListener(e, callback, true);
209
- }
210
- }
211
- class Tick {
212
- constructor(delay, startImmediate = true) {
213
- __publicField(this, "tick");
214
- __publicField(this, "callbackFinal");
215
- this.delay = delay;
216
- this.startImmediate = startImmediate;
217
- }
218
- start(callback, callbackFinal) {
219
- this.stop();
220
- this.callbackFinal = callbackFinal;
221
- if (this.startImmediate) callback();
222
- this.tick = window.setInterval(callback, this.delay);
223
- }
224
- stop() {
225
- if (this.tick !== void 0) {
226
- clearInterval(this.tick);
227
- this.tick = void 0;
228
- }
229
- if (this.callbackFinal) {
230
- this.callbackFinal();
231
- this.callbackFinal = void 0;
232
- }
233
- }
234
- }
235
- function isMob() {
236
- return /iPhone|Android/i.test(navigator.userAgent);
237
- }
238
- async function computeAsyncOneAtTime(iterable) {
239
- const res = [];
240
- for await (const f of iterable) {
241
- res.push(await f());
242
- }
243
- return res;
244
- }
245
- function wait(milliseconds) {
246
- return new Promise((resolve) => setTimeout(resolve, milliseconds));
247
- }
248
- class AsyncPool {
249
- constructor(max = 1, pool = []) {
250
- __publicField(this, "cur", 0);
251
- __publicField(this, "finished");
252
- __publicField(this, "_resolve");
253
- this.max = max;
254
- this.pool = pool;
255
- this.finished = new Promise((resolve) => {
256
- this._resolve = resolve;
257
- });
258
- }
259
- static async doNAsyncAtOnce(max = 1, pool = []) {
260
- const spool = new AsyncPool(max);
261
- pool.forEach((f) => spool.push(f));
262
- return spool.run();
263
- }
264
- getHighPriorityFirst(p = 0) {
265
- if (p > 3 || this.pool.length === 0) return void 0;
266
- const i = this.pool.findIndex((e) => e.p === p);
267
- if (i >= 0) {
268
- const res = this.pool[i].v;
269
- this.pool.splice(i, 1);
270
- return res;
271
- }
272
- return this.getHighPriorityFirst(p + 1);
273
- }
274
- async runTask() {
275
- this.cur++;
276
- const f = this.getHighPriorityFirst();
277
- await f?.();
278
- this.cur--;
279
- this.runTasks();
280
- }
281
- runTasks() {
282
- if (!this.pool.length) {
283
- this._resolve?.(true);
284
- return;
285
- }
286
- if (this.cur < this.max) {
287
- this.runTask();
288
- this.runTasks();
289
- }
290
- }
291
- async run() {
292
- this.runTasks();
293
- return this.finished;
294
- }
295
- push(x) {
296
- this.pool.push("p" in x ? x : { v: x, p: 0 });
297
- }
298
- }
299
- function chunks(arr, n) {
300
- return Array.from({ length: Math.ceil(arr.length / n) }, (_, i) => arr.slice(i * n, i * n + n));
55
+ function stringToWords(s) {
56
+ return s.split(",").map((s2) => s2.trim().toLowerCase()).filter((_) => _);
301
57
  }
302
- function range(size, startAt = 1, step = 1) {
303
- return Array.from({ length: size }, (_, index) => startAt + index * step);
58
+ function sanitizeStr(s) {
59
+ return s?.replace(/\n|\t/, " ").replace(/ {2,}/, " ").trim().toLowerCase() || "";
304
60
  }
305
61
  class DataFilter {
306
62
  constructor(rules, state) {
@@ -395,7 +151,9 @@ class DataManager {
395
151
  }
396
152
  }
397
153
  requestAnimationFrame(() => {
398
- updates.forEach((update) => update());
154
+ updates.forEach((update) => {
155
+ update();
156
+ });
399
157
  });
400
158
  });
401
159
  __publicField(this, "filterAll", (offset) => {
@@ -434,7 +192,8 @@ class DataManager {
434
192
  (target) => !this.isFiltered(target)
435
193
  );
436
194
  this.dataFilters = new DataFilter(rules, state).filters;
437
- [window, unsafeWindow || {}].forEach((w) => {
195
+ const targets = [window, globalThis.unsafeWindow].filter(Boolean);
196
+ targets.forEach((w) => {
438
197
  Object.assign(w, {
439
198
  sortByViews: () => this.sort("view"),
440
199
  sortByDuration: () => this.sort("duration")
@@ -443,7 +202,7 @@ class DataManager {
443
202
  }
444
203
  static filterDSLToRegex(str) {
445
204
  const toFullWord = (w) => `(^|\\ )${w}($|\\ )`;
446
- const str_ = str.replace(/f\:(\w+)/g, (_, w) => toFullWord(w));
205
+ const str_ = str.replace(/f:(\w+)/g, (_, w) => toFullWord(w));
447
206
  return stringToWords(str_).map((expr) => new RegExp(expr, "i"));
448
207
  }
449
208
  isFiltered(el) {
@@ -461,9 +220,117 @@ class DataManager {
461
220
  });
462
221
  }
463
222
  }
464
- class InfiniteScroller {
465
- constructor({
466
- enabled = true,
223
+ function parseDom(html) {
224
+ const parsed = new DOMParser().parseFromString(html, "text/html").body;
225
+ return parsed.children.length > 1 ? parsed : parsed.firstElementChild;
226
+ }
227
+ function copyAttributes(target, source) {
228
+ for (const attr of source.attributes) {
229
+ attr.nodeValue && target.setAttribute(attr.nodeName, attr.nodeValue);
230
+ }
231
+ }
232
+ function replaceElementTag(e, tagName) {
233
+ const newTagElement = document.createElement(tagName);
234
+ copyAttributes(newTagElement, e);
235
+ newTagElement.innerHTML = e.innerHTML;
236
+ e.parentNode?.replaceChild(newTagElement, e);
237
+ return newTagElement;
238
+ }
239
+ function getAllUniqueParents(elements) {
240
+ return Array.from(elements).reduce((acc, v) => {
241
+ if (v.parentElement && !acc.includes(v.parentElement)) {
242
+ acc.push(v.parentElement);
243
+ }
244
+ return acc;
245
+ }, []);
246
+ }
247
+ function findNextSibling(el) {
248
+ if (el.nextElementSibling) return el.nextElementSibling;
249
+ if (el.parentElement) return findNextSibling(el.parentElement);
250
+ return null;
251
+ }
252
+ function waitForElementExists(parent, selector, callback) {
253
+ const observer = new MutationObserver((_mutations) => {
254
+ const el = parent.querySelector(selector);
255
+ if (el) {
256
+ observer.disconnect();
257
+ callback(el);
258
+ }
259
+ });
260
+ observer.observe(document.body, { childList: true, subtree: true });
261
+ }
262
+ function watchElementChildrenCount(element, callback) {
263
+ let count = element.children.length;
264
+ const observer = new MutationObserver((mutationList, observer2) => {
265
+ for (const mutation of mutationList) {
266
+ if (mutation.type === "childList") {
267
+ if (count !== element.children.length) {
268
+ count = element.children.length;
269
+ callback(observer2, count);
270
+ }
271
+ }
272
+ }
273
+ });
274
+ observer.observe(element, { childList: true });
275
+ }
276
+ function watchDomChangesWithThrottle(element, callback, throttle = 1e3, times = Infinity, options = { childList: true, subtree: true, attributes: true }) {
277
+ let lastMutationTime;
278
+ let timeout;
279
+ let times_ = times;
280
+ const observer = new MutationObserver((_mutationList, _observer) => {
281
+ if (times_ !== Infinity && times_ < 1) {
282
+ observer.disconnect();
283
+ return;
284
+ }
285
+ times_--;
286
+ const now = Date.now();
287
+ if (lastMutationTime && now - lastMutationTime < throttle) {
288
+ timeout && clearTimeout(timeout);
289
+ }
290
+ timeout = setTimeout(callback, throttle);
291
+ lastMutationTime = now;
292
+ });
293
+ observer.observe(element, options);
294
+ return observer;
295
+ }
296
+ function downloader(options = { append: "", after: "", button: "", cbBefore: () => {
297
+ } }) {
298
+ const btn = parseDom(options.button);
299
+ if (options.append) document.querySelector(options.append)?.append(btn);
300
+ if (options.after) document.querySelector(options.after)?.after(btn);
301
+ btn.addEventListener("click", (e) => {
302
+ e.preventDefault();
303
+ if (options.cbBefore) options.cbBefore();
304
+ waitForElementExists(document.body, "video", (video) => {
305
+ window.location.href = video.getAttribute("src");
306
+ });
307
+ });
308
+ }
309
+ function exterminateVideo(video) {
310
+ video.removeAttribute("src");
311
+ video.load();
312
+ video.remove();
313
+ }
314
+ const MOBILE_UA = [
315
+ "Mozilla/5.0 (Linux; Android 10; K)",
316
+ "AppleWebKit/537.36 (KHTML, like Gecko)",
317
+ "Chrome/114.0.0.0 Mobile Safari/537.36"
318
+ ].join(" ");
319
+ function fetchWith(url, options = { html: false, mobile: false }) {
320
+ const reqOpts = {};
321
+ if (options.mobile) Object.assign(reqOpts, { headers: new Headers({ "User-Agent": MOBILE_UA }) });
322
+ return fetch(url, reqOpts).then((r) => r.text()).then((r) => options.html ? parseDom(r) : r);
323
+ }
324
+ const fetchHtml = (url) => fetchWith(url, { html: true });
325
+ const fetchText = (url) => fetchWith(url);
326
+ function objectToFormData(object) {
327
+ const formData = new FormData();
328
+ Object.entries(object).forEach(([k, v]) => formData.append(k, v));
329
+ return formData;
330
+ }
331
+ class InfiniteScroller {
332
+ constructor({
333
+ enabled = true,
467
334
  delay = 350,
468
335
  writeHistory = false,
469
336
  paginationOffset,
@@ -484,10 +351,7 @@ class InfiniteScroller {
484
351
  __publicField(this, "onScrollCBs", []);
485
352
  __publicField(this, "generatorConsumer", async () => {
486
353
  if (!this.enabled) return false;
487
- const {
488
- value: { url, offset } = {},
489
- done
490
- } = await this.paginationGenerator.next();
354
+ const { value: { url, offset } = {}, done } = await this.paginationGenerator.next();
491
355
  if (!done) {
492
356
  const nextPageHTML = await fetchHtml(url);
493
357
  const prevScrollPos = document.documentElement.scrollTop;
@@ -521,7 +385,9 @@ class InfiniteScroller {
521
385
  return this;
522
386
  }
523
387
  _onScroll() {
524
- this.onScrollCBs.forEach((cb) => cb(this));
388
+ this.onScrollCBs.forEach((cb) => {
389
+ cb(this);
390
+ });
525
391
  }
526
392
  static *createPaginationGenerator(currentPage, totalPages, generateURL) {
527
393
  for (let offset = currentPage + 1; offset <= totalPages; offset++) {
@@ -532,10 +398,6 @@ class InfiniteScroller {
532
398
  }
533
399
  function createInfiniteScroller(store, handleHtmlCallback, rules) {
534
400
  const enabled = store.state.infiniteScrollEnabled;
535
- rules.paginationOffset = rules.paginationStrategy.getPaginationOffset();
536
- rules.paginationLast = rules.paginationStrategy.getPaginationLast();
537
- rules.paginationUrlGenerator = rules.paginationStrategy.getPaginationUrlGenerator();
538
- rules.paginationElement = rules.paginationStrategy.getPaginationElement();
539
401
  const iscroller = new InfiniteScroller({
540
402
  enabled,
541
403
  handleHtmlCallback,
@@ -549,6 +411,333 @@ function createInfiniteScroller(store, handleHtmlCallback, rules) {
549
411
  });
550
412
  return iscroller;
551
413
  }
414
+ function getPaginationLinks(doc = document, url = location.href, pathnameSelector = /\/(page\/)?\d+\/?$/) {
415
+ const currentUrl = parseURL(url);
416
+ currentUrl.pathname = currentUrl.pathname.replace(pathnameSelector, "/");
417
+ const pageLinks = Array.from(
418
+ doc.querySelectorAll("a[href]") || [],
419
+ (a) => a.href
420
+ ).filter((h) => {
421
+ try {
422
+ const linkUrl = new URL(h.replace(/#$/, ""), doc.baseURI || currentUrl.origin);
423
+ return linkUrl.origin === currentUrl.origin && linkUrl.pathname.startsWith(currentUrl.pathname);
424
+ } catch {
425
+ return false;
426
+ }
427
+ });
428
+ return pageLinks;
429
+ }
430
+ function parseURL(s) {
431
+ if (typeof s === "string") return new URL(s);
432
+ return new URL(s.href);
433
+ }
434
+ class PaginationStrategy {
435
+ constructor(options) {
436
+ __publicField(this, "doc", document);
437
+ __publicField(this, "url");
438
+ __publicField(this, "paginationSelector", ".pagination");
439
+ __publicField(this, "fixPaginationLast");
440
+ __publicField(this, "offsetMin", 1);
441
+ if (options) {
442
+ Object.entries(options).forEach(([k, v]) => {
443
+ Object.assign(this, { [k]: v });
444
+ });
445
+ }
446
+ this.url = parseURL(options?.url || this.doc.URL);
447
+ }
448
+ getPaginationElement() {
449
+ return this.doc.querySelector(this.paginationSelector) || this.doc;
450
+ }
451
+ }
452
+ function formatTimeToHHMMSS(timeString) {
453
+ const regex = /(?:(\d+)\s*h\s*)?(?:(\d+)\s*mi?n?\s*)?(?:(\d+)\s*sec)?/;
454
+ const match = timeString.match(regex);
455
+ const h = parseInt(match?.[1] || "0");
456
+ const m = parseInt(match?.[2] || "0");
457
+ const s = parseInt(match?.[3] || "0");
458
+ const pad = (num) => String(num).padStart(2, "0");
459
+ return `${pad(h)}:${pad(m)}:${pad(s)}`;
460
+ }
461
+ function timeToSeconds(t) {
462
+ const r = /sec|min|h|m/.test(t) ? formatTimeToHHMMSS(t) : t;
463
+ return (r?.match(/\d+/gm) || [0]).reverse().map((s, i) => parseInt(s) * 60 ** i).reduce((a, b) => a + b);
464
+ }
465
+ function parseIntegerOr(n, or) {
466
+ return ((num) => Number.isNaN(num) ? or : num)(parseInt(n));
467
+ }
468
+ function parseDataParams(str) {
469
+ const paramsStr = decodeURI(str.trim()).split(";");
470
+ return paramsStr.reduce((acc, s) => {
471
+ const parsed = s.match(/([\+\w]+):([\w\-\ ]+)?/);
472
+ if (parsed) {
473
+ const [, key, value] = parsed;
474
+ if (value) {
475
+ key.split("+").forEach((p) => {
476
+ acc[p] = value;
477
+ });
478
+ }
479
+ }
480
+ return acc;
481
+ }, {});
482
+ }
483
+ function parseCSSUrl(s) {
484
+ return s.replace(/url\("|\"\).*/g, "");
485
+ }
486
+ class PaginationStrategyDataParams extends PaginationStrategy {
487
+ getPaginationLast() {
488
+ const links = this.getPaginationElement()?.querySelectorAll("[data-parameters *= from]");
489
+ const pages = Array.from(links || [], (l) => {
490
+ const p = l.getAttribute("data-parameters");
491
+ const v = p?.match(/from\w*:(\d+)/)?.[1] || this.offsetMin.toString();
492
+ return parseInt(v);
493
+ });
494
+ const lastPage = Math.max(...pages, this.offsetMin);
495
+ if (this.fixPaginationLast) return this.fixPaginationLast(lastPage);
496
+ return lastPage;
497
+ }
498
+ getPaginationOffset() {
499
+ const link = this.getPaginationElement()?.querySelector(
500
+ ".prev[data-parameters *= from], .prev [data-parameters *= from]"
501
+ );
502
+ if (!link) return this.offsetMin;
503
+ const p = link.getAttribute("data-parameters");
504
+ const v = p?.match(/from\w*:(\d+)/)?.[1] || this.offsetMin.toString();
505
+ return parseInt(v);
506
+ }
507
+ getPaginationUrlGenerator() {
508
+ const url = new URL(this.url.href);
509
+ const parametersElement = this.getPaginationElement()?.querySelector(
510
+ "a[data-block-id][data-parameters]"
511
+ );
512
+ const block_id = parametersElement?.getAttribute("data-block-id") || "";
513
+ const parameters = parseDataParams(parametersElement?.getAttribute("data-parameters") || "");
514
+ const attrs = {
515
+ mode: "async",
516
+ function: "get_block",
517
+ block_id,
518
+ ...parameters
519
+ };
520
+ Object.keys(attrs).forEach((k) => {
521
+ url.searchParams.set(k, attrs[k]);
522
+ });
523
+ const paginationUrlGenerator = (n) => {
524
+ Object.keys(attrs).forEach((k) => {
525
+ k.includes("from") && url.searchParams.set(k, n.toString());
526
+ });
527
+ url.searchParams.set("_", Date.now().toString());
528
+ return url.href;
529
+ };
530
+ return paginationUrlGenerator;
531
+ }
532
+ }
533
+ class PaginationStrategyPathnameParams extends PaginationStrategy {
534
+ constructor() {
535
+ super(...arguments);
536
+ __publicField(this, "pathnameSelector", /\/(\d+)\/?$/);
537
+ __publicField(this, "extractPage", (a) => {
538
+ const href = typeof a === "string" ? a : a.href;
539
+ const { pathname } = new URL(href, this.doc.baseURI || this.url.origin);
540
+ return parseInt(pathname.match(this.pathnameSelector)?.pop() || this.offsetMin.toString());
541
+ });
542
+ }
543
+ getPaginationLast() {
544
+ const links = getPaginationLinks(
545
+ this.getPaginationElement(),
546
+ this.url.href,
547
+ this.pathnameSelector
548
+ );
549
+ const pages = Array.from(links, this.extractPage);
550
+ const lastPage = Math.max(...pages, this.offsetMin);
551
+ if (this.fixPaginationLast) return this.fixPaginationLast(lastPage);
552
+ return lastPage;
553
+ }
554
+ getPaginationOffset() {
555
+ return this.extractPage(this.url.href);
556
+ }
557
+ getPaginationUrlGenerator(url_ = this.url) {
558
+ const url = new URL(url_.href);
559
+ const pathnameSelectorPlaceholder = this.pathnameSelector.toString().replace(/[/|\\|$|?|(|)]+/g, "/");
560
+ if (!this.pathnameSelector.test(url.pathname)) {
561
+ url.pathname = url.pathname.concat(pathnameSelectorPlaceholder.replace(/d\+/, this.offsetMin.toString())).replace(/\/{2,}/g, "/");
562
+ }
563
+ const paginationUrlGenerator = (offset) => {
564
+ url.pathname = url.pathname.replace(
565
+ this.pathnameSelector,
566
+ pathnameSelectorPlaceholder.replace(/d\+/, offset.toString())
567
+ );
568
+ return url.href;
569
+ };
570
+ return paginationUrlGenerator;
571
+ }
572
+ }
573
+ class PaginationStrategySearchParams extends PaginationStrategy {
574
+ constructor() {
575
+ super(...arguments);
576
+ __publicField(this, "searchParamSelector", "page");
577
+ }
578
+ getPaginationElement() {
579
+ return this.doc.querySelector(this.paginationSelector) || this.doc;
580
+ }
581
+ extractPage(a) {
582
+ const href = typeof a === "string" ? a : a.href;
583
+ const p = new URL(href).searchParams.get(this.searchParamSelector);
584
+ return parseInt(p) || this.offsetMin;
585
+ }
586
+ getPaginationLast() {
587
+ const links = getPaginationLinks(this.getPaginationElement(), this.url.href).filter(
588
+ (h) => /(page|p)=\d+/.test(h)
589
+ );
590
+ const pages = links.map(this.extractPage);
591
+ const lastPage = Math.max(...pages, this.offsetMin);
592
+ if (this.fixPaginationLast) return this.fixPaginationLast(lastPage);
593
+ return lastPage;
594
+ }
595
+ getPaginationOffset() {
596
+ if (this.doc === document) {
597
+ return this.extractPage(this.url);
598
+ }
599
+ const link = this.getPaginationElement().querySelector(
600
+ `a.active[href *= "${this.searchParamSelector}="]`
601
+ );
602
+ return this.extractPage(link);
603
+ }
604
+ getPaginationUrlGenerator() {
605
+ const url = new URL(this.url.href);
606
+ const paginationUrlGenerator = (offset) => {
607
+ url.searchParams.set(this.searchParamSelector, offset.toString());
608
+ return url.href;
609
+ };
610
+ return paginationUrlGenerator;
611
+ }
612
+ }
613
+ function getPaginationStrategy(options) {
614
+ const { doc = document, url = location.href } = options;
615
+ const pageLinks = getPaginationLinks(doc, url);
616
+ console.log({ pageLinks });
617
+ const getStrategy = () => {
618
+ if (pageLinks.some((h) => /(page|p)=\d+/.test(h))) {
619
+ const l = pageLinks.filter((h) => /(page|p)=\d+/.test(h));
620
+ console.log("PaginationStrategySearchParams", l);
621
+ return PaginationStrategySearchParams;
622
+ }
623
+ if (pageLinks.some((h) => /\/(page\/)?\d+\/?$/.test(h))) {
624
+ const l = pageLinks.filter((h) => /\/(page\/)?\d+\/?$/.test(h));
625
+ console.log("PaginationStrategyPathnameParams", l);
626
+ return PaginationStrategyPathnameParams;
627
+ }
628
+ const type5Links = Array.from(document.querySelectorAll("[data-parameters *= from]"));
629
+ if (type5Links.length > 0) {
630
+ console.log("PaginationStrategyDataParams", type5Links);
631
+ return PaginationStrategyDataParams;
632
+ }
633
+ console.error("Found No Strategy");
634
+ return PaginationStrategy;
635
+ };
636
+ const paginationStrategy = new (getStrategy())(options);
637
+ return paginationStrategy;
638
+ }
639
+ function chunks(arr, n) {
640
+ return Array.from({ length: Math.ceil(arr.length / n) }, (_, i) => arr.slice(i * n, i * n + n));
641
+ }
642
+ function range(size, startAt = 1, step = 1) {
643
+ return Array.from({ length: size }, (_, index) => startAt + index * step);
644
+ }
645
+ async function computeAsyncOneAtTime(iterable) {
646
+ const res = [];
647
+ for await (const f of iterable) {
648
+ res.push(await f());
649
+ }
650
+ return res;
651
+ }
652
+ function wait(milliseconds) {
653
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
654
+ }
655
+ class AsyncPool {
656
+ constructor(max = 1, pool = []) {
657
+ __publicField(this, "cur", 0);
658
+ __publicField(this, "finished");
659
+ __publicField(this, "_resolve");
660
+ this.max = max;
661
+ this.pool = pool;
662
+ this.finished = new Promise((resolve) => {
663
+ this._resolve = resolve;
664
+ });
665
+ }
666
+ static async doNAsyncAtOnce(max = 1, pool = []) {
667
+ const spool = new AsyncPool(max);
668
+ pool.forEach((f) => spool.push(f));
669
+ return spool.run();
670
+ }
671
+ getHighPriorityFirst(p = 0) {
672
+ if (p > 3 || this.pool.length === 0) return void 0;
673
+ const i = this.pool.findIndex((e) => e.p === p);
674
+ if (i >= 0) {
675
+ const res = this.pool[i].v;
676
+ this.pool.splice(i, 1);
677
+ return res;
678
+ }
679
+ return this.getHighPriorityFirst(p + 1);
680
+ }
681
+ async runTask() {
682
+ this.cur++;
683
+ const f = this.getHighPriorityFirst();
684
+ await f?.();
685
+ this.cur--;
686
+ this.runTasks();
687
+ }
688
+ runTasks() {
689
+ if (!this.pool.length) {
690
+ this._resolve?.(true);
691
+ return;
692
+ }
693
+ if (this.cur < this.max) {
694
+ this.runTask();
695
+ this.runTasks();
696
+ }
697
+ }
698
+ async run() {
699
+ this.runTasks();
700
+ return this.finished;
701
+ }
702
+ push(x) {
703
+ this.pool.push("p" in x ? x : { v: x, p: 0 });
704
+ }
705
+ }
706
+ function isMob() {
707
+ return /iPhone|Android/i.test(navigator.userAgent);
708
+ }
709
+ function listenEvents(dom, events, callback) {
710
+ for (const e of events) {
711
+ dom.addEventListener(e, callback, true);
712
+ }
713
+ }
714
+ class Tick {
715
+ constructor(delay, startImmediate = true) {
716
+ __publicField(this, "tick");
717
+ __publicField(this, "callbackFinal");
718
+ this.delay = delay;
719
+ this.startImmediate = startImmediate;
720
+ }
721
+ start(callback, callbackFinal) {
722
+ this.stop();
723
+ this.callbackFinal = callbackFinal;
724
+ if (this.startImmediate) callback();
725
+ this.tick = window.setInterval(callback, this.delay);
726
+ }
727
+ stop() {
728
+ if (this.tick !== void 0) {
729
+ clearInterval(this.tick);
730
+ this.tick = void 0;
731
+ }
732
+ if (this.callbackFinal) {
733
+ this.callbackFinal();
734
+ this.callbackFinal = void 0;
735
+ }
736
+ }
737
+ }
738
+ function circularShift(n, c = 6, s = 1) {
739
+ return (n + s) % c || c;
740
+ }
552
741
  export {
553
742
  AsyncPool,
554
743
  DataManager,
@@ -556,6 +745,10 @@ export {
556
745
  LazyImgLoader,
557
746
  MOBILE_UA,
558
747
  Observer,
748
+ PaginationStrategy,
749
+ PaginationStrategyDataParams,
750
+ PaginationStrategyPathnameParams,
751
+ PaginationStrategySearchParams,
559
752
  Tick,
560
753
  chunks,
561
754
  circularShift,
@@ -569,6 +762,7 @@ export {
569
762
  fetchWith,
570
763
  findNextSibling,
571
764
  getAllUniqueParents,
765
+ getPaginationStrategy,
572
766
  isMob,
573
767
  listenEvents,
574
768
  objectToFormData,