{
  "version": 3,
  "sources": ["../../src/collections/LinkedList.ts", "../../src/collections/Pager.ts"],
  "sourcesContent": ["/**\r\n * A node in the @see LinkedList.\r\n */\r\nexport class Node<T> {\r\n    /**\r\n     * Next node unless last one.\r\n     */\r\n    public next: Node<T> | null = null;\r\n    /**\r\n     * Previous node unless first one.\r\n     */\r\n    public prev: Node<T> | null = null;\r\n\r\n    /**\r\n     * Constructor.\r\n     * @param value Value contained in the node.\r\n     */\r\n    constructor(public value: T, private removeCallback: () => void) {}\r\n\r\n    /**\r\n     * Remove this node.\r\n     * Will notify the list of the update to ensure correct element count.\r\n     */\r\n    remove() {\r\n        if (this.prev) this.prev.next = this.next;\r\n        if (this.next) this.next.prev = this.prev;\r\n        this.removeCallback();\r\n    }\r\n}\r\n\r\n/**\r\n * A trivial linked list implementation.\r\n */\r\nexport class LinkedList<T> {\r\n    private _first: Node<T> | null = null;\r\n    private _last: Node<T> | null = null;\r\n    private _length = 0;\r\n\r\n    /**\r\n     * Add a value to the beginning of the list.\r\n     * @param value Value that should be contained in the node.\r\n     */\r\n    addFirst(value: T) {\r\n        const newNode = this.createNode(value);\r\n        if (!this._first) {\r\n            this._first = newNode;\r\n            this._last = this._first;\r\n        } else {\r\n            newNode.next = this._first;\r\n            this._first.prev = newNode;\r\n            this._first = newNode;\r\n        }\r\n\r\n        this._length++;\r\n    }\r\n\r\n    /**\r\n     * Add a value to the end of the list.\r\n     * @param value Value that should be contained in a node.\r\n     */\r\n    addLast(value: T) {\r\n        const newNode = this.createNode(value);\r\n        if (!this._last) {\r\n            this._first = newNode;\r\n            this._last = newNode;\r\n        } else {\r\n            newNode.prev = this._last;\r\n            this._last.next = newNode;\r\n            this._last = newNode;\r\n        }\r\n\r\n        this._length++;\r\n    }\r\n\r\n    private createNode(value: T): Node<T> {\r\n        let node: Node<T>;\r\n        node = new Node(value, () => {\r\n            if (this._first === node) this._first = node.next;\r\n            if (this._last === node) this._last = node.prev;\r\n            this._length--;\r\n        });\r\n        return node;\r\n    }\r\n\r\n    /**\r\n     * Remove a node from the beginning of the list.\r\n     * @returns Value contained in the first node.\r\n     */\r\n    removeFirst(): T {\r\n        if (!this._first) {\r\n            throw new Error('The list is empty.');\r\n        }\r\n\r\n        const value = this._first.value;\r\n        this._first = this._first.next;\r\n        if (!this._first) this._last = null;\r\n        this._length--;\r\n        return value;\r\n    }\r\n\r\n    /**\r\n     * Remove a node from the end of the list.\r\n     * @returns Value contained in the last node.\r\n     */\r\n    removeLast(): T {\r\n        if (!this._last) {\r\n            throw new Error('The list is empty.');\r\n        }\r\n\r\n        const value = this._last.value;\r\n        this._last = this._last.prev;\r\n        if (!this._last) this._first = null;\r\n        this._length--;\r\n        return value;\r\n    }\r\n\r\n    /**\r\n     * Number of nodes in the list.\r\n     *\r\n     * The count works as long as you do not manually remove nodes (by assigning next/prev to the neighbors).\r\n     */\r\n    get length(): number {\r\n        return this._length;\r\n    }\r\n\r\n    /**\r\n     * First node, or `null` if the list is empty.\r\n     */\r\n    get first(): Node<T> | null {\r\n        return this._first;\r\n    }\r\n\r\n    /**\r\n     * Contained value of the first node, or `undefined` if the list is empty.\r\n     */\r\n    get firstValue(): T | undefined {\r\n        return this._first?.value;\r\n    }\r\n\r\n    /**\r\n     * Last node, or `null` if the list is empty.\r\n     */\r\n    get last(): Node<T> | null {\r\n        return this._last;\r\n    }\r\n\r\n    /**\r\n     * Contained value of the last node, or `undefined` if the list is empty.\r\n     */\r\n    get lastValue(): T | undefined {\r\n        return this._last?.value;\r\n    }\r\n}\r\n", "export class PageSelectedEvent extends Event {\r\n  constructor(public page: number) {\r\n    super('pageselected', {\r\n      bubbles: true,\r\n      composed: true,\r\n    });\r\n  }\r\n}\r\n\r\ndeclare global {\r\n  interface HTMLElementEventMap {\r\n    'pageselected': PageSelectedEvent;\r\n  }\r\n}\r\n\r\nexport class Pager {\r\n  private container: HTMLElement;\r\n  private totalCount: number;\r\n  private pageSize: number;\r\n  private currentPage: number = 1;\r\n\r\n  constructor(container: HTMLElement, totalCount: number, pageSize: number) {\r\n    this.container = container;\r\n    this.totalCount = totalCount;\r\n    this.pageSize = pageSize;\r\n\r\n    this.render();\r\n  }\r\n\r\n  private render() {\r\n    this.container.innerHTML = '';\r\n\r\n    const pageCount = Math.max(1, Math.ceil(this.totalCount / this.pageSize));\r\n\r\n    const createButton = (label: string, page: number, disabled: boolean = false) => {\r\n      const btn = document.createElement('button');\r\n      btn.textContent = label;\r\n      btn.disabled = disabled;\r\n      btn.addEventListener('click', () => this.selectPage(page));\r\n      return btn;\r\n    };\r\n\r\n    this.container.appendChild(\r\n      createButton('Previous', this.currentPage - 1, this.currentPage === 1)\r\n    );\r\n\r\n    for (let i = 1; i <= pageCount; i++) {\r\n      const btn = createButton(i.toString(), i);\r\n      if (i === this.currentPage) {\r\n        btn.classList.add('selected');\r\n      }\r\n      this.container.appendChild(btn);\r\n    }\r\n\r\n    this.container.appendChild(\r\n      createButton('Next', this.currentPage + 1, this.currentPage === pageCount)\r\n    );\r\n  }\r\n\r\n  private selectPage(page: number) {\r\n    const pageCount = Math.max(1, Math.ceil(this.totalCount / this.pageSize));\r\n    if (page < 1 || page > pageCount || page === this.currentPage) return;\r\n\r\n    this.currentPage = page;\r\n    this.render();\r\n\r\n    this.container.dispatchEvent(new PageSelectedEvent(this.currentPage));\r\n  }\r\n\r\n  public update(totalCount: number) {\r\n    this.totalCount = totalCount;\r\n    const pageCount = Math.max(1, Math.ceil(this.totalCount / this.pageSize));\r\n    if (this.currentPage > pageCount) {\r\n      this.currentPage = pageCount;\r\n    }\r\n    this.render();\r\n  }\r\n\r\n  public getCurrentPage(): number {\r\n    return this.currentPage;\r\n  }\r\n}\r\n"],
  "mappings": "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",
  "names": ["Node", "value", "removeCallback", "LinkedList", "newNode", "node", "PageSelectedEvent", "page", "Pager", "container", "totalCount", "pageSize", "pageCount", "createButton", "label", "disabled", "btn"]
}
