pagy 9.3.3 → 43.0.0.rc1

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.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/apps/calendar.ru +547 -551
  4. data/apps/demo.ru +221 -178
  5. data/apps/index.rb +3 -1
  6. data/apps/keynav.ru +258 -0
  7. data/apps/{keyset_ar.ru → keyset.ru} +27 -32
  8. data/apps/{keyset_s.ru → keyset_sequel.ru} +24 -29
  9. data/apps/rails.ru +51 -48
  10. data/apps/repro.ru +46 -43
  11. data/bin/pagy +22 -23
  12. data/config/pagy.rb +35 -207
  13. data/javascripts/ai_widget.js +76 -0
  14. data/javascripts/pagy.js +151 -0
  15. data/javascripts/pagy.js.map +10 -0
  16. data/javascripts/pagy.min.js +1 -4
  17. data/javascripts/pagy.mjs +111 -63
  18. data/javascripts/wand.js +1166 -0
  19. data/lib/pagy/classes/calendar/calendar.rb +98 -0
  20. data/lib/pagy/{calendar → classes/calendar}/day.rb +7 -11
  21. data/lib/pagy/{calendar → classes/calendar}/month.rb +5 -10
  22. data/lib/pagy/{calendar → classes/calendar}/quarter.rb +10 -15
  23. data/lib/pagy/classes/calendar/unit.rb +92 -0
  24. data/lib/pagy/{calendar → classes/calendar}/week.rb +5 -9
  25. data/lib/pagy/{calendar → classes/calendar}/year.rb +5 -6
  26. data/lib/pagy/classes/exceptions.rb +33 -0
  27. data/lib/pagy/classes/keyset/active_record.rb +11 -0
  28. data/lib/pagy/classes/keyset/adapters/active_record.rb +50 -0
  29. data/lib/pagy/classes/keyset/adapters/sequel.rb +63 -0
  30. data/lib/pagy/classes/keyset/keynav/active_record.rb +13 -0
  31. data/lib/pagy/classes/keyset/keynav/sequel.rb +13 -0
  32. data/lib/pagy/classes/keyset/keynav.rb +77 -0
  33. data/lib/pagy/classes/keyset/keyset.rb +126 -0
  34. data/lib/pagy/classes/keyset/sequel.rb +11 -0
  35. data/lib/pagy/classes/offset/countless.rb +56 -0
  36. data/lib/pagy/classes/offset/offset.rb +54 -0
  37. data/lib/pagy/classes/offset/search.rb +38 -0
  38. data/lib/pagy/classes/request.rb +36 -0
  39. data/lib/pagy/modules/abilities/configurable.rb +36 -0
  40. data/lib/pagy/modules/abilities/linkable.rb +59 -0
  41. data/lib/pagy/modules/abilities/rangeable.rb +15 -0
  42. data/lib/pagy/modules/abilities/shiftable.rb +12 -0
  43. data/lib/pagy/{b64.rb → modules/b64.rb} +3 -7
  44. data/lib/pagy/modules/console.rb +38 -0
  45. data/lib/pagy/modules/i18n/i18n.rb +48 -0
  46. data/lib/pagy/modules/i18n/p11n/arabic.rb +29 -0
  47. data/lib/pagy/modules/i18n/p11n/east_slavic.rb +26 -0
  48. data/lib/pagy/modules/i18n/p11n/one_other.rb +15 -0
  49. data/lib/pagy/modules/i18n/p11n/one_upto_two_other.rb +15 -0
  50. data/lib/pagy/modules/i18n/p11n/other.rb +13 -0
  51. data/lib/pagy/modules/i18n/p11n/polish.rb +26 -0
  52. data/lib/pagy/modules/i18n/p11n/west_slavic.rb +22 -0
  53. data/lib/pagy/modules/i18n/p11n.rb +16 -0
  54. data/lib/pagy/modules/searcher.rb +20 -0
  55. data/lib/pagy/toolbox/helpers/anchor_tags.rb +25 -0
  56. data/lib/pagy/toolbox/helpers/bootstrap/input_nav_js.rb +24 -0
  57. data/lib/pagy/toolbox/helpers/bootstrap/previous_next_html.rb +18 -0
  58. data/lib/pagy/toolbox/helpers/bootstrap/series_nav.rb +29 -0
  59. data/lib/pagy/toolbox/helpers/bootstrap/series_nav_js.rb +21 -0
  60. data/lib/pagy/toolbox/helpers/bulma/input_nav_js.rb +21 -0
  61. data/lib/pagy/toolbox/helpers/bulma/previous_next_html.rb +19 -0
  62. data/lib/pagy/toolbox/helpers/bulma/series_nav.rb +28 -0
  63. data/lib/pagy/toolbox/helpers/bulma/series_nav_js.rb +20 -0
  64. data/lib/pagy/toolbox/helpers/data_hash.rb +26 -0
  65. data/lib/pagy/toolbox/helpers/headers_hash.rb +20 -0
  66. data/lib/pagy/toolbox/helpers/info_tag.rb +26 -0
  67. data/lib/pagy/toolbox/helpers/input_nav_js.rb +19 -0
  68. data/lib/pagy/toolbox/helpers/limit_tag_js.rb +23 -0
  69. data/lib/pagy/toolbox/helpers/loader.rb +33 -0
  70. data/lib/pagy/toolbox/helpers/page_url.rb +23 -0
  71. data/lib/pagy/toolbox/helpers/series_nav.rb +29 -0
  72. data/lib/pagy/toolbox/helpers/series_nav_js.rb +19 -0
  73. data/lib/pagy/toolbox/helpers/support/a_lambda.rb +34 -0
  74. data/lib/pagy/toolbox/helpers/support/data_pagy_attribute.rb +15 -0
  75. data/lib/pagy/toolbox/helpers/support/nav_aria_label_attribute.rb +12 -0
  76. data/lib/pagy/toolbox/helpers/support/series.rb +38 -0
  77. data/lib/pagy/toolbox/helpers/support/wrap_input_nav_js.rb +20 -0
  78. data/lib/pagy/toolbox/helpers/support/wrap_series_nav.rb +17 -0
  79. data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +36 -0
  80. data/lib/pagy/toolbox/helpers/urls_hash.rb +13 -0
  81. data/lib/pagy/toolbox/paginators/calendar.rb +30 -0
  82. data/lib/pagy/toolbox/paginators/countless.rb +25 -0
  83. data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +32 -0
  84. data/lib/pagy/toolbox/paginators/keynav_js.rb +29 -0
  85. data/lib/pagy/toolbox/paginators/keyset.rb +18 -0
  86. data/lib/pagy/toolbox/paginators/meilisearch.rb +32 -0
  87. data/lib/pagy/toolbox/paginators/method.rb +26 -0
  88. data/lib/pagy/toolbox/paginators/offset.rb +33 -0
  89. data/lib/pagy/toolbox/paginators/searchkick.rb +32 -0
  90. data/lib/pagy.rb +59 -97
  91. data/locales/ar.yml +9 -6
  92. data/locales/be.yml +9 -6
  93. data/locales/bg.yml +9 -6
  94. data/locales/bs.yml +9 -6
  95. data/locales/ca.yml +9 -6
  96. data/locales/ckb.yml +8 -6
  97. data/locales/cs.yml +9 -6
  98. data/locales/da.yml +9 -6
  99. data/locales/de.yml +9 -6
  100. data/locales/dz.yml +9 -6
  101. data/locales/en.yml +9 -6
  102. data/locales/es.yml +9 -6
  103. data/locales/fr.yml +9 -6
  104. data/locales/hr.yml +9 -6
  105. data/locales/id.yml +9 -6
  106. data/locales/it.yml +9 -6
  107. data/locales/ja.yml +9 -6
  108. data/locales/km.yml +9 -6
  109. data/locales/ko.yml +9 -6
  110. data/locales/nb.yml +9 -6
  111. data/locales/nl.yml +9 -6
  112. data/locales/nn.yml +9 -6
  113. data/locales/pl.yml +9 -6
  114. data/locales/pt-BR.yml +10 -7
  115. data/locales/pt.yml +10 -7
  116. data/locales/ru.yml +9 -6
  117. data/locales/sr.yml +9 -6
  118. data/locales/sv-SE.yml +9 -6
  119. data/locales/sv.yml +9 -6
  120. data/locales/sw.yml +12 -9
  121. data/locales/ta.yml +12 -9
  122. data/locales/tr.yml +9 -6
  123. data/locales/uk.yml +9 -6
  124. data/locales/vi.yml +9 -6
  125. data/locales/zh-CN.yml +9 -6
  126. data/locales/zh-HK.yml +9 -6
  127. data/locales/zh-TW.yml +9 -6
  128. data/stylesheets/pagy-tailwind.css +64 -0
  129. data/stylesheets/pagy.css +63 -27
  130. metadata +114 -56
  131. data/javascripts/pagy.min.js.map +0 -10
  132. data/lib/pagy/backend.rb +0 -44
  133. data/lib/pagy/calendar/unit.rb +0 -103
  134. data/lib/pagy/calendar.rb +0 -84
  135. data/lib/pagy/console.rb +0 -23
  136. data/lib/pagy/countless.rb +0 -38
  137. data/lib/pagy/exceptions.rb +0 -25
  138. data/lib/pagy/extras/arel.rb +0 -28
  139. data/lib/pagy/extras/array.rb +0 -19
  140. data/lib/pagy/extras/bootstrap.rb +0 -97
  141. data/lib/pagy/extras/bulma.rb +0 -93
  142. data/lib/pagy/extras/calendar.rb +0 -79
  143. data/lib/pagy/extras/countless.rb +0 -32
  144. data/lib/pagy/extras/elasticsearch_rails.rb +0 -71
  145. data/lib/pagy/extras/gearbox.rb +0 -55
  146. data/lib/pagy/extras/headers.rb +0 -54
  147. data/lib/pagy/extras/i18n.rb +0 -26
  148. data/lib/pagy/extras/js_tools.rb +0 -70
  149. data/lib/pagy/extras/jsonapi.rb +0 -86
  150. data/lib/pagy/extras/keyset.rb +0 -30
  151. data/lib/pagy/extras/limit.rb +0 -63
  152. data/lib/pagy/extras/meilisearch.rb +0 -57
  153. data/lib/pagy/extras/metadata.rb +0 -42
  154. data/lib/pagy/extras/overflow.rb +0 -81
  155. data/lib/pagy/extras/pagy.rb +0 -82
  156. data/lib/pagy/extras/searchkick.rb +0 -59
  157. data/lib/pagy/extras/size.rb +0 -40
  158. data/lib/pagy/extras/standalone.rb +0 -60
  159. data/lib/pagy/extras/trim.rb +0 -29
  160. data/lib/pagy/frontend.rb +0 -99
  161. data/lib/pagy/i18n.rb +0 -166
  162. data/lib/pagy/keyset/active_record.rb +0 -38
  163. data/lib/pagy/keyset/sequel.rb +0 -51
  164. data/lib/pagy/keyset.rb +0 -118
  165. data/lib/pagy/shared_methods.rb +0 -26
  166. data/lib/pagy/url_helpers.rb +0 -26
  167. data/stylesheets/pagy.scss +0 -48
  168. data/stylesheets/pagy.tailwind.css +0 -21
data/config/pagy.rb CHANGED
@@ -1,220 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Pagy initializer file (9.3.3)
4
- # Customize only what you really need and notice that the core Pagy works also without any of the following lines.
5
- # Should you just cherry pick part of this file, please maintain the require-order of the extras
3
+ # Pagy initializer file (43.0.0.rc1)
4
+ # See https://ddnexus.github.io/pagy/resources/initializer/
6
5
 
7
-
8
- # Pagy Variables
9
- # See https://ddnexus.github.io/pagy/docs/api/pagy#variables
10
- # You can set any pagy variable as a Pagy::DEFAULT. They can also be overridden per instance by just passing them to
11
- # Pagy.new|Pagy::Countless.new|Pagy::Calendar::*.new or any of the #pagy* controller methods
12
- # Here are the few that make more sense as DEFAULTs:
13
- # Pagy::DEFAULT[:limit] = 20 # default
14
- # Pagy::DEFAULT[:size] = 7 # default
15
- # Pagy::DEFAULT[:ends] = true # default
16
- # Pagy::DEFAULT[:page_param] = :page # default
17
- # Pagy::DEFAULT[:count_args] = [] # example for non AR ORMs
18
- # Pagy::DEFAULT[:max_pages] = 3000 # example
19
-
20
-
21
- # Extras
22
- # See https://ddnexus.github.io/pagy/categories/extra
23
-
24
-
25
- # Legacy Compatibility Extras
26
-
27
- # Size extra: Enable the Array type for the `:size` variable (e.g. `size: [1,4,4,1]`)
28
- # See https://ddnexus.github.io/pagy/docs/extras/size
29
- # require 'pagy/extras/size' # must be required before the other extras
30
-
31
-
32
- # Backend Extras
33
-
34
- # Arel extra: For better performance utilizing grouped ActiveRecord collections:
35
- # See: https://ddnexus.github.io/pagy/docs/extras/arel
36
- # require 'pagy/extras/arel'
37
-
38
- # Array extra: Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
39
- # See https://ddnexus.github.io/pagy/docs/extras/array
40
- # require 'pagy/extras/array'
41
-
42
- # Calendar extra: Add pagination filtering by calendar time unit (year, quarter, month, week, day)
43
- # See https://ddnexus.github.io/pagy/docs/extras/calendar
44
- # require 'pagy/extras/calendar'
45
- # Default for each calendar unit class in IRB:
46
- # >> Pagy::Calendar::Year::DEFAULT
47
- # >> Pagy::Calendar::Quarter::DEFAULT
48
- # >> Pagy::Calendar::Month::DEFAULT
49
- # >> Pagy::Calendar::Week::DEFAULT
50
- # >> Pagy::Calendar::Day::DEFAULT
6
+ ############ Global Options ################################################################
7
+ # See https://ddnexus.github.io/pagy/toolbox/options/ for details.
8
+ # Add your global options below. They will be applied globally.
9
+ # For example:
51
10
  #
52
- # Uncomment the following lines, if you need calendar localization without using the I18n extra
53
- # module LocalizePagyCalendar
54
- # def localize(time, opts)
55
- # ::I18n.l(time, **opts)
56
- # end
57
- # end
58
- # Pagy::Calendar.prepend LocalizePagyCalendar
59
-
60
- # Countless extra: Paginate without any count, saving one query per rendering
61
- # See https://ddnexus.github.io/pagy/docs/extras/countless
62
- # require 'pagy/extras/countless'
63
- # Pagy::DEFAULT[:countless_minimal] = false # default (eager loading)
64
-
65
- # Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects
66
- # See https://ddnexus.github.io/pagy/docs/extras/elasticsearch_rails
67
- # Default :pagy_search method: change only if you use also
68
- # the searchkick or meilisearch extra that defines the same
69
- # Pagy::DEFAULT[:elasticsearch_rails_pagy_search] = :pagy_search
70
- # Default original :search method called internally to do the actual search
71
- # Pagy::DEFAULT[:elasticsearch_rails_search] = :search
72
- # require 'pagy/extras/elasticsearch_rails'
73
-
74
- # Headers extra: http response headers (and other helpers) useful for API pagination
75
- # See https://ddnexus.github.io/pagy/docs/extras/headers
76
- # require 'pagy/extras/headers'
77
- # Pagy::DEFAULT[:headers] = { page: 'Current-Page',
78
- # limit: 'Page-Items',
79
- # count: 'Total-Count',
80
- # pages: 'Total-Pages' } # default
81
-
82
- # Keyset extra: Paginate with the Pagy keyset pagination technique
83
- # See https://ddnexus.github.io/pagy/docs/extras/keyset
84
- # require 'pagy/extras/keyset'
85
-
86
- # Meilisearch extra: Paginate `Meilisearch` result objects
87
- # See https://ddnexus.github.io/pagy/docs/extras/meilisearch
88
- # Default :pagy_search method: change only if you use also
89
- # the elasticsearch_rails or searchkick extra that define the same method
90
- # Pagy::DEFAULT[:meilisearch_pagy_search] = :pagy_search
91
- # Default original :search method called internally to do the actual search
92
- # Pagy::DEFAULT[:meilisearch_search] = :ms_search
93
- # require 'pagy/extras/meilisearch'
94
-
95
- # Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
96
- # See https://ddnexus.github.io/pagy/docs/extras/metadata
97
- # you must require the JS Tools internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels
98
- # require 'pagy/extras/js_tools'
99
- # require 'pagy/extras/metadata'
100
- # For performance reasons, you should explicitly set ONLY the metadata you use in the frontend
101
- # Pagy::DEFAULT[:metadata] = %i[scaffold_url page prev next last] # example
102
-
103
- # Searchkick extra: Paginate `Searchkick::Results` objects
104
- # See https://ddnexus.github.io/pagy/docs/extras/searchkick
105
- # Default :pagy_search method: change only if you use also
106
- # the elasticsearch_rails or meilisearch extra that defines the same
107
- # Pagy::DEFAULT[:searchkick_pagy_search] = :pagy_search
108
- # Default original :search method called internally to do the actual search
109
- # Pagy::DEFAULT[:searchkick_search] = :search
110
- # require 'pagy/extras/searchkick'
111
- # uncomment if you are going to use Searchkick.pagy_search
112
- # Searchkick.extend Pagy::Searchkick
113
-
11
+ # Pagy.options[:limit] = 10 # Limit the items per page
12
+ # Pagy.options[:client_max_limit] = 100 # The client can request a limit up to 100
13
+ # Pagy.options[:max_pages] = 200 # Allow only 200 pages
14
+ # Pagy.options[:jsonapi] = true # Use JSON:API compliant URLs
114
15
 
115
- # Frontend Extras
116
16
 
117
- # Bootstrap extra: Add nav, nav_js and combo_nav_js helpers and templates for Bootstrap pagination
118
- # See https://ddnexus.github.io/pagy/docs/extras/bootstrap
119
- # require 'pagy/extras/bootstrap'
120
-
121
- # Bulma extra: Add nav, nav_js and combo_nav_js helpers and templates for Bulma pagination
122
- # See https://ddnexus.github.io/pagy/docs/extras/bulma
123
- # require 'pagy/extras/bulma'
124
-
125
- # Pagy extra: Add the pagy styled versions of the javascript-powered navs
126
- # and a few other components to the Pagy::Frontend module.
127
- # See https://ddnexus.github.io/pagy/docs/extras/pagy
128
- # require 'pagy/extras/pagy'
129
-
130
- # Multi size var used by the *_nav_js helpers
131
- # See https://ddnexus.github.io/pagy/docs/extras/pagy#steps
132
- # Pagy::DEFAULT[:steps] = { 0 => 5, 540 => 7, 720 => 9 } # example
133
-
134
-
135
- # Feature Extras
136
-
137
- # Gearbox extra: Automatically change the limit per page depending on the page number
138
- # See https://ddnexus.github.io/pagy/docs/extras/gearbox
139
- # require 'pagy/extras/gearbox'
140
- # set to false only if you want to make :gearbox_extra an opt-in variable
141
- # Pagy::DEFAULT[:gearbox_extra] = false # default true
142
- # Pagy::DEFAULT[:gearbox_limit] = [15, 30, 60, 100] # default
143
-
144
- # Limit extra: Allow the client to request a custom limit per page with an optional selector UI
145
- # See https://ddnexus.github.io/pagy/docs/extras/limit
146
- # require 'pagy/extras/limit'
147
- # set to false only if you want to make :limit_extra an opt-in variable
148
- # Pagy::DEFAULT[:limit_extra] = false # default true
149
- # Pagy::DEFAULT[:limit_param] = :limit # default
150
- # Pagy::DEFAULT[:limit_max] = 100 # default
151
-
152
- # Overflow extra: Allow for easy handling of overflowing pages
153
- # See https://ddnexus.github.io/pagy/docs/extras/overflow
154
- # require 'pagy/extras/overflow'
155
- # Pagy::DEFAULT[:overflow] = :empty_page # default (other options: :last_page and :exception)
156
-
157
- # Trim extra: Remove the page=1 param from links
158
- # See https://ddnexus.github.io/pagy/docs/extras/trim
159
- # require 'pagy/extras/trim'
160
- # set to false only if you want to make :trim_extra an opt-in variable
161
- # Pagy::DEFAULT[:trim_extra] = false # default true
162
-
163
- # Standalone extra: Use pagy in non Rack environment/gem
164
- # See https://ddnexus.github.io/pagy/docs/extras/standalone
165
- # require 'pagy/extras/standalone'
166
- # Pagy::DEFAULT[:url] = 'http://www.example.com/subdir' # optional default
167
-
168
- # Jsonapi extra: Implements JSON:API specifications
169
- # See https://ddnexus.github.io/pagy/docs/extras/jsonapi
170
- # require 'pagy/extras/jsonapi' # must be required after the other extras
171
- # set to false only if you want to make :jsonapi an opt-in variable
172
- # Pagy::DEFAULT[:jsonapi] = false # default true
173
-
174
- # Rails
175
- # Enable the .js file required by the helpers that use javascript
176
- # (pagy*_nav_js, pagy*_combo_nav_js, and pagy_limit_selector_js)
177
- # See https://ddnexus.github.io/pagy/docs/api/javascript
178
-
179
- # With the asset pipeline
180
- # Sprockets need to look into the pagy javascripts dir, so add it to the assets paths
181
- # Rails.application.config.assets.paths << Pagy.root.join('javascripts')
17
+ ############ JavaScript ####################################################################
18
+ # See https://ddnexus.github.io/pagy/resources/javascript/ for details.
19
+ # Examples for Rails:
20
+ # For apps with an assets pipeline
21
+ # Rails.application.config.assets.paths << Pagy::ROOT.join('javascripts')
22
+ #
23
+ # For apps with a javascript builder (e.g. esbuild, webpack, etc.)
24
+ # javascript_dir = Rails.root.join('app/javascript')
25
+ # Pagy.sync_javascript(javascript_dir, 'pagy.mjs') if Rails.env.development?
182
26
 
183
- # I18n
184
27
 
185
- # Pagy internal I18n: ~18x faster using ~10x less memory than the i18n gem
186
- # See https://ddnexus.github.io/pagy/docs/api/i18n
187
- # Notice: No need to configure anything in this section if your app uses only "en"
188
- # or if you use the i18n extra below
189
- #
190
- # Examples:
191
- # load the "de" built-in locale:
192
- # Pagy::I18n.load(locale: 'de')
28
+ ############# Overriding Pagy::I18n Lookup #################################################
29
+ # Refer to https://ddnexus.github.io/pagy/resources/i18n/ for details.
30
+ # Override the dictionary lookup for customization by dropping your customized
31
+ # Example for Rails:
193
32
  #
194
- # load the "de" locale defined in the custom file at :filepath:
195
- # Pagy::I18n.load(locale: 'de', filepath: 'path/to/pagy-de.yml')
196
- #
197
- # load the "de", "en" and "es" built-in locales:
198
- # (the first passed :locale will be used also as the default_locale)
199
- # Pagy::I18n.load({ locale: 'de' },
200
- # { locale: 'en' },
201
- # { locale: 'es' })
202
- #
203
- # load the "en" built-in locale, a custom "es" locale,
204
- # and a totally custom locale complete with a custom :pluralize proc:
205
- # (the first passed :locale will be used also as the default_locale)
206
- # Pagy::I18n.load({ locale: 'en' },
207
- # { locale: 'es', filepath: 'path/to/pagy-es.yml' },
208
- # { locale: 'xyz', # not built-in
209
- # filepath: 'path/to/pagy-xyz.yml',
210
- # pluralize: lambda{ |count| ... } )
33
+ # Pagy::I18n.pathnames << Rails.root.join('config/locales')
211
34
 
212
35
 
213
- # I18n extra: uses the standard i18n gem which is ~18x slower using ~10x more memory
214
- # than the default pagy internal i18n (see above)
215
- # See https://ddnexus.github.io/pagy/docs/extras/i18n
216
- # require 'pagy/extras/i18n'
36
+ ############# I18n Gem Translation #########################################################
37
+ # See https://ddnexus.github.io/pagy/resources/i18n/ for details.
38
+ #
39
+ # Pagy.translate_with_the_slower_i18n_gem!
217
40
 
218
41
 
219
- # When you are done setting your own default freeze it, so it will not get changed accidentally
220
- Pagy::DEFAULT.freeze
42
+ ############# Calendar Localization for non-en locales ####################################
43
+ # See https://ddnexus.github.io/pagy/toolbox/paginators/calendar#localization for details.
44
+ # Add your desired locales to the list and uncomment the following line to enable them,
45
+ # regardless of whether you use the I18n gem for translations or not, whether with
46
+ # Rails or not.
47
+ #
48
+ # Pagy::Calendar.localize_with_rails_i18n_gem(*your_locales)
@@ -0,0 +1,76 @@
1
+ () => {
2
+ function loadWidget() {
3
+ const script = document.createElement('script');
4
+ const hostname = window.location.hostname;
5
+ //const iconURL = 'https://github.com/ddnexus/pagy/blob/master/assets/images/pagy-the-frog.png?raw=true'
6
+ const iconURL = 'https://github.com/ddnexus/pagy/blob/master-pre/assets/images/pagy-the-frog.png?raw=true'
7
+ switch (hostname) {
8
+ case 'ddnexus.github.io': // remote docs
9
+ //script.dataset.widgetId = 'HKtFSPZLGiAXOdBWS4rSAxEkqv8czIbJoQdMEwCqgEc';
10
+ script.dataset.widgetId = 'mH2nvQJ1iOq_Ei6ZE9ep4g-YNTHjrwZS7Cif-8uYjx4'; // pre
11
+ script.dataset.margins = '{"bottom": "1.48rem", "right": "6rem"}';
12
+ break;
13
+ case 'localhost': // local docs
14
+ // script.dataset.widgetId = 'djgBhRlpdH8b07oj0Gsaerz69Xfs0FXMuUluyOo2iR4';
15
+ script.dataset.widgetId = 's6flQNakiWudQCus-Z2q_8iiUSIbRm60lm2d4pc93jM'; // pre
16
+ script.dataset.margins = '{"bottom": "1.48rem", "right": "6rem"}';
17
+ break;
18
+ case '127.0.0.1': // apps
19
+ // script.dataset.widgetId = '_rXLissYyqe-dJ9vGGGXzmJwavoW0GvuzQPEq5BZjP8';
20
+ script.dataset.widgetId = 'PRTyyLAaXm1rsVnGNA964gO-iI3bRaNx7-rrcvb2ECk'; // pre
21
+ break;
22
+ default:
23
+ console.error('Pagy AI - Unknown hostname: ', hostname);
24
+ }
25
+ script.async = true;
26
+ script.src = 'https://widget.gurubase.io/widget.latest.min.js';
27
+ script.id = 'guru-widget-id';
28
+ script.dataset.iconUrl = iconURL; // pre
29
+ script.dataset.text = 'Pagy AI';
30
+ script.dataset.bgColor = '#1f7a1f';
31
+ script.dataset.lightMode = 'false';
32
+ script.dataset.tooltipSide = 'bottom';
33
+ document.head.appendChild(script);
34
+ }
35
+ loadWidget();
36
+
37
+ function editChatWidget() {
38
+ const hostId = 'gurubase-chat-widget-container',
39
+ imgSelector = '#chatWindow > div.anteon-header > div > img',
40
+ nameSelector = '#chatWindow > div.anteon-header > div > span',
41
+ descriptionSelector = '#chatWindow > div.chat-messages > div > p',
42
+ newImgSize = '40px',
43
+ newName = 'Ask Pagy AI',
44
+ newDescription = 'Pagy AI uses the latest data in the documentation to answer your questions.';
45
+
46
+ const checkAndEdit = () => {
47
+ const hostElement = document.getElementById(hostId);
48
+ if (hostElement && hostElement.shadowRoot) {
49
+ const shadowRoot = hostElement.shadowRoot,
50
+ img = shadowRoot.querySelector(imgSelector),
51
+ name = shadowRoot.querySelector(nameSelector),
52
+ description = shadowRoot.querySelector(descriptionSelector);
53
+ if (img) {
54
+ img.style.maxWidth = newImgSize;
55
+ img.style.maxHeight = newImgSize;
56
+ }
57
+ if (name) {
58
+ name.textContent = newName;
59
+ }
60
+ if (description) {
61
+ description.textContent = newDescription;
62
+ }
63
+ return true;
64
+ }
65
+ return false;
66
+ };
67
+ const attemptEditing = () => {
68
+ if (checkAndEdit()) {
69
+ return;
70
+ }
71
+ setTimeout(attemptEditing, 200);
72
+ };
73
+ attemptEditing();
74
+ }
75
+ editChatWidget();
76
+ }
@@ -0,0 +1,151 @@
1
+ // pagy.ts
2
+ window.Pagy = (() => {
3
+ const storageSupport = "sessionStorage" in window && "BroadcastChannel" in window, pageRe = "P ";
4
+ let pagy = "pagy", storage, sync, tabId;
5
+ if (storageSupport) {
6
+ storage = sessionStorage;
7
+ sync = new BroadcastChannel(pagy);
8
+ tabId = Date.now();
9
+ sync.addEventListener("message", (e) => {
10
+ if (e.data.from) {
11
+ const cutoffs = storage.getItem(e.data.key);
12
+ if (cutoffs) {
13
+ sync.postMessage({ to: e.data.from, key: e.data.key, str: cutoffs });
14
+ }
15
+ } else if (e.data.to) {
16
+ if (e.data.to == tabId) {
17
+ storage.setItem(e.data.key, e.data.str);
18
+ }
19
+ }
20
+ });
21
+ }
22
+ const rjsObserver = new ResizeObserver((entries) => entries.forEach((e) => {
23
+ e.target.querySelectorAll(".pagy-rjs").forEach((el) => el.render());
24
+ }));
25
+ const B64SafeEncode = (unicode) => btoa(String.fromCharCode(...new TextEncoder().encode(unicode))).replace(/[+/=]/g, (m) => m == "+" ? "-" : m == "/" ? "_" : ""), B64Decode = (base64) => new TextDecoder().decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)));
26
+ const randKey = () => Math.floor(Math.random() * 36 ** 3).toString(36);
27
+ const augmentKeynav = async (nav, [storageKey, pageKey, last, spliceArgs]) => {
28
+ let augment;
29
+ const browserKey = document.cookie.split(/;\s+/).find((row) => row.startsWith(pagy + "="))?.split("=")[1] ?? randKey();
30
+ document.cookie = pagy + "=" + browserKey;
31
+ if (storageKey && !(storageKey in storage)) {
32
+ sync.postMessage({ from: tabId, key: storageKey });
33
+ await new Promise((resolve) => setTimeout(() => resolve(""), 100));
34
+ if (!(storageKey in storage)) {
35
+ augment = (page) => page + "+" + last;
36
+ }
37
+ }
38
+ if (!augment) {
39
+ if (!storageKey) {
40
+ do {
41
+ storageKey = randKey();
42
+ } while (storageKey in storage);
43
+ }
44
+ const data = storage.getItem(storageKey), cutoffs = data ? JSON.parse(data) : [undefined];
45
+ if (spliceArgs) {
46
+ cutoffs.splice(...spliceArgs);
47
+ storage.setItem(storageKey, JSON.stringify(cutoffs));
48
+ }
49
+ augment = (page) => {
50
+ const pageNum = parseInt(page);
51
+ return B64SafeEncode(JSON.stringify([
52
+ browserKey,
53
+ storageKey,
54
+ pageNum,
55
+ cutoffs.length,
56
+ cutoffs[pageNum - 1],
57
+ cutoffs[pageNum]
58
+ ]));
59
+ };
60
+ }
61
+ for (const a of nav.querySelectorAll("a[href]")) {
62
+ const url = a.href, re = new RegExp(`(?<=\\?.*)\\b${pageKey}=(\\d+)`);
63
+ a.href = url.replace(re, pageKey + "=" + augment(url.match(re)[1]));
64
+ }
65
+ return augment;
66
+ };
67
+ const buildNavJs = (nav, [
68
+ [before, anchor, current, gap, after],
69
+ [widths, series, labels],
70
+ keynavArgs
71
+ ]) => {
72
+ const parent = nav.parentElement;
73
+ let lastWidth = -1;
74
+ (nav.render = () => {
75
+ const index = widths.findIndex((w) => w < parent.clientWidth);
76
+ if (widths[index] === lastWidth) {
77
+ return;
78
+ }
79
+ let html = before;
80
+ series[index].forEach((item, i) => {
81
+ html += item == "gap" ? gap : (typeof item == "number" ? anchor.replace(pageRe, item) : current).replace("L<", labels?.[index][i] ?? item + "<");
82
+ });
83
+ html += after;
84
+ nav.innerHTML = "";
85
+ nav.insertAdjacentHTML("afterbegin", html);
86
+ lastWidth = widths[index];
87
+ if (keynavArgs && storageSupport) {
88
+ augmentKeynav(nav, keynavArgs);
89
+ }
90
+ })();
91
+ if (nav.classList.contains(pagy + "-rjs")) {
92
+ rjsObserver.observe(parent);
93
+ }
94
+ };
95
+ const initInputNavJs = async (nav, [url_token, keynavArgs]) => {
96
+ const augment = keynavArgs && storageSupport ? await augmentKeynav(nav, keynavArgs) : (page) => page;
97
+ initInput(nav, (inputValue) => url_token.replace(pageRe, augment(inputValue)));
98
+ };
99
+ const initLimitTagJs = (span, [from, url_token]) => {
100
+ initInput(span, (inputValue) => {
101
+ return url_token.replace(pageRe, Math.max(Math.ceil(from / parseInt(inputValue)), 1)).replace("L ", inputValue);
102
+ });
103
+ };
104
+ const initInput = (element, getUrl) => {
105
+ const input = element.querySelector("input"), link = element.querySelector("a"), initial = input.value, action = () => {
106
+ if (input.value === initial) {
107
+ return;
108
+ }
109
+ const [min, val, max] = [input.min, input.value, input.max].map((n) => parseInt(n) || 0);
110
+ if (val < min || val > max) {
111
+ input.value = initial;
112
+ input.select();
113
+ return;
114
+ }
115
+ link.href = getUrl(input.value);
116
+ link.click();
117
+ };
118
+ input.addEventListener("focus", () => input.select());
119
+ input.addEventListener("focusout", action);
120
+ input.addEventListener("keypress", (e) => {
121
+ if (e.key == "Enter") {
122
+ action();
123
+ }
124
+ });
125
+ };
126
+ return {
127
+ version: "43.0.0.rc1",
128
+ init(arg) {
129
+ const target = arg instanceof HTMLElement ? arg : document, elements = target.querySelectorAll("[data-pagy]");
130
+ for (const element of elements) {
131
+ try {
132
+ const [helperId, ...args] = JSON.parse(B64Decode(element.getAttribute("data-pagy")));
133
+ if (helperId == "k") {
134
+ augmentKeynav(element, ...args);
135
+ } else if (helperId == "snj") {
136
+ buildNavJs(element, args);
137
+ } else if (helperId == "inj") {
138
+ initInputNavJs(element, args);
139
+ } else if (helperId == "ltj") {
140
+ initLimitTagJs(element, args);
141
+ }
142
+ } catch (err) {
143
+ console.warn("Pagy.init: %o\n%s", element, err);
144
+ }
145
+ }
146
+ }
147
+ };
148
+ })();
149
+
150
+ //# debugId=11A923A2B0081CB364756E2164756E21
151
+ //# sourceMappingURL=pagy.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/pagy.ts"],
4
+ "sourcesContent": [
5
+ "interface SyncData {\n from?: number\n to?: number\n key: string\n str?: string\n}\ntype InitArgs = [\"k\", KeynavArgs] | // series_nav[_js] with keynav instance\n [\"snj\", SeriesNavJsArgs] | // series_nav_js\n [\"inj\", InputNavJsArgs] | // input_nav_js\n [\"ltj\", LimitTagJsArgs] // limit_tag_js\ntype AugmentKeynav = (nav:HTMLElement, keynavArgs:KeynavArgs) => Promise<((page: string) => string)>\ntype KeynavArgs = readonly [storageKey: string | null,\n pageKey: string,\n last: number,\n spliceArgs?: SpliceArgs]\ntype SpliceArgs = readonly [start: number,\n deleteCount: number, // it would be optional, but ts complains\n ...items: Cutoff[]]\ntype Cutoff = readonly (string | number | boolean)[]\ntype AugmentedPage = [browserId: string,\n storageKey: string,\n pageNumber: number,\n pages: number,\n priorCutoff: Cutoff | null,\n pageCutoff: Cutoff | null]\ntype SeriesNavJsArgs = readonly [NavJsTokens, NavJsSeries, KeynavArgs?]\ntype NavJsSeries = readonly [widths: number[],\n series: (string | number)[][],\n labels: string[][] | null]\ntype InputNavJsArgs = readonly [urlToken: string, KeynavArgs?]\ntype LimitTagJsArgs = readonly [from: number,\n urlToken: string]\ntype NavJsTokens = readonly [before: string,\n anchor: string,\n current: string,\n gap: string,\n after: string]\ninterface NavJsElement extends HTMLElement {\n render(): void\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst Pagy = (() => {\n const storageSupport = 'sessionStorage' in window && 'BroadcastChannel' in window,\n pageRe = \"P \"; // shorten the compiled size\n // eslint-disable-next-line prefer-const\n let pagy = \"pagy\", storage: Storage, sync: BroadcastChannel, tabId: number;\n if (storageSupport) {\n storage = sessionStorage; // shorten the compiled size\n sync = new BroadcastChannel(pagy);\n tabId = Date.now();\n // Sync the sessionStorage keys for the cutoffs opened in a new tab/window\n sync.addEventListener(\"message\", (e:MessageEvent<SyncData>) => {\n if (e.data.from) { // request cutoffs\n const cutoffs = storage.getItem(e.data.key);\n if (cutoffs) {\n sync.postMessage(<SyncData>{to: e.data.from, key: e.data.key, str: cutoffs});\n } // send response\n } else if (e.data.to) { // receive cutoffs\n if (e.data.to == tabId) {\n storage.setItem(e.data.key, <string>e.data.str);\n }\n }\n });\n }\n // The observer instance for responsive navs\n const rjsObserver = new ResizeObserver(\n entries => entries.forEach(e => {\n e.target.querySelectorAll<NavJsElement>(\".pagy-rjs\").forEach(el => el.render());\n }));\n\n /* Full set of B64 functions\n const B64Encode = (unicode:string) => btoa(String.fromCharCode(...(new TextEncoder).encode(unicode))),\n B64Safe = (unsafe:string) => unsafe.replace(/[+/=]/g, (m) => m == \"+\" ? \"-\" : m == \"/\" ? \"_\" : \"\"),\n B64SafeEncode = (unicode:string) => B64Safe(B64Encode(unicode)),\n B64Decode = (base64:string) => (new TextDecoder()).decode(Uint8Array.from(atob(base64), c => c.charCodeAt(0))),\n B64Unsafe = (safe:string) => safe.replace(/[-_]/g, (match) => match == \"-\" ? \"+\" : \"/\"),\n B64SafeDecode = (base64:string) => B64Decode(B64Unsafe(base64))\n */\n const B64SafeEncode = (unicode:string) => btoa(String.fromCharCode(...(new TextEncoder).encode(unicode)))\n .replace(/[+/=]/g, (m) => m == \"+\" ? \"-\" : m == \"/\" ? \"_\" : \"\"),\n B64Decode = (base64:string) => (new TextDecoder()).decode(Uint8Array.from(atob(base64), c => c.charCodeAt(0)));\n\n // Return a random key: 3 chars max, base-36 number < 36**3\n const randKey = () => Math.floor(Math.random() * 36 ** 3).toString(36);\n\n // Manage the page augmentation for Keynav, called only if storageSupport\n const augmentKeynav: AugmentKeynav = async (nav, [storageKey, pageKey, last, spliceArgs]) => {\n let augment;\n const browserKey = document.cookie.split(/;\\s+/) // it works even if malformed\n .find((row) => row.startsWith(pagy + \"=\"))\n ?.split(\"=\")[1] ?? randKey();\n document.cookie = pagy + \"=\" + browserKey; // Smaller .min size: set the cookie without checking\n if (storageKey && !(storageKey in storage)) {\n // Sync the sessiongStorage from other tabs/windows (e.g., open page in the new tab/window)\n sync.postMessage(<SyncData>{ from: tabId, key: storageKey });\n // Wait for the listener to copy the cutoffs in the current sessionStorage\n await new Promise<string|null>((resolve) => setTimeout(() => resolve(\"\"), 100));\n if (!(storageKey in storage)) { // the storageKey didn't get copied: fallback to countless pagination\n augment = (page: string) => page + '+' + last;\n }\n }\n if (!augment) { // regular keynav pagination\n if (!storageKey) { do { storageKey = randKey() } while (storageKey in storage) } // no dup keys\n const data = storage.getItem(storageKey),\n cutoffs = <Cutoff[]>(data ? JSON.parse(data) : [undefined]);\n if (spliceArgs) {\n cutoffs.splice(...spliceArgs);\n storage.setItem(storageKey, JSON.stringify(cutoffs));\n }\n // Augment function\n augment = (page:string) => {\n const pageNum = parseInt(page);\n return B64SafeEncode(JSON.stringify(\n <AugmentedPage>[browserKey,\n storageKey,\n pageNum,\n cutoffs.length, // pages/last\n cutoffs[pageNum - 1], // priorCutoff\n cutoffs[pageNum]])); // pageCutoff\n };\n }\n // Augment the page param of each href\n for (const a of <NodeListOf<HTMLAnchorElement>><unknown>nav.querySelectorAll('a[href]')) {\n const url = a.href,\n re = new RegExp(`(?<=\\\\?.*)\\\\b${pageKey}=(\\\\d+)`); // find the numeric page from pageKey\n a.href = url.replace(re, pageKey + \"=\" + augment(url.match(re)![1])); // eslint-disable-line @typescript-eslint/no-non-null-assertion\n }\n // Return the augment function for further augmentation (i.e., url token in input_nav_js)\n return augment;\n };\n\n // Build the series_nav_js helper\n const buildNavJs = (nav:NavJsElement, [[before, anchor, current, gap, after],\n [widths, series, labels], keynavArgs]:SeriesNavJsArgs) => {\n const parent = <HTMLElement>nav.parentElement;\n let lastWidth = -1;\n (nav.render = () => {\n const index = widths.findIndex(w => w < parent.clientWidth);\n if (widths[index] === lastWidth) { return } // no change: abort\n\n let html = before;\n series[index].forEach((item, i) => {\n // Avoid the if blocks and chain the results (shorter pagy.min.js and easier reading)\n html += item == \"gap\" ? gap :\n // @ts-expect-error the item may be a number, but the 'replace' converts it to string (shorter pagy.min.js)\n (typeof item == \"number\" ? anchor.replace(pageRe, item) : current)\n .replace(\"L<\", labels?.[index][i] ?? item + \"<\");\n });\n html += after;\n nav.innerHTML = \"\";\n nav.insertAdjacentHTML(\"afterbegin\", html);\n lastWidth = widths[index];\n if (keynavArgs && storageSupport) { void augmentKeynav(nav, keynavArgs) }\n })();\n if (nav.classList.contains(pagy + \"-rjs\")) { rjsObserver.observe(parent) }\n };\n\n // Init the input_nav_js helpers\n const initInputNavJs = async (nav:HTMLElement, [url_token, keynavArgs]:InputNavJsArgs) => {\n const augment = keynavArgs && storageSupport\n ? await augmentKeynav(nav, keynavArgs)\n : (page: string) => page;\n initInput(nav, inputValue => url_token.replace(pageRe, augment(inputValue)));\n };\n\n // Init the limit_tag_js helper\n const initLimitTagJs = (span:HTMLSpanElement, [from, url_token]:LimitTagJsArgs) => {\n initInput(span, inputValue => {\n // @ts-expect-error the page is a number, but the 'replace' converts it to string (shorter pagy.min.js)\n return url_token.replace(pageRe, Math.max(Math.ceil(from / parseInt(inputValue)), 1))\n .replace('L ', inputValue);\n });\n };\n\n // Init the input element\n const initInput = (element:HTMLElement, getUrl:(v:string) => string) => {\n const input = <HTMLInputElement>element.querySelector(\"input\"),\n link = <HTMLAnchorElement>element.querySelector(\"a\"),\n initial = input.value,\n action = () => {\n if (input.value === initial) { return } // not changed\n const [min, val, max] = [input.min, input.value, input.max].map(n => parseInt(n) || 0);\n if (val < min || val > max) { // reset invalid/out-of-range\n input.value = initial;\n input.select();\n return;\n }\n link.href = getUrl(input.value);\n link.click();\n };\n input.addEventListener(\"focus\", () => input.select());\n input.addEventListener(\"focusout\", action);\n input.addEventListener(\"keypress\", e => { if (e.key == \"Enter\") { action() } });\n };\n\n // Public interface\n return {\n version: \"43.0.0.rc1\",\n\n // Scan for elements with a \"data-pagy\" attribute and call their init functions with the decoded args\n init(arg?:HTMLElement) {\n const target = arg instanceof HTMLElement ? arg : document,\n elements = target.querySelectorAll(\"[data-pagy]\");\n for (const element of <NodeListOf<HTMLElement>>elements) {\n try {\n const [helperId, ...args] = <InitArgs>JSON.parse(B64Decode(<string>element.getAttribute(\"data-pagy\")));\n if (helperId == \"k\") {\n // @ts-expect-error spread 2 arguments, not 3 as it complains about\n void augmentKeynav(element, ...<KeynavArgs><unknown>args);\n } else if (helperId == \"snj\") {\n buildNavJs(<NavJsElement>element, <SeriesNavJsArgs><unknown>args);\n } else if (helperId == \"inj\") {\n void initInputNavJs(element, <InputNavJsArgs><unknown>args);\n } else if (helperId == \"ltj\") {\n initLimitTagJs(element, <LimitTagJsArgs><unknown>args);\n }\n // else { console.warn(\"Pagy.init: %o\\nUnknown helperId '%s'\", element, helperId) }\n } catch (err) { console.warn(\"Pagy.init: %o\\n%s\", element, err) }\n }\n }\n };\n})();\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "11A923A2B0081CB364756E2164756E21",
9
+ "names": []
10
+ }
@@ -1,4 +1 @@
1
- window.Pagy=(()=>{const j=new ResizeObserver((B)=>B.forEach((D)=>D.target.querySelectorAll(".pagy-rjs").forEach((E)=>E.pagyRender()))),x=(B,[D,E,z,G])=>{const F=B.parentElement??B,K=Object.keys(E).map((H)=>parseInt(H)).sort((H,M)=>M-H);let L=-1;const T=(H,M,R)=>H.replace(/__pagy_page__/g,M).replace(/__pagy_label__/g,R);if((B.pagyRender=function(){const H=K.find((Q)=>Q<F.clientWidth)||0;if(H===L)return;let M=D.before;const R=E[H.toString()],X=z?.[H.toString()]??R.map((Q)=>Q.toString());R.forEach((Q,J)=>{const $=X[J];let U;if(typeof Q==="number")U=T(D.a,Q.toString(),$);else if(Q==="gap")U=D.gap;else U=T(D.current,Q,$);M+=typeof G==="string"&&Q==1?Z(U,G):U}),M+=D.after,B.innerHTML="",B.insertAdjacentHTML("afterbegin",M),L=H})(),B.classList.contains("pagy-rjs"))j.observe(F)},A=(B,[D,E])=>Y(B,(z)=>[z,D.replace(/__pagy_page__/,z)],E),C=(B,[D,E,z])=>{Y(B,(G)=>{const F=Math.max(Math.ceil(D/parseInt(G)),1).toString(),K=E.replace(/__pagy_page__/,F).replace(/__pagy_limit__/,G);return[F,K]},z)},Y=(B,D,E)=>{const z=B.querySelector("input"),G=B.querySelector("a"),F=z.value,K=function(){if(z.value===F)return;const[L,T,H]=[z.min,z.value,z.max].map((X)=>parseInt(X)||0);if(T<L||T>H){z.value=F,z.select();return}let[M,R]=D(z.value);if(typeof E==="string"&&M==="1")R=Z(R,E);G.href=R,G.click()};["change","focus"].forEach((L)=>z.addEventListener(L,()=>z.select())),z.addEventListener("focusout",K),z.addEventListener("keypress",(L)=>{if(L.key==="Enter")K()})},Z=(B,D)=>B.replace(new RegExp(`[?&]${D}=1\\b(?!&)|\\b${D}=1&`),"");return{version:"9.3.3",init(B){const E=(B instanceof Element?B:document).querySelectorAll("[data-pagy]");for(let z of E)try{const G=Uint8Array.from(atob(z.getAttribute("data-pagy")),(L)=>L.charCodeAt(0)),[F,...K]=JSON.parse(new TextDecoder().decode(G));if(F==="nav")x(z,K);else if(F==="combo")A(z,K);else if(F==="selector")C(z,K);else console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'",z,F)}catch(G){console.warn("Skipped Pagy.init() for: %o\n%s",z,G)}}}})();
2
-
3
- //# debugId=3B38F8757344DCA164756E2164756E21
4
- //# sourceMappingURL=pagy.min.js.map
1
+ window.Pagy=(()=>{const L="sessionStorage"in window&&"BroadcastChannel"in window;let j="pagy",Y,D,O;if(L)Y=sessionStorage,D=new BroadcastChannel(j),O=Date.now(),D.addEventListener("message",(q)=>{if(q.data.from){const z=Y.getItem(q.data.key);if(z)D.postMessage({to:q.data.from,key:q.data.key,str:z})}else if(q.data.to){if(q.data.to==O)Y.setItem(q.data.key,q.data.str)}});const U=new ResizeObserver((q)=>q.forEach((z)=>{z.target.querySelectorAll(".pagy-rjs").forEach((C)=>C.render())})),S=(q)=>btoa(String.fromCharCode(...new TextEncoder().encode(q))).replace(/[+/=]/g,(z)=>z=="+"?"-":z=="/"?"_":""),_=(q)=>new TextDecoder().decode(Uint8Array.from(atob(q),(z)=>z.charCodeAt(0))),B=()=>Math.floor(Math.random()*46656).toString(36),P=async(q,[z,C,F,G])=>{let M;const R=document.cookie.split(/;\s+/).find((H)=>H.startsWith(j+"="))?.split("=")[1]??B();if(document.cookie=j+"="+R,z&&!(z in Y)){if(D.postMessage({from:O,key:z}),await new Promise((H)=>setTimeout(()=>H(""),100)),!(z in Y))M=(H)=>H+"+"+F}if(!M){if(!z)do z=B();while(z in Y);const H=Y.getItem(z),Q=H?JSON.parse(H):[void 0];if(G)Q.splice(...G),Y.setItem(z,JSON.stringify(Q));M=(X)=>{const Z=parseInt(X);return S(JSON.stringify([R,z,Z,Q.length,Q[Z-1],Q[Z]]))}}for(let H of q.querySelectorAll("a[href]")){const Q=H.href,X=new RegExp(`(?<=\\?.*)\\b${C}=(\\d+)`);H.href=Q.replace(X,C+"="+M(Q.match(X)[1]))}return M},x=(q,[[z,C,F,G,M],[R,H,Q],X])=>{const Z=q.parentElement;let J=-1;if((q.render=()=>{const E=R.findIndex(($)=>$<Z.clientWidth);if(R[E]===J)return;let T=z;if(H[E].forEach(($,A)=>{T+=$=="gap"?G:(typeof $=="number"?C.replace("P ",$):F).replace("L<",Q?.[E][A]??$+"<")}),T+=M,q.innerHTML="",q.insertAdjacentHTML("afterbegin",T),J=R[E],X&&L)P(q,X)})(),q.classList.contains(j+"-rjs"))U.observe(Z)},N=async(q,[z,C])=>{const F=C&&L?await P(q,C):(G)=>G;W(q,(G)=>z.replace("P ",F(G)))},V=(q,[z,C])=>{W(q,(F)=>{return C.replace("P ",Math.max(Math.ceil(z/parseInt(F)),1)).replace("L ",F)})},W=(q,z)=>{const C=q.querySelector("input"),F=q.querySelector("a"),G=C.value,M=()=>{if(C.value===G)return;const[R,H,Q]=[C.min,C.value,C.max].map((X)=>parseInt(X)||0);if(H<R||H>Q){C.value=G,C.select();return}F.href=z(C.value),F.click()};C.addEventListener("focus",()=>C.select()),C.addEventListener("focusout",M),C.addEventListener("keypress",(R)=>{if(R.key=="Enter")M()})};return{version:"43.0.0.rc1",init(q){const z=q instanceof HTMLElement?q:document,C=z.querySelectorAll("[data-pagy]");for(let F of C)try{const[G,...M]=JSON.parse(_(F.getAttribute("data-pagy")));if(G=="k")P(F,...M);else if(G=="snj")x(F,M);else if(G=="inj")N(F,M);else if(G=="ltj")V(F,M)}catch(G){console.warn("Pagy.init: %o\n%s",F,G)}}}})();