WordPress Popular Posts - Version 5.3.3

Version Description

  • Fixes a potential XSS vulnerability (props to Yu Iwama of Secure Sky Technology Inc. and the JPCERT/CC Vulnerability Coordination Group).
  • Fixes a potential code injection vulnerability (props to Jerome & NinTechNet).
  • Fixes a srcset bug that affects specific PHP locales (props to @fredel).
  • Fixes a srcset not loading images due to improper SSL/HTTPS configuration (props to @aj4h).
  • Updates ChartJS to version 2.9.4.

If you're using a caching plugin flushing its cache after upgrading to this version is highly recommended.

Release notes

Download this release

Release Info

Developer hcabrera
Plugin Icon 128x128 WordPress Popular Posts
Version 5.3.3
Comparing to
See all releases

Code changes from version 5.3.2 to 5.3.3

Files changed (47) hide show
  1. LICENSE +339 -339
  2. assets/css/admin.css +418 -418
  3. assets/css/datepicker.css +399 -399
  4. assets/css/fontello.css +49 -49
  5. assets/css/wpp.css +76 -76
  6. assets/fonts/fontello.svg +17 -17
  7. assets/js/admin.js +356 -356
  8. assets/js/chart.js +191 -191
  9. assets/js/vendor/Chart.min.js +7 -14
  10. assets/js/wpp.js +159 -159
  11. assets/themes/cards-compact/config.json +50 -50
  12. assets/themes/cards-compact/style.css +63 -63
  13. assets/themes/cards/config.json +50 -50
  14. assets/themes/cards/style.css +63 -63
  15. assets/themes/cardview-compact/config.json +50 -50
  16. assets/themes/cardview-compact/style.css +72 -72
  17. assets/themes/cardview/config.json +50 -50
  18. assets/themes/cardview/style.css +76 -76
  19. assets/themes/evergreen/config.json +50 -50
  20. assets/themes/evergreen/style.css +48 -48
  21. assets/themes/midnight/config.json +50 -50
  22. assets/themes/midnight/style.css +48 -48
  23. assets/themes/sunrise/config.json +50 -50
  24. assets/themes/sunrise/style.css +48 -48
  25. assets/themes/sunset/config.json +50 -50
  26. assets/themes/sunset/style.css +48 -48
  27. assets/themes/tiles/config.json +50 -50
  28. assets/themes/tiles/style.css +64 -64
  29. assets/themes/tiny/config.json +41 -41
  30. assets/themes/tiny/style.css +36 -36
  31. i18n/wordpress-popular-posts.pot +1225 -1225
  32. index.php +2 -2
  33. readme.txt +18 -97
  34. src/Activation/Activator.php +129 -129
  35. src/Activation/Deactivator.php +66 -66
  36. src/Admin/Admin.php +1383 -1383
  37. src/Admin/admin-page.php +966 -951
  38. src/Bootstrap.php +25 -25
  39. src/Cache.php +111 -111
  40. src/Container/Container.php +110 -110
  41. src/Container/ContainerConfigurationInterface.php +17 -17
  42. src/Container/WordPressPopularPostsConfiguration.php +71 -71
  43. src/Front/Front.php +516 -516
  44. src/Helper.php +337 -337
  45. src/I18N.php +49 -49
  46. src/Image.php +954 -936
  47. src/Output.php +0 -3
LICENSE CHANGED
@@ -1,339 +1,339 @@
1
- GNU GENERAL PUBLIC LICENSE
2
- Version 2, June 1991
3
-
4
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
- Everyone is permitted to copy and distribute verbatim copies
7
- of this license document, but changing it is not allowed.
8
-
9
- Preamble
10
-
11
- The licenses for most software are designed to take away your
12
- freedom to share and change it. By contrast, the GNU General Public
13
- License is intended to guarantee your freedom to share and change free
14
- software--to make sure the software is free for all its users. This
15
- General Public License applies to most of the Free Software
16
- Foundation's software and to any other program whose authors commit to
17
- using it. (Some other Free Software Foundation software is covered by
18
- the GNU Lesser General Public License instead.) You can apply it to
19
- your programs, too.
20
-
21
- When we speak of free software, we are referring to freedom, not
22
- price. Our General Public Licenses are designed to make sure that you
23
- have the freedom to distribute copies of free software (and charge for
24
- this service if you wish), that you receive source code or can get it
25
- if you want it, that you can change the software or use pieces of it
26
- in new free programs; and that you know you can do these things.
27
-
28
- To protect your rights, we need to make restrictions that forbid
29
- anyone to deny you these rights or to ask you to surrender the rights.
30
- These restrictions translate to certain responsibilities for you if you
31
- distribute copies of the software, or if you modify it.
32
-
33
- For example, if you distribute copies of such a program, whether
34
- gratis or for a fee, you must give the recipients all the rights that
35
- you have. You must make sure that they, too, receive or can get the
36
- source code. And you must show them these terms so they know their
37
- rights.
38
-
39
- We protect your rights with two steps: (1) copyright the software, and
40
- (2) offer you this license which gives you legal permission to copy,
41
- distribute and/or modify the software.
42
-
43
- Also, for each author's protection and ours, we want to make certain
44
- that everyone understands that there is no warranty for this free
45
- software. If the software is modified by someone else and passed on, we
46
- want its recipients to know that what they have is not the original, so
47
- that any problems introduced by others will not reflect on the original
48
- authors' reputations.
49
-
50
- Finally, any free program is threatened constantly by software
51
- patents. We wish to avoid the danger that redistributors of a free
52
- program will individually obtain patent licenses, in effect making the
53
- program proprietary. To prevent this, we have made it clear that any
54
- patent must be licensed for everyone's free use or not licensed at all.
55
-
56
- The precise terms and conditions for copying, distribution and
57
- modification follow.
58
-
59
- GNU GENERAL PUBLIC LICENSE
60
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
-
62
- 0. This License applies to any program or other work which contains
63
- a notice placed by the copyright holder saying it may be distributed
64
- under the terms of this General Public License. The "Program", below,
65
- refers to any such program or work, and a "work based on the Program"
66
- means either the Program or any derivative work under copyright law:
67
- that is to say, a work containing the Program or a portion of it,
68
- either verbatim or with modifications and/or translated into another
69
- language. (Hereinafter, translation is included without limitation in
70
- the term "modification".) Each licensee is addressed as "you".
71
-
72
- Activities other than copying, distribution and modification are not
73
- covered by this License; they are outside its scope. The act of
74
- running the Program is not restricted, and the output from the Program
75
- is covered only if its contents constitute a work based on the
76
- Program (independent of having been made by running the Program).
77
- Whether that is true depends on what the Program does.
78
-
79
- 1. You may copy and distribute verbatim copies of the Program's
80
- source code as you receive it, in any medium, provided that you
81
- conspicuously and appropriately publish on each copy an appropriate
82
- copyright notice and disclaimer of warranty; keep intact all the
83
- notices that refer to this License and to the absence of any warranty;
84
- and give any other recipients of the Program a copy of this License
85
- along with the Program.
86
-
87
- You may charge a fee for the physical act of transferring a copy, and
88
- you may at your option offer warranty protection in exchange for a fee.
89
-
90
- 2. You may modify your copy or copies of the Program or any portion
91
- of it, thus forming a work based on the Program, and copy and
92
- distribute such modifications or work under the terms of Section 1
93
- above, provided that you also meet all of these conditions:
94
-
95
- a) You must cause the modified files to carry prominent notices
96
- stating that you changed the files and the date of any change.
97
-
98
- b) You must cause any work that you distribute or publish, that in
99
- whole or in part contains or is derived from the Program or any
100
- part thereof, to be licensed as a whole at no charge to all third
101
- parties under the terms of this License.
102
-
103
- c) If the modified program normally reads commands interactively
104
- when run, you must cause it, when started running for such
105
- interactive use in the most ordinary way, to print or display an
106
- announcement including an appropriate copyright notice and a
107
- notice that there is no warranty (or else, saying that you provide
108
- a warranty) and that users may redistribute the program under
109
- these conditions, and telling the user how to view a copy of this
110
- License. (Exception: if the Program itself is interactive but
111
- does not normally print such an announcement, your work based on
112
- the Program is not required to print an announcement.)
113
-
114
- These requirements apply to the modified work as a whole. If
115
- identifiable sections of that work are not derived from the Program,
116
- and can be reasonably considered independent and separate works in
117
- themselves, then this License, and its terms, do not apply to those
118
- sections when you distribute them as separate works. But when you
119
- distribute the same sections as part of a whole which is a work based
120
- on the Program, the distribution of the whole must be on the terms of
121
- this License, whose permissions for other licensees extend to the
122
- entire whole, and thus to each and every part regardless of who wrote it.
123
-
124
- Thus, it is not the intent of this section to claim rights or contest
125
- your rights to work written entirely by you; rather, the intent is to
126
- exercise the right to control the distribution of derivative or
127
- collective works based on the Program.
128
-
129
- In addition, mere aggregation of another work not based on the Program
130
- with the Program (or with a work based on the Program) on a volume of
131
- a storage or distribution medium does not bring the other work under
132
- the scope of this License.
133
-
134
- 3. You may copy and distribute the Program (or a work based on it,
135
- under Section 2) in object code or executable form under the terms of
136
- Sections 1 and 2 above provided that you also do one of the following:
137
-
138
- a) Accompany it with the complete corresponding machine-readable
139
- source code, which must be distributed under the terms of Sections
140
- 1 and 2 above on a medium customarily used for software interchange; or,
141
-
142
- b) Accompany it with a written offer, valid for at least three
143
- years, to give any third party, for a charge no more than your
144
- cost of physically performing source distribution, a complete
145
- machine-readable copy of the corresponding source code, to be
146
- distributed under the terms of Sections 1 and 2 above on a medium
147
- customarily used for software interchange; or,
148
-
149
- c) Accompany it with the information you received as to the offer
150
- to distribute corresponding source code. (This alternative is
151
- allowed only for noncommercial distribution and only if you
152
- received the program in object code or executable form with such
153
- an offer, in accord with Subsection b above.)
154
-
155
- The source code for a work means the preferred form of the work for
156
- making modifications to it. For an executable work, complete source
157
- code means all the source code for all modules it contains, plus any
158
- associated interface definition files, plus the scripts used to
159
- control compilation and installation of the executable. However, as a
160
- special exception, the source code distributed need not include
161
- anything that is normally distributed (in either source or binary
162
- form) with the major components (compiler, kernel, and so on) of the
163
- operating system on which the executable runs, unless that component
164
- itself accompanies the executable.
165
-
166
- If distribution of executable or object code is made by offering
167
- access to copy from a designated place, then offering equivalent
168
- access to copy the source code from the same place counts as
169
- distribution of the source code, even though third parties are not
170
- compelled to copy the source along with the object code.
171
-
172
- 4. You may not copy, modify, sublicense, or distribute the Program
173
- except as expressly provided under this License. Any attempt
174
- otherwise to copy, modify, sublicense or distribute the Program is
175
- void, and will automatically terminate your rights under this License.
176
- However, parties who have received copies, or rights, from you under
177
- this License will not have their licenses terminated so long as such
178
- parties remain in full compliance.
179
-
180
- 5. You are not required to accept this License, since you have not
181
- signed it. However, nothing else grants you permission to modify or
182
- distribute the Program or its derivative works. These actions are
183
- prohibited by law if you do not accept this License. Therefore, by
184
- modifying or distributing the Program (or any work based on the
185
- Program), you indicate your acceptance of this License to do so, and
186
- all its terms and conditions for copying, distributing or modifying
187
- the Program or works based on it.
188
-
189
- 6. Each time you redistribute the Program (or any work based on the
190
- Program), the recipient automatically receives a license from the
191
- original licensor to copy, distribute or modify the Program subject to
192
- these terms and conditions. You may not impose any further
193
- restrictions on the recipients' exercise of the rights granted herein.
194
- You are not responsible for enforcing compliance by third parties to
195
- this License.
196
-
197
- 7. If, as a consequence of a court judgment or allegation of patent
198
- infringement or for any other reason (not limited to patent issues),
199
- conditions are imposed on you (whether by court order, agreement or
200
- otherwise) that contradict the conditions of this License, they do not
201
- excuse you from the conditions of this License. If you cannot
202
- distribute so as to satisfy simultaneously your obligations under this
203
- License and any other pertinent obligations, then as a consequence you
204
- may not distribute the Program at all. For example, if a patent
205
- license would not permit royalty-free redistribution of the Program by
206
- all those who receive copies directly or indirectly through you, then
207
- the only way you could satisfy both it and this License would be to
208
- refrain entirely from distribution of the Program.
209
-
210
- If any portion of this section is held invalid or unenforceable under
211
- any particular circumstance, the balance of the section is intended to
212
- apply and the section as a whole is intended to apply in other
213
- circumstances.
214
-
215
- It is not the purpose of this section to induce you to infringe any
216
- patents or other property right claims or to contest validity of any
217
- such claims; this section has the sole purpose of protecting the
218
- integrity of the free software distribution system, which is
219
- implemented by public license practices. Many people have made
220
- generous contributions to the wide range of software distributed
221
- through that system in reliance on consistent application of that
222
- system; it is up to the author/donor to decide if he or she is willing
223
- to distribute software through any other system and a licensee cannot
224
- impose that choice.
225
-
226
- This section is intended to make thoroughly clear what is believed to
227
- be a consequence of the rest of this License.
228
-
229
- 8. If the distribution and/or use of the Program is restricted in
230
- certain countries either by patents or by copyrighted interfaces, the
231
- original copyright holder who places the Program under this License
232
- may add an explicit geographical distribution limitation excluding
233
- those countries, so that distribution is permitted only in or among
234
- countries not thus excluded. In such case, this License incorporates
235
- the limitation as if written in the body of this License.
236
-
237
- 9. The Free Software Foundation may publish revised and/or new versions
238
- of the General Public License from time to time. Such new versions will
239
- be similar in spirit to the present version, but may differ in detail to
240
- address new problems or concerns.
241
-
242
- Each version is given a distinguishing version number. If the Program
243
- specifies a version number of this License which applies to it and "any
244
- later version", you have the option of following the terms and conditions
245
- either of that version or of any later version published by the Free
246
- Software Foundation. If the Program does not specify a version number of
247
- this License, you may choose any version ever published by the Free Software
248
- Foundation.
249
-
250
- 10. If you wish to incorporate parts of the Program into other free
251
- programs whose distribution conditions are different, write to the author
252
- to ask for permission. For software which is copyrighted by the Free
253
- Software Foundation, write to the Free Software Foundation; we sometimes
254
- make exceptions for this. Our decision will be guided by the two goals
255
- of preserving the free status of all derivatives of our free software and
256
- of promoting the sharing and reuse of software generally.
257
-
258
- NO WARRANTY
259
-
260
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
- FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
- OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
- PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
- OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
- TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
- PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
- REPAIR OR CORRECTION.
269
-
270
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
- REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
- INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
- OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
- TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
- YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
- PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
- POSSIBILITY OF SUCH DAMAGES.
279
-
280
- END OF TERMS AND CONDITIONS
281
-
282
- How to Apply These Terms to Your New Programs
283
-
284
- If you develop a new program, and you want it to be of the greatest
285
- possible use to the public, the best way to achieve this is to make it
286
- free software which everyone can redistribute and change under these terms.
287
-
288
- To do so, attach the following notices to the program. It is safest
289
- to attach them to the start of each source file to most effectively
290
- convey the exclusion of warranty; and each file should have at least
291
- the "copyright" line and a pointer to where the full notice is found.
292
-
293
- <one line to give the program's name and a brief idea of what it does.>
294
- Copyright (C) <year> <name of author>
295
-
296
- This program is free software; you can redistribute it and/or modify
297
- it under the terms of the GNU General Public License as published by
298
- the Free Software Foundation; either version 2 of the License, or
299
- (at your option) any later version.
300
-
301
- This program is distributed in the hope that it will be useful,
302
- but WITHOUT ANY WARRANTY; without even the implied warranty of
303
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
- GNU General Public License for more details.
305
-
306
- You should have received a copy of the GNU General Public License along
307
- with this program; if not, write to the Free Software Foundation, Inc.,
308
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
-
310
- Also add information on how to contact you by electronic and paper mail.
311
-
312
- If the program is interactive, make it output a short notice like this
313
- when it starts in an interactive mode:
314
-
315
- Gnomovision version 69, Copyright (C) year name of author
316
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
- This is free software, and you are welcome to redistribute it
318
- under certain conditions; type `show c' for details.
319
-
320
- The hypothetical commands `show w' and `show c' should show the appropriate
321
- parts of the General Public License. Of course, the commands you use may
322
- be called something other than `show w' and `show c'; they could even be
323
- mouse-clicks or menu items--whatever suits your program.
324
-
325
- You should also get your employer (if you work as a programmer) or your
326
- school, if any, to sign a "copyright disclaimer" for the program, if
327
- necessary. Here is a sample; alter the names:
328
-
329
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
-
332
- <signature of Ty Coon>, 1 April 1989
333
- Ty Coon, President of Vice
334
-
335
- This General Public License does not permit incorporating your program into
336
- proprietary programs. If your program is a subroutine library, you may
337
- consider it more useful to permit linking proprietary applications with the
338
- library. If this is what you want to do, use the GNU Lesser General
339
- Public License instead of this License.
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that redistributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ <one line to give the program's name and a brief idea of what it does.>
294
+ Copyright (C) <year> <name of author>
295
+
296
+ This program is free software; you can redistribute it and/or modify
297
+ it under the terms of the GNU General Public License as published by
298
+ the Free Software Foundation; either version 2 of the License, or
299
+ (at your option) any later version.
300
+
301
+ This program is distributed in the hope that it will be useful,
302
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
+ GNU General Public License for more details.
305
+
306
+ You should have received a copy of the GNU General Public License along
307
+ with this program; if not, write to the Free Software Foundation, Inc.,
308
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+ Also add information on how to contact you by electronic and paper mail.
311
+
312
+ If the program is interactive, make it output a short notice like this
313
+ when it starts in an interactive mode:
314
+
315
+ Gnomovision version 69, Copyright (C) year name of author
316
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+ This is free software, and you are welcome to redistribute it
318
+ under certain conditions; type `show c' for details.
319
+
320
+ The hypothetical commands `show w' and `show c' should show the appropriate
321
+ parts of the General Public License. Of course, the commands you use may
322
+ be called something other than `show w' and `show c'; they could even be
323
+ mouse-clicks or menu items--whatever suits your program.
324
+
325
+ You should also get your employer (if you work as a programmer) or your
326
+ school, if any, to sign a "copyright disclaimer" for the program, if
327
+ necessary. Here is a sample; alter the names:
328
+
329
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+ <signature of Ty Coon>, 1 April 1989
333
+ Ty Coon, President of Vice
334
+
335
+ This General Public License does not permit incorporating your program into
336
+ proprietary programs. If your program is a subroutine library, you may
337
+ consider it more useful to permit linking proprietary applications with the
338
+ library. If this is what you want to do, use the GNU Lesser General
339
+ Public License instead of this License.
assets/css/admin.css CHANGED
@@ -1,418 +1,418 @@
1
- #wpp-message { display: none; }
2
-
3
- /*
4
- * Navigation
5
- */
6
- #wpp-menu {
7
- float: none;
8
- clear: both;
9
- }
10
-
11
- #wpp-menu ul {
12
- text-align: center;
13
- }
14
-
15
- #wpp-menu ul li {
16
- padding: 0 15px 0 10px;
17
- margin: 0 0px;
18
- display: inline;
19
- border-right: #ddd 1px solid;
20
- }
21
-
22
- #wpp-menu ul li:first-child {
23
- display: none;
24
- }
25
-
26
- #wpp-menu ul li:last-child {
27
- border: none;
28
- }
29
-
30
- #wpp-menu ul li a {
31
- }
32
-
33
- #wpp-menu ul li.current a {
34
- color: #00a0d2;
35
- text-decoration: none;
36
- }
37
-
38
- .wpp-wrapper {
39
- margin: 20px 20px 0 2px;
40
- -webkit-font-smoothing: subpixel-antialiased;
41
- }
42
-
43
- .wpp-lightbox {
44
- display: none;
45
- position: fixed;
46
- top: 50%;
47
- left: 50%;
48
- z-index: 999;
49
- margin: -140px 0 0 -140px;
50
- padding: 15px;
51
- width: 250px;
52
- max-height: 280px;
53
- background: #fff;
54
- -webkit-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
55
- -moz-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
56
- box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
57
- }
58
-
59
- .wpp-lightbox-tabs {
60
- margin: 0 0 25px 0;
61
- padding: 0 0 0 0;
62
- text-align: center;
63
- }
64
-
65
- .wpp-lightbox-tabs li {
66
- display: inline;
67
- list-style: none;
68
- margin: 0;
69
- padding: 0 15px 0 10px;
70
- border-right: #ddd 1px solid;
71
- }
72
-
73
- .wpp-lightbox-tabs li:first-child {
74
- padding: 0 15px 0 0;
75
- }
76
-
77
- .wpp-lightbox-tabs li:last-child {
78
- padding: 0 0 0 10px;
79
- border-right: none;
80
- }
81
-
82
- .wpp-lightbox-tabs li.active a {
83
- color: #00a0d2;
84
- text-decoration: none;
85
- }
86
-
87
- .wpp-lightbox-tab-content {
88
- overflow: hidden;
89
- display: none;
90
- width: 100%;
91
- }
92
-
93
- .wpp-lightbox-tab-content-active {
94
- display: block;
95
- }
96
-
97
- .wpp-lightbox form {
98
- display: block;
99
- }
100
-
101
- .wpp-lightbox form input[type=text] {
102
- display: block;
103
- margin: 0 0 15px 0;
104
- width: 100%;
105
- box-sizing: border-box;
106
- }
107
-
108
- .wpp-section-stats {
109
- position: relative;
110
- }
111
-
112
- .wpp-section-stats .dashicons-admin-generic {
113
- position: absolute;
114
- top: 22px;
115
- left: 0;
116
- width: 21px;
117
- height: 21px;
118
- transition: transform 0.3s;
119
- }
120
-
121
- .wpp-section-stats .dashicons-admin-generic:hover {
122
- transform: rotate(360deg);
123
- }
124
-
125
- .wpp-header {
126
- overflow: hidden;
127
- display: block;
128
- padding: 25px 0 0 0;
129
- }
130
-
131
- .wpp-header h2,
132
- .wpp-header h3,
133
- .wpp-header h4,
134
- .wpp-header h5 {
135
- text-align: center;
136
- }
137
-
138
- .wpp-header h2 {
139
- margin: 0 0 5px 0;
140
- font-size: 1.0em;
141
- font-weight: 400;
142
- line-height: 1.0em;
143
- }
144
-
145
- .wpp-header h3 {
146
- margin: 0 0 30px 0;
147
- font-size: 3.5em;
148
- letter-spacing: -1px;
149
- line-height: 1.0em;
150
- }
151
-
152
- .wpp-header h4,
153
- #wpp-chart-wrapper h4 {
154
- margin: 0 0 8px 0;
155
- font-size: 2.0em;
156
- font-weight: 100;
157
- line-height: 1.0em;
158
- letter-spacing: -2px;
159
- }
160
-
161
- .wpp-header h5,
162
- #wpp-chart-wrapper h5 {
163
- margin: 0 0 0 0;
164
- font-size: 0.9em;
165
- font-weight: 300;
166
- line-height: 0.9em;
167
- }
168
-
169
- .wpp-header-nav {
170
- margin: 55px auto 0px auto;
171
- padding: 0;
172
- text-align: center;
173
- }
174
-
175
- .wpp-header-nav li {
176
- display: inline;
177
- list-style: none;
178
- margin: 0 4px;
179
- padding: 0;
180
- }
181
-
182
- .wpp-header-nav li a {
183
- display: inline-block;
184
- padding: 6px 12px 7px;
185
- line-height: 1.1em;
186
- }
187
-
188
- .wpp-section-stats .wpp-header-nav li a:hover,
189
- .wpp-section-stats .wpp-header-nav li.current a {
190
- color: #00a0d2;
191
- }
192
-
193
- .wpp-section-stats .wpp-header-nav li.current a {
194
- text-decoration: none;
195
- }
196
-
197
- #wpp-chart-wrapper {
198
- width: 100%;
199
- }
200
-
201
- #wpp-chart-wrapper h4,
202
- #wpp-chart-wrapper h5 {
203
- text-align: center;
204
- }
205
-
206
- #wpp-chart-wrapper #wpp-chart {
207
- position: relative;
208
- overflow: hidden;
209
- margin: 20px auto 0 auto;
210
- width: 100%;
211
- height: 250px;
212
- }
213
-
214
- #wpp-chart-wrapper #wpp-chart p {
215
- margin: 0 10px;
216
- text-align: center;
217
- }
218
-
219
- #wpp-chart-wrapper #wpp-chart a:hover {
220
- text-decoration: underline;
221
- }
222
-
223
- .wpp-content {
224
- float: none;
225
- clear: both;
226
- width: 100%;
227
- background: #fff;
228
- }
229
-
230
- .wpp-content .wpp-tabbed-nav {
231
- overflow: hidden;
232
- margin: 0 0 0 0;
233
- padding: 0;
234
- background: #f9f9f9;
235
- }
236
-
237
- .wpp-content .wpp-tabbed-nav li {
238
- display: inline;
239
- float: left;
240
- margin: 0;
241
- padding: 0;
242
- width: 25%;
243
- border-bottom: #f0f0f0 1px solid;
244
- }
245
-
246
- .wpp-content .wpp-tabbed-nav li.active {
247
- border-bottom: #bbb 1px solid;
248
- }
249
-
250
- .wpp-content .wpp-tabbed-nav li a {
251
- display: block;
252
- padding: 15px;
253
- font-size: 1.2em;
254
- text-align: center;
255
- text-decoration: none;
256
- outline: none;
257
- box-shadow: none;
258
- }
259
-
260
- #wpp-listing .wpp-tabbed-nav li a .fa {
261
- display: inline-block;
262
- margin: 0 8px 0 0;
263
- }
264
-
265
- .wpp-tab-content {
266
- display: none;
267
- overflow: hidden;
268
- padding: 2% 30px;
269
- width: 100%;
270
- box-sizing: border-box;
271
- }
272
-
273
- .wpp-tab-content-active {
274
- display: block;
275
- }
276
-
277
- .wpp-tab-content .spinner {
278
- display: block;
279
- visibility: visible;
280
- float: none;
281
- margin-left: auto;
282
- margin-right: auto;
283
- }
284
-
285
- .popular-posts-list {
286
- margin: 0 0 0 0;
287
- padding: 0;
288
- list-style: none;
289
- counter-reset: wpp-counter;
290
- font-size: 1rem;
291
- line-height: 1.2;
292
- }
293
-
294
- .popular-posts-list li {
295
- counter-increment: wpp-counter;
296
- margin: 0 1% 15px 1%;
297
- padding: 0 0 10px 0;
298
- border-bottom: #f0f0f0 1px solid;
299
- }
300
-
301
- .popular-posts-list li::before {
302
- display: inline-block;
303
- width: 20px;
304
- content: counter(wpp-counter) ". ";
305
- }
306
-
307
- .popular-posts-list li:last-child,
308
- .popular-posts-list li:last-child {
309
- margin: 0 1%;
310
- border: none;
311
- }
312
-
313
- .popular-posts-list li a.wpp-title {
314
- display: inline;
315
- font-size: 1em;
316
- text-decoration: none;
317
- }
318
-
319
- .popular-posts-list li:first-child,
320
- .popular-posts-list li:first-child a.wpp-title {
321
- font-size: 1.15em;
322
- }
323
-
324
- .popular-posts-list li:nth-child(2),
325
- .popular-posts-list li:nth-child(2) a.wpp-title {
326
- font-size: 1.05em;
327
- }
328
-
329
- .popular-posts-list li:first-child a.wpp-title,
330
- .popular-posts-list li:nth-child(2) a.wpp-title,
331
- .popular-posts-list li:nth-child(3) a.wpp-title {
332
- font-weight: bold;
333
- letter-spacing: -1px;
334
- }
335
-
336
- .popular-posts-list li a.wpp-title:hover {
337
- text-decoration: underline;
338
- }
339
-
340
- .popular-posts-list li span {
341
- color: #bbb;
342
- font-size: 13px;
343
- }
344
-
345
- .popular-posts-list li small {
346
- display: none;
347
- font-size: 13px;
348
- }
349
-
350
- .popular-posts-list li:hover small {
351
- display: inline;
352
- }
353
-
354
- #wpp_params {}
355
-
356
- #wpp_params div {
357
- }
358
-
359
- #wpp_params div table {
360
- width: 100%;
361
- min-width: 800px;
362
- background: white;
363
- }
364
-
365
- #wpp_params div table tr th {
366
- font-size: 1.2em;
367
- text-align: left;
368
- border-bottom: #dedede 1px solid;
369
- }
370
-
371
- #wpp_params div table tr th,
372
- #wpp_params div table tr td {
373
- padding: 1em;
374
- }
375
-
376
- #wpp_params div table tr td {
377
- position: static !important;
378
- clear: none !important;
379
- display: table-cell !important;
380
- vertical-align: top;
381
- }
382
-
383
- .clear {
384
- float:none;
385
- clear:both;
386
- width:100%;
387
- }
388
-
389
- /*
390
- * Media Queries
391
- */
392
-
393
- /* Small devices */
394
- @media only screen and (max-width: 480px){
395
-
396
- }
397
-
398
- /* Tablets & small desktops */
399
- @media only screen and (max-width: 768px) {
400
-
401
- .wpp-wrapper {
402
- margin: 20px 12px 0 2px;
403
- }
404
-
405
- #wpp-listing .wpp-tabbed-nav li a span:last-child {
406
- display: none;
407
- }
408
-
409
- #wpp-listing .wpp-tabbed-nav li a .fa {
410
- margin: 0 0 0 0;
411
- }
412
-
413
- }
414
-
415
- /* Medium desktops, Large desktops & other devices */
416
- @media only screen and (max-width: 992px) { /* 960 + 16 + 16 */
417
-
418
- }
1
+ #wpp-message { display: none; }
2
+
3
+ /*
4
+ * Navigation
5
+ */
6
+ #wpp-menu {
7
+ float: none;
8
+ clear: both;
9
+ }
10
+
11
+ #wpp-menu ul {
12
+ text-align: center;
13
+ }
14
+
15
+ #wpp-menu ul li {
16
+ padding: 0 15px 0 10px;
17
+ margin: 0 0px;
18
+ display: inline;
19
+ border-right: #ddd 1px solid;
20
+ }
21
+
22
+ #wpp-menu ul li:first-child {
23
+ display: none;
24
+ }
25
+
26
+ #wpp-menu ul li:last-child {
27
+ border: none;
28
+ }
29
+
30
+ #wpp-menu ul li a {
31
+ }
32
+
33
+ #wpp-menu ul li.current a {
34
+ color: #00a0d2;
35
+ text-decoration: none;
36
+ }
37
+
38
+ .wpp-wrapper {
39
+ margin: 20px 20px 0 2px;
40
+ -webkit-font-smoothing: subpixel-antialiased;
41
+ }
42
+
43
+ .wpp-lightbox {
44
+ display: none;
45
+ position: fixed;
46
+ top: 50%;
47
+ left: 50%;
48
+ z-index: 999;
49
+ margin: -140px 0 0 -140px;
50
+ padding: 15px;
51
+ width: 250px;
52
+ max-height: 280px;
53
+ background: #fff;
54
+ -webkit-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
55
+ -moz-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
56
+ box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
57
+ }
58
+
59
+ .wpp-lightbox-tabs {
60
+ margin: 0 0 25px 0;
61
+ padding: 0 0 0 0;
62
+ text-align: center;
63
+ }
64
+
65
+ .wpp-lightbox-tabs li {
66
+ display: inline;
67
+ list-style: none;
68
+ margin: 0;
69
+ padding: 0 15px 0 10px;
70
+ border-right: #ddd 1px solid;
71
+ }
72
+
73
+ .wpp-lightbox-tabs li:first-child {
74
+ padding: 0 15px 0 0;
75
+ }
76
+
77
+ .wpp-lightbox-tabs li:last-child {
78
+ padding: 0 0 0 10px;
79
+ border-right: none;
80
+ }
81
+
82
+ .wpp-lightbox-tabs li.active a {
83
+ color: #00a0d2;
84
+ text-decoration: none;
85
+ }
86
+
87
+ .wpp-lightbox-tab-content {
88
+ overflow: hidden;
89
+ display: none;
90
+ width: 100%;
91
+ }
92
+
93
+ .wpp-lightbox-tab-content-active {
94
+ display: block;
95
+ }
96
+
97
+ .wpp-lightbox form {
98
+ display: block;
99
+ }
100
+
101
+ .wpp-lightbox form input[type=text] {
102
+ display: block;
103
+ margin: 0 0 15px 0;
104
+ width: 100%;
105
+ box-sizing: border-box;
106
+ }
107
+
108
+ .wpp-section-stats {
109
+ position: relative;
110
+ }
111
+
112
+ .wpp-section-stats .dashicons-admin-generic {
113
+ position: absolute;
114
+ top: 22px;
115
+ left: 0;
116
+ width: 21px;
117
+ height: 21px;
118
+ transition: transform 0.3s;
119
+ }
120
+
121
+ .wpp-section-stats .dashicons-admin-generic:hover {
122
+ transform: rotate(360deg);
123
+ }
124
+
125
+ .wpp-header {
126
+ overflow: hidden;
127
+ display: block;
128
+ padding: 25px 0 0 0;
129
+ }
130
+
131
+ .wpp-header h2,
132
+ .wpp-header h3,
133
+ .wpp-header h4,
134
+ .wpp-header h5 {
135
+ text-align: center;
136
+ }
137
+
138
+ .wpp-header h2 {
139
+ margin: 0 0 5px 0;
140
+ font-size: 1.0em;
141
+ font-weight: 400;
142
+ line-height: 1.0em;
143
+ }
144
+
145
+ .wpp-header h3 {
146
+ margin: 0 0 30px 0;
147
+ font-size: 3.5em;
148
+ letter-spacing: -1px;
149
+ line-height: 1.0em;
150
+ }
151
+
152
+ .wpp-header h4,
153
+ #wpp-chart-wrapper h4 {
154
+ margin: 0 0 8px 0;
155
+ font-size: 2.0em;
156
+ font-weight: 100;
157
+ line-height: 1.0em;
158
+ letter-spacing: -2px;
159
+ }
160
+
161
+ .wpp-header h5,
162
+ #wpp-chart-wrapper h5 {
163
+ margin: 0 0 0 0;
164
+ font-size: 0.9em;
165
+ font-weight: 300;
166
+ line-height: 0.9em;
167
+ }
168
+
169
+ .wpp-header-nav {
170
+ margin: 55px auto 0px auto;
171
+ padding: 0;
172
+ text-align: center;
173
+ }
174
+
175
+ .wpp-header-nav li {
176
+ display: inline;
177
+ list-style: none;
178
+ margin: 0 4px;
179
+ padding: 0;
180
+ }
181
+
182
+ .wpp-header-nav li a {
183
+ display: inline-block;
184
+ padding: 6px 12px 7px;
185
+ line-height: 1.1em;
186
+ }
187
+
188
+ .wpp-section-stats .wpp-header-nav li a:hover,
189
+ .wpp-section-stats .wpp-header-nav li.current a {
190
+ color: #00a0d2;
191
+ }
192
+
193
+ .wpp-section-stats .wpp-header-nav li.current a {
194
+ text-decoration: none;
195
+ }
196
+
197
+ #wpp-chart-wrapper {
198
+ width: 100%;
199
+ }
200
+
201
+ #wpp-chart-wrapper h4,
202
+ #wpp-chart-wrapper h5 {
203
+ text-align: center;
204
+ }
205
+
206
+ #wpp-chart-wrapper #wpp-chart {
207
+ position: relative;
208
+ overflow: hidden;
209
+ margin: 20px auto 0 auto;
210
+ width: 100%;
211
+ height: 250px;
212
+ }
213
+
214
+ #wpp-chart-wrapper #wpp-chart p {
215
+ margin: 0 10px;
216
+ text-align: center;
217
+ }
218
+
219
+ #wpp-chart-wrapper #wpp-chart a:hover {
220
+ text-decoration: underline;
221
+ }
222
+
223
+ .wpp-content {
224
+ float: none;
225
+ clear: both;
226
+ width: 100%;
227
+ background: #fff;
228
+ }
229
+
230
+ .wpp-content .wpp-tabbed-nav {
231
+ overflow: hidden;
232
+ margin: 0 0 0 0;
233
+ padding: 0;
234
+ background: #f9f9f9;
235
+ }
236
+
237
+ .wpp-content .wpp-tabbed-nav li {
238
+ display: inline;
239
+ float: left;
240
+ margin: 0;
241
+ padding: 0;
242
+ width: 25%;
243
+ border-bottom: #f0f0f0 1px solid;
244
+ }
245
+
246
+ .wpp-content .wpp-tabbed-nav li.active {
247
+ border-bottom: #bbb 1px solid;
248
+ }
249
+
250
+ .wpp-content .wpp-tabbed-nav li a {
251
+ display: block;
252
+ padding: 15px;
253
+ font-size: 1.2em;
254
+ text-align: center;
255
+ text-decoration: none;
256
+ outline: none;
257
+ box-shadow: none;
258
+ }
259
+
260
+ #wpp-listing .wpp-tabbed-nav li a .fa {
261
+ display: inline-block;
262
+ margin: 0 8px 0 0;
263
+ }
264
+
265
+ .wpp-tab-content {
266
+ display: none;
267
+ overflow: hidden;
268
+ padding: 2% 30px;
269
+ width: 100%;
270
+ box-sizing: border-box;
271
+ }
272
+
273
+ .wpp-tab-content-active {
274
+ display: block;
275
+ }
276
+
277
+ .wpp-tab-content .spinner {
278
+ display: block;
279
+ visibility: visible;
280
+ float: none;
281
+ margin-left: auto;
282
+ margin-right: auto;
283
+ }
284
+
285
+ .popular-posts-list {
286
+ margin: 0 0 0 0;
287
+ padding: 0;
288
+ list-style: none;
289
+ counter-reset: wpp-counter;
290
+ font-size: 1rem;
291
+ line-height: 1.2;
292
+ }
293
+
294
+ .popular-posts-list li {
295
+ counter-increment: wpp-counter;
296
+ margin: 0 1% 15px 1%;
297
+ padding: 0 0 10px 0;
298
+ border-bottom: #f0f0f0 1px solid;
299
+ }
300
+
301
+ .popular-posts-list li::before {
302
+ display: inline-block;
303
+ width: 20px;
304
+ content: counter(wpp-counter) ". ";
305
+ }
306
+
307
+ .popular-posts-list li:last-child,
308
+ .popular-posts-list li:last-child {
309
+ margin: 0 1%;
310
+ border: none;
311
+ }
312
+
313
+ .popular-posts-list li a.wpp-title {
314
+ display: inline;
315
+ font-size: 1em;
316
+ text-decoration: none;
317
+ }
318
+
319
+ .popular-posts-list li:first-child,
320
+ .popular-posts-list li:first-child a.wpp-title {
321
+ font-size: 1.15em;
322
+ }
323
+
324
+ .popular-posts-list li:nth-child(2),
325
+ .popular-posts-list li:nth-child(2) a.wpp-title {
326
+ font-size: 1.05em;
327
+ }
328
+
329
+ .popular-posts-list li:first-child a.wpp-title,
330
+ .popular-posts-list li:nth-child(2) a.wpp-title,
331
+ .popular-posts-list li:nth-child(3) a.wpp-title {
332
+ font-weight: bold;
333
+ letter-spacing: -1px;
334
+ }
335
+
336
+ .popular-posts-list li a.wpp-title:hover {
337
+ text-decoration: underline;
338
+ }
339
+
340
+ .popular-posts-list li span {
341
+ color: #bbb;
342
+ font-size: 13px;
343
+ }
344
+
345
+ .popular-posts-list li small {
346
+ display: none;
347
+ font-size: 13px;
348
+ }
349
+
350
+ .popular-posts-list li:hover small {
351
+ display: inline;
352
+ }
353
+
354
+ #wpp_params {}
355
+
356
+ #wpp_params div {
357
+ }
358
+
359
+ #wpp_params div table {
360
+ width: 100%;
361
+ min-width: 800px;
362
+ background: white;
363
+ }
364
+
365
+ #wpp_params div table tr th {
366
+ font-size: 1.2em;
367
+ text-align: left;
368
+ border-bottom: #dedede 1px solid;
369
+ }
370
+
371
+ #wpp_params div table tr th,
372
+ #wpp_params div table tr td {
373
+ padding: 1em;
374
+ }
375
+
376
+ #wpp_params div table tr td {
377
+ position: static !important;
378
+ clear: none !important;
379
+ display: table-cell !important;
380
+ vertical-align: top;
381
+ }
382
+
383
+ .clear {
384
+ float:none;
385
+ clear:both;
386
+ width:100%;
387
+ }
388
+
389
+ /*
390
+ * Media Queries
391
+ */
392
+
393
+ /* Small devices */
394
+ @media only screen and (max-width: 480px){
395
+
396
+ }
397
+
398
+ /* Tablets & small desktops */
399
+ @media only screen and (max-width: 768px) {
400
+
401
+ .wpp-wrapper {
402
+ margin: 20px 12px 0 2px;
403
+ }
404
+
405
+ #wpp-listing .wpp-tabbed-nav li a span:last-child {
406
+ display: none;
407
+ }
408
+
409
+ #wpp-listing .wpp-tabbed-nav li a .fa {
410
+ margin: 0 0 0 0;
411
+ }
412
+
413
+ }
414
+
415
+ /* Medium desktops, Large desktops & other devices */
416
+ @media only screen and (max-width: 992px) { /* 960 + 16 + 16 */
417
+
418
+ }
assets/css/datepicker.css CHANGED
@@ -1,399 +1,399 @@
1
- /*! jQuery UI - v1.12.1 - 2017-08-15
2
- * http://jqueryui.com
3
- * Includes: core.css, datepicker.css
4
- * Copyright jQuery Foundation and other contributors; Licensed MIT */
5
-
6
- /* Layout helpers
7
- ----------------------------------*/
8
- .ui-helper-hidden {
9
- display: none;
10
- }
11
- .ui-helper-hidden-accessible {
12
- border: 0;
13
- clip: rect(0 0 0 0);
14
- height: 1px;
15
- margin: -1px;
16
- overflow: hidden;
17
- padding: 0;
18
- position: absolute;
19
- width: 1px;
20
- }
21
- .ui-helper-reset {
22
- margin: 0;
23
- padding: 0;
24
- border: 0;
25
- outline: 0;
26
- line-height: 1.3;
27
- text-decoration: none;
28
- font-size: 100%;
29
- list-style: none;
30
- }
31
- .ui-helper-clearfix:before,
32
- .ui-helper-clearfix:after {
33
- content: "";
34
- display: table;
35
- border-collapse: collapse;
36
- }
37
- .ui-helper-clearfix:after {
38
- clear: both;
39
- }
40
- .ui-helper-zfix {
41
- width: 100%;
42
- height: 100%;
43
- top: 0;
44
- left: 0;
45
- position: absolute;
46
- opacity: 0;
47
- filter:Alpha(Opacity=0); /* support: IE8 */
48
- }
49
-
50
- .ui-front {
51
- z-index: 100;
52
- }
53
-
54
-
55
- /* Interaction Cues
56
- ----------------------------------*/
57
- .ui-state-disabled {
58
- cursor: default !important;
59
- pointer-events: none;
60
- }
61
-
62
-
63
- /* Icons
64
- ----------------------------------*/
65
- .ui-icon {
66
- display: inline-block;
67
- vertical-align: middle;
68
- margin-top: -.25em;
69
- position: relative;
70
- text-indent: -99999px;
71
- overflow: hidden;
72
- background-repeat: no-repeat;
73
- }
74
-
75
- .ui-widget-icon-block {
76
- left: 50%;
77
- margin-left: -8px;
78
- display: block;
79
- }
80
-
81
- /* Misc visuals
82
- ----------------------------------*/
83
-
84
- /* Overlays */
85
- .ui-widget-overlay {
86
- position: fixed;
87
- top: 0;
88
- left: 0;
89
- width: 100%;
90
- height: 100%;
91
- }
92
- .ui-datepicker {
93
- width: 17em;
94
- padding: .2em .2em 0;
95
- display: none;
96
- }
97
- .ui-datepicker .ui-datepicker-header {
98
- position: relative;
99
- padding: .2em 0;
100
- }
101
- .ui-datepicker .ui-datepicker-prev,
102
- .ui-datepicker .ui-datepicker-next {
103
- position: absolute;
104
- top: 2px;
105
- width: 1.8em;
106
- height: 1.8em;
107
- }
108
- .ui-datepicker .ui-datepicker-prev-hover,
109
- .ui-datepicker .ui-datepicker-next-hover {
110
- top: 1px;
111
- }
112
- .ui-datepicker .ui-datepicker-prev {
113
- left: 2px;
114
- }
115
- .ui-datepicker .ui-datepicker-next {
116
- right: 2px;
117
- }
118
- .ui-datepicker .ui-datepicker-prev-hover {
119
- left: 1px;
120
- }
121
- .ui-datepicker .ui-datepicker-next-hover {
122
- right: 1px;
123
- }
124
- .ui-datepicker .ui-datepicker-prev span,
125
- .ui-datepicker .ui-datepicker-next span {
126
- display: block;
127
- position: absolute;
128
- left: 50%;
129
- margin-left: -8px;
130
- top: 50%;
131
- margin-top: -8px;
132
- }
133
- .ui-datepicker .ui-datepicker-title {
134
- margin: 0 2.3em;
135
- line-height: 1.8em;
136
- text-align: center;
137
- }
138
- .ui-datepicker .ui-datepicker-title select {
139
- font-size: 1em;
140
- margin: 1px 0;
141
- }
142
- .ui-datepicker select.ui-datepicker-month,
143
- .ui-datepicker select.ui-datepicker-year {
144
- width: 45%;
145
- }
146
- .ui-datepicker table {
147
- width: 100%;
148
- font-size: .9em;
149
- border-collapse: collapse;
150
- margin: 0 0 .4em;
151
- }
152
- .ui-datepicker th {
153
- padding: .7em .3em;
154
- text-align: center;
155
- font-weight: bold;
156
- border: 0;
157
- }
158
- .ui-datepicker td {
159
- border: 0;
160
- padding: 1px;
161
- }
162
- .ui-datepicker td span,
163
- .ui-datepicker td a {
164
- display: block;
165
- padding: .2em;
166
- text-align: right;
167
- text-decoration: none;
168
- }
169
- .ui-datepicker .ui-datepicker-buttonpane {
170
- background-image: none;
171
- margin: .7em 0 0 0;
172
- padding: 0 .2em;
173
- border-left: 0;
174
- border-right: 0;
175
- border-bottom: 0;
176
- }
177
- .ui-datepicker .ui-datepicker-buttonpane button {
178
- float: right;
179
- margin: .5em .2em .4em;
180
- cursor: pointer;
181
- padding: .2em .6em .3em .6em;
182
- width: auto;
183
- overflow: visible;
184
- }
185
- .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
186
- float: left;
187
- }
188
-
189
- /* with multiple calendars */
190
- .ui-datepicker.ui-datepicker-multi {
191
- width: auto;
192
- }
193
- .ui-datepicker-multi .ui-datepicker-group {
194
- float: left;
195
- }
196
- .ui-datepicker-multi .ui-datepicker-group table {
197
- width: 95%;
198
- margin: 0 auto .4em;
199
- }
200
- .ui-datepicker-multi-2 .ui-datepicker-group {
201
- width: 50%;
202
- }
203
- .ui-datepicker-multi-3 .ui-datepicker-group {
204
- width: 33.3%;
205
- }
206
- .ui-datepicker-multi-4 .ui-datepicker-group {
207
- width: 25%;
208
- }
209
- .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
210
- .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
211
- border-left-width: 0;
212
- }
213
- .ui-datepicker-multi .ui-datepicker-buttonpane {
214
- clear: left;
215
- }
216
- .ui-datepicker-row-break {
217
- clear: both;
218
- width: 100%;
219
- font-size: 0;
220
- }
221
-
222
- /* RTL support */
223
- .ui-datepicker-rtl {
224
- direction: rtl;
225
- }
226
- .ui-datepicker-rtl .ui-datepicker-prev {
227
- right: 2px;
228
- left: auto;
229
- }
230
- .ui-datepicker-rtl .ui-datepicker-next {
231
- left: 2px;
232
- right: auto;
233
- }
234
- .ui-datepicker-rtl .ui-datepicker-prev:hover {
235
- right: 1px;
236
- left: auto;
237
- }
238
- .ui-datepicker-rtl .ui-datepicker-next:hover {
239
- left: 1px;
240
- right: auto;
241
- }
242
- .ui-datepicker-rtl .ui-datepicker-buttonpane {
243
- clear: right;
244
- }
245
- .ui-datepicker-rtl .ui-datepicker-buttonpane button {
246
- float: left;
247
- }
248
- .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
249
- .ui-datepicker-rtl .ui-datepicker-group {
250
- float: right;
251
- }
252
- .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
253
- .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
254
- border-right-width: 0;
255
- border-left-width: 1px;
256
- }
257
-
258
- /* Icons */
259
- .ui-datepicker .ui-icon {
260
- display: block;
261
- text-indent: -99999px;
262
- overflow: hidden;
263
- background-repeat: no-repeat;
264
- left: .5em;
265
- top: .3em;
266
- }
267
-
268
-
269
- /*
270
- * Custom datepicker theme for WPP.
271
- *
272
- * @author Hector Cabrera
273
- */
274
-
275
- .ui-datepicker {
276
- background: #fff;
277
- -webkit-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
278
- -moz-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
279
- box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
280
- border-radius: 5px;
281
- }
282
-
283
- .ui-datepicker-header {}
284
-
285
- .ui-datepicker .ui-datepicker-prev {
286
- left: 0;
287
- }
288
-
289
- .ui-datepicker .ui-datepicker-next {
290
- right: 0;
291
- }
292
-
293
- .ui-datepicker .ui-datepicker-prev span,
294
- .ui-datepicker .ui-datepicker-next span {
295
- display: block;
296
- position: absolute;
297
- /*left: 50%;
298
- margin-left: -8px;
299
- top: 50%;
300
- margin-top: -8px;*/
301
- }
302
-
303
- .ui-datepicker-prev:before,
304
- .ui-datepicker-next:after {
305
- position: absolute;
306
- top: 6px;
307
- display: inline-block;
308
- font-family: 'FontAwesome';
309
- line-height: 1.1em;
310
- }
311
-
312
- .ui-datepicker-prev:before {
313
- left: 9px;
314
- content: "\f060";
315
- }
316
-
317
- .ui-datepicker-next:after {
318
- right: 9px;
319
- content: "\f061";
320
- }
321
-
322
- .ui-datepicker .ui-datepicker-prev-hover,
323
- .ui-datepicker .ui-datepicker-next-hover {
324
- top: 2px !important;
325
- }
326
-
327
- .ui-datepicker-calendar {}
328
-
329
- .ui-datepicker-calendar tr td {
330
- text-align: center;
331
- }
332
-
333
- .ui-datepicker-unselectable span {
334
- color: #ccc;
335
- text-align: center !important;
336
- }
337
-
338
- .ui-datepicker-calendar tr td a {
339
- text-align: center;
340
- background: #fcfcfc;
341
- }
342
-
343
- .ui-datepicker-calendar tr td.date-range-selected a {
344
- color: #fff;
345
- text-shadow: 0 -1px 1px #ba281e, 1px 0 1px #ba281e, 0 1px 1px #ba281e, -1px 0 1px #ba281e;
346
- background: #e14d43;
347
- }
348
-
349
- .ui-datepicker-buttonpane {}
350
-
351
- .ui-datepicker-buttonpane button {
352
- display: inline-block;
353
- text-decoration: none;
354
- font-size: 13px;
355
- line-height: 26px;
356
- height: 28px;
357
- margin: 0;
358
- padding: 0 10px 1px !important;
359
- border-color: #ccc;
360
- background: #f7f7f7;
361
- vertical-align: top;
362
- cursor: pointer;
363
- border-width: 1px;
364
- border-style: solid;
365
- -webkit-appearance: none;
366
- -webkit-border-radius: 3px;
367
- border-radius: 3px;
368
- white-space: nowrap;
369
- -webkit-box-sizing: border-box;
370
- -moz-box-sizing: border-box;
371
- box-sizing: border-box;
372
- }
373
-
374
- /* Today button */
375
- .ui-datepicker-buttonpane .ui-datepicker-current {
376
- display: none;
377
- }
378
-
379
- .ui-datepicker-buttonpane .ui-priority-primary {
380
- color: #fff;
381
- background: #e14d43;
382
- border-color: #d02c21 #ba281e #ba281e;
383
- -webkit-box-shadow: 0 1px 0 #ba281e;
384
- box-shadow: 0 1px 0 #ba281e;
385
- text-shadow: 0 -1px 1px #ba281e, 1px 0 1px #ba281e, 0 1px 1px #ba281e, -1px 0 1px #ba281e;
386
- }
387
-
388
- .ui-datepicker-buttonpane .ui-priority-primary:hover {
389
- background: #e35950;
390
- border-color: #ba281e;
391
- }
392
-
393
- .ui-datepicker-buttonpane .ui-priority-secondary {
394
- color: #555;
395
- border-color: #ccc;
396
- background: #f7f7f7;
397
- -webkit-box-shadow: 0 1px 0 #ccc;
398
- box-shadow: 0 1px 0 #ccc;
399
- }
1
+ /*! jQuery UI - v1.12.1 - 2017-08-15
2
+ * http://jqueryui.com
3
+ * Includes: core.css, datepicker.css
4
+ * Copyright jQuery Foundation and other contributors; Licensed MIT */
5
+
6
+ /* Layout helpers
7
+ ----------------------------------*/
8
+ .ui-helper-hidden {
9
+ display: none;
10
+ }
11
+ .ui-helper-hidden-accessible {
12
+ border: 0;
13
+ clip: rect(0 0 0 0);
14
+ height: 1px;
15
+ margin: -1px;
16
+ overflow: hidden;
17
+ padding: 0;
18
+ position: absolute;
19
+ width: 1px;
20
+ }
21
+ .ui-helper-reset {
22
+ margin: 0;
23
+ padding: 0;
24
+ border: 0;
25
+ outline: 0;
26
+ line-height: 1.3;
27
+ text-decoration: none;
28
+ font-size: 100%;
29
+ list-style: none;
30
+ }
31
+ .ui-helper-clearfix:before,
32
+ .ui-helper-clearfix:after {
33
+ content: "";
34
+ display: table;
35
+ border-collapse: collapse;
36
+ }
37
+ .ui-helper-clearfix:after {
38
+ clear: both;
39
+ }
40
+ .ui-helper-zfix {
41
+ width: 100%;
42
+ height: 100%;
43
+ top: 0;
44
+ left: 0;
45
+ position: absolute;
46
+ opacity: 0;
47
+ filter:Alpha(Opacity=0); /* support: IE8 */
48
+ }
49
+
50
+ .ui-front {
51
+ z-index: 100;
52
+ }
53
+
54
+
55
+ /* Interaction Cues
56
+ ----------------------------------*/
57
+ .ui-state-disabled {
58
+ cursor: default !important;
59
+ pointer-events: none;
60
+ }
61
+
62
+
63
+ /* Icons
64
+ ----------------------------------*/
65
+ .ui-icon {
66
+ display: inline-block;
67
+ vertical-align: middle;
68
+ margin-top: -.25em;
69
+ position: relative;
70
+ text-indent: -99999px;
71
+ overflow: hidden;
72
+ background-repeat: no-repeat;
73
+ }
74
+
75
+ .ui-widget-icon-block {
76
+ left: 50%;
77
+ margin-left: -8px;
78
+ display: block;
79
+ }
80
+
81
+ /* Misc visuals
82
+ ----------------------------------*/
83
+
84
+ /* Overlays */
85
+ .ui-widget-overlay {
86
+ position: fixed;
87
+ top: 0;
88
+ left: 0;
89
+ width: 100%;
90
+ height: 100%;
91
+ }
92
+ .ui-datepicker {
93
+ width: 17em;
94
+ padding: .2em .2em 0;
95
+ display: none;
96
+ }
97
+ .ui-datepicker .ui-datepicker-header {
98
+ position: relative;
99
+ padding: .2em 0;
100
+ }
101
+ .ui-datepicker .ui-datepicker-prev,
102
+ .ui-datepicker .ui-datepicker-next {
103
+ position: absolute;
104
+ top: 2px;
105
+ width: 1.8em;
106
+ height: 1.8em;
107
+ }
108
+ .ui-datepicker .ui-datepicker-prev-hover,
109
+ .ui-datepicker .ui-datepicker-next-hover {
110
+ top: 1px;
111
+ }
112
+ .ui-datepicker .ui-datepicker-prev {
113
+ left: 2px;
114
+ }
115
+ .ui-datepicker .ui-datepicker-next {
116
+ right: 2px;
117
+ }
118
+ .ui-datepicker .ui-datepicker-prev-hover {
119
+ left: 1px;
120
+ }
121
+ .ui-datepicker .ui-datepicker-next-hover {
122
+ right: 1px;
123
+ }
124
+ .ui-datepicker .ui-datepicker-prev span,
125
+ .ui-datepicker .ui-datepicker-next span {
126
+ display: block;
127
+ position: absolute;
128
+ left: 50%;
129
+ margin-left: -8px;
130
+ top: 50%;
131
+ margin-top: -8px;
132
+ }
133
+ .ui-datepicker .ui-datepicker-title {
134
+ margin: 0 2.3em;
135
+ line-height: 1.8em;
136
+ text-align: center;
137
+ }
138
+ .ui-datepicker .ui-datepicker-title select {
139
+ font-size: 1em;
140
+ margin: 1px 0;
141
+ }
142
+ .ui-datepicker select.ui-datepicker-month,
143
+ .ui-datepicker select.ui-datepicker-year {
144
+ width: 45%;
145
+ }
146
+ .ui-datepicker table {
147
+ width: 100%;
148
+ font-size: .9em;
149
+ border-collapse: collapse;
150
+ margin: 0 0 .4em;
151
+ }
152
+ .ui-datepicker th {
153
+ padding: .7em .3em;
154
+ text-align: center;
155
+ font-weight: bold;
156
+ border: 0;
157
+ }
158
+ .ui-datepicker td {
159
+ border: 0;
160
+ padding: 1px;
161
+ }
162
+ .ui-datepicker td span,
163
+ .ui-datepicker td a {
164
+ display: block;
165
+ padding: .2em;
166
+ text-align: right;
167
+ text-decoration: none;
168
+ }
169
+ .ui-datepicker .ui-datepicker-buttonpane {
170
+ background-image: none;
171
+ margin: .7em 0 0 0;
172
+ padding: 0 .2em;
173
+ border-left: 0;
174
+ border-right: 0;
175
+ border-bottom: 0;
176
+ }
177
+ .ui-datepicker .ui-datepicker-buttonpane button {
178
+ float: right;
179
+ margin: .5em .2em .4em;
180
+ cursor: pointer;
181
+ padding: .2em .6em .3em .6em;
182
+ width: auto;
183
+ overflow: visible;
184
+ }
185
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
186
+ float: left;
187
+ }
188
+
189
+ /* with multiple calendars */
190
+ .ui-datepicker.ui-datepicker-multi {
191
+ width: auto;
192
+ }
193
+ .ui-datepicker-multi .ui-datepicker-group {
194
+ float: left;
195
+ }
196
+ .ui-datepicker-multi .ui-datepicker-group table {
197
+ width: 95%;
198
+ margin: 0 auto .4em;
199
+ }
200
+ .ui-datepicker-multi-2 .ui-datepicker-group {
201
+ width: 50%;
202
+ }
203
+ .ui-datepicker-multi-3 .ui-datepicker-group {
204
+ width: 33.3%;
205
+ }
206
+ .ui-datepicker-multi-4 .ui-datepicker-group {
207
+ width: 25%;
208
+ }
209
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
210
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
211
+ border-left-width: 0;
212
+ }
213
+ .ui-datepicker-multi .ui-datepicker-buttonpane {
214
+ clear: left;
215
+ }
216
+ .ui-datepicker-row-break {
217
+ clear: both;
218
+ width: 100%;
219
+ font-size: 0;
220
+ }
221
+
222
+ /* RTL support */
223
+ .ui-datepicker-rtl {
224
+ direction: rtl;
225
+ }
226
+ .ui-datepicker-rtl .ui-datepicker-prev {
227
+ right: 2px;
228
+ left: auto;
229
+ }
230
+ .ui-datepicker-rtl .ui-datepicker-next {
231
+ left: 2px;
232
+ right: auto;
233
+ }
234
+ .ui-datepicker-rtl .ui-datepicker-prev:hover {
235
+ right: 1px;
236
+ left: auto;
237
+ }
238
+ .ui-datepicker-rtl .ui-datepicker-next:hover {
239
+ left: 1px;
240
+ right: auto;
241
+ }
242
+ .ui-datepicker-rtl .ui-datepicker-buttonpane {
243
+ clear: right;
244
+ }
245
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button {
246
+ float: left;
247
+ }
248
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
249
+ .ui-datepicker-rtl .ui-datepicker-group {
250
+ float: right;
251
+ }
252
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
253
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
254
+ border-right-width: 0;
255
+ border-left-width: 1px;
256
+ }
257
+
258
+ /* Icons */
259
+ .ui-datepicker .ui-icon {
260
+ display: block;
261
+ text-indent: -99999px;
262
+ overflow: hidden;
263
+ background-repeat: no-repeat;
264
+ left: .5em;
265
+ top: .3em;
266
+ }
267
+
268
+
269
+ /*
270
+ * Custom datepicker theme for WPP.
271
+ *
272
+ * @author Hector Cabrera
273
+ */
274
+
275
+ .ui-datepicker {
276
+ background: #fff;
277
+ -webkit-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
278
+ -moz-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
279
+ box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.25);
280
+ border-radius: 5px;
281
+ }
282
+
283
+ .ui-datepicker-header {}
284
+
285
+ .ui-datepicker .ui-datepicker-prev {
286
+ left: 0;
287
+ }
288
+
289
+ .ui-datepicker .ui-datepicker-next {
290
+ right: 0;
291
+ }
292
+
293
+ .ui-datepicker .ui-datepicker-prev span,
294
+ .ui-datepicker .ui-datepicker-next span {
295
+ display: block;
296
+ position: absolute;
297
+ /*left: 50%;
298
+ margin-left: -8px;
299
+ top: 50%;
300
+ margin-top: -8px;*/
301
+ }
302
+
303
+ .ui-datepicker-prev:before,
304
+ .ui-datepicker-next:after {
305
+ position: absolute;
306
+ top: 6px;
307
+ display: inline-block;
308
+ font-family: 'FontAwesome';
309
+ line-height: 1.1em;
310
+ }
311
+
312
+ .ui-datepicker-prev:before {
313
+ left: 9px;
314
+ content: "\f060";
315
+ }
316
+
317
+ .ui-datepicker-next:after {
318
+ right: 9px;
319
+ content: "\f061";
320
+ }
321
+
322
+ .ui-datepicker .ui-datepicker-prev-hover,
323
+ .ui-datepicker .ui-datepicker-next-hover {
324
+ top: 2px !important;
325
+ }
326
+
327
+ .ui-datepicker-calendar {}
328
+
329
+ .ui-datepicker-calendar tr td {
330
+ text-align: center;
331
+ }
332
+
333
+ .ui-datepicker-unselectable span {
334
+ color: #ccc;
335
+ text-align: center !important;
336
+ }
337
+
338
+ .ui-datepicker-calendar tr td a {
339
+ text-align: center;
340
+ background: #fcfcfc;
341
+ }
342
+
343
+ .ui-datepicker-calendar tr td.date-range-selected a {
344
+ color: #fff;
345
+ text-shadow: 0 -1px 1px #ba281e, 1px 0 1px #ba281e, 0 1px 1px #ba281e, -1px 0 1px #ba281e;
346
+ background: #e14d43;
347
+ }
348
+
349
+ .ui-datepicker-buttonpane {}
350
+
351
+ .ui-datepicker-buttonpane button {
352
+ display: inline-block;
353
+ text-decoration: none;
354
+ font-size: 13px;
355
+ line-height: 26px;
356
+ height: 28px;
357
+ margin: 0;
358
+ padding: 0 10px 1px !important;
359
+ border-color: #ccc;
360
+ background: #f7f7f7;
361
+ vertical-align: top;
362
+ cursor: pointer;
363
+ border-width: 1px;
364
+ border-style: solid;
365
+ -webkit-appearance: none;
366
+ -webkit-border-radius: 3px;
367
+ border-radius: 3px;
368
+ white-space: nowrap;
369
+ -webkit-box-sizing: border-box;
370
+ -moz-box-sizing: border-box;
371
+ box-sizing: border-box;
372
+ }
373
+
374
+ /* Today button */
375
+ .ui-datepicker-buttonpane .ui-datepicker-current {
376
+ display: none;
377
+ }
378
+
379
+ .ui-datepicker-buttonpane .ui-priority-primary {
380
+ color: #fff;
381
+ background: #e14d43;
382
+ border-color: #d02c21 #ba281e #ba281e;
383
+ -webkit-box-shadow: 0 1px 0 #ba281e;
384
+ box-shadow: 0 1px 0 #ba281e;
385
+ text-shadow: 0 -1px 1px #ba281e, 1px 0 1px #ba281e, 0 1px 1px #ba281e, -1px 0 1px #ba281e;
386
+ }
387
+
388
+ .ui-datepicker-buttonpane .ui-priority-primary:hover {
389
+ background: #e35950;
390
+ border-color: #ba281e;
391
+ }
392
+
393
+ .ui-datepicker-buttonpane .ui-priority-secondary {
394
+ color: #555;
395
+ border-color: #ccc;
396
+ background: #f7f7f7;
397
+ -webkit-box-shadow: 0 1px 0 #ccc;
398
+ box-shadow: 0 1px 0 #ccc;
399
+ }
assets/css/fontello.css CHANGED
@@ -1,50 +1,50 @@
1
- @font-face {
2
- font-family: 'fontello';
3
- src: url('../fonts/fontello.eot?57329479');
4
- src: url('../fonts/fontello.eot?57329479#iefix') format('embedded-opentype'),
5
- url('../fonts/fontello.woff2?57329479') format('woff2'),
6
- url('../fonts/fontello.woff?57329479') format('woff'),
7
- url('../fonts/fontello.ttf?57329479') format('truetype'),
8
- url('../fonts/fontello.svg?57329479#fontello') format('svg');
9
- font-weight: normal;
10
- font-style: normal;
11
- }
12
- [class^="wpp-icon-"]:before, [class*=" icon-"]:before {
13
- font-family: "fontello";
14
- font-style: normal;
15
- font-weight: normal;
16
- speak: none;
17
-
18
- display: inline-block;
19
- text-decoration: inherit;
20
- width: 1em;
21
- margin-right: .2em;
22
- text-align: center;
23
- /* opacity: .8; */
24
-
25
- /* For safety - reset parent styles, that can break glyph codes*/
26
- font-variant: normal;
27
- text-transform: none;
28
-
29
- /* fix buttons height, for twitter bootstrap */
30
- line-height: 1em;
31
-
32
- /* Animation center compensation - margins should be symmetric */
33
- /* remove if not needed */
34
- margin-left: .2em;
35
-
36
- /* you can be more comfortable with increased icons size */
37
- /* font-size: 120%; */
38
-
39
- /* Font smoothing. That was taken from TWBS */
40
- -webkit-font-smoothing: antialiased;
41
- -moz-osx-font-smoothing: grayscale;
42
-
43
- /* Uncomment for 3D effect */
44
- /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
45
- }
46
-
47
- .wpp-icon-eye:before { content: '\e800'; }
48
- .wpp-icon-award:before { content: '\e801'; }
49
- .wpp-icon-comment:before { content: '\f0e5'; }
50
  .wpp-icon-rocket:before { content: '\f135'; }
1
+ @font-face {
2
+ font-family: 'fontello';
3
+ src: url('../fonts/fontello.eot?57329479');
4
+ src: url('../fonts/fontello.eot?57329479#iefix') format('embedded-opentype'),
5
+ url('../fonts/fontello.woff2?57329479') format('woff2'),
6
+ url('../fonts/fontello.woff?57329479') format('woff'),
7
+ url('../fonts/fontello.ttf?57329479') format('truetype'),
8
+ url('../fonts/fontello.svg?57329479#fontello') format('svg');
9
+ font-weight: normal;
10
+ font-style: normal;
11
+ }
12
+ [class^="wpp-icon-"]:before, [class*=" icon-"]:before {
13
+ font-family: "fontello";
14
+ font-style: normal;
15
+ font-weight: normal;
16
+ speak: none;
17
+
18
+ display: inline-block;
19
+ text-decoration: inherit;
20
+ width: 1em;
21
+ margin-right: .2em;
22
+ text-align: center;
23
+ /* opacity: .8; */
24
+
25
+ /* For safety - reset parent styles, that can break glyph codes*/
26
+ font-variant: normal;
27
+ text-transform: none;
28
+
29
+ /* fix buttons height, for twitter bootstrap */
30
+ line-height: 1em;
31
+
32
+ /* Animation center compensation - margins should be symmetric */
33
+ /* remove if not needed */
34
+ margin-left: .2em;
35
+
36
+ /* you can be more comfortable with increased icons size */
37
+ /* font-size: 120%; */
38
+
39
+ /* Font smoothing. That was taken from TWBS */
40
+ -webkit-font-smoothing: antialiased;
41
+ -moz-osx-font-smoothing: grayscale;
42
+
43
+ /* Uncomment for 3D effect */
44
+ /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
45
+ }
46
+
47
+ .wpp-icon-eye:before { content: '\e800'; }
48
+ .wpp-icon-award:before { content: '\e801'; }
49
+ .wpp-icon-comment:before { content: '\f0e5'; }
50
  .wpp-icon-rocket:before { content: '\f135'; }
assets/css/wpp.css CHANGED
@@ -1,77 +1,77 @@
1
- /*
2
- Wordpress Popular Posts plugin stylesheet
3
- Developed by Hector Cabrera
4
- cabrerahector.com | @cabrerahector
5
-
6
- Use the following classes to style your popular posts list as you like.
7
- */
8
-
9
- /* Styles the "Sorry, no data so far" message */
10
- .wpp-no-data {
11
- }
12
-
13
- /* UL - Popular Posts container styles */
14
- .wpp-list {
15
- }
16
-
17
- /* LI - Post container styles */
18
- .wpp-list li {
19
- overflow: hidden;
20
- float: none;
21
- clear: both;
22
- margin-bottom: 1rem;
23
- }
24
-
25
- .wpp-list li:last-of-type {
26
- margin-bottom: 0;
27
- }
28
-
29
- /* Styles for the popular post in view */
30
- .wpp-list li.current {
31
- }
32
-
33
- /* Thumbnail styles */
34
- .wpp-thumbnail {
35
- display: inline;
36
- float: left;
37
- margin: 0 1rem 0 0;
38
- border: none;
39
- }
40
-
41
- /* Title styles */
42
- .wpp-post-title {
43
- }
44
-
45
- /* Excerpt styles */
46
- .wpp-excerpt {
47
- }
48
-
49
- /* Stats tag styles */
50
- .wpp-meta, .post-stats {
51
- display: block;
52
- font-size: 0.8em;
53
- }
54
-
55
- /* Comments count styles */
56
- .wpp-comments {
57
- }
58
-
59
- /* Views count styles */
60
- .wpp-views {
61
- }
62
-
63
- /* Author styles */
64
- .wpp-author {
65
- }
66
-
67
- /* Post date styles */
68
- .wpp-date {
69
- }
70
-
71
- /* Post category styles */
72
- .wpp-category {
73
- }
74
-
75
- /* WP-PostRatings styles */
76
- .wpp-rating {
77
  }
1
+ /*
2
+ Wordpress Popular Posts plugin stylesheet
3
+ Developed by Hector Cabrera
4
+ cabrerahector.com | @cabrerahector
5
+
6
+ Use the following classes to style your popular posts list as you like.
7
+ */
8
+
9
+ /* Styles the "Sorry, no data so far" message */
10
+ .wpp-no-data {
11
+ }
12
+
13
+ /* UL - Popular Posts container styles */
14
+ .wpp-list {
15
+ }
16
+
17
+ /* LI - Post container styles */
18
+ .wpp-list li {
19
+ overflow: hidden;
20
+ float: none;
21
+ clear: both;
22
+ margin-bottom: 1rem;
23
+ }
24
+
25
+ .wpp-list li:last-of-type {
26
+ margin-bottom: 0;
27
+ }
28
+
29
+ /* Styles for the popular post in view */
30
+ .wpp-list li.current {
31
+ }
32
+
33
+ /* Thumbnail styles */
34
+ .wpp-thumbnail {
35
+ display: inline;
36
+ float: left;
37
+ margin: 0 1rem 0 0;
38
+ border: none;
39
+ }
40
+
41
+ /* Title styles */
42
+ .wpp-post-title {
43
+ }
44
+
45
+ /* Excerpt styles */
46
+ .wpp-excerpt {
47
+ }
48
+
49
+ /* Stats tag styles */
50
+ .wpp-meta, .post-stats {
51
+ display: block;
52
+ font-size: 0.8em;
53
+ }
54
+
55
+ /* Comments count styles */
56
+ .wpp-comments {
57
+ }
58
+
59
+ /* Views count styles */
60
+ .wpp-views {
61
+ }
62
+
63
+ /* Author styles */
64
+ .wpp-author {
65
+ }
66
+
67
+ /* Post date styles */
68
+ .wpp-date {
69
+ }
70
+
71
+ /* Post category styles */
72
+ .wpp-category {
73
+ }
74
+
75
+ /* WP-PostRatings styles */
76
+ .wpp-rating {
77
  }
assets/fonts/fontello.svg CHANGED
@@ -1,18 +1,18 @@
1
- <?xml version="1.0" standalone="no"?>
2
- <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
- <svg xmlns="http://www.w3.org/2000/svg">
4
- <metadata>Copyright (C) 2019 by original authors @ fontello.com</metadata>
5
- <defs>
6
- <font id="fontello" horiz-adv-x="1000" >
7
- <font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
8
- <missing-glyph horiz-adv-x="1000" />
9
- <glyph glyph-name="eye" unicode="&#xe800;" d="M929 314q-85 132-213 197 34-58 34-125 0-103-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 243 68 186 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m473-215q0-19-11-38-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38t11 39q78 128 210 205t279 78 279-78 210-205q11-20 11-39z" horiz-adv-x="1000" />
10
-
11
- <glyph glyph-name="award" unicode="&#xe801;" d="M256 357q-42 91-42 207h-143v-53q0-44 53-91t132-63z m601 154v53h-143q0-116-41-207 79 16 131 63t53 91z m72 71v-71q0-40-24-80t-62-73-97-54-120-25q-23-30-53-53-21-19-29-40t-8-50q0-30 17-51t54-21q42 0 75-25t32-64v-36q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v36q0 39 33 64t74 25q38 0 55 21t17 51q0 28-8 50t-29 40q-30 23-53 53-64 3-121 25t-96 54-63 73-23 80v71q0 23 16 38t38 16h160v53q0 37 27 63t63 27h321q37 0 63-27t26-63v-53h161q22 0 38-16t16-38z" horiz-adv-x="928.6" />
12
-
13
- <glyph glyph-name="comment-empty" unicode="&#xf0e5;" d="M500 636q-114 0-213-39t-157-105-59-142q0-62 40-119t113-98l48-28-15-53q-13-51-39-97 85 36 154 96l24 21 32-3q38-5 72-5 114 0 213 39t157 105 59 142-59 142-157 105-213 39z m500-286q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-8-63-12h-3q-8 0-15 6t-9 15v1q-2 2 0 6t1 6 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 97 67 179t182 130 251 48 251-48 182-130 67-179z" horiz-adv-x="1000" />
14
-
15
- <glyph glyph-name="rocket" unicode="&#xf135;" d="M804 600q0 22-16 38t-38 16-38-16-16-38 16-38 38-16 38 16 16 38z m125 161q0-139-43-240t-141-202q-45-44-109-98l-11-211q-1-9-9-15l-214-125q-4-2-9-2-7 0-13 5l-36 36q-7 7-4 17l47 155-156 156-154-47q-2-1-6-1-7 0-12 5l-36 36q-10 11-3 22l125 214q6 8 15 9l211 11q54 64 98 109 105 104 200 144t241 40q7 0 13-6t6-12z" horiz-adv-x="928.6" />
16
- </font>
17
- </defs>
18
  </svg>
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg xmlns="http://www.w3.org/2000/svg">
4
+ <metadata>Copyright (C) 2019 by original authors @ fontello.com</metadata>
5
+ <defs>
6
+ <font id="fontello" horiz-adv-x="1000" >
7
+ <font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
8
+ <missing-glyph horiz-adv-x="1000" />
9
+ <glyph glyph-name="eye" unicode="&#xe800;" d="M929 314q-85 132-213 197 34-58 34-125 0-103-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 243 68 186 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m473-215q0-19-11-38-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38t11 39q78 128 210 205t279 78 279-78 210-205q11-20 11-39z" horiz-adv-x="1000" />
10
+
11
+ <glyph glyph-name="award" unicode="&#xe801;" d="M256 357q-42 91-42 207h-143v-53q0-44 53-91t132-63z m601 154v53h-143q0-116-41-207 79 16 131 63t53 91z m72 71v-71q0-40-24-80t-62-73-97-54-120-25q-23-30-53-53-21-19-29-40t-8-50q0-30 17-51t54-21q42 0 75-25t32-64v-36q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v36q0 39 33 64t74 25q38 0 55 21t17 51q0 28-8 50t-29 40q-30 23-53 53-64 3-121 25t-96 54-63 73-23 80v71q0 23 16 38t38 16h160v53q0 37 27 63t63 27h321q37 0 63-27t26-63v-53h161q22 0 38-16t16-38z" horiz-adv-x="928.6" />
12
+
13
+ <glyph glyph-name="comment-empty" unicode="&#xf0e5;" d="M500 636q-114 0-213-39t-157-105-59-142q0-62 40-119t113-98l48-28-15-53q-13-51-39-97 85 36 154 96l24 21 32-3q38-5 72-5 114 0 213 39t157 105 59 142-59 142-157 105-213 39z m500-286q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-8-63-12h-3q-8 0-15 6t-9 15v1q-2 2 0 6t1 6 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 97 67 179t182 130 251 48 251-48 182-130 67-179z" horiz-adv-x="1000" />
14
+
15
+ <glyph glyph-name="rocket" unicode="&#xf135;" d="M804 600q0 22-16 38t-38 16-38-16-16-38 16-38 38-16 38 16 16 38z m125 161q0-139-43-240t-141-202q-45-44-109-98l-11-211q-1-9-9-15l-214-125q-4-2-9-2-7 0-13 5l-36 36q-7 7-4 17l47 155-156 156-154-47q-2-1-6-1-7 0-12 5l-36 36q-10 11-3 22l125 214q6 8 15 9l211 11q54 64 98 109 105 104 200 144t241 40q7 0 13-6t6-12z" horiz-adv-x="928.6" />
16
+ </font>
17
+ </defs>
18
  </svg>
assets/js/admin.js CHANGED
@@ -1,357 +1,357 @@
1
- (function ($) {
2
- "use strict";
3
- $(function () {
4
-
5
- // Stats config
6
- $("#wpp-stats-config-btn, #wpp_stats_options .button-secondary").on("click", function(e){
7
- e.preventDefault();
8
-
9
- // Hide custom range modal box
10
- if ( $("#wpp-stats-range").is(":visible") ) {
11
- $("#wpp-stats-range").hide();
12
- }
13
-
14
- if ( $("#wpp-stats-config").is(":visible") ) {
15
- $("#wpp-stats-config").hide();
16
- }
17
- else{
18
- $("#wpp-stats-config").show();
19
- }
20
- });
21
-
22
- // Stats range
23
- $("#wpp-stats-range form").on('submit', function(e){
24
- e.preventDefault();
25
-
26
- if ( $("#wpp-stats-range").is(":visible") ) {
27
- $("#wpp-stats-range").hide();
28
- }
29
-
30
- get_chart_data( $("#wpp-time-ranges li a[data-range='custom']") );
31
-
32
- $(".wpp-lightbox-tabs li:eq(0) a").trigger("click");
33
- });
34
-
35
- $("#wpp-stats-range form .button-secondary").on('click', function(e){
36
- e.preventDefault();
37
-
38
- if ( $("#wpp-stats-range").is(":visible") ) {
39
- $("#wpp-stats-range").hide();
40
- }
41
-
42
- $("#stats_range_date").val('');
43
-
44
- $(".wpp-lightbox-tabs li:eq(0) a").trigger("click");
45
- });
46
-
47
- function get_chart_data(me) {
48
- var args = {
49
- action: 'wpp_update_chart',
50
- nonce: wpp_admin_params.nonce,
51
- range: me.data("range"),
52
- time_quantity: $("#stats_range_time_quantity").val(),
53
- time_unit: $("#stats_range_time_unit").val()
54
- };
55
-
56
- if ( '' != $("#stats_range_date").val() ){
57
- args.dates = $("#stats_range_date").val();
58
- }
59
-
60
- $.get(
61
- ajaxurl,
62
- args,
63
- function( response ){
64
- if ( 'ok' == response.status ) {
65
- me.parent().addClass("current").siblings().removeClass("current");
66
-
67
- // Update titles
68
- $("#wpp-chart-wrapper h4").html( response.data.totals.label_summary );
69
- $("#wpp-chart-wrapper h5").html( response.data.totals.label_date_range );
70
-
71
- // Update chart
72
- WPPChart.populate(response.data);
73
-
74
- $("#wpp-listing .wpp-tabbed-nav li:eq(0) a").trigger("click");
75
-
76
- // Update lists
77
- args = {
78
- action: 'wpp_get_most_viewed',
79
- nonce: wpp_admin_params.nonce,
80
- items: 'most-viewed'
81
- };
82
-
83
- if ( '' != $("#stats_range_date").val() ){
84
- args.dates = $("#stats_range_date").val();
85
- }
86
-
87
- $("#wpp-listing .wpp-tab-content:eq(0)").html('<span class="spinner"></span>');
88
-
89
- $.get(
90
- ajaxurl,
91
- args,
92
- function( response ){
93
- $("#wpp-listing .wpp-tab-content:eq(0)").html(response);
94
- }
95
- );
96
-
97
- args = {
98
- action: 'wpp_get_most_commented',
99
- nonce: wpp_admin_params.nonce,
100
- items: 'most-commented'
101
- };
102
-
103
- if ( '' != $("#stats_range_date").val() ){
104
- args.dates = $("#stats_range_date").val();
105
- }
106
-
107
- $("#wpp-listing .wpp-tab-content:eq(1)").html('<span class="spinner"></span>');
108
-
109
- $.get(
110
- ajaxurl,
111
- args,
112
- function( response ){
113
- $("#wpp-listing .wpp-tab-content:eq(1)").html(response);
114
- }
115
- );
116
-
117
- args = {
118
- action: 'wpp_get_trending',
119
- nonce: wpp_admin_params.nonce,
120
- items: 'trending'
121
- };
122
-
123
- if ( '' != $("#stats_range_date").val() ){
124
- args.dates = $("#stats_range_date").val();
125
- }
126
-
127
- $("#wpp-listing .wpp-tab-content:eq(2)").html('<span class="spinner"></span>');
128
-
129
- $.get(
130
- ajaxurl,
131
- args,
132
- function( response ){
133
- $("#wpp-listing .wpp-tab-content:eq(2)").html(response);
134
- }
135
- );
136
-
137
- // Unset date range
138
- $("#stats_range_date").val('');
139
- }
140
- }
141
- );
142
-
143
- }
144
-
145
- $("#wpp-time-ranges li a").on("click", function(e){
146
- e.preventDefault();
147
-
148
- var me = $(this);
149
-
150
- // Update chart
151
- if ( WPPChart.canRender() ) {
152
- if ( 'custom' != me.data("range") ) {
153
- get_chart_data(me);
154
- }
155
- else {
156
- // Hide Config modal box
157
- if ( $("#wpp-stats-config").is(":visible") ) {
158
- $("#wpp-stats-config").hide();
159
- }
160
-
161
- if ( !$("#wpp-stats-range").is(":visible") ) {
162
- $("#wpp-stats-range").show();
163
- }
164
- }
165
- }
166
- });
167
-
168
- $("#wpp-time-ranges li.current a").trigger("click");
169
-
170
- $(".wpp-lightbox-tabs li a").on("click", function(e){
171
- e.preventDefault();
172
-
173
- var me = $(this);
174
- me.parent().addClass("active").siblings().removeClass("active");
175
-
176
- me.closest(".wpp-lightbox").find(".wpp-lightbox-tab-content").removeClass("wpp-lightbox-tab-content-active").filter(function( index ) {
177
- return me.parent().index() == index;
178
- }).addClass("wpp-lightbox-tab-content-active");
179
- });
180
-
181
- // Datepicker
182
- $.datepicker._defaults.onAfterUpdate = null;
183
- var datepicker__updateDatepicker = $.datepicker._updateDatepicker;
184
-
185
- $.datepicker._updateDatepicker = function( instance ){
186
- datepicker__updateDatepicker.call( this, instance );
187
-
188
- var onAfterUpdate = this._get( instance, 'onAfterUpdate' );
189
-
190
- if ( onAfterUpdate ) {
191
- onAfterUpdate.apply( ( instance.input ? instance.input[0] : null ), [( instance.input ? instance.input.val() : '' ), instance] );
192
- }
193
- };
194
-
195
- var curr = -1,
196
- prev = -1;
197
-
198
- var dp_field = $("#stats_range_date");
199
-
200
- var wpp_datepicker = dp_field.datepicker({
201
- maxDate: 0,
202
- dateFormat: 'yy-mm-dd',
203
- showButtonPanel: true,
204
- beforeShowDay: function(date){
205
- return [true, ( (date.getTime() >= Math.min(prev, curr) && date.getTime() <= Math.max(prev, curr) ) ? 'date-range-selected' : '' )]
206
- },
207
- onSelect: function(dateText, instance){
208
-
209
- var d1, d2;
210
-
211
- prev = curr;
212
-
213
- curr = ( new Date(instance.selectedYear, instance.selectedMonth, instance.selectedDay) ).getTime();
214
-
215
- if (
216
- -1 == prev
217
- || prev == curr
218
- ) {
219
- prev = curr;
220
- dp_field.val( dateText );
221
- }
222
- else {
223
-
224
- d1 = $.datepicker.formatDate('yy-mm-dd', new Date( Math.min(prev, curr) ), {});
225
- d2 = $.datepicker.formatDate('yy-mm-dd', new Date( Math.max(prev, curr) ), {});
226
-
227
- dp_field.val( d1 + ' ~ ' + d2 );
228
-
229
- }
230
-
231
- $(this).data('datepicker').inline = true;
232
-
233
- },
234
- onClose: function(){
235
- $(this).data('datepicker').inline = false;
236
- },
237
- onAfterUpdate: function( instance ){
238
- var calendar = $(this);
239
-
240
- if (
241
- prev > -1
242
- && curr > -1
243
- ){
244
-
245
- $('<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">OK</button>').appendTo( $(".ui-datepicker-buttonpane") ).on('click', function(){
246
- dp_field.datepicker('hide');
247
- });
248
- }
249
- }
250
- });
251
-
252
- // STATISTICS TABS
253
- $("#wpp-listing .wpp-tabbed-nav li a").on("click", function(e){
254
- e.preventDefault();
255
-
256
- var me = $(this),
257
- target = me.parent().index();
258
-
259
- me.parent().addClass("active").siblings().removeClass("active");
260
-
261
- me.closest("#wpp-listing").children(".wpp-tab-content:eq(" + target + ")").addClass("wpp-tab-content-active").siblings().removeClass("wpp-tab-content-active");
262
-
263
- });
264
-
265
- // TOOLS
266
- // thumb source selection
267
- $("#thumb_source").change(function() {
268
- if ($(this).val() == "custom_field") {
269
- $("#lbl_field, #thumb_field, #row_custom_field, #row_custom_field_resize").show();
270
- } else {
271
- $("#lbl_field, #thumb_field, #row_custom_field, #row_custom_field_resize").hide();
272
- }
273
- });
274
- // file upload
275
- $('#upload_thumb_button').click(function(e) {
276
- e.preventDefault();
277
-
278
- var custom_uploader = wp.media({
279
- title: 'WordPress Popular Posts',
280
- library: { type : 'image' },
281
- button: { text: wpp_admin_params.label_media_upload_button },
282
- id: 'library-' + (Math.random() * 10),
283
- multiple: false
284
- }).on('select', function() {
285
- var attachment = custom_uploader.state().get('selection').first().toJSON();
286
- $('#upload_thumb_src').val( attachment.url );
287
-
288
- var img = new Image();
289
- img.onload = function() {
290
- $("#thumb-review").html( this ).parent().fadeIn();
291
- }
292
- img.src = attachment.url;
293
-
294
- })
295
- .open();
296
-
297
- });
298
- // log limit
299
- $("#log_limit").change(function(){
300
- var me = $(this);
301
-
302
- if (me.val() == 1) {
303
- me.parent().children("label, .description").show();
304
- me.parent().children("br").hide();
305
- } else {
306
- me.parent().children("label, .description").hide();
307
- me.parent().children("br").show();
308
- }
309
- });
310
- // cache interval
311
- $("#cache").change(function() {
312
- if ($(this).val() == 1) {
313
- $("#cache_refresh_interval").show();
314
- } else {
315
- $("#cache_refresh_interval, #cache_too_long").hide();
316
- }
317
- });
318
- // interval
319
- $("#cache_interval_time").change(function() {
320
- var value = parseInt( $("#cache_interval_value").val() );
321
- var time = $(this).val();
322
-
323
- if ( time == "hour" && value > 72 ) {
324
- $("#cache_too_long").show();
325
- } else if ( time == "day" && value > 3 ) {
326
- $("#cache_too_long").show();
327
- } else if ( time == "week" && value > 1 ) {
328
- $("#cache_too_long").show();
329
- } else if ( time == "month" && value >= 1 ) {
330
- $("#cache_too_long").show();
331
- } else if ( time == "year" && value >= 1 ) {
332
- $("#cache_too_long").show();
333
- } else {
334
- $("#cache_too_long").hide();
335
- }
336
- });
337
-
338
- $("#cache_interval_value").change(function() {
339
- var value = parseInt( $(this).val() );
340
- var time = $("#cache_interval_time").val();
341
-
342
- if ( time == "hour" && value > 72 ) {
343
- $("#cache_too_long").show();
344
- } else if ( time == "day" && value > 3 ) {
345
- $("#cache_too_long").show();
346
- } else if ( time == "week" && value > 1 ) {
347
- $("#cache_too_long").show();
348
- } else if ( time == "month" && value >= 1 ) {
349
- $("#cache_too_long").show();
350
- } else if ( time == "year" && value >= 1 ) {
351
- $("#cache_too_long").show();
352
- } else {
353
- $("#cache_too_long").hide();
354
- }
355
- });
356
- });
357
  }(jQuery));
1
+ (function ($) {
2
+ "use strict";
3
+ $(function () {
4
+
5
+ // Stats config
6
+ $("#wpp-stats-config-btn, #wpp_stats_options .button-secondary").on("click", function(e){
7
+ e.preventDefault();
8
+
9
+ // Hide custom range modal box
10
+ if ( $("#wpp-stats-range").is(":visible") ) {
11
+ $("#wpp-stats-range").hide();
12
+ }
13
+
14
+ if ( $("#wpp-stats-config").is(":visible") ) {
15
+ $("#wpp-stats-config").hide();
16
+ }
17
+ else{
18
+ $("#wpp-stats-config").show();
19
+ }
20
+ });
21
+
22
+ // Stats range
23
+ $("#wpp-stats-range form").on('submit', function(e){
24
+ e.preventDefault();
25
+
26
+ if ( $("#wpp-stats-range").is(":visible") ) {
27
+ $("#wpp-stats-range").hide();
28
+ }
29
+
30
+ get_chart_data( $("#wpp-time-ranges li a[data-range='custom']") );
31
+
32
+ $(".wpp-lightbox-tabs li:eq(0) a").trigger("click");
33
+ });
34
+
35
+ $("#wpp-stats-range form .button-secondary").on('click', function(e){
36
+ e.preventDefault();
37
+
38
+ if ( $("#wpp-stats-range").is(":visible") ) {
39
+ $("#wpp-stats-range").hide();
40
+ }
41
+
42
+ $("#stats_range_date").val('');
43
+
44
+ $(".wpp-lightbox-tabs li:eq(0) a").trigger("click");
45
+ });
46
+
47
+ function get_chart_data(me) {
48
+ var args = {
49
+ action: 'wpp_update_chart',
50
+ nonce: wpp_admin_params.nonce,
51
+ range: me.data("range"),
52
+ time_quantity: $("#stats_range_time_quantity").val(),
53
+ time_unit: $("#stats_range_time_unit").val()
54
+ };
55
+
56
+ if ( '' != $("#stats_range_date").val() ){
57
+ args.dates = $("#stats_range_date").val();
58
+ }
59
+
60
+ $.get(
61
+ ajaxurl,
62
+ args,
63
+ function( response ){
64
+ if ( 'ok' == response.status ) {
65
+ me.parent().addClass("current").siblings().removeClass("current");
66
+
67
+ // Update titles
68
+ $("#wpp-chart-wrapper h4").html( response.data.totals.label_summary );
69
+ $("#wpp-chart-wrapper h5").html( response.data.totals.label_date_range );
70
+
71
+ // Update chart
72
+ WPPChart.populate(response.data);
73
+
74
+ $("#wpp-listing .wpp-tabbed-nav li:eq(0) a").trigger("click");
75
+
76
+ // Update lists
77
+ args = {
78
+ action: 'wpp_get_most_viewed',
79
+ nonce: wpp_admin_params.nonce,
80
+ items: 'most-viewed'
81
+ };
82
+
83
+ if ( '' != $("#stats_range_date").val() ){
84
+ args.dates = $("#stats_range_date").val();
85
+ }
86
+
87
+ $("#wpp-listing .wpp-tab-content:eq(0)").html('<span class="spinner"></span>');
88
+
89
+ $.get(
90
+ ajaxurl,
91
+ args,
92
+ function( response ){
93
+ $("#wpp-listing .wpp-tab-content:eq(0)").html(response);
94
+ }
95
+ );
96
+
97
+ args = {
98
+ action: 'wpp_get_most_commented',
99
+ nonce: wpp_admin_params.nonce,
100
+ items: 'most-commented'
101
+ };
102
+
103
+ if ( '' != $("#stats_range_date").val() ){
104
+ args.dates = $("#stats_range_date").val();
105
+ }
106
+
107
+ $("#wpp-listing .wpp-tab-content:eq(1)").html('<span class="spinner"></span>');
108
+
109
+ $.get(
110
+ ajaxurl,
111
+ args,
112
+ function( response ){
113
+ $("#wpp-listing .wpp-tab-content:eq(1)").html(response);
114
+ }
115
+ );
116
+
117
+ args = {
118
+ action: 'wpp_get_trending',
119
+ nonce: wpp_admin_params.nonce,
120
+ items: 'trending'
121
+ };
122
+
123
+ if ( '' != $("#stats_range_date").val() ){
124
+ args.dates = $("#stats_range_date").val();
125
+ }
126
+
127
+ $("#wpp-listing .wpp-tab-content:eq(2)").html('<span class="spinner"></span>');
128
+
129
+ $.get(
130
+ ajaxurl,
131
+ args,
132
+ function( response ){
133
+ $("#wpp-listing .wpp-tab-content:eq(2)").html(response);
134
+ }
135
+ );
136
+
137
+ // Unset date range
138
+ $("#stats_range_date").val('');
139
+ }
140
+ }
141
+ );
142
+
143
+ }
144
+
145
+ $("#wpp-time-ranges li a").on("click", function(e){
146
+ e.preventDefault();
147
+
148
+ var me = $(this);
149
+
150
+ // Update chart
151
+ if ( WPPChart.canRender() ) {
152
+ if ( 'custom' != me.data("range") ) {
153
+ get_chart_data(me);
154
+ }
155
+ else {
156
+ // Hide Config modal box
157
+ if ( $("#wpp-stats-config").is(":visible") ) {
158
+ $("#wpp-stats-config").hide();
159
+ }
160
+
161
+ if ( !$("#wpp-stats-range").is(":visible") ) {
162
+ $("#wpp-stats-range").show();
163
+ }
164
+ }
165
+ }
166
+ });
167
+
168
+ $("#wpp-time-ranges li.current a").trigger("click");
169
+
170
+ $(".wpp-lightbox-tabs li a").on("click", function(e){
171
+ e.preventDefault();
172
+
173
+ var me = $(this);
174
+ me.parent().addClass("active").siblings().removeClass("active");
175
+
176
+ me.closest(".wpp-lightbox").find(".wpp-lightbox-tab-content").removeClass("wpp-lightbox-tab-content-active").filter(function( index ) {
177
+ return me.parent().index() == index;
178
+ }).addClass("wpp-lightbox-tab-content-active");
179
+ });
180
+
181
+ // Datepicker
182
+ $.datepicker._defaults.onAfterUpdate = null;
183
+ var datepicker__updateDatepicker = $.datepicker._updateDatepicker;
184
+
185
+ $.datepicker._updateDatepicker = function( instance ){
186
+ datepicker__updateDatepicker.call( this, instance );
187
+
188
+ var onAfterUpdate = this._get( instance, 'onAfterUpdate' );
189
+
190
+ if ( onAfterUpdate ) {
191
+ onAfterUpdate.apply( ( instance.input ? instance.input[0] : null ), [( instance.input ? instance.input.val() : '' ), instance] );
192
+ }
193
+ };
194
+
195
+ var curr = -1,
196
+ prev = -1;
197
+
198
+ var dp_field = $("#stats_range_date");
199
+
200
+ var wpp_datepicker = dp_field.datepicker({
201
+ maxDate: 0,
202
+ dateFormat: 'yy-mm-dd',
203
+ showButtonPanel: true,
204
+ beforeShowDay: function(date){
205
+ return [true, ( (date.getTime() >= Math.min(prev, curr) && date.getTime() <= Math.max(prev, curr) ) ? 'date-range-selected' : '' )]
206
+ },
207
+ onSelect: function(dateText, instance){
208
+
209
+ var d1, d2;
210
+
211
+ prev = curr;
212
+
213
+ curr = ( new Date(instance.selectedYear, instance.selectedMonth, instance.selectedDay) ).getTime();
214
+
215
+ if (
216
+ -1 == prev
217
+ || prev == curr
218
+ ) {
219
+ prev = curr;
220
+ dp_field.val( dateText );
221
+ }
222
+ else {
223
+
224
+ d1 = $.datepicker.formatDate('yy-mm-dd', new Date( Math.min(prev, curr) ), {});
225
+ d2 = $.datepicker.formatDate('yy-mm-dd', new Date( Math.max(prev, curr) ), {});
226
+
227
+ dp_field.val( d1 + ' ~ ' + d2 );
228
+
229
+ }
230
+
231
+ $(this).data('datepicker').inline = true;
232
+
233
+ },
234
+ onClose: function(){
235
+ $(this).data('datepicker').inline = false;
236
+ },
237
+ onAfterUpdate: function( instance ){
238
+ var calendar = $(this);
239
+
240
+ if (
241
+ prev > -1
242
+ && curr > -1
243
+ ){
244
+
245
+ $('<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" data-handler="hide" data-event="click">OK</button>').appendTo( $(".ui-datepicker-buttonpane") ).on('click', function(){
246
+ dp_field.datepicker('hide');
247
+ });
248
+ }
249
+ }
250
+ });
251
+
252
+ // STATISTICS TABS
253
+ $("#wpp-listing .wpp-tabbed-nav li a").on("click", function(e){
254
+ e.preventDefault();
255
+
256
+ var me = $(this),
257
+ target = me.parent().index();
258
+
259
+ me.parent().addClass("active").siblings().removeClass("active");
260
+
261
+ me.closest("#wpp-listing").children(".wpp-tab-content:eq(" + target + ")").addClass("wpp-tab-content-active").siblings().removeClass("wpp-tab-content-active");
262
+
263
+ });
264
+
265
+ // TOOLS
266
+ // thumb source selection
267
+ $("#thumb_source").change(function() {
268
+ if ($(this).val() == "custom_field") {
269
+ $("#lbl_field, #thumb_field, #row_custom_field, #row_custom_field_resize").show();
270
+ } else {
271
+ $("#lbl_field, #thumb_field, #row_custom_field, #row_custom_field_resize").hide();
272
+ }
273
+ });
274
+ // file upload
275
+ $('#upload_thumb_button').click(function(e) {
276
+ e.preventDefault();
277
+
278
+ var custom_uploader = wp.media({
279
+ title: 'WordPress Popular Posts',
280
+ library: { type : 'image' },
281
+ button: { text: wpp_admin_params.label_media_upload_button },
282
+ id: 'library-' + (Math.random() * 10),
283
+ multiple: false
284
+ }).on('select', function() {
285
+ var attachment = custom_uploader.state().get('selection').first().toJSON();
286
+ $('#upload_thumb_src').val( attachment.url );
287
+
288
+ var img = new Image();
289
+ img.onload = function() {
290
+ $("#thumb-review").html( this ).parent().fadeIn();
291
+ }
292
+ img.src = attachment.url;
293
+
294
+ })
295
+ .open();
296
+
297
+ });
298
+ // log limit
299
+ $("#log_limit").change(function(){
300
+ var me = $(this);
301
+
302
+ if (me.val() == 1) {
303
+ me.parent().children("label, .description").show();
304
+ me.parent().children("br").hide();
305
+ } else {
306
+ me.parent().children("label, .description").hide();
307
+ me.parent().children("br").show();
308
+ }
309
+ });
310
+ // cache interval
311
+ $("#cache").change(function() {
312
+ if ($(this).val() == 1) {
313
+ $("#cache_refresh_interval").show();
314
+ } else {
315
+ $("#cache_refresh_interval, #cache_too_long").hide();
316
+ }
317
+ });
318
+ // interval
319
+ $("#cache_interval_time").change(function() {
320
+ var value = parseInt( $("#cache_interval_value").val() );
321
+ var time = $(this).val();
322
+
323
+ if ( time == "hour" && value > 72 ) {
324
+ $("#cache_too_long").show();
325
+ } else if ( time == "day" && value > 3 ) {
326
+ $("#cache_too_long").show();
327
+ } else if ( time == "week" && value > 1 ) {
328
+ $("#cache_too_long").show();
329
+ } else if ( time == "month" && value >= 1 ) {
330
+ $("#cache_too_long").show();
331
+ } else if ( time == "year" && value >= 1 ) {
332
+ $("#cache_too_long").show();
333
+ } else {
334
+ $("#cache_too_long").hide();
335
+ }
336
+ });
337
+
338
+ $("#cache_interval_value").change(function() {
339
+ var value = parseInt( $(this).val() );
340
+ var time = $("#cache_interval_time").val();
341
+
342
+ if ( time == "hour" && value > 72 ) {
343
+ $("#cache_too_long").show();
344
+ } else if ( time == "day" && value > 3 ) {
345
+ $("#cache_too_long").show();
346
+ } else if ( time == "week" && value > 1 ) {
347
+ $("#cache_too_long").show();
348
+ } else if ( time == "month" && value >= 1 ) {
349
+ $("#cache_too_long").show();
350
+ } else if ( time == "year" && value >= 1 ) {
351
+ $("#cache_too_long").show();
352
+ } else {
353
+ $("#cache_too_long").hide();
354
+ }
355
+ });
356
+ });
357
  }(jQuery));
assets/js/chart.js CHANGED
@@ -1,191 +1,191 @@
1
- var WPPChart = (function() {
2
- "use strict";
3
-
4
- /**
5
- * Private functions and variables
6
- */
7
-
8
- var defaults = {
9
- type: 'line',
10
- data: {
11
- labels: [],
12
- datasets: [
13
- {
14
- label: "",
15
- fill: true,
16
- lineTension: 0.2,
17
- borderWidth: 3,
18
- backgroundColor: "rgba(221, 66, 66, 0.8)",
19
- borderColor: "#881111",
20
- borderCapStyle: 'butt',
21
- borderDash: [],
22
- borderDashOffset: 0.0,
23
- borderJoinStyle: 'miter',
24
- pointBorderColor: "#881111",
25
- pointBackgroundColor: "#fff",
26
- pointBorderWidth: 2,
27
- pointHoverRadius: 4,
28
- pointHoverBackgroundColor: "#881111",
29
- pointHoverBorderColor: "#881111",
30
- pointHoverBorderWidth: 3,
31
- pointRadius: 3,
32
- pointHitRadius: 10,
33
- data: [],
34
- },
35
- {
36
- label: "",
37
- fill: true,
38
- lineTension: 0.2,
39
- borderWidth: 3,
40
- backgroundColor: "rgba(136, 17, 17, 0.3)",
41
- borderColor: "#a80000",
42
- borderCapStyle: 'butt',
43
- borderDash: [],
44
- borderDashOffset: 0.0,
45
- borderJoinStyle: 'miter',
46
- pointBorderColor: "#a80000",
47
- pointBackgroundColor: "#fff",
48
- pointBorderWidth: 2,
49
- pointHoverRadius: 4,
50
- pointHoverBackgroundColor: "#a80000",
51
- pointHoverBorderColor: "#a80000",
52
- pointHoverBorderWidth: 3,
53
- pointRadius: 3,
54
- pointHitRadius: 10,
55
- data: [],
56
- }
57
- ]
58
- },
59
- options: {
60
- legend: {
61
- display: true,
62
- labels: {
63
- fontColor: '#23282d',
64
- fontFamily: '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif',
65
- fontSize: 12
66
- }
67
- },
68
- responsive: true,
69
- maintainAspectRatio: false,
70
- layout: {
71
- padding: {
72
- top: 2,
73
- right: 5,
74
- bottom: 0,
75
- left: 5
76
- }
77
- },
78
- scales: {
79
- xAxes: [{
80
- display: true,
81
- gridLines: {
82
- display: false,
83
- },
84
- ticks: {
85
- fontSize: 10,
86
- fontColor: '#23282d',
87
- autoSkip: false,
88
- maxRotation: 90,
89
- minRotation: 90
90
- }
91
- }],
92
- yAxes: [{
93
- display: false
94
- }]
95
- }
96
- }
97
- },
98
- chart = null,
99
- canRender = !! window.CanvasRenderingContext2D,
100
- element = null,
101
- cvs = null;
102
-
103
- var canRender = function(){
104
- return canRender;
105
- };
106
-
107
- // Source: http://stackoverflow.com/a/5624139
108
- var HexToRGB = function( hex ){
109
- var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
110
-
111
- hex = hex.replace(shorthandRegex, function( m, r, g, b ) {
112
- return r + r + g + g + b + b;
113
- });
114
-
115
- var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
116
-
117
- return result ? {
118
- r: parseInt( result[1], 16 ),
119
- g: parseInt( result[2], 16 ),
120
- b: parseInt( result[3], 16 )
121
- } : null;
122
- };
123
-
124
- /**
125
- * Public functions
126
- */
127
-
128
- var init = function(container, options){
129
- if ( ! canRender() ) {
130
- throw new Error('Your browser is too old, WPPChart cannot create its data chart.');
131
- }
132
-
133
- if ( 'undefined' == typeof container ) {
134
- throw new Error('Please tell WPPChart where to inject the chart.');
135
- }
136
-
137
- element = document.getElementById(container);
138
-
139
- if ( ! element ) {
140
- throw new Error('WPPChart cannot find ' + container);
141
- }
142
-
143
- if ( 'undefined' == typeof Chart ) {
144
- throw new Error('ChartJS library not found');
145
- }
146
-
147
- cvs = document.createElement('canvas');
148
- element.appendChild(cvs);
149
- };
150
-
151
- var populate = function(data){
152
- if ( chart ) {
153
- chart.destroy();
154
- }
155
-
156
- var config = defaults;
157
-
158
- config.data.labels = data.labels;
159
- config.data.datasets[0].label = data.datasets[0].label;
160
- config.data.datasets[0].data = data.datasets[0].data;
161
- config.data.datasets[1].label = data.datasets[1].label;
162
- config.data.datasets[1].data = data.datasets[1].data;
163
-
164
-
165
- var rgb_comments = HexToRGB(wpp_chart_params.colors[2]);
166
- config.data.datasets[1].backgroundColor = "rgba(" + rgb_comments.r + ", " + rgb_comments.g + ", " + rgb_comments.b + ", 0.9)";
167
- config.data.datasets[1].borderColor = wpp_chart_params.colors[2];
168
- config.data.datasets[1].pointBorderColor = wpp_chart_params.colors[2];
169
- config.data.datasets[1].pointHoverBackgroundColor = wpp_chart_params.colors[2];
170
- config.data.datasets[1].pointHoverBorderColor = wpp_chart_params.colors[2];
171
-
172
- var rgb_views = HexToRGB(wpp_chart_params.colors[3]);
173
- config.data.datasets[0].backgroundColor = "rgba(" + rgb_views.r + ", " + rgb_views.g + ", " + rgb_views.b + ", 0.7)";
174
- config.data.datasets[0].borderColor = wpp_chart_params.colors[3];
175
- config.data.datasets[0].pointBorderColor = wpp_chart_params.colors[3];
176
- config.data.datasets[0].pointHoverBackgroundColor = wpp_chart_params.colors[3];
177
- config.data.datasets[0].pointHoverBorderColor = wpp_chart_params.colors[3];
178
-
179
- chart = new Chart(cvs, config);
180
- };
181
-
182
- /**
183
- * Provide access to public methods
184
- */
185
-
186
- return {
187
- init: init,
188
- populate: populate,
189
- canRender: canRender
190
- };
191
- })();
1
+ var WPPChart = (function() {
2
+ "use strict";
3
+
4
+ /**
5
+ * Private functions and variables
6
+ */
7
+
8
+ var defaults = {
9
+ type: 'line',
10
+ data: {
11
+ labels: [],
12
+ datasets: [
13
+ {
14
+ label: "",
15
+ fill: true,
16
+ lineTension: 0.2,
17
+ borderWidth: 3,
18
+ backgroundColor: "rgba(221, 66, 66, 0.8)",
19
+ borderColor: "#881111",
20
+ borderCapStyle: 'butt',
21
+ borderDash: [],
22
+ borderDashOffset: 0.0,
23
+ borderJoinStyle: 'miter',
24
+ pointBorderColor: "#881111",
25
+ pointBackgroundColor: "#fff",
26
+ pointBorderWidth: 2,
27
+ pointHoverRadius: 4,
28
+ pointHoverBackgroundColor: "#881111",
29
+ pointHoverBorderColor: "#881111",
30
+ pointHoverBorderWidth: 3,
31
+ pointRadius: 3,
32
+ pointHitRadius: 10,
33
+ data: [],
34
+ },
35
+ {
36
+ label: "",
37
+ fill: true,
38
+ lineTension: 0.2,
39
+ borderWidth: 3,
40
+ backgroundColor: "rgba(136, 17, 17, 0.3)",
41
+ borderColor: "#a80000",
42
+ borderCapStyle: 'butt',
43
+ borderDash: [],
44
+ borderDashOffset: 0.0,
45
+ borderJoinStyle: 'miter',
46
+ pointBorderColor: "#a80000",
47
+ pointBackgroundColor: "#fff",
48
+ pointBorderWidth: 2,
49
+ pointHoverRadius: 4,
50
+ pointHoverBackgroundColor: "#a80000",
51
+ pointHoverBorderColor: "#a80000",
52
+ pointHoverBorderWidth: 3,
53
+ pointRadius: 3,
54
+ pointHitRadius: 10,
55
+ data: [],
56
+ }
57
+ ]
58
+ },
59
+ options: {
60
+ legend: {
61
+ display: true,
62
+ labels: {
63
+ fontColor: '#23282d',
64
+ fontFamily: '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif',
65
+ fontSize: 12
66
+ }
67
+ },
68
+ responsive: true,
69
+ maintainAspectRatio: false,
70
+ layout: {
71
+ padding: {
72
+ top: 2,
73
+ right: 5,
74
+ bottom: 0,
75
+ left: 5
76
+ }
77
+ },
78
+ scales: {
79
+ xAxes: [{
80
+ display: true,
81
+ gridLines: {
82
+ display: false,
83
+ },
84
+ ticks: {
85
+ fontSize: 10,
86
+ fontColor: '#23282d',
87
+ autoSkip: false,
88
+ maxRotation: 90,
89
+ minRotation: 90
90
+ }
91
+ }],
92
+ yAxes: [{
93
+ display: false
94
+ }]
95
+ }
96
+ }
97
+ },
98
+ chart = null,
99
+ canRender = !! window.CanvasRenderingContext2D,
100
+ element = null,
101
+ cvs = null;
102
+
103
+ var canRender = function(){
104
+ return canRender;
105
+ };
106
+
107
+ // Source: http://stackoverflow.com/a/5624139
108
+ var HexToRGB = function( hex ){
109
+ var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
110
+
111
+ hex = hex.replace(shorthandRegex, function( m, r, g, b ) {
112
+ return r + r + g + g + b + b;
113
+ });
114
+
115
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
116
+
117
+ return result ? {
118
+ r: parseInt( result[1], 16 ),
119
+ g: parseInt( result[2], 16 ),
120
+ b: parseInt( result[3], 16 )
121
+ } : null;
122
+ };
123
+
124
+ /**
125
+ * Public functions
126
+ */
127
+
128
+ var init = function(container, options){
129
+ if ( ! canRender() ) {
130
+ throw new Error('Your browser is too old, WPPChart cannot create its data chart.');
131
+ }
132
+
133
+ if ( 'undefined' == typeof container ) {
134
+ throw new Error('Please tell WPPChart where to inject the chart.');
135
+ }
136
+
137
+ element = document.getElementById(container);
138
+
139
+ if ( ! element ) {
140
+ throw new Error('WPPChart cannot find ' + container);
141
+ }
142
+
143
+ if ( 'undefined' == typeof Chart ) {
144
+ throw new Error('ChartJS library not found');
145
+ }
146
+
147
+ cvs = document.createElement('canvas');
148
+ element.appendChild(cvs);
149
+ };
150
+
151
+ var populate = function(data){
152
+ if ( chart ) {
153
+ chart.destroy();
154
+ }
155
+
156
+ var config = defaults;
157
+
158
+ config.data.labels = data.labels;
159
+ config.data.datasets[0].label = data.datasets[0].label;
160
+ config.data.datasets[0].data = data.datasets[0].data;
161
+ config.data.datasets[1].label = data.datasets[1].label;
162
+ config.data.datasets[1].data = data.datasets[1].data;
163
+
164
+
165
+ var rgb_comments = HexToRGB(wpp_chart_params.colors[2]);
166
+ config.data.datasets[1].backgroundColor = "rgba(" + rgb_comments.r + ", " + rgb_comments.g + ", " + rgb_comments.b + ", 0.9)";
167
+ config.data.datasets[1].borderColor = wpp_chart_params.colors[2];
168
+ config.data.datasets[1].pointBorderColor = wpp_chart_params.colors[2];
169
+ config.data.datasets[1].pointHoverBackgroundColor = wpp_chart_params.colors[2];
170
+ config.data.datasets[1].pointHoverBorderColor = wpp_chart_params.colors[2];
171
+
172
+ var rgb_views = HexToRGB(wpp_chart_params.colors[3]);
173
+ config.data.datasets[0].backgroundColor = "rgba(" + rgb_views.r + ", " + rgb_views.g + ", " + rgb_views.b + ", 0.7)";
174
+ config.data.datasets[0].borderColor = wpp_chart_params.colors[3];
175
+ config.data.datasets[0].pointBorderColor = wpp_chart_params.colors[3];
176
+ config.data.datasets[0].pointHoverBackgroundColor = wpp_chart_params.colors[3];
177
+ config.data.datasets[0].pointHoverBorderColor = wpp_chart_params.colors[3];
178
+
179
+ chart = new Chart(cvs, config);
180
+ };
181
+
182
+ /**
183
+ * Provide access to public methods
184
+ */
185
+
186
+ return {
187
+ init: init,
188
+ populate: populate,
189
+ canRender: canRender
190
+ };
191
+ })();
assets/js/vendor/Chart.min.js CHANGED
@@ -1,14 +1,7 @@
1
- /*!
2
- * Chart.js
3
- * http://chartjs.org/
4
- * Version: 2.5.0
5
- *
6
- * Copyright 2017 Nick Downie
7
- * Released under the MIT license
8
- * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md
9
- */
10
- !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){return function t(e,a,i){function n(r,s){if(!a[r]){if(!e[r]){var l="function"==typeof require&&require;if(!s&&l)return l(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=a[r]={exports:{}};e[r][0].call(d.exports,function(t){var a=e[r][1][t];return n(a?a:t)},d,d.exports,t,e,a,i)}return a[r].exports}for(var o="function"==typeof require&&require,r=0;r<i.length;r++)n(i[r]);return n}({1:[function(t,e,a){},{}],2:[function(t,e,a){function i(t){if(t){var e=/^#([a-fA-F0-9]{3})$/,a=/^#([a-fA-F0-9]{6})$/,i=/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,n=/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/,o=/(\w+)/,r=[0,0,0],s=1,l=t.match(e);if(l){l=l[1];for(var u=0;u<r.length;u++)r[u]=parseInt(l[u]+l[u],16)}else if(l=t.match(a)){l=l[1];for(var u=0;u<r.length;u++)r[u]=parseInt(l.slice(2*u,2*u+2),16)}else if(l=t.match(i)){for(var u=0;u<r.length;u++)r[u]=parseInt(l[u+1]);s=parseFloat(l[4])}else if(l=t.match(n)){for(var u=0;u<r.length;u++)r[u]=Math.round(2.55*parseFloat(l[u+1]));s=parseFloat(l[4])}else if(l=t.match(o)){if("transparent"==l[1])return[0,0,0,0];if(r=y[l[1]],!r)return}for(var u=0;u<r.length;u++)r[u]=b(r[u],0,255);return s=s||0==s?b(s,0,1):1,r[3]=s,r}}function n(t){if(t){var e=/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,a=t.match(e);if(a){var i=parseFloat(a[4]),n=b(parseInt(a[1]),0,360),o=b(parseFloat(a[2]),0,100),r=b(parseFloat(a[3]),0,100),s=b(isNaN(i)?1:i,0,1);return[n,o,r,s]}}}function o(t){if(t){var e=/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/,a=t.match(e);if(a){var i=parseFloat(a[4]),n=b(parseInt(a[1]),0,360),o=b(parseFloat(a[2]),0,100),r=b(parseFloat(a[3]),0,100),s=b(isNaN(i)?1:i,0,1);return[n,o,r,s]}}}function r(t){var e=i(t);return e&&e.slice(0,3)}function s(t){var e=n(t);return e&&e.slice(0,3)}function l(t){var e=i(t);return e?e[3]:(e=n(t))?e[3]:(e=o(t))?e[3]:void 0}function u(t){return"#"+x(t[0])+x(t[1])+x(t[2])}function d(t,e){return e<1||t[3]&&t[3]<1?c(t,e):"rgb("+t[0]+", "+t[1]+", "+t[2]+")"}function c(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function h(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);var a=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),n=Math.round(t[2]/255*100);return"rgb("+a+"%, "+i+"%, "+n+"%)"}function f(t,e){var a=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),n=Math.round(t[2]/255*100);return"rgba("+a+"%, "+i+"%, "+n+"%, "+(e||t[3]||1)+")"}function g(t,e){return e<1||t[3]&&t[3]<1?p(t,e):"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"}function v(t){return k[t.slice(0,3)]}function b(t,e,a){return Math.min(Math.max(e,t),a)}function x(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var y=t(6);e.exports={getRgba:i,getHsla:n,getRgb:r,getHsl:s,getHwb:o,getAlpha:l,hexString:u,rgbString:d,rgbaString:c,percentString:h,percentaString:f,hslString:g,hslaString:p,hwbString:m,keyword:v};var k={};for(var S in y)k[y[S]]=S},{6:6}],3:[function(t,e,a){var i=t(5),n=t(2),o=function(t){if(t instanceof o)return t;if(!(this instanceof o))return new o(t);this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1};var e;if("string"==typeof t)if(e=n.getRgba(t))this.setValues("rgb",e);else if(e=n.getHsla(t))this.setValues("hsl",e);else{if(!(e=n.getHwb(t)))throw new Error('Unable to parse color from string "'+t+'"');this.setValues("hwb",e)}else if("object"==typeof t)if(e=t,void 0!==e.r||void 0!==e.red)this.setValues("rgb",e);else if(void 0!==e.l||void 0!==e.lightness)this.setValues("hsl",e);else if(void 0!==e.v||void 0!==e.value)this.setValues("hsv",e);else if(void 0!==e.w||void 0!==e.whiteness)this.setValues("hwb",e);else{if(void 0===e.c&&void 0===e.cyan)throw new Error("Unable to parse color from object "+JSON.stringify(t));this.setValues("cmyk",e)}};o.prototype={rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t%=360,t=t<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return n.hexString(this.values.rgb)},rgbString:function(){return n.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return n.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return n.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return n.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return n.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return n.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return n.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],a=0;a<t.length;a++){var i=t[a]/255;e[a]=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),a=t.luminosity();return e>a?(e+.05)/(a+.05):(a+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return e<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,a=(e[0]+t)%360;return e[0]=a<0?360+a:a,this.setValues("hsl",e),this},mix:function(t,e){var a=this,i=t,n=void 0===e?.5:e,o=2*n-1,r=a.alpha()-i.alpha(),s=((o*r===-1?o:(o+r)/(1+o*r))+1)/2,l=1-s;return this.rgb(s*a.red()+l*i.red(),s*a.green()+l*i.green(),s*a.blue()+l*i.blue()).alpha(a.alpha()*n+i.alpha()*(1-n))},toJSON:function(){return this.rgb()},clone:function(){var t,e,a=new o,i=this.values,n=a.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],e={}.toString.call(t),"[object Array]"===e?n[r]=t.slice(0):"[object Number]"===e?n[r]=t:console.error("unexpected color value:",t));return a}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,a={},i=0;i<t.length;i++)a[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(a.a=e.alpha),a},o.prototype.setValues=function(t,e){var a,n=this.values,o=this.spaces,r=this.maxes,s=1;if("alpha"===t)s=e;else if(e.length)n[t]=e.slice(0,t.length),s=e[t.length];else if(void 0!==e[t.charAt(0)]){for(a=0;a<t.length;a++)n[t][a]=e[t.charAt(a)];s=e.a}else if(void 0!==e[o[t][0]]){var l=o[t];for(a=0;a<t.length;a++)n[t][a]=e[l[a]];s=e.alpha}if(n.alpha=Math.max(0,Math.min(1,void 0===s?n.alpha:s)),"alpha"===t)return!1;var u;for(a=0;a<t.length;a++)u=Math.max(0,Math.min(r[t][a],n[t][a])),n[t][a]=Math.round(u);for(var d in o)d!==t&&(n[d]=i[t][d](n[t]));return!0},o.prototype.setSpace=function(t,e){var a=e[0];return void 0===a?this.getValues(t):("number"==typeof a&&(a=Array.prototype.slice.call(e)),this.setValues(t,a),this)},o.prototype.setChannel=function(t,e,a){var i=this.values[t];return void 0===a?i[e]:a===i[e]?this:(i[e]=a,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=o),e.exports=o},{2:2,5:5}],4:[function(t,e,a){function i(t){var e,a,i,n=t[0]/255,o=t[1]/255,r=t[2]/255,s=Math.min(n,o,r),l=Math.max(n,o,r),u=l-s;return l==s?e=0:n==l?e=(o-r)/u:o==l?e=2+(r-n)/u:r==l&&(e=4+(n-o)/u),e=Math.min(60*e,360),e<0&&(e+=360),i=(s+l)/2,a=l==s?0:i<=.5?u/(l+s):u/(2-l-s),[e,100*a,100*i]}function n(t){var e,a,i,n=t[0],o=t[1],r=t[2],s=Math.min(n,o,r),l=Math.max(n,o,r),u=l-s;return a=0==l?0:u/l*1e3/10,l==s?e=0:n==l?e=(o-r)/u:o==l?e=2+(r-n)/u:r==l&&(e=4+(n-o)/u),e=Math.min(60*e,360),e<0&&(e+=360),i=l/255*1e3/10,[e,a,i]}function o(t){var e=t[0],a=t[1],n=t[2],o=i(t)[0],r=1/255*Math.min(e,Math.min(a,n)),n=1-1/255*Math.max(e,Math.max(a,n));return[o,100*r,100*n]}function s(t){var e,a,i,n,o=t[0]/255,r=t[1]/255,s=t[2]/255;return n=Math.min(1-o,1-r,1-s),e=(1-o-n)/(1-n)||0,a=(1-r-n)/(1-n)||0,i=(1-s-n)/(1-n)||0,[100*e,100*a,100*i,100*n]}function l(t){return Z[JSON.stringify(t)]}function u(t){var e=t[0]/255,a=t[1]/255,i=t[2]/255;e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,a=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var n=.4124*e+.3576*a+.1805*i,o=.2126*e+.7152*a+.0722*i,r=.0193*e+.1192*a+.9505*i;return[100*n,100*o,100*r]}function d(t){var e,a,i,n=u(t),o=n[0],r=n[1],s=n[2];return o/=95.047,r/=100,s/=108.883,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,e=116*r-16,a=500*(o-r),i=200*(r-s),[e,a,i]}function c(t){return z(d(t))}function h(t){var e,a,i,n,o,r=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return o=255*l,[o,o,o];a=l<.5?l*(1+s):l+s-l*s,e=2*l-a,n=[0,0,0];for(var u=0;u<3;u++)i=r+1/3*-(u-1),i<0&&i++,i>1&&i--,o=6*i<1?e+6*(a-e)*i:2*i<1?a:3*i<2?e+(a-e)*(2/3-i)*6:e,n[u]=255*o;return n}function f(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,n*=o<=1?o:2-o,a=(o+n)/2,e=2*n/(o+n),[i,100*e,100*a])}function p(t){return o(h(t))}function m(t){return s(h(t))}function v(t){return l(h(t))}function x(t){var e=t[0]/60,a=t[1]/100,i=t[2]/100,n=Math.floor(e)%6,o=e-Math.floor(e),r=255*i*(1-a),s=255*i*(1-a*o),l=255*i*(1-a*(1-o)),i=255*i;switch(n){case 0:return[i,l,r];case 1:return[s,i,r];case 2:return[r,i,l];case 3:return[r,s,i];case 4:return[l,r,i];case 5:return[i,r,s]}}function y(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return a=(2-n)*o,e=n*o,e/=a<=1?a:2-a,e=e||0,a/=2,[i,100*e,100*a]}function k(t){return o(x(t))}function S(t){return s(x(t))}function M(t){return l(x(t))}function w(t){var e,a,i,n,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),e=Math.floor(6*o),a=1-l,i=6*o-e,0!=(1&e)&&(i=1-i),n=s+i*(a-s),e){default:case 6:case 0:r=a,g=n,b=s;break;case 1:r=n,g=a,b=s;break;case 2:r=s,g=a,b=n;break;case 3:r=s,g=n,b=a;break;case 4:r=n,g=s,b=a;break;case 5:r=a,g=s,b=n}return[255*r,255*g,255*b]}function C(t){return i(w(t))}function I(t){return n(w(t))}function D(t){return s(w(t))}function A(t){return l(w(t))}function T(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100,s=t[3]/100;return e=1-Math.min(1,n*(1-s)+s),a=1-Math.min(1,o*(1-s)+s),i=1-Math.min(1,r*(1-s)+s),[255*e,255*a,255*i]}function P(t){return i(T(t))}function _(t){return n(T(t))}function F(t){return o(T(t))}function V(t){return l(T(t))}function R(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100;return e=3.2406*n+o*-1.5372+r*-.4986,a=n*-.9689+1.8758*o+.0415*r,i=.0557*n+o*-.204+1.057*r,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,a=a>.0031308?1.055*Math.pow(a,1/2.4)-.055:a*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,e=Math.min(Math.max(0,e),1),a=Math.min(Math.max(0,a),1),i=Math.min(Math.max(0,i),1),[255*e,255*a,255*i]}function O(t){var e,a,i,n=t[0],o=t[1],r=t[2];return n/=95.047,o/=100,r/=108.883,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,e=116*o-16,a=500*(n-o),i=200*(o-r),[e,a,i]}function L(t){return z(O(t))}function B(t){var e,a,i,n,o=t[0],r=t[1],s=t[2];return o<=8?(a=100*o/903.3,n=7.787*(a/100)+16/116):(a=100*Math.pow((o+16)/116,3),n=Math.pow(a/100,1/3)),e=e/95.047<=.008856?e=95.047*(r/500+n-16/116)/7.787:95.047*Math.pow(r/500+n,3),i=i/108.883<=.008859?i=108.883*(n-s/200-16/116)/7.787:108.883*Math.pow(n-s/200,3),[e,a,i]}function z(t){var e,a,i,n=t[0],o=t[1],r=t[2];return e=Math.atan2(r,o),a=360*e/2/Math.PI,a<0&&(a+=360),i=Math.sqrt(o*o+r*r),[n,i,a]}function W(t){return R(B(t))}function N(t){var e,a,i,n=t[0],o=t[1],r=t[2];return i=r/360*2*Math.PI,e=o*Math.cos(i),a=o*Math.sin(i),[n,e,a]}function E(t){return B(N(t))}function H(t){return W(N(t))}function j(t){return G[t]}function U(t){return i(j(t))}function q(t){return n(j(t))}function Y(t){return o(j(t))}function X(t){return s(j(t))}function K(t){return d(j(t))}function J(t){return u(j(t))}e.exports={rgb2hsl:i,rgb2hsv:n,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:x,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:S,hsv2keyword:M,hwb2rgb:w,hwb2hsl:C,hwb2hsv:I,hwb2cmyk:D,hwb2keyword:A,cmyk2rgb:T,cmyk2hsl:P,cmyk2hsv:_,cmyk2hwb:F,cmyk2keyword:V,keyword2rgb:j,keyword2hsl:U,keyword2hsv:q,keyword2hwb:Y,keyword2cmyk:X,keyword2lab:K,keyword2xyz:J,xyz2rgb:R,xyz2lab:O,xyz2lch:L,lab2xyz:B,lab2rgb:W,lab2lch:z,lch2lab:N,lch2xyz:E,lch2rgb:H};var G={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Z={};for(var Q in G)Z[JSON.stringify(G[Q])]=Q},{}],5:[function(t,e,a){var i=t(4),n=function(){return new u};for(var o in i){n[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),s=r[1],l=r[2];n[s]=n[s]||{},n[s][l]=n[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var a=i[t](e);if("string"==typeof a||void 0===a)return a;for(var n=0;n<a.length;n++)a[n]=Math.round(a[n]);return a}}(o)}var u=function(){this.convs={}};u.prototype.routeSpace=function(t,e){var a=e[0];return void 0===a?this.getValues(t):("number"==typeof a&&(a=Array.prototype.slice.call(e)),this.setValues(t,a))},u.prototype.setValues=function(t,e){return this.space=t,this.convs={},this.convs[t]=e,this},u.prototype.getValues=function(t){var e=this.convs[t];if(!e){var a=this.space,i=this.convs[a];e=n[a][t](i),this.convs[t]=e}return e},["rgb","hsl","hsv","cmyk","keyword"].forEach(function(t){u.prototype[t]=function(e){return this.routeSpace(t,arguments)}}),e.exports=n},{4:4}],6:[function(t,e,a){e.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},{}],7:[function(t,e,a){var i=t(28)();t(26)(i),t(42)(i),t(22)(i),t(31)(i),t(25)(i),t(21)(i),t(23)(i),t(24)(i),t(29)(i),t(33)(i),t(34)(i),t(32)(i),t(35)(i),t(30)(i),t(27)(i),t(36)(i),t(37)(i),t(38)(i),t(39)(i),t(40)(i),t(45)(i),t(43)(i),t(44)(i),t(46)(i),t(47)(i),t(48)(i),t(15)(i),t(16)(i),t(17)(i),t(18)(i),t(19)(i),t(20)(i),t(8)(i),t(9)(i),t(10)(i),t(11)(i),t(12)(i),t(13)(i),t(14)(i),window.Chart=e.exports=i},{10:10,11:11,12:12,13:13,14:14,15:15,16:16,17:17,18:18,19:19,20:20,21:21,22:22,23:23,24:24,25:25,26:26,27:27,28:28,29:29,30:30,31:31,32:32,33:33,34:34,35:35,36:36,37:37,38:38,39:39,40:40,42:42,43:43,44:44,45:45,46:46,47:47,48:48,8:8,9:9}],8:[function(t,e,a){"use strict";e.exports=function(t){t.Bar=function(e,a){return a.type="bar",new t(e,a)}}},{}],9:[function(t,e,a){"use strict";e.exports=function(t){t.Bubble=function(e,a){return a.type="bubble",new t(e,a)}}},{}],10:[function(t,e,a){"use strict";e.exports=function(t){t.Doughnut=function(e,a){return a.type="doughnut",new t(e,a)}}},{}],11:[function(t,e,a){"use strict";e.exports=function(t){t.Line=function(e,a){return a.type="line",new t(e,a)}}},{}],12:[function(t,e,a){"use strict";e.exports=function(t){t.PolarArea=function(e,a){return a.type="polarArea",new t(e,a)}}},{}],13:[function(t,e,a){"use strict";e.exports=function(t){t.Radar=function(e,a){return a.type="radar",new t(e,a)}}},{}],14:[function(t,e,a){"use strict";e.exports=function(t){var e={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-1"}],yAxes:[{type:"linear",position:"left",id:"y-axis-1"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}};t.defaults.scatter=e,t.controllers.scatter=t.controllers.line,t.Scatter=function(e,a){return a.type="scatter",new t(e,a)}}},{}],15:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bar={hover:{mode:"label"},scales:{xAxes:[{type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}},t.controllers.bar=t.DatasetController.extend({dataElementType:t.elements.Rectangle,initialize:function(e,a){t.DatasetController.prototype.initialize.call(this,e,a);var i=this,n=i.getMeta(),o=i.getDataset();n.stack=o.stack,n.bar=!0},getStackCount:function(){var t=this,a=t.getMeta(),i=t.getScaleForId(a.yAxisID),n=[];return e.each(t.chart.data.datasets,function(e,a){var o=t.chart.getDatasetMeta(a);o.bar&&t.chart.isDatasetVisible(a)&&(i.options.stacked===!1||i.options.stacked===!0&&n.indexOf(o.stack)===-1||void 0===i.options.stacked&&(void 0===o.stack||n.indexOf(o.stack)===-1))&&n.push(o.stack)},t),n.length},update:function(t){var a=this;e.each(a.getMeta().data,function(e,i){a.updateElement(e,i,t)},a)},updateElement:function(t,a,i){var n=this,o=n.getMeta(),r=n.getScaleForId(o.xAxisID),s=n.getScaleForId(o.yAxisID),l=s.getBasePixel(),u=n.chart.options.elements.rectangle,d=t.custom||{},c=n.getDataset();t._xScale=r,t._yScale=s,t._datasetIndex=n.index,t._index=a;var h=n.getRuler(a);t._model={x:n.calculateBarX(a,n.index,h),y:i?l:n.calculateBarY(a,n.index),label:n.chart.data.labels[a],datasetLabel:c.label,horizontal:!1,base:i?l:n.calculateBarBase(n.index,a),width:n.calculateBarWidth(h),backgroundColor:d.backgroundColor?d.backgroundColor:e.getValueAtIndexOrDefault(c.backgroundColor,a,u.backgroundColor),borderSkipped:d.borderSkipped?d.borderSkipped:u.borderSkipped,borderColor:d.borderColor?d.borderColor:e.getValueAtIndexOrDefault(c.borderColor,a,u.borderColor),borderWidth:d.borderWidth?d.borderWidth:e.getValueAtIndexOrDefault(c.borderWidth,a,u.borderWidth)},t.pivot()},calculateBarBase:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=n.getBaseValue(),r=o;if(n.options.stacked===!0||void 0===n.options.stacked&&void 0!==i.stack){for(var s=a.chart,l=s.data.datasets,u=Number(l[t].data[e]),d=0;d<t;d++){var c=l[d],h=s.getDatasetMeta(d);if(h.bar&&h.yAxisID===n.id&&s.isDatasetVisible(d)&&i.stack===h.stack){var f=Number(c.data[e]);o+=u<0?Math.min(f,r):Math.max(f,r)}}return n.getPixelForValue(o)}return n.getBasePixel()},getRuler:function(){var t=this,e=t.getMeta(),a=t.getScaleForId(e.xAxisID),i=t.getStackCount(),n=a.width/a.ticks.length,o=n*a.options.categoryPercentage,r=(n-n*a.options.categoryPercentage)/2,s=o/i,l=s*a.options.barPercentage,u=s-s*a.options.barPercentage;return{stackCount:i,tickWidth:n,categoryWidth:o,categorySpacing:r,fullBarWidth:s,barWidth:l,barSpacing:u}},calculateBarWidth:function(t){var e=this,a=e.getMeta(),i=e.getScaleForId(a.xAxisID);return i.options.barThickness?i.options.barThickness:t.barWidth},getStackIndex:function(t){var e,a,i=this,n=i.chart.getDatasetMeta(t),o=i.getScaleForId(n.yAxisID),r=[n.stack];for(a=0;a<t;++a)e=this.chart.getDatasetMeta(a),e.bar&&this.chart.isDatasetVisible(a)&&(o.options.stacked===!1||o.options.stacked===!0&&r.indexOf(e.stack)===-1||void 0===o.options.stacked&&(void 0===e.stack||r.indexOf(e.stack)===-1))&&r.push(e.stack);return r.length-1},calculateBarX:function(t,e,a){var i=this,n=i.getMeta(),o=i.getScaleForId(n.xAxisID),r=i.getStackIndex(e),s=o.getPixelForValue(null,t,e,i.chart.isCombo);return s-=i.chart.isCombo?a.tickWidth/2:0,s+a.barWidth/2+a.categorySpacing+a.barWidth*r+a.barSpacing/2+a.barSpacing*r},calculateBarY:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.yAxisID),o=Number(a.getDataset().data[t]);if(n.options.stacked||void 0===n.options.stacked&&void 0!==i.stack){for(var r=n.getBaseValue(),s=r,l=r,u=0;u<e;u++){var d=a.chart.data.datasets[u],c=a.chart.getDatasetMeta(u);if(c.bar&&c.yAxisID===n.id&&a.chart.isDatasetVisible(u)&&i.stack===c.stack){var h=Number(d.data[t]);h<0?l+=h||0:s+=h||0}}return o<0?n.getPixelForValue(l+o):n.getPixelForValue(s+o)}return n.getPixelForValue(o)},draw:function(e){var a,i,n=this,o=e||1,r=n.getMeta().data,s=n.getDataset();for(t.canvasHelpers.clipArea(n.chart.chart.ctx,n.chart.chartArea),a=0,i=r.length;a<i;++a){var l=s.data[a];null===l||void 0===l||isNaN(l)||r[a].transition(o).draw()}t.canvasHelpers.unclipArea(n.chart.chart.ctx)},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model;o.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.hoverBackgroundColor,i,e.getHoverColor(o.backgroundColor)),o.borderColor=n.hoverBorderColor?n.hoverBorderColor:e.getValueAtIndexOrDefault(a.hoverBorderColor,i,e.getHoverColor(o.borderColor)),o.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:e.getValueAtIndexOrDefault(a.hoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model,r=this.chart.options.elements.rectangle;o.backgroundColor=n.backgroundColor?n.backgroundColor:e.getValueAtIndexOrDefault(a.backgroundColor,i,r.backgroundColor),o.borderColor=n.borderColor?n.borderColor:e.getValueAtIndexOrDefault(a.borderColor,i,r.borderColor),o.borderWidth=n.borderWidth?n.borderWidth:e.getValueAtIndexOrDefault(a.borderWidth,i,r.borderWidth)}}),t.defaults.horizontalBar={hover:{mode:"label"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{position:"left",type:"category",categoryPercentage:.8,barPercentage:.9,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{callbacks:{title:function(t,e){var a="";return t.length>0&&(t[0].yLabel?a=t[0].yLabel:e.labels.length>0&&t[0].index<e.labels.length&&(a=e.labels[t[0].index])),a},label:function(t,e){var a=e.datasets[t.datasetIndex].label||"";return a+": "+t.xLabel}}}},t.controllers.horizontalBar=t.controllers.bar.extend({getStackCount:function(){var t=this,a=t.getMeta(),i=t.getScaleForId(a.xAxisID),n=[];return e.each(t.chart.data.datasets,function(e,a){var o=t.chart.getDatasetMeta(a);o.bar&&t.chart.isDatasetVisible(a)&&(i.options.stacked===!1||i.options.stacked===!0&&n.indexOf(o.stack)===-1||void 0===i.options.stacked&&(void 0===o.stack||n.indexOf(o.stack)===-1))&&n.push(o.stack)},t),n.length},updateElement:function(t,a,i){var n=this,o=n.getMeta(),r=n.getScaleForId(o.xAxisID),s=n.getScaleForId(o.yAxisID),l=r.getBasePixel(),u=t.custom||{},d=n.getDataset(),c=n.chart.options.elements.rectangle;t._xScale=r,t._yScale=s,t._datasetIndex=n.index,t._index=a;var h=n.getRuler(a);t._model={x:i?l:n.calculateBarX(a,n.index),y:n.calculateBarY(a,n.index,h),label:n.chart.data.labels[a],datasetLabel:d.label,horizontal:!0,base:i?l:n.calculateBarBase(n.index,a),height:n.calculateBarHeight(h),backgroundColor:u.backgroundColor?u.backgroundColor:e.getValueAtIndexOrDefault(d.backgroundColor,a,c.backgroundColor),borderSkipped:u.borderSkipped?u.borderSkipped:c.borderSkipped,borderColor:u.borderColor?u.borderColor:e.getValueAtIndexOrDefault(d.borderColor,a,c.borderColor),
11
- borderWidth:u.borderWidth?u.borderWidth:e.getValueAtIndexOrDefault(d.borderWidth,a,c.borderWidth)},t.pivot()},calculateBarBase:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=n.getBaseValue(),r=o;if(n.options.stacked||void 0===n.options.stacked&&void 0!==i.stack){for(var s=a.chart,l=s.data.datasets,u=Number(l[t].data[e]),d=0;d<t;d++){var c=l[d],h=s.getDatasetMeta(d);if(h.bar&&h.xAxisID===n.id&&s.isDatasetVisible(d)&&i.stack===h.stack){var f=Number(c.data[e]);o+=u<0?Math.min(f,r):Math.max(f,r)}}return n.getPixelForValue(o)}return n.getBasePixel()},getRuler:function(){var t=this,e=t.getMeta(),a=t.getScaleForId(e.yAxisID),i=t.getStackCount(),n=a.height/a.ticks.length,o=n*a.options.categoryPercentage,r=(n-n*a.options.categoryPercentage)/2,s=o/i,l=s*a.options.barPercentage,u=s-s*a.options.barPercentage;return{stackCount:i,tickHeight:n,categoryHeight:o,categorySpacing:r,fullBarHeight:s,barHeight:l,barSpacing:u}},calculateBarHeight:function(t){var e=this,a=e.getMeta(),i=e.getScaleForId(a.yAxisID);return i.options.barThickness?i.options.barThickness:t.barHeight},getStackIndex:function(t){var e,a,i=this,n=i.chart.getDatasetMeta(t),o=i.getScaleForId(n.xAxisID),r=[n.stack];for(a=0;a<t;++a)e=this.chart.getDatasetMeta(a),e.bar&&this.chart.isDatasetVisible(a)&&(o.options.stacked===!1||o.options.stacked===!0&&r.indexOf(e.stack)===-1||void 0===o.options.stacked&&(void 0===e.stack||r.indexOf(e.stack)===-1))&&r.push(e.stack);return r.length-1},calculateBarX:function(t,e){var a=this,i=a.getMeta(),n=a.getScaleForId(i.xAxisID),o=Number(a.getDataset().data[t]);if(n.options.stacked||void 0===n.options.stacked&&void 0!==i.stack){for(var r=n.getBaseValue(),s=r,l=r,u=0;u<e;u++){var d=a.chart.data.datasets[u],c=a.chart.getDatasetMeta(u);if(c.bar&&c.xAxisID===n.id&&a.chart.isDatasetVisible(u)&&i.stack===c.stack){var h=Number(d.data[t]);h<0?l+=h||0:s+=h||0}}return o<0?n.getPixelForValue(l+o):n.getPixelForValue(s+o)}return n.getPixelForValue(o)},calculateBarY:function(t,e,a){var i=this,n=i.getMeta(),o=i.getScaleForId(n.yAxisID),r=i.getStackIndex(e),s=o.getPixelForValue(null,t,e,i.chart.isCombo);return s-=i.chart.isCombo?a.tickHeight/2:0,s+a.barHeight/2+a.categorySpacing+a.barHeight*r+a.barSpacing/2+a.barSpacing*r}})}},{}],16:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.bubble={hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var a=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return a+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}},t.controllers.bubble=t.DatasetController.extend({dataElementType:t.elements.Point,update:function(t){var a=this,i=a.getMeta(),n=i.data;e.each(n,function(e,i){a.updateElement(e,i,t)})},updateElement:function(a,i,n){var o=this,r=o.getMeta(),s=o.getScaleForId(r.xAxisID),l=o.getScaleForId(r.yAxisID),u=a.custom||{},d=o.getDataset(),c=d.data[i],h=o.chart.options.elements.point,f=o.index;e.extend(a,{_xScale:s,_yScale:l,_datasetIndex:f,_index:i,_model:{x:n?s.getPixelForDecimal(.5):s.getPixelForValue("object"==typeof c?c:NaN,i,f,o.chart.isCombo),y:n?l.getBasePixel():l.getPixelForValue(c,i,f),radius:n?0:u.radius?u.radius:o.getRadius(c),hitRadius:u.hitRadius?u.hitRadius:e.getValueAtIndexOrDefault(d.hitRadius,i,h.hitRadius)}}),t.DatasetController.prototype.removeHoverStyle.call(o,a,h);var g=a._model;g.skip=u.skip?u.skip:isNaN(g.x)||isNaN(g.y),a.pivot()},getRadius:function(t){return t.r||this.chart.options.elements.point.radius},setHoverStyle:function(a){var i=this;t.DatasetController.prototype.setHoverStyle.call(i,a);var n=i.chart.data.datasets[a._datasetIndex],o=a._index,r=a.custom||{},s=a._model;s.radius=r.hoverRadius?r.hoverRadius:e.getValueAtIndexOrDefault(n.hoverRadius,o,i.chart.options.elements.point.hoverRadius)+i.getRadius(n.data[o])},removeHoverStyle:function(e){var a=this;t.DatasetController.prototype.removeHoverStyle.call(a,e,a.chart.options.elements.point);var i=a.chart.data.datasets[e._datasetIndex].data[e._index],n=e.custom||{},o=e._model;o.radius=n.radius?n.radius:a.getRadius(i)}})}},{}],17:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults;a.doughnut={animation:{animateRotate:!0,animateScale:!1},aspectRatio:1,hover:{mode:"single"},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),n[o]&&e.push(n[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],s=o.data[n],l=s&&s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),h=l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),f=l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;a<i;++a)n=r.getDatasetMeta(a),n.data[o]&&(n.data[o].hidden=!n.data[o].hidden);r.update()}},cutoutPercentage:50,rotation:Math.PI*-.5,circumference:2*Math.PI,tooltips:{callbacks:{title:function(){return""},label:function(t,a){var i=a.labels[t.index],n=": "+a.datasets[t.datasetIndex].data[t.index];return e.isArray(i)?(i=i.slice(),i[0]+=n):i+=n,i}}}},a.pie=e.clone(a.doughnut),e.extend(a.pie,{cutoutPercentage:0}),t.controllers.doughnut=t.controllers.pie=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,getRingIndex:function(t){for(var e=0,a=0;a<t;++a)this.chart.isDatasetVisible(a)&&++e;return e},update:function(t){var a=this,i=a.chart,n=i.chartArea,o=i.options,r=o.elements.arc,s=n.right-n.left-r.borderWidth,l=n.bottom-n.top-r.borderWidth,u=Math.min(s,l),d={x:0,y:0},c=a.getMeta(),h=o.cutoutPercentage,f=o.circumference;if(f<2*Math.PI){var g=o.rotation%(2*Math.PI);g+=2*Math.PI*(g>=Math.PI?-1:g<-Math.PI?1:0);var p=g+f,m={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(p),y:Math.sin(p)},b=g<=0&&0<=p||g<=2*Math.PI&&2*Math.PI<=p,x=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,y=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,k=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,M={x:y?-1:Math.min(m.x*(m.x<0?1:S),v.x*(v.x<0?1:S)),y:k?-1:Math.min(m.y*(m.y<0?1:S),v.y*(v.y<0?1:S))},w={x:b?1:Math.max(m.x*(m.x>0?1:S),v.x*(v.x>0?1:S)),y:x?1:Math.max(m.y*(m.y>0?1:S),v.y*(v.y>0?1:S))},C={width:.5*(w.x-M.x),height:.5*(w.y-M.y)};u=Math.min(s/C.width,l/C.height),d={x:(w.x+M.x)*-.5,y:(w.y+M.y)*-.5}}i.borderWidth=a.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=a.calculateTotal(),a.outerRadius=i.outerRadius-i.radiusLength*a.getRingIndex(a.index),a.innerRadius=Math.max(a.outerRadius-i.radiusLength,0),e.each(c.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){var n=this,o=n.chart,r=o.chartArea,s=o.options,l=s.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=s.rotation,h=s.rotation,f=n.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[a])*(s.circumference/(2*Math.PI)),p=i&&l.animateScale?0:n.innerRadius,m=i&&l.animateScale?0:n.outerRadius,v=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:n.index,_index:a,_model:{x:u+o.offsetX,y:d+o.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,a,o.data.labels[a])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(0===a?b.startAngle=s.rotation:b.startAngle=n.getMeta().data[a-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,a=this.getDataset(),i=this.getMeta(),n=0;return e.each(i.data,function(e,i){t=a.data[i],isNaN(t)||e.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,a,i=0,n=this.index,o=t.length,r=0;r<o;r++)e=t[r]._model?t[r]._model.borderWidth:0,a=t[r]._chart?t[r]._chart.config.data.datasets[n].hoverBorderWidth:0,i=e>i?e:i,i=a>i?a:i;return i}})}},{}],18:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return a.getValueOrDefault(t.showLine,e.showLines)}var a=t.helpers;t.defaults.line={showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,update:function(t){var i,n,o,r=this,s=r.getMeta(),l=s.dataset,u=s.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(s.yAxisID),f=r.getDataset(),g=e(f,d);for(g&&(o=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=r.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:o.tension?o.tension:a.getValueOrDefault(f.lineTension,c.tension),backgroundColor:o.backgroundColor?o.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:f.borderWidth||c.borderWidth,borderColor:o.borderColor?o.borderColor:f.borderColor||c.borderColor,borderCapStyle:o.borderCapStyle?o.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:o.borderDash?o.borderDash:f.borderDash||c.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:o.fill?o.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:o.steppedLine?o.steppedLine:a.getValueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:o.cubicInterpolationMode?o.cubicInterpolationMode:a.getValueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode),scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},l.pivot()),i=0,n=u.length;i<n;++i)r.updateElement(u[i],i,t);for(g&&0!==l._model.tension&&r.updateBezierControlPoints(),i=0,n=u.length;i<n;++i)u[i].pivot()},getPointBackgroundColor:function(t,e){var i=this.chart.options.elements.point.backgroundColor,n=this.getDataset(),o=t.custom||{};return o.backgroundColor?i=o.backgroundColor:n.pointBackgroundColor?i=a.getValueAtIndexOrDefault(n.pointBackgroundColor,e,i):n.backgroundColor&&(i=n.backgroundColor),i},getPointBorderColor:function(t,e){var i=this.chart.options.elements.point.borderColor,n=this.getDataset(),o=t.custom||{};return o.borderColor?i=o.borderColor:n.pointBorderColor?i=a.getValueAtIndexOrDefault(n.pointBorderColor,e,i):n.borderColor&&(i=n.borderColor),i},getPointBorderWidth:function(t,e){var i=this.chart.options.elements.point.borderWidth,n=this.getDataset(),o=t.custom||{};return isNaN(o.borderWidth)?isNaN(n.pointBorderWidth)?isNaN(n.borderWidth)||(i=n.borderWidth):i=a.getValueAtIndexOrDefault(n.pointBorderWidth,e,i):i=o.borderWidth,i},updateElement:function(t,e,i){var n,o,r=this,s=r.getMeta(),l=t.custom||{},u=r.getDataset(),d=r.index,c=u.data[e],h=r.getScaleForId(s.yAxisID),f=r.getScaleForId(s.xAxisID),g=r.chart.options.elements.point,p=r.chart.data.labels||[],m=1===p.length||1===u.data.length||r.chart.isCombo;void 0!==u.radius&&void 0===u.pointRadius&&(u.pointRadius=u.radius),void 0!==u.hitRadius&&void 0===u.pointHitRadius&&(u.pointHitRadius=u.hitRadius),n=f.getPixelForValue("object"==typeof c?c:NaN,e,d,m),o=i?h.getBasePixel():r.calculatePointY(c,e,d),t._xScale=f,t._yScale=h,t._datasetIndex=d,t._index=e,t._model={x:n,y:o,skip:l.skip||isNaN(n)||isNaN(o),radius:l.radius||a.getValueAtIndexOrDefault(u.pointRadius,e,g.radius),pointStyle:l.pointStyle||a.getValueAtIndexOrDefault(u.pointStyle,e,g.pointStyle),backgroundColor:r.getPointBackgroundColor(t,e),borderColor:r.getPointBorderColor(t,e),borderWidth:r.getPointBorderWidth(t,e),tension:s.dataset._model?s.dataset._model.tension:0,steppedLine:!!s.dataset._model&&s.dataset._model.steppedLine,hitRadius:l.hitRadius||a.getValueAtIndexOrDefault(u.pointHitRadius,e,g.hitRadius)}},calculatePointY:function(t,e,a){var i,n,o,r=this,s=r.chart,l=r.getMeta(),u=r.getScaleForId(l.yAxisID),d=0,c=0;if(u.options.stacked){for(i=0;i<a;i++)if(n=s.data.datasets[i],o=s.getDatasetMeta(i),"line"===o.type&&o.yAxisID===u.id&&s.isDatasetVisible(i)){var h=Number(u.getRightValue(n.data[e]));h<0?c+=h||0:d+=h||0}var f=Number(u.getRightValue(t));return f<0?u.getPixelForValue(c+f):u.getPixelForValue(d+f)}return u.getPixelForValue(t)},updateBezierControlPoints:function(){function t(t,e,a){return Math.max(Math.min(t,a),e)}var e,i,n,o,r,s=this,l=s.getMeta(),u=s.chart.chartArea,d=l.data||[];if(l.dataset._model.spanGaps&&(d=d.filter(function(t){return!t._model.skip})),"monotone"===l.dataset._model.cubicInterpolationMode)a.splineCurveMonotone(d);else for(e=0,i=d.length;e<i;++e)n=d[e],o=n._model,r=a.splineCurve(a.previousItem(d,e)._model,o,a.nextItem(d,e)._model,l.dataset._model.tension),o.controlPointPreviousX=r.previous.x,o.controlPointPreviousY=r.previous.y,o.controlPointNextX=r.next.x,o.controlPointNextY=r.next.y;if(s.chart.options.elements.line.capBezierPoints)for(e=0,i=d.length;e<i;++e)o=d[e]._model,o.controlPointPreviousX=t(o.controlPointPreviousX,u.left,u.right),o.controlPointPreviousY=t(o.controlPointPreviousY,u.top,u.bottom),o.controlPointNextX=t(o.controlPointNextX,u.left,u.right),o.controlPointNextY=t(o.controlPointNextY,u.top,u.bottom)},draw:function(a){var i,n,o=this,r=o.getMeta(),s=r.data||[],l=a||1;for(i=0,n=s.length;i<n;++i)s[i].transition(l);for(t.canvasHelpers.clipArea(o.chart.chart.ctx,o.chart.chartArea),e(o.getDataset(),o.chart.options)&&r.dataset.transition(l).draw(),t.canvasHelpers.unclipArea(o.chart.chart.ctx),i=0,n=s.length;i<n;++i)s[i].draw(o.chart.chartArea)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],i=t._index,n=t.custom||{},o=t._model;o.radius=n.hoverRadius||a.getValueAtIndexOrDefault(e.pointHoverRadius,i,this.chart.options.elements.point.hoverRadius),o.backgroundColor=n.hoverBackgroundColor||a.getValueAtIndexOrDefault(e.pointHoverBackgroundColor,i,a.getHoverColor(o.backgroundColor)),o.borderColor=n.hoverBorderColor||a.getValueAtIndexOrDefault(e.pointHoverBorderColor,i,a.getHoverColor(o.borderColor)),o.borderWidth=n.hoverBorderWidth||a.getValueAtIndexOrDefault(e.pointHoverBorderWidth,i,o.borderWidth)},removeHoverStyle:function(t){var e=this,i=e.chart.data.datasets[t._datasetIndex],n=t._index,o=t.custom||{},r=t._model;void 0!==i.radius&&void 0===i.pointRadius&&(i.pointRadius=i.radius),r.radius=o.radius||a.getValueAtIndexOrDefault(i.pointRadius,n,e.chart.options.elements.point.radius),r.backgroundColor=e.getPointBackgroundColor(t,n),r.borderColor=e.getPointBorderColor(t,n),r.borderWidth=e.getPointBorderWidth(t,n)}})}},{}],19:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.polarArea={scale:{type:"radialLinear",lineArc:!0,ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,aspectRatio:1,legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o<i[0].data.length;++o)e.push('<li><span style="background-color:'+i[0].backgroundColor[o]+'"></span>'),n[o]&&e.push(n[o]),e.push("</li>");return e.push("</ul>"),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],s=o.data[n],l=s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),h=l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),f=l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;a<i;++a)n=r.getDatasetMeta(a),n.data[o].hidden=!n.data[o].hidden;r.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}},t.controllers.polarArea=t.DatasetController.extend({dataElementType:t.elements.Arc,linkScales:e.noop,update:function(t){var a=this,i=a.chart,n=i.chartArea,o=a.getMeta(),r=i.options,s=r.elements.arc,l=Math.min(n.right-n.left,n.bottom-n.top);i.outerRadius=Math.max((l-s.borderWidth/2)/2,0),i.innerRadius=Math.max(r.cutoutPercentage?i.outerRadius/100*r.cutoutPercentage:1,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),a.outerRadius=i.outerRadius-i.radiusLength*a.index,a.innerRadius=a.outerRadius-i.radiusLength,o.count=a.countVisibleElements(),e.each(o.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){for(var n=this,o=n.chart,r=n.getDataset(),s=o.options,l=s.animation,u=o.scale,d=e.getValueAtIndexOrDefault,c=o.data.labels,h=n.calculateCircumference(r.data[a]),f=u.xCenter,g=u.yCenter,p=0,m=n.getMeta(),v=0;v<a;++v)isNaN(r.data[v])||m.data[v].hidden||++p;var b=s.startAngle,x=t.hidden?0:u.getDistanceFromCenterForValue(r.data[a]),y=b+h*p,k=y+(t.hidden?0:h),S=l.animateScale?0:u.getDistanceFromCenterForValue(r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:u,_model:{x:f,y:g,innerRadius:0,outerRadius:i?S:x,startAngle:i&&l.animateRotate?b:y,endAngle:i&&l.animateRotate?b:k,label:d(c,a,c[a])}}),n.removeHoverStyle(t),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},countVisibleElements:function(){var t=this.getDataset(),a=this.getMeta(),i=0;return e.each(a.data,function(e,a){isNaN(t.data[a])||e.hidden||i++}),i},calculateCircumference:function(t){var e=this.getMeta().count;return e>0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={aspectRatio:1,scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,update:function(t){var a=this,i=a.getMeta(),n=i.dataset,o=i.data,r=n.custom||{},s=a.getDataset(),l=a.chart.options.elements.line,u=a.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),e.extend(i.dataset,{_datasetIndex:a.index,_children:o,_loop:!0,_model:{tension:r.tension?r.tension:e.getValueOrDefault(s.lineTension,l.tension),backgroundColor:r.backgroundColor?r.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:s.borderWidth||l.borderWidth,borderColor:r.borderColor?r.borderColor:s.borderColor||l.borderColor,fill:r.fill?r.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:r.borderDash?r.borderDash:s.borderDash||l.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle,scaleTop:u.top,scaleBottom:u.bottom,scaleZero:u.getBasePosition()}}),i.dataset.pivot(),e.each(o,function(e,i){a.updateElement(e,i,t)},a),a.updateBezierControlPoints()},updateElement:function(t,a,i){var n=this,o=t.custom||{},r=n.getDataset(),s=n.chart.scale,l=n.chart.options.elements.point,u=s.getPointPositionForValue(a,r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:o.tension?o.tension:e.getValueOrDefault(r.lineTension,n.chart.options.elements.line.tension),radius:o.radius?o.radius:e.getValueAtIndexOrDefault(r.pointRadius,a,l.radius),backgroundColor:o.backgroundColor?o.backgroundColor:e.getValueAtIndexOrDefault(r.pointBackgroundColor,a,l.backgroundColor),borderColor:o.borderColor?o.borderColor:e.getValueAtIndexOrDefault(r.pointBorderColor,a,l.borderColor),borderWidth:o.borderWidth?o.borderWidth:e.getValueAtIndexOrDefault(r.pointBorderWidth,a,l.borderWidth),pointStyle:o.pointStyle?o.pointStyle:e.getValueAtIndexOrDefault(r.pointStyle,a,l.pointStyle),hitRadius:o.hitRadius?o.hitRadius:e.getValueAtIndexOrDefault(r.hitRadius,a,l.hitRadius)}}),t._model.skip=o.skip?o.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,a=this.getMeta();e.each(a.data,function(i,n){var o=i._model,r=e.splineCurve(e.previousItem(a.data,n,!0)._model,o,e.nextItem(a.data,n,!0)._model,o.tension);o.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),o.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),o.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),o.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var a=this.getMeta(),i=t||1;e.each(a.data,function(t){t.transition(i)}),a.dataset.transition(i).draw(),e.each(a.data,function(t){t.draw()})},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model;o.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(a.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),o.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.pointHoverBackgroundColor,n,e.getHoverColor(o.backgroundColor)),o.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(a.pointHoverBorderColor,n,e.getHoverColor(o.borderColor)),o.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(a.pointHoverBorderWidth,n,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model,r=this.chart.options.elements.point;o.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(a.radius,n,r.radius),o.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(a.pointBackgroundColor,n,r.backgroundColor),o.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(a.pointBorderColor,n,r.borderColor),o.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(a.pointBorderWidth,n,r.borderWidth)}})}},{}],21:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,a,i){var n=this;i||(t.animating=!0);for(var o=0;o<n.animations.length;++o)if(n.animations[o].chartInstance===t)return void(n.animations[o].animationObject=e);n.animations.push({chartInstance:t,animationObject:e}),1===n.animations.length&&n.requestAnimationFrame()},cancelAnimation:function(t){var a=e.findIndex(this.animations,function(e){return e.chartInstance===t});a!==-1&&(this.animations.splice(a,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=e.requestAnimFrame.call(window,function(){t.request=null,t.startDigest()}))},startDigest:function(){var t=this,e=Date.now(),a=0;t.dropFrames>1&&(a=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;i<t.animations.length;)null===t.animations[i].animationObject.currentStep&&(t.animations[i].animationObject.currentStep=0),t.animations[i].animationObject.currentStep+=1+a,t.animations[i].animationObject.currentStep>t.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var n=Date.now(),o=(n-e)/t.frameDuration;t.dropFrames+=o,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,a){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(e,a,i,n,o){var r,s,l,u,d,c;if("object"==typeof a&&(r=a.toString(),"[object HTMLImageElement]"===r||"[object HTMLCanvasElement]"===r))return void e.drawImage(a,n-a.width/2,o-a.height/2);if(!(isNaN(i)||i<=0)){switch(a){default:e.beginPath(),e.arc(n,o,i,0,2*Math.PI),e.closePath(),e.fill();break;case"triangle":e.beginPath(),s=3*i/Math.sqrt(3),d=s*Math.sqrt(3)/2,e.moveTo(n-s/2,o+d/3),e.lineTo(n+s/2,o+d/3),e.lineTo(n,o-2*d/3),e.closePath(),e.fill();break;case"rect":c=1/Math.SQRT2*i,e.beginPath(),e.fillRect(n-c,o-c,2*c,2*c),e.strokeRect(n-c,o-c,2*c,2*c);break;case"rectRounded":var h=i/Math.SQRT2,f=n-h,g=o-h,p=Math.SQRT2*i;t.helpers.drawRoundedRectangle(e,f,g,p,p,i/2),e.fill();break;case"rectRot":c=1/Math.SQRT2*i,e.beginPath(),e.moveTo(n-c,o),e.lineTo(n,o+c),e.lineTo(n+c,o),e.lineTo(n,o-c),e.closePath(),e.fill();break;case"cross":e.beginPath(),e.moveTo(n,o+i),e.lineTo(n,o-i),e.moveTo(n-i,o),e.lineTo(n+i,o),e.closePath();break;case"crossRot":e.beginPath(),l=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(n-l,o-u),e.lineTo(n+l,o+u),e.moveTo(n-l,o+u),e.lineTo(n+l,o-u),e.closePath();break;case"star":e.beginPath(),e.moveTo(n,o+i),e.lineTo(n,o-i),e.moveTo(n-i,o),e.lineTo(n+i,o),l=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(n-l,o-u),e.lineTo(n+l,o+u),e.moveTo(n-l,o+u),e.lineTo(n+l,o-u),e.closePath();break;case"line":e.beginPath(),e.moveTo(n-i,o),e.lineTo(n+i,o),e.closePath();break;case"dash":e.beginPath(),e.moveTo(n,o),e.lineTo(n+i,o),e.closePath()}e.stroke()}},e.clipArea=function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},e.unclipArea=function(t){t.restore()}}},{}],23:[function(t,e,a){"use strict";e.exports=function(t){function e(e){e=e||{};var a=e.data=e.data||{};return a.datasets=a.datasets||[],a.labels=a.labels||[],e.options=i.configMerge(t.defaults.global,t.defaults[e.type],e.options||{}),e}function a(t){var e=t.options;e.scale?t.scale.options=e.scale:e.scales&&e.scales.xAxes.concat(e.scales.yAxes).forEach(function(e){t.scales[e.id].options=e}),t.tooltip._options=e.tooltips}var i=t.helpers,n=t.plugins,o=t.platform;t.types={},t.instances={},t.controllers={},t.Controller=function(a,n,r){var s=this;n=e(n);var l=o.acquireContext(a,n),u=l&&l.canvas,d=u&&u.height,c=u&&u.width;return r.ctx=l,r.canvas=u,r.config=n,r.width=c,r.height=d,r.aspectRatio=d?c/d:null,s.id=i.uid(),s.chart=r,s.config=n,s.options=n.options,s._bufferedRender=!1,t.instances[s.id]=s,Object.defineProperty(s,"data",{get:function(){return s.config.data}}),l&&u?(s.initialize(),s.update(),s):(console.error("Failed to create chart: can't acquire context from the given item"),s)},i.extend(t.Controller.prototype,{initialize:function(){var t=this;return n.notify(t,"beforeInit"),i.retinaScale(t.chart),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildScales(),t.initToolTip(),n.notify(t,"afterInit"),t},clear:function(){return i.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,a=e.chart,o=e.options,r=a.canvas,s=o.maintainAspectRatio&&a.aspectRatio||null,l=Math.floor(i.getMaximumWidth(r)),u=Math.floor(s?l/s:i.getMaximumHeight(r));if((a.width!==l||a.height!==u)&&(r.width=a.width=l,r.height=a.height=u,r.style.width=l+"px",r.style.height=u+"px",i.retinaScale(a),!t)){var d={width:l,height:u};n.notify(e,"resize",[d]),e.options.onResize&&e.options.onResize(e,d),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},a=t.scale;i.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),i.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),a&&(a.id=a.id||"scale")},buildScales:function(){var e=this,a=e.options,n=e.scales={},o=[];a.scales&&(o=o.concat((a.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(a.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),a.scale&&o.push({options:a.scale,dtype:"radialLinear",isDefault:!0}),i.each(o,function(a){var o=a.options,r=i.getValueOrDefault(o.type,a.dtype),s=t.scaleService.getScaleConstructor(r);if(s){var l=new s({id:o.id,options:o,ctx:e.chart.ctx,chart:e});n[l.id]=l,a.isDefault&&(e.scale=l)}}),t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,a=[],n=[];if(i.each(e.data.datasets,function(i,o){var r=e.getDatasetMeta(o);r.type||(r.type=i.type||e.config.type),a.push(r.type),r.controller?r.controller.updateIndex(o):(r.controller=new t.controllers[r.type](e,o),n.push(r.controller))},e),a.length>1)for(var o=1;o<a.length;o++)if(a[o]!==a[o-1]){e.isCombo=!0;break}return n},resetElements:function(){var t=this;i.each(t.data.datasets,function(e,a){t.getDatasetMeta(a).controller.reset()},t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t,e){var o=this;if(a(o),n.notify(o,"beforeUpdate")!==!1){o.tooltip._data=o.data;var r=o.buildOrUpdateControllers();i.each(o.data.datasets,function(t,e){o.getDatasetMeta(e).controller.buildOrUpdateElements()},o),o.updateLayout(),i.each(r,function(t){t.reset()}),o.updateDatasets(),n.notify(o,"afterUpdate"),o._bufferedRender?o._bufferedRequest={lazy:e,duration:t}:o.render(t,e)}},updateLayout:function(){var e=this;n.notify(e,"beforeLayout")!==!1&&(t.layoutService.update(this,this.chart.width,this.chart.height),n.notify(e,"afterScaleUpdate"),n.notify(e,"afterLayout"))},updateDatasets:function(){var t=this;if(n.notify(t,"beforeDatasetsUpdate")!==!1){for(var e=0,a=t.data.datasets.length;e<a;++e)t.getDatasetMeta(e).controller.update();n.notify(t,"afterDatasetsUpdate")}},render:function(e,a){var o=this;if(n.notify(o,"beforeRender")!==!1){var r=o.options.animation,s=function(){n.notify(o,"afterRender");var t=r&&r.onComplete;t&&t.call&&t.call(o)};if(r&&("undefined"!=typeof e&&0!==e||"undefined"==typeof e&&0!==r.duration)){var l=new t.Animation;l.numSteps=(e||r.duration)/16.66,l.easing=r.easing,l.render=function(t,e){var a=i.easingEffects[e.easing],n=e.currentStep/e.numSteps,o=a(n);t.draw(o,n,e.currentStep)},l.onAnimationProgress=r.onProgress,l.onAnimationComplete=s,t.animationService.addAnimation(o,l,e,a)}else o.draw(),s();return o}},draw:function(t){var e=this;e.clear(),void 0!==t&&null!==t||(t=1),n.notify(e,"beforeDraw",[t])!==!1&&(i.each(e.boxes,function(t){t.draw(e.chartArea)},e),e.scale&&e.scale.draw(),e.drawDatasets(t),e.tooltip.transition(t).draw(),n.notify(e,"afterDraw",[t]))},drawDatasets:function(t){var e=this;n.notify(e,"beforeDatasetsDraw",[t])!==!1&&(i.each(e.data.datasets,function(a,i){e.isDatasetVisible(i)&&e.getDatasetMeta(i).controller.draw(t)},e,!0),n.notify(e,"afterDatasetsDraw",[t]))},getElementAtEvent:function(e){return t.Interaction.modes.single(this,e)},getElementsAtEvent:function(e){return t.Interaction.modes.label(this,e,{intersect:!0})},getElementsAtXAxis:function(e){return t.Interaction.modes["x-axis"](this,e,{intersect:!0})},getElementsAtEventForMode:function(e,a,i){
12
- var n=t.Interaction.modes[a];return"function"==typeof n?n(this,e,i):[]},getDatasetAtEvent:function(e){return t.Interaction.modes.dataset(this,e,{intersect:!0})},getDatasetMeta:function(t){var e=this,a=e.data.datasets[t];a._meta||(a._meta={});var i=a._meta[e.id];return i||(i=a._meta[e.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null}),i},getVisibleDatasetCount:function(){for(var t=0,e=0,a=this.data.datasets.length;e<a;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroy:function(){var e,a,r,s=this,l=s.chart.canvas;for(s.stop(),a=0,r=s.data.datasets.length;a<r;++a)e=s.getDatasetMeta(a),e.controller&&(e.controller.destroy(),e.controller=null);l&&(s.unbindEvents(),i.clear(s.chart),o.releaseContext(s.chart.ctx),s.chart.canvas=null,s.chart.ctx=null),n.notify(s,"destroy"),delete t.instances[s.id]},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)},initToolTip:function(){var e=this;e.tooltip=new t.Tooltip({_chart:e.chart,_chartInstance:e,_data:e.data,_options:e.options.tooltips},e),e.tooltip.initialize()},bindEvents:function(){var t=this,e=t._listeners={},a=function(){t.eventHandler.apply(t,arguments)};i.each(t.options.events,function(i){o.addEventListener(t,i,a),e[i]=a}),t.options.responsive&&(a=function(){t.resize()},o.addEventListener(t,"resize",a),e.resize=a)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,i.each(e,function(e,a){o.removeEventListener(t,a,e)}))},updateHoverStyle:function(t,e,a){var i,n,o,r=a?"setHoverStyle":"removeHoverStyle";for(n=0,o=t.length;n<o;++n)i=t[n],i&&this.getDatasetMeta(i._datasetIndex).controller[r](i)},eventHandler:function(t){var e=this,a=e.tooltip;if(n.notify(e,"beforeEvent",[t])!==!1){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);i|=a&&a.handleEvent(t),n.notify(e,"afterEvent",[t]);var o=e._bufferedRequest;return o?e.render(o.duration,o.lazy):i&&!e.animating&&(e.stop(),e.render(e.options.hover.animationDuration,!0)),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e=this,a=e.options||{},n=a.hover,o=!1;return e.lastActive=e.lastActive||[],"mouseout"===t.type?e.active=[]:e.active=e.getElementsAtEventForMode(t,n.mode,n),n.onHover&&n.onHover.call(e,t.native,e.active),"mouseup"!==t.type&&"click"!==t.type||a.onClick&&a.onClick.call(e,t.native,e.active),e.lastActive.length&&e.updateHoverStyle(e.lastActive,n.mode,!1),e.active.length&&n.mode&&e.updateHoverStyle(e.active,n.mode,!0),o=!i.arrayEquals(e.active,e.lastActive),e.lastActive=e.active,o}})}},{}],24:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return t._chartjs?void t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),void n.forEach(function(e){var a="onData"+e.charAt(0).toUpperCase()+e.slice(1),n=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),o=n.apply(this,e);return i.each(t._chartjs.listeners,function(t){"function"==typeof t[a]&&t[a].apply(t,e)}),o}})}))}function a(t,e){var a=t._chartjs;if(a){var i=a.listeners,o=i.indexOf(e);o!==-1&&i.splice(o,1),i.length>0||(n.forEach(function(e){delete t[e]}),delete t._chartjs)}}var i=t.helpers,n=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var a=this;a.chart=t,a.index=e,a.linkScales(),a.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),a=t.getDataset();null===e.xAxisID&&(e.xAxisID=a.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=a.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&a(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,a=e.dataElementType;return a&&new a({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,a=this,i=a.getMeta(),n=a.getDataset().data||[],o=i.data;for(t=0,e=n.length;t<e;++t)o[t]=o[t]||a.createMetaData(t);i.dataset=i.dataset||a.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t=this,i=t.getDataset(),n=i.data||(i.data=[]);t._data!==n&&(t._data&&a(t._data,t),e(n,t),t._data=n),t.resyncElements()},update:i.noop,draw:function(t){var e,a,i=t||1,n=this.getMeta().data;for(e=0,a=n.length;e<a;++e)n[e].transition(i).draw()},removeHoverStyle:function(t,e){var a=this.chart.data.datasets[t._datasetIndex],n=t._index,o=t.custom||{},r=i.getValueAtIndexOrDefault,s=t._model;s.backgroundColor=o.backgroundColor?o.backgroundColor:r(a.backgroundColor,n,e.backgroundColor),s.borderColor=o.borderColor?o.borderColor:r(a.borderColor,n,e.borderColor),s.borderWidth=o.borderWidth?o.borderWidth:r(a.borderWidth,n,e.borderWidth)},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],a=t._index,n=t.custom||{},o=i.getValueAtIndexOrDefault,r=i.getHoverColor,s=t._model;s.backgroundColor=n.hoverBackgroundColor?n.hoverBackgroundColor:o(e.hoverBackgroundColor,a,r(s.backgroundColor)),s.borderColor=n.hoverBorderColor?n.hoverBorderColor:o(e.hoverBorderColor,a,r(s.borderColor)),s.borderWidth=n.hoverBorderWidth?n.hoverBorderWidth:o(e.hoverBorderWidth,a,s.borderWidth)},resyncElements:function(){var t=this,e=t.getMeta(),a=t.getDataset().data,i=e.data.length,n=a.length;n<i?e.data.splice(n,i-n):n>i&&t.insertElements(i,n-i)},insertElements:function(t,e){for(var a=0;a<e;++a)this.addElementAndReset(t+a)},onDataPush:function(){this.insertElements(this.getDataset().data.length-1,arguments.length)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),t.DatasetController.extend=i.inherits}},{}],25:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.elements={},t.Element=function(t){e.extend(this,t),this.initialize.apply(this,arguments)},e.extend(t.Element.prototype,{initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=e.clone(t._model)),t._start=e.clone(t._view),t},transition:function(t){var a=this;return a._view||(a._view=e.clone(a._model)),1===t?(a._view=a._model,a._start=null,a):(a._start||a.pivot(),e.each(a._model,function(i,n){if("_"===n[0]);else if(a._view.hasOwnProperty(n))if(i===a._view[n]);else if("string"==typeof i)try{var o=e.color(a._model[n]).mix(e.color(a._start[n]),t);a._view[n]=o.rgbString()}catch(t){a._view[n]=i}else if("number"==typeof i){var r=void 0!==a._start[n]&&isNaN(a._start[n])===!1?a._start[n]:0;a._view[n]=(a._model[n]-r)*t+r}else a._view[n]=i;else"number"!=typeof i||isNaN(a._view[n])?a._view[n]=i:a._view[n]=i*t},a),a)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return e.isNumber(this._model.x)&&e.isNumber(this._model.y)}}),t.Element.extend=e.inherits}},{}],26:[function(t,e,a){"use strict";var i=t(3);e.exports=function(t){function e(t,e,a){var i;return"string"==typeof t?(i=parseInt(t,10),t.indexOf("%")!==-1&&(i=i/100*e.parentNode[a])):i=t,i}function a(t){return void 0!==t&&null!==t&&"none"!==t}function n(t,i,n){var o=document.defaultView,r=t.parentNode,s=o.getComputedStyle(t)[i],l=o.getComputedStyle(r)[i],u=a(s),d=a(l),c=Number.POSITIVE_INFINITY;return u||d?Math.min(u?e(s,t,n):c,d?e(l,r,n):c):"none"}var o=t.helpers={};o.each=function(t,e,a,i){var n,r;if(o.isArray(t))if(r=t.length,i)for(n=r-1;n>=0;n--)e.call(a,t[n],n);else for(n=0;n<r;n++)e.call(a,t[n],n);else if("object"==typeof t){var s=Object.keys(t);for(r=s.length,n=0;n<r;n++)e.call(a,t[s[n]],s[n])}},o.clone=function(t){var e={};return o.each(t,function(t,a){o.isArray(t)?e[a]=t.slice(0):"object"==typeof t&&null!==t?e[a]=o.clone(t):e[a]=t}),e},o.extend=function(t){for(var e=function(e,a){t[a]=e},a=1,i=arguments.length;a<i;a++)o.each(arguments[a],e);return t},o.configMerge=function(e){var a=o.clone(e);return o.each(Array.prototype.slice.call(arguments,1),function(e){o.each(e,function(e,i){var n=a.hasOwnProperty(i),r=n?a[i]:{};"scales"===i?a[i]=o.scaleMerge(r,e):"scale"===i?a[i]=o.configMerge(r,t.scaleService.getScaleDefaults(e.type),e):!n||"object"!=typeof r||o.isArray(r)||null===r||"object"!=typeof e||o.isArray(e)?a[i]=e:a[i]=o.configMerge(r,e)})}),a},o.scaleMerge=function(e,a){var i=o.clone(e);return o.each(a,function(e,a){"xAxes"===a||"yAxes"===a?i.hasOwnProperty(a)?o.each(e,function(e,n){var r=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear"),s=t.scaleService.getScaleDefaults(r);n>=i[a].length||!i[a][n].type?i[a].push(o.configMerge(s,e)):e.type&&e.type!==i[a][n].type?i[a][n]=o.configMerge(i[a][n],s,e):i[a][n]=o.configMerge(i[a][n],e)}):(i[a]=[],o.each(e,function(e){var n=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear");i[a].push(o.configMerge(t.scaleService.getScaleDefaults(n),e))})):i.hasOwnProperty(a)&&"object"==typeof i[a]&&null!==i[a]&&"object"==typeof e?i[a]=o.configMerge(i[a],e):i[a]=e}),i},o.getValueAtIndexOrDefault=function(t,e,a){return void 0===t||null===t?a:o.isArray(t)?e<t.length?t[e]:a:t},o.getValueOrDefault=function(t,e){return void 0===t?e:t},o.indexOf=Array.prototype.indexOf?function(t,e){return t.indexOf(e)}:function(t,e){for(var a=0,i=t.length;a<i;++a)if(t[a]===e)return a;return-1},o.where=function(t,e){if(o.isArray(t)&&Array.prototype.filter)return t.filter(e);var a=[];return o.each(t,function(t){e(t)&&a.push(t)}),a},o.findIndex=Array.prototype.findIndex?function(t,e,a){return t.findIndex(e,a)}:function(t,e,a){a=void 0===a?t:a;for(var i=0,n=t.length;i<n;++i)if(e.call(a,t[i],i,t))return i;return-1},o.findNextWhere=function(t,e,a){void 0!==a&&null!==a||(a=-1);for(var i=a+1;i<t.length;i++){var n=t[i];if(e(n))return n}},o.findPreviousWhere=function(t,e,a){void 0!==a&&null!==a||(a=t.length);for(var i=a-1;i>=0;i--){var n=t[i];if(e(n))return n}},o.inherits=function(t){var e=this,a=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=a};return i.prototype=e.prototype,a.prototype=new i,a.extend=o.inherits,t&&o.extend(a.prototype,t),a.__super__=e.prototype,a},o.noop=function(){},o.uid=function(){var t=0;return function(){return t++}}(),o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,a){return Math.abs(t-e)<a},o.almostWhole=function(t,e){var a=Math.round(t);return a-e<t&&a+e>t},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var a=e.x-t.x,i=e.y-t.y,n=Math.sqrt(a*a+i*i),o=Math.atan2(i,a);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:n}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2===0?0:.5},o.splineCurve=function(t,e,a,i){var n=t.skip?e:t,o=e,r=a.skip?e:a,s=Math.sqrt(Math.pow(o.x-n.x,2)+Math.pow(o.y-n.y,2)),l=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=s/(s+l),d=l/(s+l);u=isNaN(u)?0:u,d=isNaN(d)?0:d;var c=i*u,h=i*d;return{previous:{x:o.x-c*(r.x-n.x),y:o.y-c*(r.y-n.y)},next:{x:o.x+h*(r.x-n.x),y:o.y+h*(r.y-n.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,a,i,n,r=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),s=r.length;for(e=0;e<s;++e)if(i=r[e],!i.model.skip){if(a=e>0?r[e-1]:null,n=e<s-1?r[e+1]:null,n&&!n.model.skip){var l=n.model.x-i.model.x;i.deltaK=0!==l?(n.model.y-i.model.y)/l:0}!a||a.model.skip?i.mK=i.deltaK:!n||n.model.skip?i.mK=a.deltaK:this.sign(a.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(a.deltaK+i.deltaK)/2}var u,d,c,h;for(e=0;e<s-1;++e)i=r[e],n=r[e+1],i.model.skip||n.model.skip||(o.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=n.mK=0:(u=i.mK/i.deltaK,d=n.mK/i.deltaK,h=Math.pow(u,2)+Math.pow(d,2),h<=9||(c=3/Math.sqrt(h),i.mK=u*c*i.deltaK,n.mK=d*c*i.deltaK)));var f;for(e=0;e<s;++e)i=r[e],i.model.skip||(a=e>0?r[e-1]:null,n=e<s-1?r[e+1]:null,a&&!a.model.skip&&(f=(i.model.x-a.model.x)/3,i.model.controlPointPreviousX=i.model.x-f,i.model.controlPointPreviousY=i.model.y-f*i.mK),n&&!n.model.skip&&(f=(n.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+f,i.model.controlPointNextY=i.model.y+f*i.mK))},o.nextItem=function(t,e,a){return a?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,a){return a?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var a,i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return a=e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10,a*Math.pow(10,i)};var r=o.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),-(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)))},easeOutElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((1*t-e)*(2*Math.PI)/a)+1)},easeInOutElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:2===(t/=.5)?1:(a||(a=1*(.3*1.5)),i<Math.abs(1)?(i=1,e=a/4):e=a/(2*Math.PI)*Math.asin(1/i),t<1?-.5*(i*Math.pow(2,10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)):i*Math.pow(2,-10*(t-=1))*Math.sin((1*t-e)*(2*Math.PI)/a)*.5+1)},easeInBack:function(t){var e=1.70158;return 1*(t/=1)*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return 1*((t=t/1-1)*t*((e+1)*t+e)+1)},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?.5*(t*t*(((e*=1.525)+1)*t-e)):.5*((t-=2)*t*(((e*=1.525)+1)*t+e)+2)},easeInBounce:function(t){return 1-r.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?1*(7.5625*t*t):t<2/2.75?1*(7.5625*(t-=1.5/2.75)*t+.75):t<2.5/2.75?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return t<.5?.5*r.easeInBounce(2*t):.5*r.easeOutBounce(2*t-1)+.5}};o.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),o.getRelativePosition=function(t,e){var a,i,n=t.originalEvent||t,r=t.currentTarget||t.srcElement,s=r.getBoundingClientRect(),l=n.touches;l&&l.length>0?(a=l[0].clientX,i=l[0].clientY):(a=n.clientX,i=n.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return a=Math.round((a-s.left-u)/f*r.width/e.currentDevicePixelRatio),i=Math.round((i-s.top-d)/g*r.height/e.currentDevicePixelRatio),{x:a,y:i}},o.addEvent=function(t,e,a){t.addEventListener?t.addEventListener(e,a):t.attachEvent?t.attachEvent("on"+e,a):t["on"+e]=a},o.removeEvent=function(t,e,a){t.removeEventListener?t.removeEventListener(e,a,!1):t.detachEvent?t.detachEvent("on"+e,a):t["on"+e]=o.noop},o.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-left"),10),i=parseInt(o.getStyle(e,"padding-right"),10),n=e.clientWidth-a-i,r=o.getConstraintWidth(t);return isNaN(r)?n:Math.min(n,r)},o.getMaximumHeight=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-top"),10),i=parseInt(o.getStyle(e,"padding-bottom"),10),n=e.clientHeight-a-i,r=o.getConstraintHeight(t);return isNaN(r)?n:Math.min(n,r)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t){var e=t.currentDevicePixelRatio=window.devicePixelRatio||1;if(1!==e){var a=t.canvas,i=t.height,n=t.width;a.height=i*e,a.width=n*e,t.ctx.scale(e,e),a.style.height=i+"px",a.style.width=n+"px"}},o.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},o.fontString=function(t,e,a){return e+" "+t+"px "+a},o.longestText=function(t,e,a,i){i=i||{};var n=i.data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(n=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var s=0;o.each(a,function(e){void 0!==e&&null!==e&&o.isArray(e)!==!0?s=o.measureText(t,n,r,s,e):o.isArray(e)&&o.each(e,function(e){void 0===e||null===e||o.isArray(e)||(s=o.measureText(t,n,r,s,e))})});var l=r.length/2;if(l>a.length){for(var u=0;u<l;u++)delete n[r[u]];r.splice(0,l)}return s},o.measureText=function(t,e,a,i,n){var o=e[n];return o||(o=e[n]=t.measureText(n).width,a.push(n)),o>i&&(i=o),i},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.drawRoundedRectangle=function(t,e,a,i,n,o){t.beginPath(),t.moveTo(e+o,a),t.lineTo(e+i-o,a),t.quadraticCurveTo(e+i,a,e+i,a+o),t.lineTo(e+i,a+n-o),t.quadraticCurveTo(e+i,a+n,e+i-o,a+n),t.lineTo(e+o,a+n),t.quadraticCurveTo(e,a+n,e,a+n-o),t.lineTo(e,a+o),t.quadraticCurveTo(e,a,e+o,a),t.closePath()},o.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.error("Color.js not found!"),e)},o.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},o.arrayEquals=function(t,e){var a,i,n,r;if(!t||!e||t.length!==e.length)return!1;for(a=0,i=t.length;a<i;++a)if(n=t[a],r=e[a],n instanceof Array&&r instanceof Array){if(!o.arrayEquals(n,r))return!1}else if(n!==r)return!1;return!0},o.callCallback=function(t,e,a){t&&"function"==typeof t.call&&t.apply(a,e)},o.getHoverColor=function(t){return t instanceof CanvasPattern?t:o.color(t).saturate(.5).darken(.1).rgbString()}}},{3:3}],27:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return t.native?{x:t.x,y:t.y}:r.getRelativePosition(t,e)}function a(t,e){var a,i,n,o,r,s=t.data.datasets;for(i=0,o=s.length;i<o;++i)if(t.isDatasetVisible(i))for(a=t.getDatasetMeta(i),n=0,r=a.data.length;n<r;++n){var l=a.data[n];l._view.skip||e(l)}}function i(t,e){var i=[];return a(t,function(t){t.inRange(e.x,e.y)&&i.push(t)}),i}function n(t,e,i,n){var o=Number.POSITIVE_INFINITY,s=[];return n||(n=r.distanceBetweenPoints),a(t,function(t){if(!i||t.inRange(e.x,e.y)){var a=t.getCenterPoint(),r=n(e,a);r<o?(s=[t],o=r):r===o&&s.push(t)}}),s}function o(t,a,o){var r=e(a,t.chart),s=function(t,e){return Math.abs(t.x-e.x)},l=o.intersect?i(t,r):n(t,r,!1,s),u=[];return l.length?(t.data.datasets.forEach(function(e,a){if(t.isDatasetVisible(a)){var i=t.getDatasetMeta(a),n=i.data[l[0]._index];n&&!n._view.skip&&u.push(n)}}),u):[]}var r=t.helpers;t.Interaction={modes:{single:function(t,i){var n=e(i,t.chart),o=[];return a(t,function(t){if(t.inRange(n.x,n.y))return o.push(t),o}),o.slice(0,1)},label:o,index:o,dataset:function(t,a,o){var r=e(a,t.chart),s=o.intersect?i(t,r):n(t,r,!1);return s.length>0&&(s=t.getDatasetMeta(s[0]._datasetIndex).data),s},"x-axis":function(t,e){return o(t,e,!0)},point:function(t,a){var n=e(a,t.chart);return i(t,n)},nearest:function(t,a,i){var o=e(a,t.chart),r=n(t,o,i.intersect);return r.length>1&&r.sort(function(t,e){var a=t.getArea(),i=e.getArea(),n=a-i;return 0===n&&(n=t._datasetIndex-e._datasetIndex),n}),r.slice(0,1)},x:function(t,i,n){var o=e(i,t.chart),r=[],s=!1;return a(t,function(t){t.inXRange(o.x)&&r.push(t),t.inRange(o.x,o.y)&&(s=!0)}),n.intersect&&!s&&(r=[]),r},y:function(t,i,n){var o=e(i,t.chart),r=[],s=!1;return a(t,function(t){t.inYRange(o.y)&&r.push(t),t.inRange(o.x,o.y)&&(s=!0)}),n.intersect&&!s&&(r=[]),r}}}}},{}],28:[function(t,e,a){"use strict";e.exports=function(){var t=function(e,a){return this.controller=new t.Controller(e,a,this),this.controller};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('<ul class="'+t.id+'-legend">');for(var a=0;a<t.data.datasets.length;a++)e.push('<li><span style="background-color:'+t.data.datasets[a].backgroundColor+'"></span>'),t.data.datasets[a].label&&e.push(t.data.datasets[a].label),e.push("</li>");return e.push("</ul>"),e.join("")}}},t.Chart=t,t}},{}],29:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,a,i){function n(t){var e,a=t.isHorizontal();a?(e=t.update(t.options.fullWidth?x:C,w),I-=e.height):(e=t.update(M,S),C-=e.width),D.push({horizontal:a,minSize:e,box:t})}function o(t){var a=e.findNextWhere(D,function(e){return e.box===t});if(a)if(t.isHorizontal()){var i={left:Math.max(F,A),right:Math.max(V,T),top:0,bottom:0};t.update(t.options.fullWidth?x:C,y/2,i)}else t.update(a.minSize.width,I)}function r(t){var a=e.findNextWhere(D,function(e){return e.box===t}),i={left:0,right:0,top:R,bottom:O};a&&t.update(a.minSize.width,I,i)}function s(t){t.isHorizontal()?(t.left=t.options.fullWidth?d:F,t.right=t.options.fullWidth?a-c:F+C,t.top=E,t.bottom=E+t.height,E=t.bottom):(t.left=N,t.right=N+t.width,t.top=R,t.bottom=R+I,N=t.right)}if(t){var l=t.options.layout,u=l?l.padding:null,d=0,c=0,h=0,f=0;isNaN(u)?(d=u.left||0,c=u.right||0,h=u.top||0,f=u.bottom||0):(d=u,c=u,h=u,f=u);var g=e.where(t.boxes,function(t){return"left"===t.options.position}),p=e.where(t.boxes,function(t){return"right"===t.options.position}),m=e.where(t.boxes,function(t){return"top"===t.options.position}),v=e.where(t.boxes,function(t){return"bottom"===t.options.position}),b=e.where(t.boxes,function(t){return"chartArea"===t.options.position});m.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),v.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var x=a-d-c,y=i-h-f,k=x/2,S=y/2,M=(a-k)/(g.length+p.length),w=(i-S)/(m.length+v.length),C=x,I=y,D=[];e.each(g.concat(p,m,v),n);var A=0,T=0,P=0,_=0;e.each(m.concat(v),function(t){if(t.getPadding){var e=t.getPadding();A=Math.max(A,e.left),T=Math.max(T,e.right)}}),e.each(g.concat(p),function(t){if(t.getPadding){var e=t.getPadding();P=Math.max(P,e.top),_=Math.max(_,e.bottom)}});var F=d,V=c,R=h,O=f;e.each(g.concat(p),o),e.each(g,function(t){F+=t.width}),e.each(p,function(t){V+=t.width}),e.each(m.concat(v),o),e.each(m,function(t){R+=t.height}),e.each(v,function(t){O+=t.height}),e.each(g.concat(p),r),F=d,V=c,R=h,O=f,e.each(g,function(t){F+=t.width}),e.each(p,function(t){V+=t.width}),e.each(m,function(t){R+=t.height}),e.each(v,function(t){O+=t.height});var L=Math.max(A-F,0);F+=L,V+=Math.max(T-V,0);var B=Math.max(P-R,0);R+=B,O+=Math.max(_-O,0);var z=i-R-O,W=a-F-V;W===C&&z===I||(e.each(g,function(t){t.height=z}),e.each(p,function(t){t.height=z}),e.each(m,function(t){t.options.fullWidth||(t.width=W)}),e.each(v,function(t){t.options.fullWidth||(t.width=W)}),I=z,C=W);var N=d+L,E=h+B;e.each(g.concat(m),s),N+=C,E+=I,e.each(p,s),e.each(v,s),t.chartArea={left:F,top:R,right:F+C,bottom:R+I},e.each(b,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(C,I)})}}}}},{}],30:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}function a(e,a){var i=new t.Legend({ctx:e.chart.ctx,options:a,chart:e});e.legend=i,t.layoutService.addBox(e,i)}var i=t.helpers,n=i.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var a=e.datasetIndex,i=this.chart,n=i.getDatasetMeta(a);n.hidden=null===n.hidden?!i.data.datasets[a].hidden:null,i.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return i.isArray(e.datasets)?e.datasets.map(function(e,a){return{text:e.label,fillStyle:i.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(a),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:a}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){i.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:n,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:n,beforeSetDimensions:n,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:n,beforeBuildLabels:n,buildLabels:function(){var t=this,e=t.options.labels,a=e.generateLabels.call(t,t.chart);e.filter&&(a=a.filter(function(a){return e.filter(a,t.chart.data)})),t.options.reverse&&a.reverse(),t.legendItems=a},afterBuildLabels:n,beforeFit:n,fit:function(){var a=this,n=a.options,o=n.labels,r=n.display,s=a.ctx,l=t.defaults.global,u=i.getValueOrDefault,d=u(o.fontSize,l.defaultFontSize),c=u(o.fontStyle,l.defaultFontStyle),h=u(o.fontFamily,l.defaultFontFamily),f=i.fontString(d,c,h),g=a.legendHitBoxes=[],p=a.minSize,m=a.isHorizontal();if(m?(p.width=a.maxWidth,p.height=r?10:0):(p.width=r?10:0,p.height=a.maxHeight),r)if(s.font=f,m){var v=a.lineWidths=[0],b=a.legendItems.length?d+o.padding:0;s.textAlign="left",s.textBaseline="top",i.each(a.legendItems,function(t,i){var n=e(o,d),r=n+d/2+s.measureText(t.text).width;v[v.length-1]+r+o.padding>=a.width&&(b+=d+o.padding,v[v.length]=a.left),g[i]={left:0,top:0,width:r,height:d},v[v.length-1]+=r+o.padding}),p.height+=b}else{var x=o.padding,y=a.columnWidths=[],k=o.padding,S=0,M=0,w=d+x;i.each(a.legendItems,function(t,a){var i=e(o,d),n=i+d/2+s.measureText(t.text).width;M+w>p.height&&(k+=S+o.padding,y.push(S),S=0,M=0),S=Math.max(S,n),M+=w,g[a]={left:0,top:0,width:n,height:d}}),k+=S,y.push(S),p.width+=k}a.width=p.width,a.height=p.height},afterFit:n,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var a=this,n=a.options,o=n.labels,r=t.defaults.global,s=r.elements.line,l=a.width,u=a.lineWidths;if(n.display){var d,c=a.ctx,h=i.getValueOrDefault,f=h(o.fontColor,r.defaultFontColor),g=h(o.fontSize,r.defaultFontSize),p=h(o.fontStyle,r.defaultFontStyle),m=h(o.fontFamily,r.defaultFontFamily),v=i.fontString(g,p,m);c.textAlign="left",c.textBaseline="top",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=e(o,g),x=a.legendHitBoxes,y=function(e,a,i){if(!(isNaN(b)||b<=0)){c.save(),c.fillStyle=h(i.fillStyle,r.defaultColor),c.lineCap=h(i.lineCap,s.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,s.borderDashOffset),c.lineJoin=h(i.lineJoin,s.borderJoinStyle),c.lineWidth=h(i.lineWidth,s.borderWidth),c.strokeStyle=h(i.strokeStyle,r.defaultColor);var o=0===h(i.lineWidth,s.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,s.borderDash)),n.labels&&n.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=e+u,f=a+u;t.canvasHelpers.drawPoint(c,i.pointStyle,l,d,f)}else o||c.strokeRect(e,a,b,g),c.fillRect(e,a,b,g);c.restore()}},k=function(t,e,a,i){c.fillText(a.text,b+g/2+t,e),a.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(b+g/2+t,e+g/2),c.lineTo(b+g/2+t+i,e+g/2),c.stroke())},S=a.isHorizontal();d=S?{x:a.left+(l-u[0])/2,y:a.top+o.padding,line:0}:{x:a.left+o.padding,y:a.top+o.padding,line:0};var M=g+o.padding;i.each(a.legendItems,function(t,e){var i=c.measureText(t.text).width,n=b+g/2+i,r=d.x,s=d.y;S?r+n>=l&&(s=d.y+=M,d.line++,r=d.x=a.left+(l-u[d.line])/2):s+M>a.bottom&&(r=d.x=r+a.columnWidths[d.line]+o.padding,s=d.y=a.top+o.padding,d.line++),y(r,s,t),x[e].left=r,x[e].top=s,k(r,s,t,i),S?d.x+=n+o.padding:d.y+=M})}},handleEvent:function(t){var e=this,a=e.options,i="mouseup"===t.type?"click":t.type,n=!1;if("mousemove"===i){if(!a.onHover)return}else{if("click"!==i)return;if(!a.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var s=e.legendHitBoxes,l=0;l<s.length;++l){var u=s[l];if(o>=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===i){a.onClick.call(e,t.native,e.legendItems[l]),n=!0;break}if("mousemove"===i){a.onHover.call(e,t.native,e.legendItems[l]),n=!0;break}}}return n}}),t.plugins.register({beforeInit:function(t){var e=t.options.legend;e&&a(t,e)},beforeUpdate:function(e){var n=e.options.legend;n?(n=i.configMerge(t.defaults.global.legend,n),e.legend?e.legend.options=n:a(e,n)):(t.layoutService.removeBox(e,e.legend),delete e.legend)},afterEvent:function(t,e){var a=t.legend;a&&a.handleEvent(e)}})}},{}],31:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.plugins={},t.plugins={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){e.indexOf(t)===-1&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var a=e.indexOf(t);a!==-1&&e.splice(a,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length;
13
- },getAll:function(){return this._plugins},notify:function(t,e,a){var i,n,o,r,s,l=this.descriptors(t),u=l.length;for(i=0;i<u;++i)if(n=l[i],o=n.plugin,s=o[e],"function"==typeof s&&(r=[t].concat(a||[]),r.push(n.options),s.apply(o,r)===!1))return!1;return!0},descriptors:function(a){var i=a._plugins||(a._plugins={});if(i.id===this._cacheId)return i.descriptors;var n=[],o=[],r=a&&a.config||{},s=t.defaults.global.plugins,l=r.options&&r.options.plugins||{};return this._plugins.concat(r.plugins||[]).forEach(function(t){var a=n.indexOf(t);if(a===-1){var i=t.id,r=l[i];r!==!1&&(r===!0&&(r=e.clone(s[i])),n.push(t),o.push({plugin:t,options:r||{}}))}}),i.descriptors=o,i.id=this._cacheId,o}},t.pluginService=t.plugins,t.PluginBase=e.inherits({})}},{}],32:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e,a){return i.isArray(e)?i.longestText(t,a,e):t.measureText(e).width}function a(e){var a=i.getValueOrDefault,n=t.defaults.global,o=a(e.fontSize,n.defaultFontSize),r=a(e.fontStyle,n.defaultFontStyle),s=a(e.fontFamily,n.defaultFontFamily);return{size:o,style:r,family:s,font:i.fontString(o,r,s)}}var i=t.helpers;t.defaults.scale={display:!0,position:"left",gridLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{labelString:"",display:!1},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:t.Ticks.formatters.values}},t.Scale=t.Element.extend({getPadding:function(){var t=this;return{left:t.paddingLeft||0,top:t.paddingTop||0,right:t.paddingRight||0,bottom:t.paddingBottom||0}},beforeUpdate:function(){i.callCallback(this.options.beforeUpdate,[this])},update:function(t,e,a){var n=this;return n.beforeUpdate(),n.maxWidth=t,n.maxHeight=e,n.margins=i.extend({left:0,right:0,top:0,bottom:0},a),n.longestTextCache=n.longestTextCache||{},n.beforeSetDimensions(),n.setDimensions(),n.afterSetDimensions(),n.beforeDataLimits(),n.determineDataLimits(),n.afterDataLimits(),n.beforeBuildTicks(),n.buildTicks(),n.afterBuildTicks(),n.beforeTickToLabelConversion(),n.convertTicksToLabels(),n.afterTickToLabelConversion(),n.beforeCalculateTickRotation(),n.calculateTickRotation(),n.afterCalculateTickRotation(),n.beforeFit(),n.fit(),n.afterFit(),n.afterUpdate(),n.minSize},afterUpdate:function(){i.callCallback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){i.callCallback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){i.callCallback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){i.callCallback(this.options.beforeDataLimits,[this])},determineDataLimits:i.noop,afterDataLimits:function(){i.callCallback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){i.callCallback(this.options.beforeBuildTicks,[this])},buildTicks:i.noop,afterBuildTicks:function(){i.callCallback(this.options.afterBuildTicks,[this])},beforeTickToLabelConversion:function(){i.callCallback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this,e=t.options.ticks;t.ticks=t.ticks.map(e.userCallback||e.callback)},afterTickToLabelConversion:function(){i.callCallback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){i.callCallback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t=this,e=t.ctx,n=t.options.ticks,o=a(n);e.font=o.font;var r=n.minRotation||0;if(t.options.display&&t.isHorizontal())for(var s,l,u=i.longestText(e,o.font,t.ticks,t.longestTextCache),d=u,c=t.getPixelForTick(1)-t.getPixelForTick(0)-6;d>c&&r<n.maxRotation;){var h=i.toRadians(r);if(s=Math.cos(h),l=Math.sin(h),l*u>t.maxHeight){r--;break}r++,d=s*u}t.labelRotation=r},afterCalculateTickRotation:function(){i.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){i.callCallback(this.options.beforeFit,[this])},fit:function(){var t=this,n=t.minSize={width:0,height:0},o=t.options,r=o.ticks,s=o.scaleLabel,l=o.gridLines,u=o.display,d=t.isHorizontal(),c=a(r),h=1.5*a(s).size,f=o.gridLines.tickMarkLength;if(d?n.width=t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:n.width=u&&l.drawTicks?f:0,d?n.height=u&&l.drawTicks?f:0:n.height=t.maxHeight,s.display&&u&&(d?n.height+=h:n.width+=h),r.display&&u){var g=i.longestText(t.ctx,c.font,t.ticks,t.longestTextCache),p=i.numberOfLabelLines(t.ticks),m=.5*c.size;if(d){t.longestLabelWidth=g;var v=i.toRadians(t.labelRotation),b=Math.cos(v),x=Math.sin(v),y=x*g+c.size*p+m*p;n.height=Math.min(t.maxHeight,n.height+y),t.ctx.font=c.font;var k=t.ticks[0],S=e(t.ctx,k,c.font),M=t.ticks[t.ticks.length-1],w=e(t.ctx,M,c.font);0!==t.labelRotation?(t.paddingLeft="bottom"===o.position?b*S+3:b*m+3,t.paddingRight="bottom"===o.position?b*m+3:b*w+3):(t.paddingLeft=S/2+3,t.paddingRight=w/2+3)}else r.mirror?g=0:g+=t.options.ticks.padding,n.width+=g,t.paddingTop=c.size/2,t.paddingBottom=c.size/2}t.handleMargins(),t.width=n.width,t.height=n.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){i.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"!=typeof t||isFinite(t)?"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t:NaN},getLabelForIndex:i.noop,getPixelForValue:i.noop,getValueForPixel:i.noop,getPixelForTick:function(t,e){var a=this;if(a.isHorizontal()){var i=a.width-(a.paddingLeft+a.paddingRight),n=i/Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),o=n*t+a.paddingLeft;e&&(o+=n/2);var r=a.left+Math.round(o);return r+=a.isFullWidth()?a.margins.left:0}var s=a.height-(a.paddingTop+a.paddingBottom);return a.top+t*(s/(a.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var a=e.width-(e.paddingLeft+e.paddingRight),i=a*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this,e=t.min,a=t.max;return t.beginAtZero?0:e<0&&a<0?a:e>0&&a>0?e:0},draw:function(e){var n=this,o=n.options;if(o.display){var r,s,l=n.ctx,u=t.defaults.global,d=o.ticks,c=o.gridLines,h=o.scaleLabel,f=0!==n.labelRotation,g=d.autoSkip,p=n.isHorizontal();d.maxTicksLimit&&(s=d.maxTicksLimit);var m=i.getValueOrDefault(d.fontColor,u.defaultFontColor),v=a(d),b=c.drawTicks?c.tickMarkLength:0,x=i.getValueOrDefault(c.borderDash,u.borderDash),y=i.getValueOrDefault(c.borderDashOffset,u.borderDashOffset),k=i.getValueOrDefault(h.fontColor,u.defaultFontColor),S=a(h),M=i.toRadians(n.labelRotation),w=Math.cos(M),C=n.longestLabelWidth*w;l.fillStyle=m;var I=[];if(p){if(r=!1,f&&(C/=2),(C+d.autoSkipPadding)*n.ticks.length>n.width-(n.paddingLeft+n.paddingRight)&&(r=1+Math.floor((C+d.autoSkipPadding)*n.ticks.length/(n.width-(n.paddingLeft+n.paddingRight)))),s&&n.ticks.length>s)for(;!r||n.ticks.length/(r||1)>s;)r||(r=1),r+=1;g||(r=!1)}var D="right"===o.position?n.left:n.right-b,A="right"===o.position?n.left+b:n.right,T="bottom"===o.position?n.top:n.bottom-b,P="bottom"===o.position?n.top+b:n.bottom;if(i.each(n.ticks,function(t,a){if(void 0!==t&&null!==t){var s=n.ticks.length===a+1,l=r>1&&a%r>0||a%r===0&&a+r>=n.ticks.length;if((!l||s)&&void 0!==t&&null!==t){var u,h;a===("undefined"!=typeof n.zeroLineIndex?n.zeroLineIndex:0)?(u=c.zeroLineWidth,h=c.zeroLineColor):(u=i.getValueAtIndexOrDefault(c.lineWidth,a),h=i.getValueAtIndexOrDefault(c.color,a));var g,m,v,k,S,w,C,_,F,V,R="middle",O="middle";if(p){"bottom"===o.position?(O=f?"middle":"top",R=f?"right":"center",V=n.top+b):(O=f?"middle":"bottom",R=f?"left":"center",V=n.bottom-b);var L=n.getPixelForTick(a)+i.aliasPixel(u);F=n.getPixelForTick(a,c.offsetGridLines)+d.labelOffset,g=v=S=C=L,m=T,k=P,w=e.top,_=e.bottom}else{var B,z="left"===o.position,W=d.padding;d.mirror?(R=z?"left":"right",B=W):(R=z?"right":"left",B=b+W),F=z?n.right-B:n.left+B;var N=n.getPixelForTick(a);N+=i.aliasPixel(u),V=n.getPixelForTick(a,c.offsetGridLines),g=D,v=A,S=e.left,C=e.right,m=k=w=_=N}I.push({tx1:g,ty1:m,tx2:v,ty2:k,x1:S,y1:w,x2:C,y2:_,labelX:F,labelY:V,glWidth:u,glColor:h,glBorderDash:x,glBorderDashOffset:y,rotation:-1*M,label:t,textBaseline:O,textAlign:R})}}}),i.each(I,function(t){if(c.display&&(l.save(),l.lineWidth=t.glWidth,l.strokeStyle=t.glColor,l.setLineDash&&(l.setLineDash(t.glBorderDash),l.lineDashOffset=t.glBorderDashOffset),l.beginPath(),c.drawTicks&&(l.moveTo(t.tx1,t.ty1),l.lineTo(t.tx2,t.ty2)),c.drawOnChartArea&&(l.moveTo(t.x1,t.y1),l.lineTo(t.x2,t.y2)),l.stroke(),l.restore()),d.display){l.save(),l.translate(t.labelX,t.labelY),l.rotate(t.rotation),l.font=v.font,l.textBaseline=t.textBaseline,l.textAlign=t.textAlign;var e=t.label;if(i.isArray(e))for(var a=0,n=0;a<e.length;++a)l.fillText(""+e[a],0,n),n+=1.5*v.size;else l.fillText(e,0,0);l.restore()}}),h.display){var _,F,V=0;if(p)_=n.left+(n.right-n.left)/2,F="bottom"===o.position?n.bottom-S.size/2:n.top+S.size/2;else{var R="left"===o.position;_=R?n.left+S.size/2:n.right-S.size/2,F=n.top+(n.bottom-n.top)/2,V=R?-.5*Math.PI:.5*Math.PI}l.save(),l.translate(_,F),l.rotate(V),l.textAlign="center",l.textBaseline="middle",l.fillStyle=k,l.font=S.font,l.fillText(h.labelString,0,0),l.restore()}if(c.drawBorder){l.lineWidth=i.getValueAtIndexOrDefault(c.lineWidth,0),l.strokeStyle=i.getValueAtIndexOrDefault(c.color,0);var O=n.left,L=n.right,B=n.top,z=n.bottom,W=i.aliasPixel(l.lineWidth);p?(B=z="top"===o.position?n.bottom:n.top,B+=W,z+=W):(O=L="left"===o.position?n.right:n.left,O+=W,L+=W),l.beginPath(),l.moveTo(O,B),l.lineTo(L,z),l.stroke()}}}})}},{}],33:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.scaleService={constructors:{},defaults:{},registerScaleType:function(t,a,i){this.constructors[t]=a,this.defaults[t]=e.clone(i)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(a){return this.defaults.hasOwnProperty(a)?e.scaleMerge(t.defaults.scale,this.defaults[a]):{}},updateScaleDefaults:function(t,a){var i=this.defaults;i.hasOwnProperty(t)&&(i[t]=e.extend(i[t],a))},addScalesToLayout:function(a){e.each(a.scales,function(e){t.layoutService.addBox(a,e)})}}}},{}],34:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.Ticks={generators:{linear:function(t,a){var i,n=[];if(t.stepSize&&t.stepSize>0)i=t.stepSize;else{var o=e.niceNum(a.max-a.min,!1);i=e.niceNum(o/(t.maxTicks-1),!0)}var r=Math.floor(a.min/i)*i,s=Math.ceil(a.max/i)*i;t.min&&t.max&&t.stepSize&&e.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(r=t.min,s=t.max);var l=(s-r)/i;l=e.almostEquals(l,Math.round(l),i/1e3)?Math.round(l):Math.ceil(l),n.push(void 0!==t.min?t.min:r);for(var u=1;u<l;++u)n.push(r+u*i);return n.push(void 0!==t.max?t.max:s),n},logarithmic:function(t,a){var i,n,o=[],r=e.getValueOrDefault,s=r(t.min,Math.pow(10,Math.floor(e.log10(a.min)))),l=Math.floor(e.log10(a.max)),u=Math.ceil(a.max/Math.pow(10,l));0===s?(i=Math.floor(e.log10(a.minNotZero)),n=Math.floor(a.minNotZero/Math.pow(10,i)),o.push(s),s=n*Math.pow(10,i)):(i=Math.floor(e.log10(s)),n=Math.floor(s/Math.pow(10,i)));do o.push(s),++n,10===n&&(n=1,++i),s=n*Math.pow(10,i);while(i<l||i===l&&n<u);var d=r(t.max,s);return o.push(d),o}},formatters:{values:function(t){return e.isArray(t)?t:""+t},linear:function(t,a,i){var n=i.length>3?i[2]-i[1]:i[1]-i[0];Math.abs(n)>1&&t!==Math.floor(t)&&(n=t-Math.floor(t));var o=e.log10(Math.abs(n)),r="";if(0!==t){var s=-1*Math.floor(o);s=Math.max(Math.min(s,20),0),r=t.toFixed(s)}else r="0";return r},logarithmic:function(t,a,i){var n=t/Math.pow(10,Math.floor(e.log10(t)));return 0===t?"0":1===n||2===n||5===n||0===a||a===i.length-1?t.toExponential():""}}}}},{}],35:[function(t,e,a){"use strict";e.exports=function(t){function e(e,a){var i=new t.Title({ctx:e.chart.ctx,options:a,chart:e});e.titleBlock=i,t.layoutService.addBox(e,i)}var a=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var i=a.noop;t.Title=t.Element.extend({initialize:function(t){var e=this;a.extend(e,t),e.legendHitBoxes=[]},beforeUpdate:i,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:i,beforeSetDimensions:i,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:i,beforeBuildLabels:i,buildLabels:i,afterBuildLabels:i,beforeFit:i,fit:function(){var e=this,i=a.getValueOrDefault,n=e.options,o=t.defaults.global,r=n.display,s=i(n.fontSize,o.defaultFontSize),l=e.minSize;e.isHorizontal()?(l.width=e.maxWidth,l.height=r?s+2*n.padding:0):(l.width=r?s+2*n.padding:0,l.height=e.maxHeight),e.width=l.width,e.height=l.height},afterFit:i,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var e=this,i=e.ctx,n=a.getValueOrDefault,o=e.options,r=t.defaults.global;if(o.display){var s,l,u,d=n(o.fontSize,r.defaultFontSize),c=n(o.fontStyle,r.defaultFontStyle),h=n(o.fontFamily,r.defaultFontFamily),f=a.fontString(d,c,h),g=0,p=e.top,m=e.left,v=e.bottom,b=e.right;i.fillStyle=n(o.fontColor,r.defaultFontColor),i.font=f,e.isHorizontal()?(s=m+(b-m)/2,l=p+(v-p)/2,u=b-m):(s="left"===o.position?m+d/2:b-d/2,l=p+(v-p)/2,u=v-p,g=Math.PI*("left"===o.position?-.5:.5)),i.save(),i.translate(s,l),i.rotate(g),i.textAlign="center",i.textBaseline="middle",i.fillText(o.text,0,0,u),i.restore()}}}),t.plugins.register({beforeInit:function(t){var a=t.options.title;a&&e(t,a)},beforeUpdate:function(i){var n=i.options.title;n?(n=a.configMerge(t.defaults.global.title,n),i.titleBlock?i.titleBlock.options=n:e(i,n)):(t.layoutService.removeBox(i,i.titleBlock),delete i.titleBlock)}})}},{}],36:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){var a=l.color(t);return a.alpha(e*a.alpha()).rgbaString()}function a(t,e){return e&&(l.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function i(t){var e=t._xScale,a=t._yScale||t._scale,i=t._index,n=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,n):"",yLabel:a?a.getLabelForIndex(i,n):"",index:i,datasetIndex:n,x:t._model.x,y:t._model.y}}function n(e){var a=t.defaults.global,i=l.getValueOrDefault;return{xPadding:e.xPadding,yPadding:e.yPadding,xAlign:e.xAlign,yAlign:e.yAlign,bodyFontColor:e.bodyFontColor,_bodyFontFamily:i(e.bodyFontFamily,a.defaultFontFamily),_bodyFontStyle:i(e.bodyFontStyle,a.defaultFontStyle),_bodyAlign:e.bodyAlign,bodyFontSize:i(e.bodyFontSize,a.defaultFontSize),bodySpacing:e.bodySpacing,titleFontColor:e.titleFontColor,_titleFontFamily:i(e.titleFontFamily,a.defaultFontFamily),_titleFontStyle:i(e.titleFontStyle,a.defaultFontStyle),titleFontSize:i(e.titleFontSize,a.defaultFontSize),_titleAlign:e.titleAlign,titleSpacing:e.titleSpacing,titleMarginBottom:e.titleMarginBottom,footerFontColor:e.footerFontColor,_footerFontFamily:i(e.footerFontFamily,a.defaultFontFamily),_footerFontStyle:i(e.footerFontStyle,a.defaultFontStyle),footerFontSize:i(e.footerFontSize,a.defaultFontSize),_footerAlign:e.footerAlign,footerSpacing:e.footerSpacing,footerMarginTop:e.footerMarginTop,caretSize:e.caretSize,cornerRadius:e.cornerRadius,backgroundColor:e.backgroundColor,opacity:0,legendColorBackground:e.multiKeyBackground,displayColors:e.displayColors}}function o(t,e){var a=t._chart.ctx,i=2*e.yPadding,n=0,o=e.body,r=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);r+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=s*d,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=r*c,i+=r?(r-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){n=Math.max(n,a.measureText(t).width+f)};return a.font=l.fontString(d,e._titleFontStyle,e._titleFontFamily),l.each(e.title,g),a.font=l.fontString(c,e._bodyFontStyle,e._bodyFontFamily),l.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,l.each(o,function(t){l.each(t.before,g),l.each(t.lines,g),l.each(t.after,g)}),f=0,a.font=l.fontString(h,e._footerFontStyle,e._footerFontFamily),l.each(e.footer,g),n+=2*e.xPadding,{width:n,height:i}}function r(t,e){var a=t._model,i=t._chart,n=t._chartInstance.chartArea,o="center",r="center";a.y<e.height?r="top":a.y>i.height-e.height&&(r="bottom");var s,l,u,d,c,h=(n.left+n.right)/2,f=(n.top+n.bottom)/2;"center"===r?(s=function(t){return t<=h},l=function(t){return t>h}):(s=function(t){return t<=e.width/2},l=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return t<=f?"top":"bottom"},s(a.x)?(o="left",u(a.x)&&(o="center",r=c(a.y))):l(a.x)&&(o="right",d(a.x)&&(o="center",r=c(a.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:o,yAlign:g.yAlign?g.yAlign:r}}function s(t,e,a){var i=t.x,n=t.y,o=t.caretSize,r=t.caretPadding,s=t.cornerRadius,l=a.xAlign,u=a.yAlign,d=o+r,c=s+r;return"right"===l?i-=e.width:"center"===l&&(i-=e.width/2),"top"===u?n+=d:n-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===l?i+=d:"right"===l&&(i-=d):"left"===l?i-=c:"right"===l&&(i+=c),{x:i,y:n}}var l=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,callbacks:{beforeTitle:l.noop,title:function(t,e){var a="",i=e.labels,n=i?i.length:0;if(t.length>0){var o=t[0];o.xLabel?a=o.xLabel:n>0&&o.index<n&&(a=i[o.index])}return a},afterTitle:l.noop,beforeBody:l.noop,beforeLabel:l.noop,label:function(t,e){var a=e.datasets[t.datasetIndex].label||"";return a+": "+t.yLabel},labelColor:function(t,e){var a=e.getDatasetMeta(t.datasetIndex),i=a.data[t.index],n=i._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},afterLabel:l.noop,afterBody:l.noop,beforeFooter:l.noop,footer:l.noop,afterFooter:l.noop}},t.Tooltip=t.Element.extend({initialize:function(){this._model=n(this._options)},getTitle:function(){var t=this,e=t._options,i=e.callbacks,n=i.beforeTitle.apply(t,arguments),o=i.title.apply(t,arguments),r=i.afterTitle.apply(t,arguments),s=[];return s=a(s,n),s=a(s,o),s=a(s,r)},getBeforeBody:function(){var t=this._options.callbacks.beforeBody.apply(this,arguments);return l.isArray(t)?t:void 0!==t?[t]:[]},getBody:function(t,e){var i=this,n=i._options.callbacks,o=[];return l.each(t,function(t){var r={before:[],lines:[],after:[]};a(r.before,n.beforeLabel.call(i,t,e)),a(r.lines,n.label.call(i,t,e)),a(r.after,n.afterLabel.call(i,t,e)),o.push(r)}),o},getAfterBody:function(){var t=this._options.callbacks.afterBody.apply(this,arguments);return l.isArray(t)?t:void 0!==t?[t]:[]},getFooter:function(){var t=this,e=t._options.callbacks,i=e.beforeFooter.apply(t,arguments),n=e.footer.apply(t,arguments),o=e.afterFooter.apply(t,arguments),r=[];return r=a(r,i),r=a(r,n),r=a(r,o)},update:function(e){var a,u,d=this,c=d._options,h=d._model,f=d._model=n(c),g=d._active,p=d._data,m=d._chartInstance,v={xAlign:h.xAlign,yAlign:h.yAlign},b={x:h.x,y:h.y},x={width:h.width,height:h.height},y={x:h.caretX,y:h.caretY};if(g.length){f.opacity=1;var k=[];y=t.Tooltip.positioners[c.position](g,d._eventPosition);var S=[];for(a=0,u=g.length;a<u;++a)S.push(i(g[a]));c.filter&&(S=S.filter(function(t){return c.filter(t,p)})),c.itemSort&&(S=S.sort(function(t,e){return c.itemSort(t,e,p)})),l.each(S,function(t){k.push(c.callbacks.labelColor.call(d,t,m))}),f.title=d.getTitle(S,p),f.beforeBody=d.getBeforeBody(S,p),f.body=d.getBody(S,p),f.afterBody=d.getAfterBody(S,p),f.footer=d.getFooter(S,p),f.x=Math.round(y.x),f.y=Math.round(y.y),f.caretPadding=l.getValueOrDefault(y.padding,2),f.labelColors=k,f.dataPoints=S,x=o(this,f),v=r(this,x),b=s(f,x,v)}else f.opacity=0;return f.xAlign=v.xAlign,f.yAlign=v.yAlign,f.x=b.x,f.y=b.y,f.width=x.width,f.height=x.height,f.caretX=y.x,f.caretY=y.y,d._model=f,e&&c.custom&&c.custom.call(d,f),d},drawCaret:function(t,a,i){var n,o,r,s,l,u,d=this._view,c=this._chart.ctx,h=d.caretSize,f=d.cornerRadius,g=d.xAlign,p=d.yAlign,m=t.x,v=t.y,b=a.width,x=a.height;"center"===p?("left"===g?(n=m,o=n-h,r=n):(n=m+b,o=n+h,r=n),l=v+x/2,s=l-h,u=l+h):("left"===g?(n=m+f,o=n+h,r=o+h):"right"===g?(n=m+b-f,o=n-h,r=o-h):(o=m+b/2,n=o-h,r=o+h),"top"===p?(s=v,l=s-h,u=s):(s=v+x,l=s+h,u=s)),c.fillStyle=e(d.backgroundColor,i),c.beginPath(),c.moveTo(n,s),c.lineTo(o,l),c.lineTo(r,u),c.closePath(),c.fill()},drawTitle:function(t,a,i,n){var o=a.title;if(o.length){i.textAlign=a._titleAlign,i.textBaseline="top";var r=a.titleFontSize,s=a.titleSpacing;i.fillStyle=e(a.titleFontColor,n),i.font=l.fontString(r,a._titleFontStyle,a._titleFontFamily);var u,d;for(u=0,d=o.length;u<d;++u)i.fillText(o[u],t.x,t.y),t.y+=r+s,u+1===o.length&&(t.y+=a.titleMarginBottom-s)}},drawBody:function(t,a,i,n){var o=a.bodyFontSize,r=a.bodySpacing,s=a.body;i.textAlign=a._bodyAlign,i.textBaseline="top";var u=e(a.bodyFontColor,n);i.fillStyle=u,i.font=l.fontString(o,a._bodyFontStyle,a._bodyFontFamily);var d=0,c=function(e){i.fillText(e,t.x+d,t.y),t.y+=o+r};l.each(a.beforeBody,c);var h=a.displayColors;d=h?o+2:0,l.each(s,function(r,s){l.each(r.before,c),l.each(r.lines,function(r){h&&(i.fillStyle=e(a.legendColorBackground,n),i.fillRect(t.x,t.y,o,o),i.strokeStyle=e(a.labelColors[s].borderColor,n),i.strokeRect(t.x,t.y,o,o),i.fillStyle=e(a.labelColors[s].backgroundColor,n),i.fillRect(t.x+1,t.y+1,o-2,o-2),i.fillStyle=u),c(r)}),l.each(r.after,c)}),d=0,l.each(a.afterBody,c),t.y-=r},drawFooter:function(t,a,i,n){var o=a.footer;o.length&&(t.y+=a.footerMarginTop,i.textAlign=a._footerAlign,i.textBaseline="top",i.fillStyle=e(a.footerFontColor,n),i.font=l.fontString(a.footerFontSize,a._footerFontStyle,a._footerFontFamily),l.each(o,function(e){i.fillText(e,t.x,t.y),t.y+=a.footerFontSize+a.footerSpacing}))},drawBackground:function(t,a,i,n,o){i.fillStyle=e(a.backgroundColor,o),l.drawRoundedRectangle(i,t.x,t.y,n.width,n.height,a.cornerRadius),i.fill()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var a={width:e.width,height:e.height},i={x:e.x,y:e.y},n=Math.abs(e.opacity<.001)?0:e.opacity;this._options.enabled&&(this.drawBackground(i,e,t,a,n),this.drawCaret(i,a,n),i.x+=e.xPadding,i.y+=e.yPadding,this.drawTitle(i,e,t,n),this.drawBody(i,e,t,n),this.drawFooter(i,e,t,n))}},handleEvent:function(t){var e=this,a=e._options,i=!1;if(e._lastActive=e._lastActive||[],"mouseout"===t.type?e._active=[]:e._active=e._chartInstance.getElementsAtEventForMode(t,a.mode,a),i=!l.arrayEquals(e._active,e._lastActive),e._lastActive=e._active,a.enabled||a.custom){e._eventPosition={x:t.x,y:t.y};var n=e._model;e.update(!0),e.pivot(),i|=n.x!==e._model.x||n.y!==e._model.y}return i}}),t.Tooltip.positioners={average:function(t){if(!t.length)return!1;var e,a,i=0,n=0,o=0;for(e=0,a=t.length;e<a;++e){var r=t[e];if(r&&r.hasValue()){var s=r.tooltipPosition();i+=s.x,n+=s.y,++o}}return{x:Math.round(i/o),y:Math.round(n/o)}},nearest:function(t,e){var a,i,n,o=e.x,r=e.y,s=Number.POSITIVE_INFINITY;for(i=0,n=t.length;i<n;++i){var u=t[i];if(u&&u.hasValue()){var d=u.getCenterPoint(),c=l.distanceBetweenPoints(e,d);c<s&&(s=c,a=u)}}if(a){var h=a.tooltipPosition();o=h.x,r=h.y}return{x:o,y:r}}}}},{}],37:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;a.elements.arc={backgroundColor:a.defaultColor,borderColor:"#fff",borderWidth:2},t.elements.Arc=t.Element.extend({inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,a){var i=this._view;if(i){for(var n=e.getAngleFromPoint(i,{x:t,y:a}),o=n.angle,r=n.distance,s=i.startAngle,l=i.endAngle;l<s;)l+=2*Math.PI;for(;o>l;)o-=2*Math.PI;for(;o<s;)o+=2*Math.PI;var u=o>=s&&o<=l,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,a=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,a=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},draw:function(){var t=this._chart.ctx,e=this._view,a=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,a,i),t.arc(e.x,e.y,e.innerRadius,i,a,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],38:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:a.defaultColor,borderWidth:3,borderColor:a.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){function t(t,e){var a=e._view;e._view.steppedLine===!0?(l.lineTo(a.x,t._view.y),l.lineTo(a.x,a.y)):0===e._view.tension?l.lineTo(a.x,a.y):l.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,a.controlPointPreviousX,a.controlPointPreviousY,a.x,a.y)}var i=this,n=i._view,o=n.spanGaps,r=n.scaleZero,s=i._loop;s||("top"===n.fill?r=n.scaleTop:"bottom"===n.fill&&(r=n.scaleBottom));var l=i._chart.ctx;l.save();var u=i._children.slice(),d=-1;s&&u.length&&u.push(u[0]);var c,h,f,g;if(u.length&&n.fill){for(l.beginPath(),c=0;c<u.length;++c)h=u[c],f=e.previousItem(u,c),g=h._view,0===c?(s?l.moveTo(r.x,r.y):l.moveTo(g.x,r),g.skip||(d=c,l.lineTo(g.x,g.y))):(f=d===-1?f:u[d],g.skip?o||d!==c-1||(s?l.lineTo(r.x,r.y):l.lineTo(f._view.x,r)):(d!==c-1?o&&d!==-1?t(f,h):s?l.lineTo(g.x,g.y):(l.lineTo(g.x,r),l.lineTo(g.x,g.y)):t(f,h),d=c));s||d===-1||l.lineTo(u[d]._view.x,r),l.fillStyle=n.backgroundColor||a.defaultColor,l.closePath(),l.fill()}var p=a.elements.line;for(l.lineCap=n.borderCapStyle||p.borderCapStyle,l.setLineDash&&l.setLineDash(n.borderDash||p.borderDash),l.lineDashOffset=n.borderDashOffset||p.borderDashOffset,l.lineJoin=n.borderJoinStyle||p.borderJoinStyle,l.lineWidth=n.borderWidth||p.borderWidth,l.strokeStyle=n.borderColor||a.defaultColor,l.beginPath(),d=-1,c=0;c<u.length;++c)h=u[c],f=e.previousItem(u,c),g=h._view,0===c?g.skip||(l.moveTo(g.x,g.y),d=c):(f=d===-1?f:u[d],g.skip||(d!==c-1&&!o||d===-1?l.moveTo(g.x,g.y):t(f,h),d=c));l.stroke(),l.restore()}})}},{}],39:[function(t,e,a){"use strict";e.exports=function(t){function e(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hitRadius,2)}function a(t){var e=this._view;return!!e&&Math.pow(t-e.y,2)<Math.pow(e.radius+e.hitRadius,2)}var i=t.helpers,n=t.defaults.global,o=n.defaultColor;n.elements.point={radius:3,pointStyle:"circle",backgroundColor:o,borderWidth:1,borderColor:o,hitRadius:1,hoverRadius:4,hoverBorderWidth:1},t.elements.Point=t.Element.extend({inRange:function(t,e){var a=this._view;return!!a&&Math.pow(t-a.x,2)+Math.pow(e-a.y,2)<Math.pow(a.hitRadius+a.radius,2)},inLabelRange:e,inXRange:e,inYRange:a,getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(e){var a=this._view,r=this._model,s=this._chart.ctx,l=a.pointStyle,u=a.radius,d=a.x,c=a.y,h=t.helpers.color,f=1.01,g=0;a.skip||(s.strokeStyle=a.borderColor||o,s.lineWidth=i.getValueOrDefault(a.borderWidth,n.elements.point.borderWidth),s.fillStyle=a.backgroundColor||o,void 0!==e&&(r.x<e.left||e.right*f<r.x||r.y<e.top||e.bottom*f<r.y)&&(r.x<e.left?g=(d-r.x)/(e.left-r.x):e.right*f<r.x?g=(r.x-d)/(r.x-e.right):r.y<e.top?g=(c-r.y)/(e.top-r.y):e.bottom*f<r.y&&(g=(r.y-c)/(r.y-e.bottom)),g=Math.round(100*g)/100,s.strokeStyle=h(s.strokeStyle).alpha(g).rgbString(),s.fillStyle=h(s.fillStyle).alpha(g).rgbString()),t.canvasHelpers.drawPoint(s,l,u,d,c))}})}},{}],40:[function(t,e,a){"use strict";e.exports=function(t){function e(t){return void 0!==t._view.width}function a(t){var a,i,n,o,r=t._view;if(e(t)){var s=r.width/2;a=r.x-s,i=r.x+s,n=Math.min(r.y,r.base),o=Math.max(r.y,r.base)}else{var l=r.height/2;a=Math.min(r.x,r.base),i=Math.max(r.x,r.base),n=r.y-l,o=r.y+l}return{left:a,top:n,right:i,bottom:o}}var i=t.defaults.global;i.elements.rectangle={backgroundColor:i.defaultColor,borderWidth:0,borderColor:i.defaultColor,borderSkipped:"bottom"},t.elements.Rectangle=t.Element.extend({draw:function(){function t(t){return v[(x+t)%4]}var e,a,i,n,o,r,s,l=this._chart.ctx,u=this._view,d=u.borderWidth;if(u.horizontal?(e=u.base,a=u.x,i=u.y-u.height/2,n=u.y+u.height/2,o=a>e?1:-1,r=1,s=u.borderSkipped||"left"):(e=u.x-u.width/2,a=u.x+u.width/2,i=u.y,n=u.base,o=1,r=n>i?1:-1,s=u.borderSkipped||"bottom"),d){var c=Math.min(Math.abs(e-a),Math.abs(i-n));d=d>c?c:d;var h=d/2,f=e+("left"!==s?h*o:0),g=a+("right"!==s?-h*o:0),p=i+("top"!==s?h*r:0),m=n+("bottom"!==s?-h*r:0);f!==g&&(i=p,n=m),p!==m&&(e=f,a=g)}l.beginPath(),l.fillStyle=u.backgroundColor,l.strokeStyle=u.borderColor,l.lineWidth=d;var v=[[e,n],[e,i],[a,i],[a,n]],b=["bottom","left","top","right"],x=b.indexOf(s,0);x===-1&&(x=0);var y=t(0);l.moveTo(y[0],y[1]);for(var k=1;k<4;k++)y=t(k),l.lineTo(y[0],y[1]);l.fill(),d&&l.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var n=a(this);i=t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,i){var n=this;if(!n._view)return!1;var o=!1,r=a(n);return o=e(n)?t>=r.left&&t<=r.right:i>=r.top&&i<=r.bottom},inXRange:function(t){var e=a(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=a(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,a,i=this._view;return e(this)?(t=i.x,a=(i.y+i.base)/2):(t=(i.x+i.base)/2,a=i.y),{x:t,y:a}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],41:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){var a=l.getStyle(t,e),i=a&&a.match(/(\d+)px/);return i?Number(i[1]):void 0}function a(t,a){var i=t.style,n=t.getAttribute("height"),o=t.getAttribute("width");if(t._chartjs={initial:{height:n,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===o||""===o){var r=e(t,"width");void 0!==r&&(t.width=r)}if(null===n||""===n)if(""===t.style.height)t.height=t.width/(a.options.aspectRatio||2);else{var s=e(t,"height");void 0!==r&&(t.height=s)}return t}function i(t,e,a,i,n){return{type:t,chart:e,native:n||null,x:void 0!==a?a:null,y:void 0!==i?i:null}}function n(t,e){
14
- var a=u[t.type]||t.type,n=l.getRelativePosition(t,e);return i(a,e,n.x,n.y,t)}function o(t){var e=document.createElement("iframe");return e.className="chartjs-hidden-iframe",e.style.cssText="display:block;overflow:hidden;border:0;margin:0;top:0;left:0;bottom:0;right:0;height:100%;width:100%;position:absolute;pointer-events:none;z-index:-1;",e.tabIndex=-1,l.addEvent(e,"load",function(){l.addEvent(e.contentWindow||e,"resize",t),t()}),e}function r(t,e,a){var n=t._chartjs={ticking:!1},r=function(){n.ticking||(n.ticking=!0,l.requestAnimFrame.call(window,function(){if(n.resizer)return n.ticking=!1,e(i("resize",a))}))};n.resizer=o(r),t.insertBefore(n.resizer,t.firstChild)}function s(t){if(t&&t._chartjs){var e=t._chartjs.resizer;e&&(e.parentNode.removeChild(e),t._chartjs.resizer=null),delete t._chartjs}}var l=t.helpers,u={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};return{acquireContext:function(t,e){if("string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t instanceof HTMLCanvasElement){var i=t.getContext&&t.getContext("2d");if(i instanceof CanvasRenderingContext2D)return a(t,e),i}return null},releaseContext:function(t){var e=t.canvas;if(e._chartjs){var a=e._chartjs.initial;["height","width"].forEach(function(t){var i=a[t];void 0===i||null===i?e.removeAttribute(t):e.setAttribute(t,i)}),l.each(a.style||{},function(t,a){e.style[a]=t}),e.width=e.width,delete e._chartjs}},addEventListener:function(t,e,a){var i=t.chart.canvas;if("resize"===e)return void r(i.parentNode,a,t.chart);var o=a._chartjs||(a._chartjs={}),s=o.proxies||(o.proxies={}),u=s[t.id+"_"+e]=function(e){a(n(e,t.chart))};l.addEvent(i,e,u)},removeEventListener:function(t,e,a){var i=t.chart.canvas;if("resize"===e)return void s(i.parentNode,a);var n=a._chartjs||{},o=n.proxies||{},r=o[t.id+"_"+e];r&&l.removeEvent(i,e,r)}}}},{}],42:[function(t,e,a){"use strict";var i=t(41);e.exports=function(t){t.platform={acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},t.helpers.extend(t.platform,i(t))}},{41:41}],43:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"bottom"},i=t.Scale.extend({getLabels:function(){var t=this.chart.data;return(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,a=t.getLabels();t.minIndex=0,t.maxIndex=a.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(a,t.options.ticks.min),t.minIndex=i!==-1?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(a,t.options.ticks.max),t.maxIndex=i!==-1?i:t.maxIndex),t.min=a[t.minIndex],t.max=a[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var a=this,i=a.chart.data,n=a.isHorizontal();return i.yLabels&&!n?a.getRightValue(i.datasets[e].data[t]):a.ticks[t-a.minIndex]},getPixelForValue:function(t,e,a,i){var n=this,o=Math.max(n.maxIndex+1-n.minIndex-(n.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t&&isNaN(e)){var r=n.getLabels(),s=r.indexOf(t);e=s!==-1?s:e}if(n.isHorizontal()){var l=n.width/o,u=l*(e-n.minIndex);return(n.options.gridLines.offsetGridLines&&i||n.maxIndex===n.minIndex&&i)&&(u+=l/2),n.left+Math.round(u)}var d=n.height/o,c=d*(e-n.minIndex);return n.options.gridLines.offsetGridLines&&i&&(c+=d/2),n.top+Math.round(c)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,a=this,i=Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),n=a.isHorizontal(),o=(n?a.width:a.height)/i;return t-=n?a.left:a.top,a.options.gridLines.offsetGridLines&&(t-=o/2),e=t<=0?0:Math.round(t/o)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,a)}},{}],44:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:t.Ticks.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return s?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=a.chart,o=n.data,r=o.datasets,s=a.isHorizontal();a.min=null,a.max=null;var l=i.stacked;if(void 0===l&&e.each(r,function(e,a){if(!l){var i=n.getDatasetMeta(a);n.isDatasetVisible(a)&&t(i)&&void 0!==i.stack&&(l=!0)}}),i.stacked||l){var u={};e.each(r,function(o,r){var s=n.getDatasetMeta(r),l=[s.type,void 0===i.stacked&&void 0===s.stack?r:"",s.stack].join(".");void 0===u[l]&&(u[l]={positiveValues:[],negativeValues:[]});var d=u[l].positiveValues,c=u[l].negativeValues;n.isDatasetVisible(r)&&t(s)&&e.each(o.data,function(t,e){var n=+a.getRightValue(t);isNaN(n)||s.data[e].hidden||(d[e]=d[e]||0,c[e]=c[e]||0,i.relativePoints?d[e]=100:n<0?c[e]+=n:d[e]+=n)})}),e.each(u,function(t){var i=t.positiveValues.concat(t.negativeValues),n=e.min(i),o=e.max(i);a.min=null===a.min?n:Math.min(a.min,n),a.max=null===a.max?o:Math.max(a.max,o)})}else e.each(r,function(i,o){var r=n.getDatasetMeta(o);n.isDatasetVisible(o)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:i<a.min&&(a.min=i),null===a.max?a.max=i:i>a.max&&(a.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var a,i=this,n=i.options.ticks;if(i.isHorizontal())a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.width/50));else{var o=e.getValueOrDefault(n.fontSize,t.defaults.global.defaultFontSize);a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.height/(2*o)))}return a},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,a=this,i=a.start,n=+a.getRightValue(t),o=a.end-i;return a.isHorizontal()?(e=a.left+a.width/o*(n-i),Math.round(e)):(e=a.bottom-a.height/o*(n-i),Math.round(e))},getValueForPixel:function(t){var e=this,a=e.isHorizontal(),i=a?e.width:e.height,n=(a?t-e.left:e.bottom-t)/i;return e.start+(e.end-e.start)*n},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,a)}},{}],45:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,a=t.options,i=a.ticks;if(i.beginAtZero){var n=e.sign(t.min),o=e.sign(t.max);n<0&&o<0?t.max=0:n>0&&o>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:a,handleDirectionalChanges:a,buildTicks:function(){var a=this,i=a.options,n=i.ticks,o=a.getTickLimit();o=Math.max(2,o);var r={maxTicks:o,min:n.min,max:n.max,stepSize:e.getValueOrDefault(n.fixedStepSize,n.stepSize)},s=a.ticks=t.Ticks.generators.linear(r,a);a.handleDirectionalChanges(),a.max=e.max(s),a.min=e.min(s),n.reverse?(s.reverse(),a.start=a.max,a.end=a.min):(a.start=a.min,a.end=a.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],46:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:t.Ticks.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return u?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=i.ticks,o=a.chart,r=o.data,s=r.datasets,l=e.getValueOrDefault,u=a.isHorizontal();a.min=null,a.max=null,a.minNotZero=null;var d=i.stacked;if(void 0===d&&e.each(s,function(e,a){if(!d){var i=o.getDatasetMeta(a);o.isDatasetVisible(a)&&t(i)&&void 0!==i.stack&&(d=!0)}}),i.stacked||d){var c={};e.each(s,function(n,r){var s=o.getDatasetMeta(r),l=[s.type,void 0===i.stacked&&void 0===s.stack?r:"",s.stack].join(".");o.isDatasetVisible(r)&&t(s)&&(void 0===c[l]&&(c[l]=[]),e.each(n.data,function(t,e){var n=c[l],o=+a.getRightValue(t);isNaN(o)||s.data[e].hidden||(n[e]=n[e]||0,i.relativePoints?n[e]=100:n[e]+=o)}))}),e.each(c,function(t){var i=e.min(t),n=e.max(t);a.min=null===a.min?i:Math.min(a.min,i),a.max=null===a.max?n:Math.max(a.max,n)})}else e.each(s,function(i,n){var r=o.getDatasetMeta(n);o.isDatasetVisible(n)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:i<a.min&&(a.min=i),null===a.max?a.max=i:i>a.max&&(a.max=i),0!==i&&(null===a.minNotZero||i<a.minNotZero)&&(a.minNotZero=i))})});a.min=l(n.min,a.min),a.max=l(n.max,a.max),a.min===a.max&&(0!==a.min&&null!==a.min?(a.min=Math.pow(10,Math.floor(e.log10(a.min))-1),a.max=Math.pow(10,Math.floor(e.log10(a.max))+1)):(a.min=1,a.max=10))},buildTicks:function(){var a=this,i=a.options,n=i.ticks,o={min:n.min,max:n.max},r=a.ticks=t.Ticks.generators.logarithmic(o,a);a.isHorizontal()||r.reverse(),a.max=e.max(r),a.min=e.min(r),n.reverse?(r.reverse(),a.start=a.max,a.end=a.min):(a.start=a.min,a.end=a.max)},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),t.Scale.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){return this.getPixelForValue(this.tickValues[t])},getPixelForValue:function(t){var a,i,n,o=this,r=o.start,s=+o.getRightValue(t),l=o.options,u=l.ticks;return o.isHorizontal()?(n=e.log10(o.end)-e.log10(r),0===s?i=o.left:(a=o.width,i=o.left+a/n*(e.log10(s)-e.log10(r)))):(a=o.height,0!==r||u.reverse?0===o.end&&u.reverse?(n=e.log10(o.start)-e.log10(o.minNotZero),i=s===o.end?o.top:s===o.minNotZero?o.top+.02*a:o.top+.02*a+.98*a/n*(e.log10(s)-e.log10(o.minNotZero))):(n=e.log10(o.end)-e.log10(r),a=o.height,i=o.bottom-a/n*(e.log10(s)-e.log10(r))):(n=e.log10(o.end)-e.log10(o.minNotZero),i=s===r?o.bottom:s===o.minNotZero?o.bottom-.02*a:o.bottom-.02*a-.98*a/n*(e.log10(s)-e.log10(o.minNotZero)))),i},getValueForPixel:function(t){var a,i,n=this,o=e.log10(n.end)-e.log10(n.start);return n.isHorizontal()?(i=n.width,a=n.start*Math.pow(10,(t-n.left)*o/i)):(i=n.height,a=Math.pow(10,(n.bottom-t)*o/i)/n.start),a}});t.scaleService.registerScaleType("logarithmic",i,a)}},{}],47:[function(t,e,a){"use strict";e.exports=function(t){function e(t){return t.options.lineArc?0:t.chart.data.labels.length}function a(t){var e=t.options.pointLabels,a=f.getValueOrDefault(e.fontSize,g.defaultFontSize),i=f.getValueOrDefault(e.fontStyle,g.defaultFontStyle),n=f.getValueOrDefault(e.fontFamily,g.defaultFontFamily),o=f.fontString(a,i,n);return{size:a,style:i,family:n,font:o}}function i(t,e,a){return f.isArray(a)?{w:f.longestText(t,t.font,a),h:a.length*e+1.5*(a.length-1)*e}:{w:t.measureText(a).width,h:e}}function n(t,e,a,i,n){return t===i||t===n?{start:e-a/2,end:e+a/2}:t<i||t>n?{start:e-a-5,end:e}:{start:e,end:e+a+5}}function o(t){var o,r,s,l=a(t),u=Math.min(t.height/2,t.width/2),d={l:t.width,r:0,t:t.height,b:0},c={};t.ctx.font=l.font,t._pointLabelSizes=[];var h=e(t);for(o=0;o<h;o++){s=t.getPointPosition(o,u),r=i(t.ctx,l.size,t.pointLabels[o]||""),t._pointLabelSizes[o]=r;var g=t.getIndexAngle(o),p=f.toDegrees(g)%360,m=n(p,s.x,r.w,0,180),v=n(p,s.y,r.h,90,270);m.start<d.l&&(d.l=m.start,c.l=g),m.end>d.r&&(d.r=m.end,c.r=g),v.start<d.t&&(d.t=v.start,c.t=g),v.end>d.b&&(d.b=v.end,c.b=g)}t.setReductions(u,d,c)}function r(t){var e=Math.min(t.height/2,t.width/2);t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0)}function s(t){return 0===t||180===t?"center":t<180?"left":"right"}function l(t,e,a,i){if(f.isArray(e))for(var n=a.y,o=1.5*i,r=0;r<e.length;++r)t.fillText(e[r],a.x,n),n+=o;else t.fillText(e,a.x,a.y)}function u(t,e,a){90===t||270===t?a.y-=e.h/2:(t>270||t<90)&&(a.y-=e.h)}function d(t){var i=t.ctx,n=f.getValueOrDefault,o=t.options,r=o.angleLines,d=o.pointLabels;i.lineWidth=r.lineWidth,i.strokeStyle=r.color;var c=t.getDistanceFromCenterForValue(o.reverse?t.min:t.max),h=a(t);i.textBaseline="top";for(var p=e(t)-1;p>=0;p--){if(r.display){var m=t.getPointPosition(p,c);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(m.x,m.y),i.stroke(),i.closePath()}var v=t.getPointPosition(p,c+5),b=n(d.fontColor,g.defaultFontColor);i.font=h.font,i.fillStyle=b;var x=t.getIndexAngle(p),y=f.toDegrees(x);i.textAlign=s(y),u(y,t._pointLabelSizes[p],v),l(i,t.pointLabels[p]||"",v,h.size)}}function c(t,a,i,n){var o=t.ctx;if(o.strokeStyle=f.getValueAtIndexOrDefault(a.color,n-1),o.lineWidth=f.getValueAtIndexOrDefault(a.lineWidth,n-1),t.options.lineArc)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var r=e(t);if(0===r)return;o.beginPath();var s=t.getPointPosition(0,i);o.moveTo(s.x,s.y);for(var l=1;l<r;l++)s=t.getPointPosition(l,i),o.lineTo(s.x,s.y);o.closePath(),o.stroke()}}function h(t){return f.isNumber(t)?t:0}var f=t.helpers,g=t.defaults.global,p={display:!0,animate:!0,lineArc:!1,position:"chartArea",angleLines:{display:!0,color:"rgba(0, 0, 0, 0.1)",lineWidth:1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:t.Ticks.formatters.linear},pointLabels:{fontSize:10,callback:function(t){return t}}},m=t.LinearScaleBase.extend({setDimensions:function(){var t=this,e=t.options,a=e.ticks;t.width=t.maxWidth,t.height=t.maxHeight,t.xCenter=Math.round(t.width/2),t.yCenter=Math.round(t.height/2);var i=f.min([t.height,t.width]),n=f.getValueOrDefault(a.fontSize,g.defaultFontSize);t.drawingArea=e.display?i/2-(n/2+a.backdropPaddingY):i/2},determineDataLimits:function(){var t=this,e=t.chart,a=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;f.each(e.data.datasets,function(n,o){if(e.isDatasetVisible(o)){var r=e.getDatasetMeta(o);f.each(n.data,function(e,n){var o=+t.getRightValue(e);isNaN(o)||r.data[n].hidden||(a=Math.min(o,a),i=Math.max(o,i))})}}),t.min=a===Number.POSITIVE_INFINITY?0:a,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},getTickLimit:function(){var t=this.options.ticks,e=f.getValueOrDefault(t.fontSize,g.defaultFontSize);return Math.min(t.maxTicksLimit?t.maxTicksLimit:11,Math.ceil(this.drawingArea/(1.5*e)))},convertTicksToLabels:function(){var e=this;t.LinearScaleBase.prototype.convertTicksToLabels.call(e),e.pointLabels=e.chart.data.labels.map(e.options.pointLabels.callback,e)},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){this.options.lineArc?r(this):o(this)},setReductions:function(t,e,a){var i=this,n=e.l/Math.sin(a.l),o=Math.max(e.r-i.width,0)/Math.sin(a.r),r=-e.t/Math.cos(a.t),s=-Math.max(e.b-i.height,0)/Math.cos(a.b);n=h(n),o=h(o),r=h(r),s=h(s),i.drawingArea=Math.min(Math.round(t-(n+o)/2),Math.round(t-(r+s)/2)),i.setCenterPoint(n,o,r,s)},setCenterPoint:function(t,e,a,i){var n=this,o=n.width-e-n.drawingArea,r=t+n.drawingArea,s=a+n.drawingArea,l=n.height-i-n.drawingArea;n.xCenter=Math.round((r+o)/2+n.left),n.yCenter=Math.round((s+l)/2+n.top)},getIndexAngle:function(t){var a=2*Math.PI/e(this),i=this.chart.options&&this.chart.options.startAngle?this.chart.options.startAngle:0,n=i*Math.PI*2/360;return t*a+n},getDistanceFromCenterForValue:function(t){var e=this;if(null===t)return 0;var a=e.drawingArea/(e.max-e.min);return e.options.reverse?(e.max-t)*a:(t-e.min)*a},getPointPosition:function(t,e){var a=this,i=a.getIndexAngle(t)-Math.PI/2;return{x:Math.round(Math.cos(i)*e)+a.xCenter,y:Math.round(Math.sin(i)*e)+a.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(){var t=this,e=t.min,a=t.max;return t.getPointPositionForValue(0,t.beginAtZero?0:e<0&&a<0?a:e>0&&a>0?e:0)},draw:function(){var t=this,e=t.options,a=e.gridLines,i=e.ticks,n=f.getValueOrDefault;if(e.display){var o=t.ctx,r=n(i.fontSize,g.defaultFontSize),s=n(i.fontStyle,g.defaultFontStyle),l=n(i.fontFamily,g.defaultFontFamily),u=f.fontString(r,s,l);f.each(t.ticks,function(s,l){if(l>0||e.reverse){var d=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),h=t.yCenter-d;if(a.display&&0!==l&&c(t,a,d,l),i.display){var f=n(i.fontColor,g.defaultFontColor);if(o.font=u,i.showLabelBackdrop){var p=o.measureText(s).width;o.fillStyle=i.backdropColor,o.fillRect(t.xCenter-p/2-i.backdropPaddingX,h-r/2-i.backdropPaddingY,p+2*i.backdropPaddingX,r+2*i.backdropPaddingY)}o.textAlign="center",o.textBaseline="middle",o.fillStyle=f,o.fillText(s,t.xCenter,h)}}}),e.lineArc||d(t)}}});t.scaleService.registerScaleType("radialLinear",m,p)}},{}],48:[function(t,e,a){"use strict";var i=t(1);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,a={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},n={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},o=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return null===t||null===e?null:"undefined"!=typeof this.labelMoments[t]?this.labelMoments[t][e]:null},getLabelDiff:function(t,e){var a=this;return null===t||null===e?null:(void 0===a.labelDiffs&&a.buildLabelDiffs(),"undefined"!=typeof a.labelDiffs[t]?a.labelDiffs[t][e]:null)},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),a.push(i))},t),t.firstTick=i.min.call(t,a),t.lastTick=i.max.call(t,a)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(n,o){var r=[],s=t.chart.isDatasetVisible(o);"object"==typeof n.data[0]&&null!==n.data[0]?e.each(n.data,function(e){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),r.push(a),s&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,a):a,t.lastTick=null!==t.lastTick?i.max(t.lastTick,a):a))},t):r=a,t.labelMoments.push(r)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildLabelDiffs:function(){var t=this;t.labelDiffs=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0&&e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),a.push(i.diff(t.firstTick,t.tickUnit,!0)))},t),e.each(t.chart.data.datasets,function(i){var n=[];"object"==typeof i.data[0]&&null!==i.data[0]?e.each(i.data,function(e){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),n.push(a.diff(t.firstTick,t.tickUnit,!0)))},t):n=a,t.labelDiffs.push(n)},t)},buildTicks:function(){var i=this;i.ctx.save();var n=e.getValueOrDefault(i.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=e.getValueOrDefault(i.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),r=e.getValueOrDefault(i.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),s=e.fontString(n,o,r);if(i.ctx.font=s,i.ticks=[],i.unitScale=1,i.scaleSizeInUnits=0,i.options.time.unit)i.tickUnit=i.options.time.unit||"day",i.displayFormat=i.options.time.displayFormats[i.tickUnit],i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,1);else{var l=i.isHorizontal()?i.width:i.height,u=i.tickFormatFunction(i.firstTick,0,[]),d=i.ctx.measureText(u).width,c=Math.cos(e.toRadians(i.options.ticks.maxRotation)),h=Math.sin(e.toRadians(i.options.ticks.maxRotation));d=d*c+n*h;var f=l/d;i.tickUnit=i.options.time.minUnit,i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.displayFormat=i.options.time.displayFormats[i.tickUnit];for(var g=0,p=a.units[g];g<a.units.length;){if(i.unitScale=1,e.isArray(p.steps)&&Math.ceil(i.scaleSizeInUnits/f)<e.max(p.steps)){for(var m=0;m<p.steps.length;++m)if(p.steps[m]>=Math.ceil(i.scaleSizeInUnits/f)){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,p.steps[m]);break}break}if(p.maxStep===!1||Math.ceil(i.scaleSizeInUnits/f)<p.maxStep){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,Math.ceil(i.scaleSizeInUnits/f));break}++g,p=a.units[g],i.tickUnit=p.name;var v=i.firstTick.diff(i.getMomentStartOf(i.firstTick),i.tickUnit,!0),b=i.getMomentStartOf(i.lastTick.clone().add(1,i.tickUnit)).diff(i.lastTick,i.tickUnit,!0);i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)+v+b,i.displayFormat=i.options.time.displayFormats[p.name]}}var x;if(i.options.time.min?x=i.getMomentStartOf(i.firstTick):(i.firstTick=i.getMomentStartOf(i.firstTick),x=i.firstTick),!i.options.time.max){var y=i.getMomentStartOf(i.lastTick),k=y.diff(i.lastTick,i.tickUnit,!0);k<0?i.lastTick=i.getMomentStartOf(i.lastTick.add(1,i.tickUnit)):k>=0&&(i.lastTick=y),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)}i.options.time.displayFormat&&(i.displayFormat=i.options.time.displayFormat),i.ticks.push(i.firstTick.clone());for(var S=i.unitScale;S<=i.scaleSizeInUnits;S+=i.unitScale){var M=x.clone().add(S,i.tickUnit);if(i.options.time.max&&M.diff(i.lastTick,i.tickUnit,!0)>=0)break;i.ticks.push(M)}var w=i.ticks[i.ticks.length-1].diff(i.lastTick,i.tickUnit);0===w&&0!==i.scaleSizeInUnits||(i.options.time.max?(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.ticks[0],i.tickUnit,!0)):(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0))),i.ctx.restore(),i.labelDiffs=void 0},getLabelForIndex:function(t,e){var a=this,i=a.chart.data.labels&&t<a.chart.data.labels.length?a.chart.data.labels[t]:"",n=a.chart.data.datasets[e].data[t];return null!==n&&"object"==typeof n&&(i=a.getRightValue(n)),a.options.time.tooltipFormat&&(i=a.parseTime(i).format(a.options.time.tooltipFormat)),i},tickFormatFunction:function(t,a,i){var n=t.format(this.displayFormat),o=this.options.ticks,r=e.getValueOrDefault(o.callback,o.userCallback);return r?r(n,a,i):n},convertTicksToLabels:function(){var t=this;t.tickMoments=t.ticks,t.ticks=t.ticks.map(t.tickFormatFunction,t)},getPixelForValue:function(t,e,a){var i=this,n=null;if(void 0!==e&&void 0!==a&&(n=i.getLabelDiff(a,e)),null===n&&(t&&t.isValid||(t=i.parseTime(i.getRightValue(t))),t&&t.isValid&&t.isValid()&&(n=t.diff(i.firstTick,i.tickUnit,!0))),null!==n){var o=0!==n?n/i.scaleSizeInUnits:n;if(i.isHorizontal()){var r=i.width*o;return i.left+Math.round(r)}var s=i.height*o;return i.top+Math.round(s)}},getPixelForTick:function(t){return this.getPixelForValue(this.tickMoments[t],null,null)},getValueForPixel:function(t){var e=this,a=e.isHorizontal()?e.width:e.height,n=(t-(e.isHorizontal()?e.left:e.top))/a;return n*=e.scaleSizeInUnits,e.firstTick.clone().add(i.duration(n,e.tickUnit).asSeconds(),"seconds")},parseTime:function(t){var e=this;return"string"==typeof e.options.time.parser?i(t,e.options.time.parser):"function"==typeof e.options.time.parser?e.options.time.parser(t):"function"==typeof t.getMonth||"number"==typeof t?i(t):t.isValid&&t.isValid()?t:"string"!=typeof e.options.time.format&&e.options.time.format.call?(console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"),e.options.time.format(t)):i(t,e.options.time.format)}});t.scaleService.registerScaleType("time",o,n)}},{1:1}]},{},[7])(7)});
1
+ /*!
2
+ * Chart.js v2.9.4
3
+ * https://www.chartjs.org
4
+ * (c) 2020 Chart.js Contributors
5
+ * Released under the MIT License
6
+ */
7
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(function(){try{return require("moment")}catch(t){}}()):"function"==typeof define&&define.amd?define(["require"],(function(t){return e(function(){try{return t("moment")}catch(t){}}())})):(t=t||self).Chart=e(t.moment)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var e={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},n=function(t,e){return t(e={exports:{}},e.exports),e.exports}((function(t){var n={};for(var i in e)e.hasOwnProperty(i)&&(n[e[i]]=i);var a=t.exports={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};for(var r in a)if(a.hasOwnProperty(r)){if(!("channels"in a[r]))throw new Error("missing channels property: "+r);if(!("labels"in a[r]))throw new Error("missing channel labels property: "+r);if(a[r].labels.length!==a[r].channels)throw new Error("channel and label counts mismatch: "+r);var o=a[r].channels,s=a[r].labels;delete a[r].channels,delete a[r].labels,Object.defineProperty(a[r],"channels",{value:o}),Object.defineProperty(a[r],"labels",{value:s})}a.rgb.hsl=function(t){var e,n,i=t[0]/255,a=t[1]/255,r=t[2]/255,o=Math.min(i,a,r),s=Math.max(i,a,r),l=s-o;return s===o?e=0:i===s?e=(a-r)/l:a===s?e=2+(r-i)/l:r===s&&(e=4+(i-a)/l),(e=Math.min(60*e,360))<0&&(e+=360),n=(o+s)/2,[e,100*(s===o?0:n<=.5?l/(s+o):l/(2-s-o)),100*n]},a.rgb.hsv=function(t){var e,n,i,a,r,o=t[0]/255,s=t[1]/255,l=t[2]/255,u=Math.max(o,s,l),d=u-Math.min(o,s,l),h=function(t){return(u-t)/6/d+.5};return 0===d?a=r=0:(r=d/u,e=h(o),n=h(s),i=h(l),o===u?a=i-n:s===u?a=1/3+e-i:l===u&&(a=2/3+n-e),a<0?a+=1:a>1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=n[t];if(i)return i;var a,r,o,s=1/0;for(var l in e)if(e.hasOwnProperty(l)){var u=e[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d<s&&(s=d,a=l)}return a},a.keyword.rgb=function(t){return e[t]},a.rgb.xyz=function(t){var e=t[0]/255,n=t[1]/255,i=t[2]/255;return[100*(.4124*(e=e>.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));n.rgb,n.hsl,n.hsv,n.hwb,n.cmyk,n.xyz,n.lab,n.lch,n.hex,n.keyword,n.ansi16,n.ansi256,n.hcg,n.apple,n.gray;function i(t){var e=function(){for(var t={},e=Object.keys(n),i=e.length,a=0;a<i;a++)t[e[a]]={distance:-1,parent:null};return t}(),i=[t];for(e[t].distance=0;i.length;)for(var a=i.pop(),r=Object.keys(n[a]),o=r.length,s=0;s<o;s++){var l=r[s],u=e[l];-1===u.distance&&(u.distance=e[a].distance+1,u.parent=a,i.unshift(l))}return e}function a(t,e){return function(n){return e(t(n))}}function r(t,e){for(var i=[e[t].parent,t],r=n[e[t].parent][t],o=e[t].parent;e[o].parent;)i.unshift(e[o].parent),r=a(n[e[o].parent][o],r),o=e[o].parent;return r.conversion=i,r}var o={};Object.keys(n).forEach((function(t){o[t]={},Object.defineProperty(o[t],"channels",{value:n[t].channels}),Object.defineProperty(o[t],"labels",{value:n[t].labels});var e=function(t){for(var e=i(t),n={},a=Object.keys(e),o=a.length,s=0;s<o;s++){var l=a[s];null!==e[l].parent&&(n[l]=r(l,e))}return n}(t);Object.keys(e).forEach((function(n){var i=e[n];o[t][n]=function(t){var e=function(e){if(null==e)return e;arguments.length>1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a<i;a++)n[a]=Math.round(n[a]);return n};return"conversion"in t&&(e.conversion=t.conversion),e}(i),o[t][n].raw=function(t){var e=function(e){return null==e?e:(arguments.length>1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var s=o,l={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},u={getRgba:d,getHsla:h,getRgb:function(t){var e=d(t);return e&&e.slice(0,3)},getHsl:function(t){var e=h(t);return e&&e.slice(0,3)},getHwb:c,getAlpha:function(t){var e=d(t);if(e)return e[3];if(e=h(t))return e[3];if(e=c(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+v(t[0])+v(t[1])+v(t[2])+(e>=0&&e<1?v(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return f(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:f,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:g,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return b[t.slice(0,3)]}};function d(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;r<e.length;r++)e[r]=parseInt(i[r]+i[r],16);a&&(n=Math.round(parseInt(a+a,16)/255*100)/100)}else if(i=t.match(/^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i)){a=i[2],i=i[1];for(r=0;r<e.length;r++)e[r]=parseInt(i.slice(2*r,2*r+2),16);a&&(n=Math.round(parseInt(a,16)/255*100)/100)}else if(i=t.match(/^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(r=0;r<e.length;r++)e[r]=parseInt(i[r+1]);n=parseFloat(i[4])}else if(i=t.match(/^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i)){for(r=0;r<e.length;r++)e[r]=Math.round(2.55*parseFloat(i[r+1]));n=parseFloat(i[4])}else if(i=t.match(/(\w+)/)){if("transparent"==i[1])return[0,0,0,0];if(!(e=l[i[1]]))return}for(r=0;r<e.length;r++)e[r]=m(e[r],0,255);return n=n||0==n?m(n,0,1):1,e[3]=n,e}}function h(t){if(t){var e=t.match(/^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var n=parseFloat(e[4]);return[m(parseInt(e[1]),0,360),m(parseFloat(e[2]),0,100),m(parseFloat(e[3]),0,100),m(isNaN(n)?1:n,0,1)]}}}function c(t){if(t){var e=t.match(/^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/);if(e){var n=parseFloat(e[4]);return[m(parseInt(e[1]),0,360),m(parseFloat(e[2]),0,100),m(parseFloat(e[3]),0,100),m(isNaN(n)?1:n,0,1)]}}}function f(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"rgba("+t[0]+", "+t[1]+", "+t[2]+", "+e+")"}function g(t,e){return"rgba("+Math.round(t[0]/255*100)+"%, "+Math.round(t[1]/255*100)+"%, "+Math.round(t[2]/255*100)+"%, "+(e||t[3]||1)+")"}function p(t,e){return void 0===e&&(e=void 0!==t[3]?t[3]:1),"hsla("+t[0]+", "+t[1]+"%, "+t[2]+"%, "+e+")"}function m(t,e,n){return Math.min(Math.max(e,t),n)}function v(t){var e=t.toString(16).toUpperCase();return e.length<2?"0"+e:e}var b={};for(var x in l)b[l[x]]=x;var y=function(t){return t instanceof y?t:this instanceof y?(this.valid=!1,this.values={rgb:[0,0,0],hsl:[0,0,0],hsv:[0,0,0],hwb:[0,0,0],cmyk:[0,0,0,0],alpha:1},void("string"==typeof t?(e=u.getRgba(t))?this.setValues("rgb",e):(e=u.getHsla(t))?this.setValues("hsl",e):(e=u.getHwb(t))&&this.setValues("hwb",e):"object"==typeof t&&(void 0!==(e=t).r||void 0!==e.red?this.setValues("rgb",e):void 0!==e.l||void 0!==e.lightness?this.setValues("hsl",e):void 0!==e.v||void 0!==e.value?this.setValues("hsv",e):void 0!==e.w||void 0!==e.whiteness?this.setValues("hwb",e):void 0===e.c&&void 0===e.cyan||this.setValues("cmyk",e)))):new y(t);var e};y.prototype={isValid:function(){return this.valid},rgb:function(){return this.setSpace("rgb",arguments)},hsl:function(){return this.setSpace("hsl",arguments)},hsv:function(){return this.setSpace("hsv",arguments)},hwb:function(){return this.setSpace("hwb",arguments)},cmyk:function(){return this.setSpace("cmyk",arguments)},rgbArray:function(){return this.values.rgb},hslArray:function(){return this.values.hsl},hsvArray:function(){return this.values.hsv},hwbArray:function(){var t=this.values;return 1!==t.alpha?t.hwb.concat([t.alpha]):t.hwb},cmykArray:function(){return this.values.cmyk},rgbaArray:function(){var t=this.values;return t.rgb.concat([t.alpha])},hslaArray:function(){var t=this.values;return t.hsl.concat([t.alpha])},alpha:function(t){return void 0===t?this.values.alpha:(this.setValues("alpha",t),this)},red:function(t){return this.setChannel("rgb",0,t)},green:function(t){return this.setChannel("rgb",1,t)},blue:function(t){return this.setChannel("rgb",2,t)},hue:function(t){return t&&(t=(t%=360)<0?360+t:t),this.setChannel("hsl",0,t)},saturation:function(t){return this.setChannel("hsl",1,t)},lightness:function(t){return this.setChannel("hsl",2,t)},saturationv:function(t){return this.setChannel("hsv",1,t)},whiteness:function(t){return this.setChannel("hwb",1,t)},blackness:function(t){return this.setChannel("hwb",2,t)},value:function(t){return this.setChannel("hsv",2,t)},cyan:function(t){return this.setChannel("cmyk",0,t)},magenta:function(t){return this.setChannel("cmyk",1,t)},yellow:function(t){return this.setChannel("cmyk",2,t)},black:function(t){return this.setChannel("cmyk",3,t)},hexString:function(){return u.hexString(this.values.rgb)},rgbString:function(){return u.rgbString(this.values.rgb,this.values.alpha)},rgbaString:function(){return u.rgbaString(this.values.rgb,this.values.alpha)},percentString:function(){return u.percentString(this.values.rgb,this.values.alpha)},hslString:function(){return u.hslString(this.values.hsl,this.values.alpha)},hslaString:function(){return u.hslaString(this.values.hsl,this.values.alpha)},hwbString:function(){return u.hwbString(this.values.hwb,this.values.alpha)},keyword:function(){return u.keyword(this.values.rgb,this.values.alpha)},rgbNumber:function(){var t=this.values.rgb;return t[0]<<16|t[1]<<8|t[2]},luminosity:function(){for(var t=this.values.rgb,e=[],n=0;n<t.length;n++){var i=t[n]/255;e[n]=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)}return.2126*e[0]+.7152*e[1]+.0722*e[2]},contrast:function(t){var e=this.luminosity(),n=t.luminosity();return e>n?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new y,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},y.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},y.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},y.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i<t.length;i++)n[t.charAt(i)]=e[t][i];return 1!==e.alpha&&(n.a=e.alpha),n},y.prototype.setValues=function(t,e){var n,i,a=this.values,r=this.spaces,o=this.maxes,l=1;if(this.valid=!0,"alpha"===t)l=e;else if(e.length)a[t]=e.slice(0,t.length),l=e[t.length];else if(void 0!==e[t.charAt(0)]){for(n=0;n<t.length;n++)a[t][n]=e[t.charAt(n)];l=e.a}else if(void 0!==e[r[t][0]]){var u=r[t];for(n=0;n<t.length;n++)a[t][n]=e[u[n]];l=e.alpha}if(a.alpha=Math.max(0,Math.min(1,void 0===l?a.alpha:l)),"alpha"===t)return!1;for(n=0;n<t.length;n++)i=Math.max(0,Math.min(o[t][n],a[t][n])),a[t][n]=Math.round(i);for(var d in r)d!==t&&(a[d]=s[t][d](a[t]));return!0},y.prototype.setSpace=function(t,e){var n=e[0];return void 0===n?this.getValues(t):("number"==typeof n&&(n=Array.prototype.slice.call(e)),this.setValues(t,n),this)},y.prototype.setChannel=function(t,e,n){var i=this.values[t];return void 0===n?i[e]:n===i[e]?this:(i[e]=n,this.setValues(t,i),this)},"undefined"!=typeof window&&(window.Color=y);var _=y;function k(t){return-1===["__proto__","prototype","constructor"].indexOf(t)}var w,M={noop:function(){},uid:(w=0,function(){return w++}),isNullOrUndef:function(t){return null==t},isArray:function(t){if(Array.isArray&&Array.isArray(t))return!0;var e=Object.prototype.toString.call(t);return"[object"===e.substr(0,7)&&"Array]"===e.substr(-6)},isObject:function(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)},isFinite:function(t){return("number"==typeof t||t instanceof Number)&&isFinite(t)},valueOrDefault:function(t,e){return void 0===t?e:t},valueAtIndexOrDefault:function(t,e,n){return M.valueOrDefault(M.isArray(t)?t[e]:t,n)},callback:function(t,e,n){if(t&&"function"==typeof t.call)return t.apply(n,e)},each:function(t,e,n,i){var a,r,o;if(M.isArray(t))if(r=t.length,i)for(a=r-1;a>=0;a--)e.call(n,t[a],a);else for(a=0;a<r;a++)e.call(n,t[a],a);else if(M.isObject(t))for(r=(o=Object.keys(t)).length,a=0;a<r;a++)e.call(n,t[o[a]],o[a])},arrayEquals:function(t,e){var n,i,a,r;if(!t||!e||t.length!==e.length)return!1;for(n=0,i=t.length;n<i;++n)if(a=t[n],r=e[n],a instanceof Array&&r instanceof Array){if(!M.arrayEquals(a,r))return!1}else if(a!==r)return!1;return!0},clone:function(t){if(M.isArray(t))return t.map(M.clone);if(M.isObject(t)){for(var e=Object.create(t),n=Object.keys(t),i=n.length,a=0;a<i;++a)e[n[a]]=M.clone(t[n[a]]);return e}return t},_merger:function(t,e,n,i){if(k(t)){var a=e[t],r=n[t];M.isObject(a)&&M.isObject(r)?M.merge(a,r,i):e[t]=M.clone(r)}},_mergerIf:function(t,e,n){if(k(t)){var i=e[t],a=n[t];M.isObject(i)&&M.isObject(a)?M.mergeIf(i,a):e.hasOwnProperty(t)||(e[t]=M.clone(a))}},merge:function(t,e,n){var i,a,r,o,s,l=M.isArray(e)?e:[e],u=l.length;if(!M.isObject(t))return t;for(i=(n=n||{}).merger||M._merger,a=0;a<u;++a)if(e=l[a],M.isObject(e))for(s=0,o=(r=Object.keys(e)).length;s<o;++s)i(r[s],t,e,n);return t},mergeIf:function(t,e){return M.merge(t,e,{merger:M._mergerIf})},extend:Object.assign||function(t){return M.merge(t,[].slice.call(arguments,1),{merger:function(t,e,n){e[t]=n[t]}})},inherits:function(t){var e=this,n=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=n};return i.prototype=e.prototype,n.prototype=new i,n.extend=M.inherits,t&&M.extend(n.prototype,t),n.__super__=e.prototype,n},_deprecated:function(t,e,n,i){void 0!==e&&console.warn(t+': "'+n+'" is deprecated. Please use "'+i+'" instead')}},S=M;M.callCallback=M.callback,M.indexOf=function(t,e,n){return Array.prototype.indexOf.call(t,e,n)},M.getValueOrDefault=M.valueOrDefault,M.getValueAtIndexOrDefault=M.valueAtIndexOrDefault;var C={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return(t-=1)*t*t+1},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-((t-=1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return t*t*t*t*t},easeOutQuint:function(t){return(t-=1)*t*t*t*t+1},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return 1-Math.cos(t*(Math.PI/2))},easeOutSine:function(t){return Math.sin(t*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t)-1)},easeInExpo:function(t){return 0===t?0:Math.pow(2,10*(t-1))},easeOutExpo:function(t){return 1===t?1:1-Math.pow(2,-10*t)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(2-Math.pow(2,-10*--t))},easeInCirc:function(t){return t>=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-C.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*C.easeInBounce(2*t):.5*C.easeOutBounce(2*t-1)+.5}},P={effects:C};S.easingEffects=C;var A=Math.PI,D=A/180,T=2*A,I=A/2,F=A/4,O=2*A/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),s<u&&l<d?(t.arc(s,l,o,-A,-I),t.arc(u,l,o,-I,0),t.arc(u,d,o,0,I),t.arc(s,d,o,I,A)):s<u?(t.moveTo(s,n),t.arc(u,l,o,-I,I),t.arc(s,l,o,I,A+I)):l<d?(t.arc(s,l,o,-A,0),t.arc(s,d,o,0,A)):t.arc(s,l,o,-A,A),t.closePath(),t.moveTo(e,n)}else t.rect(e,n,i,a)},drawPoint:function(t,e,n,i,a,r){var o,s,l,u,d,h=(r||0)*D;if(e&&"object"==typeof e&&("[object HTMLImageElement]"===(o=e.toString())||"[object HTMLCanvasElement]"===o))return t.save(),t.translate(i,a),t.rotate(h),t.drawImage(e,-e.width/2,-e.height/2,e.width,e.height),void t.restore();if(!(isNaN(n)||n<=0)){switch(t.beginPath(),e){default:t.arc(i,a,n,0,T),t.closePath();break;case"triangle":t.moveTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=O,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),h+=O,t.lineTo(i+Math.sin(h)*n,a-Math.cos(h)*n),t.closePath();break;case"rectRounded":u=n-(d=.516*n),s=Math.cos(h+F)*u,l=Math.sin(h+F)*u,t.arc(i-s,a-l,d,h-A,h-I),t.arc(i+l,a-s,d,h-I,h),t.arc(i+s,a+l,d,h,h+I),t.arc(i-l,a+s,d,h+I,h+A),t.closePath();break;case"rect":if(!r){u=Math.SQRT1_2*n,t.rect(i-u,a-u,2*u,2*u);break}h+=F;case"rectRot":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+l,a-s),t.lineTo(i+s,a+l),t.lineTo(i-l,a+s),t.closePath();break;case"crossRot":h+=F;case"cross":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s);break;case"star":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s),h+=F,s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l),t.moveTo(i+l,a-s),t.lineTo(i-l,a+s);break;case"line":s=Math.cos(h)*n,l=Math.sin(h)*n,t.moveTo(i-s,a-l),t.lineTo(i+s,a+l);break;case"dash":t.moveTo(i,a),t.lineTo(i+Math.cos(h)*n,a+Math.sin(h)*n)}t.fill(),t.stroke()}},_isPointInArea:function(t,e){return t.x>e.left-1e-6&&t.x<e.right+1e-6&&t.y>e.top-1e-6&&t.y<e.bottom+1e-6},clipArea:function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},unclipArea:function(t){t.restore()},lineTo:function(t,e,n,i){var a=n.steppedLine;if(a){if("middle"===a){var r=(e.x+n.x)/2;t.lineTo(r,i?n.y:e.y),t.lineTo(r,i?e.y:n.y)}else"after"===a&&!i||"after"!==a&&i?t.lineTo(e.x,n.y):t.lineTo(n.x,e.y);t.lineTo(n.x,n.y)}else n.tension?t.bezierCurveTo(i?e.controlPointPreviousX:e.controlPointNextX,i?e.controlPointPreviousY:e.controlPointNextY,i?n.controlPointNextX:n.controlPointPreviousX,i?n.controlPointNextY:n.controlPointPreviousY,n.x,n.y):t.lineTo(n.x,n.y)}},R=L;S.clear=L.clear,S.drawRoundedRectangle=function(t){t.beginPath(),L.roundedRect.apply(L,arguments)};var z={_set:function(t,e){return S.merge(this[t]||(this[t]={}),e)}};z._set("global",{defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",defaultLineHeight:1.2,showLines:!0});var N=z,B=S.valueOrDefault;var E={toLineHeight:function(t,e){var n=(""+t).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/);if(!n||"normal"===n[1])return 1.2*e;switch(t=+n[2],n[3]){case"px":return t;case"%":t/=100}return e*t},toPadding:function(t){var e,n,i,a;return S.isObject(t)?(e=+t.top||0,n=+t.right||0,i=+t.bottom||0,a=+t.left||0):e=n=i=a=+t||0,{top:e,right:n,bottom:i,left:a,height:e+i,width:a+n}},_parseFont:function(t){var e=N.global,n=B(t.fontSize,e.defaultFontSize),i={family:B(t.fontFamily,e.defaultFontFamily),lineHeight:S.options.toLineHeight(B(t.lineHeight,e.defaultLineHeight),n),size:n,style:B(t.fontStyle,e.defaultFontStyle),weight:null,string:""};return i.string=function(t){return!t||S.isNullOrUndef(t.size)||S.isNullOrUndef(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}(i),i},resolve:function(t,e,n,i){var a,r,o,s=!0;for(a=0,r=t.length;a<r;++a)if(void 0!==(o=t[a])&&(void 0!==e&&"function"==typeof o&&(o=o(e),s=!1),void 0!==n&&S.isArray(o)&&(o=o[n],s=!1),void 0!==o))return i&&!s&&(i.cacheable=!1),o}},W={_factorize:function(t){var e,n=[],i=Math.sqrt(t);for(e=1;e<i;e++)t%e==0&&(n.push(e),n.push(t/e));return i===(0|i)&&n.push(i),n.sort((function(t,e){return t-e})).pop(),n},log10:Math.log10||function(t){var e=Math.log(t)*Math.LOG10E,n=Math.round(e);return t===Math.pow(10,n)?n:e}},V=W;S.log10=W.log10;var H=S,j=P,q=R,U=E,Y=V,G={getRtlAdapter:function(t,e,n){return t?function(t,e){return{x:function(n){return t+t+e-n},setWidth:function(t){e=t},textAlign:function(t){return"center"===t?t:"right"===t?"left":"right"},xPlus:function(t,e){return t-e},leftForLtr:function(t,e){return t-e}}}(e,n):{x:function(t){return t},setWidth:function(t){},textAlign:function(t){return t},xPlus:function(t,e){return t+e},leftForLtr:function(t,e){return t}}},overrideTextDirection:function(t,e){var n,i;"ltr"!==e&&"rtl"!==e||(i=[(n=t.canvas.style).getPropertyValue("direction"),n.getPropertyPriority("direction")],n.setProperty("direction",e,"important"),t.prevTextDirection=i)},restoreTextDirection:function(t){var e=t.prevTextDirection;void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}};H.easing=j,H.canvas=q,H.options=U,H.math=Y,H.rtl=G;var X=function(t){H.extend(this,t),this.initialize.apply(this,arguments)};H.extend(X.prototype,{_type:void 0,initialize:function(){this.hidden=!1},pivot:function(){var t=this;return t._view||(t._view=H.extend({},t._model)),t._start={},t},transition:function(t){var e=this,n=e._model,i=e._start,a=e._view;return n&&1!==t?(a||(a=e._view={}),i||(i=e._start={}),function(t,e,n,i){var a,r,o,s,l,u,d,h,c,f=Object.keys(n);for(a=0,r=f.length;a<r;++a)if(u=n[o=f[a]],e.hasOwnProperty(o)||(e[o]=u),(s=e[o])!==u&&"_"!==o[0]){if(t.hasOwnProperty(o)||(t[o]=s),(d=typeof u)===typeof(l=t[o]))if("string"===d){if((h=_(l)).valid&&(c=_(u)).valid){e[o]=c.mix(h,i).rgbString();continue}}else if(H.isFinite(l)&&H.isFinite(u)){e[o]=l+(u-l)*i;continue}e[o]=u}}(i,a,n,t),e):(e._view=H.extend({},n),e._start=null,e)},tooltipPosition:function(){return{x:this._model.x,y:this._model.y}},hasValue:function(){return H.isNumber(this._model.x)&&H.isNumber(this._model.y)}}),X.extend=H.inherits;var K=X,Z=K.extend({chart:null,currentStep:0,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),$=Z;Object.defineProperty(Z.prototype,"animationObject",{get:function(){return this}}),Object.defineProperty(Z.prototype,"chartInstance",{get:function(){return this.chart},set:function(t){this.chart=t}}),N._set("global",{animation:{duration:1e3,easing:"easeOutQuart",onProgress:H.noop,onComplete:H.noop}});var J={animations:[],request:null,addAnimation:function(t,e,n,i){var a,r,o=this.animations;for(e.chart=t,e.startTime=Date.now(),e.duration=n,i||(t.animating=!0),a=0,r=o.length;a<r;++a)if(o[a].chart===t)return void(o[a]=e);o.push(e),1===o.length&&this.requestAnimationFrame()},cancelAnimation:function(t){var e=H.findIndex(this.animations,(function(e){return e.chart===t}));-1!==e&&(this.animations.splice(e,1),t.animating=!1)},requestAnimationFrame:function(){var t=this;null===t.request&&(t.request=H.requestAnimFrame.call(window,(function(){t.request=null,t.startDigest()})))},startDigest:function(){this.advance(),this.animations.length>0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r<a.length;)e=(t=a[r]).chart,n=t.numSteps,i=Math.floor((Date.now()-t.startTime)/t.duration*n)+1,t.currentStep=Math.min(i,n),H.callback(t.render,[e,t],e),H.callback(t.onAnimationProgress,[t],e),t.currentStep>=n?(H.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},Q=H.options.resolve,tt=["push","pop","shift","splice","unshift"];function et(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(tt.forEach((function(e){delete t[e]})),delete t._chartjs)}}var nt=function(t,e){this.initialize(t,e)};H.extend(nt.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&et(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;t<e;++t)a[t]=a[t]||this.createMetaData(t);n.dataset=n.dataset||this.createMetaDataset()},addElementAndReset:function(t){var e=this.createMetaData(t);this.getMeta().data.splice(t,0,e),this.updateElement(e,t,!0)},buildOrUpdateElements:function(){var t,e,n=this,i=n.getDataset(),a=i.data||(i.data=[]);n._data!==a&&(n._data&&et(n._data,n),a&&Object.isExtensible(a)&&(e=n,(t=a)._chartjs?t._chartjs.listeners.push(e):(Object.defineProperty(t,"_chartjs",{configurable:!0,enumerable:!1,value:{listeners:[e]}}),tt.forEach((function(e){var n="onData"+e.charAt(0).toUpperCase()+e.slice(1),i=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value:function(){var e=Array.prototype.slice.call(arguments),a=i.apply(this,e);return H.each(t._chartjs.listeners,(function(t){"function"==typeof t[n]&&t[n].apply(t,e)})),a}})})))),n._data=a),n.resyncElements()},_configure:function(){this._config=H.merge(Object.create(null),[this.chart.options.datasets[this._type],this.getDataset()],{merger:function(t,e,n){"_meta"!==t&&"data"!==t&&H._merger(t,e,n)}})},_update:function(t){this._configure(),this._cachedDataOpts=null,this.update(t)},update:H.noop,transition:function(t){for(var e=this.getMeta(),n=e.data||[],i=n.length,a=0;a<i;++a)n[a].transition(t);e.dataset&&e.dataset.transition(t)},draw:function(){var t=this.getMeta(),e=t.data||[],n=e.length,i=0;for(t.dataset&&t.dataset.draw();i<n;++i)e[i].draw()},getStyle:function(t){var e,n=this.getMeta(),i=n.dataset;return this._configure(),i&&void 0===t?e=this._resolveDatasetElementOptions(i||{}):(t=t||0,e=this._resolveDataElementOptions(n.data[t]||{},t)),!1!==e.fill&&null!==e.fill||(e.backgroundColor=e.borderColor),e},_resolveDatasetElementOptions:function(t,e){var n,i,a,r,o=this,s=o.chart,l=o._config,u=t.custom||{},d=s.options.elements[o.datasetElementType.prototype._type]||{},h=o._datasetElementOptions,c={},f={chart:s,dataset:o.getDataset(),datasetIndex:o.index,hover:e};for(n=0,i=h.length;n<i;++n)a=h[n],r=e?"hover"+a.charAt(0).toUpperCase()+a.slice(1):a,c[a]=Q([u[r],l[r],d[r]],f);return c},_resolveDataElementOptions:function(t,e){var n=this,i=t&&t.custom,a=n._cachedDataOpts;if(a&&!i)return a;var r,o,s,l,u=n.chart,d=n._config,h=u.options.elements[n.dataElementType.prototype._type]||{},c=n._dataElementOptions,f={},g={chart:u,dataIndex:e,dataset:n.getDataset(),datasetIndex:n.index},p={cacheable:!i};if(i=i||{},H.isArray(c))for(o=0,s=c.length;o<s;++o)f[l=c[o]]=Q([i[l],d[l],h[l]],g,e,p);else for(o=0,s=(r=Object.keys(c)).length;o<s;++o)f[l=r[o]]=Q([i[l],d[c[l]],d[l],h[l]],g,e,p);return p.cacheable&&(n._cachedDataOpts=Object.freeze(f)),f},removeHoverStyle:function(t){H.merge(t._model,t.$previousStyle||{}),delete t.$previousStyle},setHoverStyle:function(t){var e=this.chart.data.datasets[t._datasetIndex],n=t._index,i=t.custom||{},a=t._model,r=H.getHoverColor;t.$previousStyle={backgroundColor:a.backgroundColor,borderColor:a.borderColor,borderWidth:a.borderWidth},a.backgroundColor=Q([i.hoverBackgroundColor,e.hoverBackgroundColor,r(a.backgroundColor)],void 0,n),a.borderColor=Q([i.hoverBorderColor,e.hoverBorderColor,r(a.borderColor)],void 0,n),a.borderWidth=Q([i.hoverBorderWidth,e.hoverBorderWidth,a.borderWidth],void 0,n)},_removeDatasetHoverStyle:function(){var t=this.getMeta().dataset;t&&this.removeHoverStyle(t)},_setDatasetHoverStyle:function(){var t,e,n,i,a,r,o=this.getMeta().dataset,s={};if(o){for(r=o._model,a=this._resolveDatasetElementOptions(o,!0),t=0,e=(i=Object.keys(a)).length;t<e;++t)s[n=i[t]]=r[n],r[n]=a[n];o.$previousStyle=s}},resyncElements:function(){var t=this.getMeta(),e=this.getDataset().data,n=t.data.length,i=e.length;i<n?t.data.splice(i,n-i):i>n&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;n<e;++n)this.addElementAndReset(t+n)},onDataPush:function(){var t=arguments.length;this.insertElements(this.getDataset().data.length-t,t)},onDataPop:function(){this.getMeta().data.pop()},onDataShift:function(){this.getMeta().data.shift()},onDataSplice:function(t,e){this.getMeta().data.splice(t,e),this.insertElements(t,arguments.length-2)},onDataUnshift:function(){this.insertElements(0,arguments.length)}}),nt.extend=H.inherits;var it=nt,at=2*Math.PI;function rt(t,e){var n=e.startAngle,i=e.endAngle,a=e.pixelMargin,r=a/e.outerRadius,o=e.x,s=e.y;t.beginPath(),t.arc(o,s,e.outerRadius,n-r,i+r),e.innerRadius>a?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function ot(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+at,rt(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=at,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+at,n.startAngle,!0),a=0;a<n.fullCircles;++a)t.stroke();for(t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.startAngle+at),a=0;a<n.fullCircles;++a)t.stroke()}(t,e,n,i),i&&rt(t,n),t.beginPath(),t.arc(n.x,n.y,e.outerRadius,n.startAngle,n.endAngle),t.arc(n.x,n.y,n.innerRadius,n.endAngle,n.startAngle,!0),t.closePath(),t.stroke()}N._set("global",{elements:{arc:{backgroundColor:N.global.defaultColor,borderColor:"#fff",borderWidth:2,borderAlign:"center"}}});var st=K.extend({_type:"arc",inLabelRange:function(t){var e=this._view;return!!e&&Math.pow(t-e.x,2)<Math.pow(e.radius+e.hoverRadius,2)},inRange:function(t,e){var n=this._view;if(n){for(var i=H.getAngleFromPoint(n,{x:t,y:e}),a=i.angle,r=i.distance,o=n.startAngle,s=n.endAngle;s<o;)s+=at;for(;a>s;)a-=at;for(;a<o;)a+=at;var l=a>=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/at)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+at,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;t<a.fullCircles;++t)e.fill();a.endAngle=a.startAngle+n.circumference%at}e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),e.fill(),n.borderWidth&&ot(e,n,a),e.restore()}}),lt=H.valueOrDefault,ut=N.global.defaultColor;N._set("global",{elements:{line:{tension:.4,backgroundColor:ut,borderWidth:3,borderColor:ut,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0}}});var dt=K.extend({_type:"line",draw:function(){var t,e,n,i=this,a=i._view,r=i._chart.ctx,o=a.spanGaps,s=i._children.slice(),l=N.global,u=l.elements.line,d=-1,h=i._loop;if(s.length){if(i._loop){for(t=0;t<s.length;++t)if(e=H.previousItem(s,t),!s[t]._view.skip&&e._view.skip){s=s.slice(t).concat(s.slice(0,t)),h=o;break}h&&s.push(s[0])}for(r.save(),r.lineCap=a.borderCapStyle||u.borderCapStyle,r.setLineDash&&r.setLineDash(a.borderDash||u.borderDash),r.lineDashOffset=lt(a.borderDashOffset,u.borderDashOffset),r.lineJoin=a.borderJoinStyle||u.borderJoinStyle,r.lineWidth=lt(a.borderWidth,u.borderWidth),r.strokeStyle=a.borderColor||l.defaultColor,r.beginPath(),(n=s[0]._view).skip||(r.moveTo(n.x,n.y),d=0),t=1;t<s.length;++t)n=s[t]._view,e=-1===d?H.previousItem(s,t):s[d],n.skip||(d!==t-1&&!o||-1===d?r.moveTo(n.x,n.y):H.canvas.lineTo(r,e._view,n),d=t);h&&r.closePath(),r.stroke(),r.restore()}}}),ht=H.valueOrDefault,ct=N.global.defaultColor;function ft(t){var e=this._view;return!!e&&Math.abs(t-e.x)<e.radius+e.hitRadius}N._set("global",{elements:{point:{radius:3,pointStyle:"circle",backgroundColor:ct,borderColor:ct,borderWidth:1,hitRadius:1,hoverRadius:4,hoverBorderWidth:1}}});var gt=K.extend({_type:"point",inRange:function(t,e){var n=this._view;return!!n&&Math.pow(t-n.x,2)+Math.pow(e-n.y,2)<Math.pow(n.hitRadius+n.radius,2)},inLabelRange:ft,inXRange:ft,inYRange:function(t){var e=this._view;return!!e&&Math.abs(t-e.y)<e.radius+e.hitRadius},getCenterPoint:function(){var t=this._view;return{x:t.x,y:t.y}},getArea:function(){return Math.PI*Math.pow(this._view.radius,2)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y,padding:t.radius+t.borderWidth}},draw:function(t){var e=this._view,n=this._chart.ctx,i=e.pointStyle,a=e.rotation,r=e.radius,o=e.x,s=e.y,l=N.global,u=l.defaultColor;e.skip||(void 0===t||H.canvas._isPointInArea(e,t))&&(n.strokeStyle=e.borderColor||u,n.lineWidth=ht(e.borderWidth,l.elements.point.borderWidth),n.fillStyle=e.backgroundColor||u,H.canvas.drawPoint(n,i,r,o,s,a))}}),pt=N.global.defaultColor;function mt(t){return t&&void 0!==t.width}function vt(t){var e,n,i,a,r;return mt(t)?(r=t.width/2,e=t.x-r,n=t.x+r,i=Math.min(t.y,t.base),a=Math.max(t.y,t.base)):(r=t.height/2,e=Math.min(t.x,t.base),n=Math.max(t.x,t.base),i=t.y-r,a=t.y+r),{left:e,top:i,right:n,bottom:a}}function bt(t,e,n){return t===e?n:t===n?e:t}function xt(t,e,n){var i,a,r,o,s=t.borderWidth,l=function(t){var e=t.borderSkipped,n={};return e?(t.horizontal?t.base>t.x&&(e=bt(e,"left","right")):t.base<t.y&&(e=bt(e,"bottom","top")),n[e]=!0,n):n}(t);return H.isObject(s)?(i=+s.top||0,a=+s.right||0,r=+s.bottom||0,o=+s.left||0):i=a=r=o=+s||0,{t:l.top||i<0?0:i>n?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function yt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&vt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}N._set("global",{elements:{rectangle:{backgroundColor:pt,borderColor:pt,borderSkipped:"bottom",borderWidth:0}}});var _t=K.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=vt(t),n=e.right-e.left,i=e.bottom-e.top,a=xt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return yt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return mt(n)?yt(n,t,null):yt(n,null,e)},inXRange:function(t){return yt(this._view,t,null)},inYRange:function(t){return yt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return mt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return mt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),kt={},wt=st,Mt=dt,St=gt,Ct=_t;kt.Arc=wt,kt.Line=Mt,kt.Point=St,kt.Rectangle=Ct;var Pt=H._deprecated,At=H.valueOrDefault;function Dt(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=H.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a<r;++a)o=Math.min(o,Math.abs(e[a]-e[a-1]));for(a=0,r=t.getTicks().length;a<r;++a)i=t.getPixelForTick(a),o=a>0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return H.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}N._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),N._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Tt=it.extend({dataElementType:kt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;it.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Pt("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Pt("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Pt("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Pt("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Pt("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e<n;++e)this.updateElement(i[e],e,t)},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=i.getDataset(),o=i._resolveDataElementOptions(t,e);t._xScale=i.getScaleForId(a.xAxisID),t._yScale=i.getScaleForId(a.yAxisID),t._datasetIndex=i.index,t._index=e,t._model={backgroundColor:o.backgroundColor,borderColor:o.borderColor,borderSkipped:o.borderSkipped,borderWidth:o.borderWidth,datasetLabel:r.label,label:i.chart.data.labels[e]},H.isArray(r.data[e])&&(t._model.borderSkipped=null),i._updateElementGeometry(t,e,n,o),t.pivot()},_updateElementGeometry:function(t,e,n,i){var a=this,r=t._model,o=a._getValueScale(),s=o.getBasePixel(),l=o.isHorizontal(),u=a._ruler||a.getRuler(),d=a.calculateBarValuePixels(a.index,e,i),h=a.calculateBarIndexPixels(a.index,e,u,i);r.horizontal=l,r.base=n?s:d.base,r.x=l?n?s:d.head:h.center,r.y=l?h.center:n?s:d.head,r.height=l?h.size:void 0,r.width=l?void 0:h.size},_getStacks:function(t){var e,n,i=this._getIndexScale(),a=i._getMatchingVisibleMetas(this._type),r=i.options.stacked,o=a.length,s=[];for(e=0;e<o&&(n=a[e],(!1===r||-1===s.indexOf(n.stack)||void 0===r&&void 0===n.stack)&&s.push(n.stack),n.index!==t);++e);return s},getStackCount:function(){return this._getStacks().length},getStackIndex:function(t,e){var n=this._getStacks(t),i=void 0!==e?n.indexOf(e):-1;return-1===i?n.length-1:i},getRuler:function(){var t,e,n=this._getIndexScale(),i=[];for(t=0,e=this.getMeta().data.length;t<e;++t)i.push(n.getPixelForValue(null,t,this.index));return{pixels:i,start:n._startPixel,end:n._endPixel,stackCount:this.getStackCount(),scale:n}},calculateBarValuePixels:function(t,e,n){var i,a,r,o,s,l,u,d=this.chart,h=this._getValueScale(),c=h.isHorizontal(),f=d.data.datasets,g=h._getMatchingVisibleMetas(this._type),p=h._parseValue(f[t].data[e]),m=n.minBarLength,v=h.options.stacked,b=this.getMeta().stack,x=void 0===p.start?0:p.max>=0&&p.min>=0?p.min:p.max,y=void 0===p.start?p.end:p.max>=0&&p.min>=0?p.max-p.min:p.min-p.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(p.min<0&&r<0||p.max>=0&&r>0)&&(x+=r));return o=h.getPixelForValue(x),l=(s=h.getPixelForValue(x+y))-o,void 0!==m&&Math.abs(l)<m&&(l=m,s=y>=0&&!c||y<0&&c?o-m:o+m),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t<a.length-1?a[t+1]:null,l=n.categoryPercentage;return null===o&&(o=r-(null===s?e.end-e.start:s-r)),null===s&&(s=r+r-o),i=r-(r-Math.min(o,s))/2*l,{chunk:Math.abs(s-o)/2*l/e.stackCount,ratio:n.barPercentage,start:i}}(e,n,i):Dt(e,n,i),r=this.getStackIndex(t,this.getMeta().stack),o=a.start+a.chunk*r+a.chunk/2,s=Math.min(At(i.maxBarThickness,1/0),a.chunk*a.ratio);return{base:o-s/2,head:o+s/2,center:o,size:s}},draw:function(){var t=this.chart,e=this._getValueScale(),n=this.getMeta().data,i=this.getDataset(),a=n.length,r=0;for(H.canvas.clipArea(t.ctx,t.chartArea);r<a;++r){var o=e._parseValue(i.data[r]);isNaN(o.min)||isNaN(o.max)||n[r].draw()}H.canvas.unclipArea(t.ctx)},_resolveDataElementOptions:function(){var t=this,e=H.extend({},it.prototype._resolveDataElementOptions.apply(t,arguments)),n=t._getIndexScale().options,i=t._getValueScale().options;return e.barPercentage=At(n.barPercentage,e.barPercentage),e.barThickness=At(n.barThickness,e.barThickness),e.categoryPercentage=At(n.categoryPercentage,e.categoryPercentage),e.maxBarThickness=At(n.maxBarThickness,e.maxBarThickness),e.minBarLength=At(i.minBarLength,e.minBarLength),e}}),It=H.valueOrDefault,Ft=H.options.resolve;N._set("bubble",{hover:{mode:"single"},scales:{xAxes:[{type:"linear",position:"bottom",id:"x-axis-0"}],yAxes:[{type:"linear",position:"left",id:"y-axis-0"}]},tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.datasets[t.datasetIndex].label||"",i=e.datasets[t.datasetIndex].data[t.index];return n+": ("+t.xLabel+", "+t.yLabel+", "+i.r+")"}}}});var Ot=it.extend({dataElementType:kt.Point,_dataElementOptions:["backgroundColor","borderColor","borderWidth","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth","hoverRadius","hitRadius","pointStyle","rotation"],update:function(t){var e=this,n=e.getMeta().data;H.each(n,(function(n,i){e.updateElement(n,i,t)}))},updateElement:function(t,e,n){var i=this,a=i.getMeta(),r=t.custom||{},o=i.getScaleForId(a.xAxisID),s=i.getScaleForId(a.yAxisID),l=i._resolveDataElementOptions(t,e),u=i.getDataset().data[e],d=i.index,h=n?o.getPixelForDecimal(.5):o.getPixelForValue("object"==typeof u?u:NaN,e,d),c=n?s.getBasePixel():s.getPixelForValue(u,e,d);t._xScale=o,t._yScale=s,t._options=l,t._datasetIndex=d,t._index=e,t._model={backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,hitRadius:l.hitRadius,pointStyle:l.pointStyle,rotation:l.rotation,radius:n?0:l.radius,skip:r.skip||isNaN(h)||isNaN(c),x:h,y:c},t.pivot()},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=It(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=It(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=It(n.hoverBorderWidth,n.borderWidth),e.radius=n.radius+n.hoverRadius},_resolveDataElementOptions:function(t,e){var n=this,i=n.chart,a=n.getDataset(),r=t.custom||{},o=a.data[e]||{},s=it.prototype._resolveDataElementOptions.apply(n,arguments),l={chart:i,dataIndex:e,dataset:a,datasetIndex:n.index};return n._cachedDataOpts===s&&(s=H.extend({},s)),s.radius=Ft([r.radius,o.r,n._config.radius,i.options.elements.point.radius],l,e),s}}),Lt=H.valueOrDefault,Rt=Math.PI,zt=2*Rt,Nt=Rt/2;N._set("doughnut",{animation:{animateRotate:!0,animateScale:!1},hover:{mode:"single"},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data,o=r.datasets,s=r.labels;if(a.setAttribute("class",t.id+"-legend"),o.length)for(e=0,n=o[0].data.length;e<n;++e)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return a.outerHTML},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map((function(n,i){var a=t.getDatasetMeta(0),r=a.controller.getStyle(i);return{text:n,fillStyle:r.backgroundColor,strokeStyle:r.borderColor,lineWidth:r.borderWidth,hidden:isNaN(e.datasets[0].data[i])||a.data[i].hidden,index:i}})):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r]&&(a.data[r].hidden=!a.data[r].hidden);o.update()}},cutoutPercentage:50,rotation:-Nt,circumference:zt,tooltips:{callbacks:{title:function(){return""},label:function(t,e){var n=e.labels[t.index],i=": "+e.datasets[t.datasetIndex].data[t.index];return H.isArray(n)?(n=n.slice())[0]+=i:n+=i,n}}}});var Bt=it.extend({dataElementType:kt.Arc,linkScales:H.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],getRingIndex:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&++e;return e},update:function(t){var e,n,i,a,r=this,o=r.chart,s=o.chartArea,l=o.options,u=1,d=1,h=0,c=0,f=r.getMeta(),g=f.data,p=l.cutoutPercentage/100||0,m=l.circumference,v=r._getRingWeight(r.index);if(m<zt){var b=l.rotation%zt,x=(b+=b>=Rt?-zt:b<-Rt?zt:0)+m,y=Math.cos(b),_=Math.sin(b),k=Math.cos(x),w=Math.sin(x),M=b<=0&&x>=0||x>=zt,S=b<=Nt&&x>=Nt||x>=zt+Nt,C=b<=-Nt&&x>=-Nt||x>=Rt+Nt,P=b===-Rt||x>=Rt?-1:Math.min(y,y*p,k,k*p),A=C?-1:Math.min(_,_*p,w,w*p),D=M?1:Math.max(y,y*p,k,k*p),T=S?1:Math.max(_,_*p,w,w*p);u=(D-P)/2,d=(T-A)/2,h=-(D+P)/2,c=-(T+A)/2}for(i=0,a=g.length;i<a;++i)g[i]._options=r._resolveDataElementOptions(g[i],i);for(o.borderWidth=r.getMaxBorderWidth(),e=(s.right-s.left-o.borderWidth)/u,n=(s.bottom-s.top-o.borderWidth)/d,o.outerRadius=Math.max(Math.min(e,n)/2,0),o.innerRadius=Math.max(o.outerRadius*p,0),o.radiusLength=(o.outerRadius-o.innerRadius)/(r._getVisibleDatasetWeightTotal()||1),o.offsetX=h*o.outerRadius,o.offsetY=c*o.outerRadius,f.total=r.calculateTotal(),r.outerRadius=o.outerRadius-o.radiusLength*r._getRingWeightOffset(r.index),r.innerRadius=Math.max(r.outerRadius-o.radiusLength*v,0),i=0,a=g.length;i<a;++i)r.updateElement(g[i],i,t)},updateElement:function(t,e,n){var i=this,a=i.chart,r=a.chartArea,o=a.options,s=o.animation,l=(r.left+r.right)/2,u=(r.top+r.bottom)/2,d=o.rotation,h=o.rotation,c=i.getDataset(),f=n&&s.animateRotate?0:t.hidden?0:i.calculateCircumference(c.data[e])*(o.circumference/zt),g=n&&s.animateScale?0:i.innerRadius,p=n&&s.animateScale?0:i.outerRadius,m=t._options||{};H.extend(t,{_datasetIndex:i.index,_index:e,_model:{backgroundColor:m.backgroundColor,borderColor:m.borderColor,borderWidth:m.borderWidth,borderAlign:m.borderAlign,x:l+a.offsetX,y:u+a.offsetY,startAngle:d,endAngle:h,circumference:f,outerRadius:p,innerRadius:g,label:H.valueAtIndexOrDefault(c.label,e,a.data.labels[e])}});var v=t._model;n&&s.animateRotate||(v.startAngle=0===e?o.rotation:i.getMeta().data[e-1]._model.endAngle,v.endAngle=v.startAngle+v.circumference),t.pivot()},calculateTotal:function(){var t,e=this.getDataset(),n=this.getMeta(),i=0;return H.each(n.data,(function(n,a){t=e.data[a],isNaN(t)||n.hidden||(i+=Math.abs(t))})),i},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?zt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e<n;++e)if(d.isDatasetVisible(e)){t=(i=d.getDatasetMeta(e)).data,e!==this.index&&(r=i.controller);break}if(!t)return 0;for(e=0,n=t.length;e<n;++e)a=t[e],r?(r._configure(),o=r._resolveDataElementOptions(a,e)):o=a._options,"inner"!==o.borderAlign&&(s=o.borderWidth,u=(l=o.hoverBorderWidth)>(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n<t;++n)this.chart.isDatasetVisible(n)&&(e+=this._getRingWeight(n));return e},_getRingWeight:function(t){return Math.max(Lt(this.chart.data.datasets[t].weight,1),0)},_getVisibleDatasetWeightTotal:function(){return this._getRingWeightOffset(this.chart.data.datasets.length)}});N._set("horizontalBar",{hover:{mode:"index",axis:"y"},scales:{xAxes:[{type:"linear",position:"bottom"}],yAxes:[{type:"category",position:"left",offset:!0,gridLines:{offsetGridLines:!0}}]},elements:{rectangle:{borderSkipped:"left"}},tooltips:{mode:"index",axis:"y"}}),N._set("global",{datasets:{horizontalBar:{categoryPercentage:.8,barPercentage:.9}}});var Et=Tt.extend({_getValueScaleId:function(){return this.getMeta().xAxisID},_getIndexScaleId:function(){return this.getMeta().yAxisID}}),Wt=H.valueOrDefault,Vt=H.options.resolve,Ht=H.canvas._isPointInArea;function jt(t,e){var n=t&&t.options.ticks||{},i=n.reverse,a=void 0===n.min?e:0,r=void 0===n.max?e:0;return{start:i?r:a,end:i?a:r}}function qt(t,e,n){var i=n/2,a=jt(t,i),r=jt(e,i);return{top:r.end,right:a.end,bottom:r.start,left:a.start}}function Ut(t){var e,n,i,a;return H.isObject(t)?(e=t.top,n=t.right,i=t.bottom,a=t.left):e=n=i=a=t,{top:e,right:n,bottom:i,left:a}}N._set("line",{showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}});var Yt=it.extend({datasetElementType:kt.Line,dataElementType:kt.Point,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth","cubicInterpolationMode","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},update:function(t){var e,n,i=this,a=i.getMeta(),r=a.dataset,o=a.data||[],s=i.chart.options,l=i._config,u=i._showLine=Wt(l.showLine,s.showLines);for(i._xScale=i.getScaleForId(a.xAxisID),i._yScale=i.getScaleForId(a.yAxisID),u&&(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),r._scale=i._yScale,r._datasetIndex=i.index,r._children=o,r._model=i._resolveDatasetElementOptions(r),r.pivot()),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(u&&0!==r._model.tension&&i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i,a,r=this,o=r.getMeta(),s=t.custom||{},l=r.getDataset(),u=r.index,d=l.data[e],h=r._xScale,c=r._yScale,f=o.dataset._model,g=r._resolveDataElementOptions(t,e);i=h.getPixelForValue("object"==typeof d?d:NaN,e,u),a=n?c.getBasePixel():r.calculatePointY(d,e,u),t._xScale=h,t._yScale=c,t._options=g,t._datasetIndex=u,t._index=e,t._model={x:i,y:a,skip:s.skip||isNaN(i)||isNaN(a),radius:g.radius,pointStyle:g.pointStyle,rotation:g.rotation,backgroundColor:g.backgroundColor,borderColor:g.borderColor,borderWidth:g.borderWidth,tension:Wt(s.tension,f?f.tension:0),steppedLine:!!f&&f.steppedLine,hitRadius:g.hitRadius}},_resolveDatasetElementOptions:function(t){var e=this,n=e._config,i=t.custom||{},a=e.chart.options,r=a.elements.line,o=it.prototype._resolveDatasetElementOptions.apply(e,arguments);return o.spanGaps=Wt(n.spanGaps,a.spanGaps),o.tension=Wt(n.lineTension,r.tension),o.steppedLine=Vt([i.steppedLine,n.steppedLine,r.stepped]),o.clip=Ut(Wt(n.clip,qt(e._xScale,e._yScale,o.borderWidth))),o},calculatePointY:function(t,e,n){var i,a,r,o,s,l,u,d=this.chart,h=this._yScale,c=0,f=0;if(h.options.stacked){for(s=+h.getRightValue(t),u=(l=d._getSortedVisibleDatasetMetas()).length,i=0;i<u&&(r=l[i]).index!==n;++i)a=d.data.datasets[r.index],"line"===r.type&&r.yAxisID===h.id&&((o=+h.getRightValue(a.data[e]))<0?f+=o||0:c+=o||0);return s<0?h.getPixelForValue(f+s):h.getPixelForValue(c+s)}return h.getPixelForValue(t)},updateBezierControlPoints:function(){var t,e,n,i,a=this.chart,r=this.getMeta(),o=r.dataset._model,s=a.chartArea,l=r.data||[];function u(t,e,n){return Math.max(Math.min(t,n),e)}if(o.spanGaps&&(l=l.filter((function(t){return!t._model.skip}))),"monotone"===o.cubicInterpolationMode)H.splineCurveMonotone(l);else for(t=0,e=l.length;t<e;++t)n=l[t]._model,i=H.splineCurve(H.previousItem(l,t)._model,n,H.nextItem(l,t)._model,o.tension),n.controlPointPreviousX=i.previous.x,n.controlPointPreviousY=i.previous.y,n.controlPointNextX=i.next.x,n.controlPointNextY=i.next.y;if(a.options.elements.line.capBezierPoints)for(t=0,e=l.length;t<e;++t)n=l[t]._model,Ht(n,s)&&(t>0&&Ht(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t<l.length-1&&Ht(l[t+1]._model,s)&&(n.controlPointNextX=u(n.controlPointNextX,s.left,s.right),n.controlPointNextY=u(n.controlPointNextY,s.top,s.bottom)))},draw:function(){var t,e=this.chart,n=this.getMeta(),i=n.data||[],a=e.chartArea,r=e.canvas,o=0,s=i.length;for(this._showLine&&(t=n.dataset._model.clip,H.canvas.clipArea(e.ctx,{left:!1===t.left?0:a.left-t.left,right:!1===t.right?r.width:a.right+t.right,top:!1===t.top?0:a.top-t.top,bottom:!1===t.bottom?r.height:a.bottom+t.bottom}),n.dataset.draw(),H.canvas.unclipArea(e.ctx));o<s;++o)i[o].draw(a)},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Wt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Wt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Wt(n.hoverBorderWidth,n.borderWidth),e.radius=Wt(n.hoverRadius,n.radius)}}),Gt=H.options.resolve;N._set("polarArea",{scale:{type:"radialLinear",angleLines:{display:!1},gridLines:{circular:!0},pointLabels:{display:!1},ticks:{beginAtZero:!0}},animation:{animateRotate:!0,animateScale:!0},startAngle:-.5*Math.PI,legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data,o=r.datasets,s=r.labels;if(a.setAttribute("class",t.id+"-legend"),o.length)for(e=0,n=o[0].data.length;e<n;++e)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=o[0].backgroundColor[e],s[e]&&i.appendChild(document.createTextNode(s[e]));return a.outerHTML},legend:{labels:{generateLabels:function(t){var e=t.data;return e.labels.length&&e.datasets.length?e.labels.map((function(n,i){var a=t.getDatasetMeta(0),r=a.controller.getStyle(i);return{text:n,fillStyle:r.backgroundColor,strokeStyle:r.borderColor,lineWidth:r.borderWidth,hidden:isNaN(e.datasets[0].data[i])||a.data[i].hidden,index:i}})):[]}},onClick:function(t,e){var n,i,a,r=e.index,o=this.chart;for(n=0,i=(o.data.datasets||[]).length;n<i;++n)(a=o.getDatasetMeta(n)).data[r].hidden=!a.data[r].hidden;o.update()}},tooltips:{callbacks:{title:function(){return""},label:function(t,e){return e.labels[t.index]+": "+t.yLabel}}}});var Xt=it.extend({dataElementType:kt.Arc,linkScales:H.noop,_dataElementOptions:["backgroundColor","borderColor","borderWidth","borderAlign","hoverBackgroundColor","hoverBorderColor","hoverBorderWidth"],_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(t){var e,n,i,a=this,r=a.getDataset(),o=a.getMeta(),s=a.chart.options.startAngle||0,l=a._starts=[],u=a._angles=[],d=o.data;for(a._updateRadius(),o.count=a.countVisibleElements(),e=0,n=r.data.length;e<n;e++)l[e]=s,i=a._computeAngle(e),u[e]=i,s+=i;for(e=0,n=d.length;e<n;++e)d[e]._options=a._resolveDataElementOptions(d[e],e),a.updateElement(d[e],e,t)},_updateRadius:function(){var t=this,e=t.chart,n=e.chartArea,i=e.options,a=Math.min(n.right-n.left,n.bottom-n.top);e.outerRadius=Math.max(a/2,0),e.innerRadius=Math.max(i.cutoutPercentage?e.outerRadius/100*i.cutoutPercentage:1,0),e.radiusLength=(e.outerRadius-e.innerRadius)/e.getVisibleDatasetCount(),t.outerRadius=e.outerRadius-e.radiusLength*t.index,t.innerRadius=t.outerRadius-e.radiusLength},updateElement:function(t,e,n){var i=this,a=i.chart,r=i.getDataset(),o=a.options,s=o.animation,l=a.scale,u=a.data.labels,d=l.xCenter,h=l.yCenter,c=o.startAngle,f=t.hidden?0:l.getDistanceFromCenterForValue(r.data[e]),g=i._starts[e],p=g+(t.hidden?0:i._angles[e]),m=s.animateScale?0:l.getDistanceFromCenterForValue(r.data[e]),v=t._options||{};H.extend(t,{_datasetIndex:i.index,_index:e,_scale:l,_model:{backgroundColor:v.backgroundColor,borderColor:v.borderColor,borderWidth:v.borderWidth,borderAlign:v.borderAlign,x:d,y:h,innerRadius:0,outerRadius:n?m:f,startAngle:n&&s.animateRotate?c:g,endAngle:n&&s.animateRotate?c:p,label:H.valueAtIndexOrDefault(u,e,u[e])}}),t.pivot()},countVisibleElements:function(){var t=this.getDataset(),e=this.getMeta(),n=0;return H.each(e.data,(function(e,i){isNaN(t.data[i])||e.hidden||n++})),n},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor,a=H.valueOrDefault;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=a(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=a(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=a(n.hoverBorderWidth,n.borderWidth)},_computeAngle:function(t){var e=this,n=this.getMeta().count,i=e.getDataset(),a=e.getMeta();if(isNaN(i.data[t])||a.data[t].hidden)return 0;var r={chart:e.chart,dataIndex:t,dataset:i,datasetIndex:e.index};return Gt([e.chart.options.elements.arc.angle,2*Math.PI/n],r,t)}});N._set("pie",H.clone(N.doughnut)),N._set("pie",{cutoutPercentage:0});var Kt=Bt,Zt=H.valueOrDefault;N._set("radar",{spanGaps:!1,scale:{type:"radialLinear"},elements:{line:{fill:"start",tension:0}}});var $t=it.extend({datasetElementType:kt.Line,dataElementType:kt.Point,linkScales:H.noop,_datasetElementOptions:["backgroundColor","borderWidth","borderColor","borderCapStyle","borderDash","borderDashOffset","borderJoinStyle","fill"],_dataElementOptions:{backgroundColor:"pointBackgroundColor",borderColor:"pointBorderColor",borderWidth:"pointBorderWidth",hitRadius:"pointHitRadius",hoverBackgroundColor:"pointHoverBackgroundColor",hoverBorderColor:"pointHoverBorderColor",hoverBorderWidth:"pointHoverBorderWidth",hoverRadius:"pointHoverRadius",pointStyle:"pointStyle",radius:"pointRadius",rotation:"pointRotation"},_getIndexScaleId:function(){return this.chart.scale.id},_getValueScaleId:function(){return this.chart.scale.id},update:function(t){var e,n,i=this,a=i.getMeta(),r=a.dataset,o=a.data||[],s=i.chart.scale,l=i._config;for(void 0!==l.tension&&void 0===l.lineTension&&(l.lineTension=l.tension),r._scale=s,r._datasetIndex=i.index,r._children=o,r._loop=!0,r._model=i._resolveDatasetElementOptions(r),r.pivot(),e=0,n=o.length;e<n;++e)i.updateElement(o[e],e,t);for(i.updateBezierControlPoints(),e=0,n=o.length;e<n;++e)o[e].pivot()},updateElement:function(t,e,n){var i=this,a=t.custom||{},r=i.getDataset(),o=i.chart.scale,s=o.getPointPositionForValue(e,r.data[e]),l=i._resolveDataElementOptions(t,e),u=i.getMeta().dataset._model,d=n?o.xCenter:s.x,h=n?o.yCenter:s.y;t._scale=o,t._options=l,t._datasetIndex=i.index,t._index=e,t._model={x:d,y:h,skip:a.skip||isNaN(d)||isNaN(h),radius:l.radius,pointStyle:l.pointStyle,rotation:l.rotation,backgroundColor:l.backgroundColor,borderColor:l.borderColor,borderWidth:l.borderWidth,tension:Zt(a.tension,u?u.tension:0),hitRadius:l.hitRadius}},_resolveDatasetElementOptions:function(){var t=this,e=t._config,n=t.chart.options,i=it.prototype._resolveDatasetElementOptions.apply(t,arguments);return i.spanGaps=Zt(e.spanGaps,n.spanGaps),i.tension=Zt(e.lineTension,n.elements.line.tension),i},updateBezierControlPoints:function(){var t,e,n,i,a=this.getMeta(),r=this.chart.chartArea,o=a.data||[];function s(t,e,n){return Math.max(Math.min(t,n),e)}for(a.dataset._model.spanGaps&&(o=o.filter((function(t){return!t._model.skip}))),t=0,e=o.length;t<e;++t)n=o[t]._model,i=H.splineCurve(H.previousItem(o,t,!0)._model,n,H.nextItem(o,t,!0)._model,n.tension),n.controlPointPreviousX=s(i.previous.x,r.left,r.right),n.controlPointPreviousY=s(i.previous.y,r.top,r.bottom),n.controlPointNextX=s(i.next.x,r.left,r.right),n.controlPointNextY=s(i.next.y,r.top,r.bottom)},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth,radius:e.radius},e.backgroundColor=Zt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Zt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Zt(n.hoverBorderWidth,n.borderWidth),e.radius=Zt(n.hoverRadius,n.radius)}});N._set("scatter",{hover:{mode:"single"},scales:{xAxes:[{id:"x-axis-1",type:"linear",position:"bottom"}],yAxes:[{id:"y-axis-1",type:"linear",position:"left"}]},tooltips:{callbacks:{title:function(){return""},label:function(t){return"("+t.xLabel+", "+t.yLabel+")"}}}}),N._set("global",{datasets:{scatter:{showLine:!1}}});var Jt={bar:Tt,bubble:Ot,doughnut:Bt,horizontalBar:Et,line:Yt,polarArea:Xt,pie:Kt,radar:$t,scatter:Yt};function Qt(t,e){return t.native?{x:t.x,y:t.y}:H.getRelativePosition(t,e)}function te(t,e){var n,i,a,r,o,s,l=t._getSortedVisibleDatasetMetas();for(i=0,r=l.length;i<r;++i)for(a=0,o=(n=l[i].data).length;a<o;++a)(s=n[a])._view.skip||e(s)}function ee(t,e){var n=[];return te(t,(function(t){t.inRange(e.x,e.y)&&n.push(t)})),n}function ne(t,e,n,i){var a=Number.POSITIVE_INFINITY,r=[];return te(t,(function(t){if(!n||t.inRange(e.x,e.y)){var o=t.getCenterPoint(),s=i(e,o);s<a?(r=[t],a=s):s===a&&r.push(t)}})),r}function ie(t){var e=-1!==t.indexOf("x"),n=-1!==t.indexOf("y");return function(t,i){var a=e?Math.abs(t.x-i.x):0,r=n?Math.abs(t.y-i.y):0;return Math.sqrt(Math.pow(a,2)+Math.pow(r,2))}}function ae(t,e,n){var i=Qt(e,t);n.axis=n.axis||"x";var a=ie(n.axis),r=n.intersect?ee(t,i):ne(t,i,!1,a),o=[];return r.length?(t._getSortedVisibleDatasetMetas().forEach((function(t){var e=t.data[r[0]._index];e&&!e._view.skip&&o.push(e)})),o):[]}var re={modes:{single:function(t,e){var n=Qt(e,t),i=[];return te(t,(function(t){if(t.inRange(n.x,n.y))return i.push(t),i})),i.slice(0,1)},label:ae,index:ae,dataset:function(t,e,n){var i=Qt(e,t);n.axis=n.axis||"xy";var a=ie(n.axis),r=n.intersect?ee(t,i):ne(t,i,!1,a);return r.length>0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ae(t,e,{intersect:!1})},point:function(t,e){return ee(t,Qt(e,t))},nearest:function(t,e,n){var i=Qt(e,t);n.axis=n.axis||"xy";var a=ie(n.axis);return ne(t,i,n.intersect,a)},x:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},oe=H.extend;function se(t,e){return H.where(t,(function(t){return t.pos===e}))}function le(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function ue(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function de(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-ue(o,t,"left","right"),a=e.outerHeight-ue(o,t,"top","bottom"),i!==t.w||a!==t.h){t.w=i,t.h=a;var l=n.horizontal?[i,t.w]:[a,t.h];return!(l[0]===l[1]||isNaN(l[0])&&isNaN(l[1]))}}function he(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function ce(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;i<a;++i)(o=(r=t[i]).box).update(r.width||e.w,r.height||e.h,he(r.horizontal,e)),de(e,n,r)&&(l=!0,u.length&&(s=!0)),o.fullWidth||u.push(r);return s&&ce(u,e,n)||l}function fe(t,e,n){var i,a,r,o,s=n.padding,l=e.x,u=e.y;for(i=0,a=t.length;i<a;++i)o=(r=t[i]).box,r.horizontal?(o.left=o.fullWidth?s.left:e.left,o.right=o.fullWidth?n.outerWidth-s.right:e.left+e.w,o.top=u,o.bottom=u+o.height,o.width=o.right-o.left,u=o.bottom):(o.left=l,o.right=l+o.width,o.top=e.top,o.bottom=e.top+e.h,o.height=o.bottom-o.top,l=o.right);e.x=l,e.y=u}N._set("global",{layout:{padding:{top:0,right:0,bottom:0,left:0}}});var ge,pe={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),e.fullWidth=e.fullWidth||!1,e.position=e.position||"top",e.weight=e.weight||0,e._layers=e._layers||function(){return[{z:0,draw:function(){e.draw.apply(e,arguments)}}]},t.boxes.push(e)},removeBox:function(t,e){var n=t.boxes?t.boxes.indexOf(e):-1;-1!==n&&t.boxes.splice(n,1)},configure:function(t,e,n){for(var i,a=["fullWidth","position","weight"],r=a.length,o=0;o<r;++o)i=a[o],n.hasOwnProperty(i)&&(e[i]=n[i])},update:function(t,e,n){if(t){var i=t.options.layout||{},a=H.options.toPadding(i.padding),r=e-a.width,o=n-a.height,s=function(t){var e=function(t){var e,n,i,a=[];for(e=0,n=(t||[]).length;e<n;++e)i=t[e],a.push({index:e,box:i,pos:i.position,horizontal:i.isHorizontal(),weight:i.weight});return a}(t),n=le(se(e,"left"),!0),i=le(se(e,"right")),a=le(se(e,"top"),!0),r=le(se(e,"bottom"));return{leftAndTop:n.concat(a),rightAndBottom:i.concat(r),chartArea:se(e,"chartArea"),vertical:n.concat(i),horizontal:a.concat(r)}}(t.boxes),l=s.vertical,u=s.horizontal,d=Object.freeze({outerWidth:e,outerHeight:n,padding:a,availableWidth:r,vBoxMaxWidth:r/2/l.length,hBoxMaxHeight:o/2}),h=oe({maxPadding:oe({},a),w:r,h:o,x:a.left,y:a.top},a);!function(t,e){var n,i,a;for(n=0,i=t.length;n<i;++n)(a=t[n]).width=a.horizontal?a.box.fullWidth&&e.availableWidth:e.vBoxMaxWidth,a.height=a.horizontal&&e.hBoxMaxHeight}(l.concat(u),d),ce(l,h,d),ce(u,h,d)&&ce(l,h,d),function(t){var e=t.maxPadding;function n(n){var i=Math.max(e[n]-t[n],0);return t[n]+=i,i}t.y+=n("top"),t.x+=n("left"),n("right"),n("bottom")}(h),fe(s.leftAndTop,h,d),h.x+=h.w,h.y+=h.h,fe(s.rightAndBottom,h,d),t.chartArea={left:h.left,top:h.top,right:h.left+h.w,bottom:h.top+h.h},H.each(s.chartArea,(function(e){var n=e.box;oe(n,t.chartArea),n.update(h.w,h.h)}))}}},me=(ge=Object.freeze({__proto__:null,default:"@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&ge.default||ge,ve="$chartjs",be="chartjs-size-monitor",xe="chartjs-render-monitor",ye="chartjs-render-animation",_e=["animationstart","webkitAnimationStart"],ke={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function we(t,e){var n=H.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var Me=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Se(t,e,n){t.addEventListener(e,n,Me)}function Ce(t,e,n){t.removeEventListener(e,n,Me)}function Pe(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Ae(t){var e=document.createElement("div");return e.className=t||"",e}function De(t,e,n){var i,a,r,o,s=t[ve]||(t[ve]={}),l=s.resizer=function(t){var e=Ae(be),n=Ae(be+"-expand"),i=Ae(be+"-shrink");n.appendChild(Ae()),i.appendChild(Ae()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Se(n,"scroll",a.bind(n,"expand")),Se(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Pe("resize",n)),i&&i.clientWidth<a&&n.canvas&&e(Pe("resize",n))}},r=!1,o=[],function(){o=Array.prototype.slice.call(arguments),a=a||this,r||(r=!0,H.requestAnimFrame.call(window,(function(){r=!1,i.apply(a,o)})))}));!function(t,e){var n=t[ve]||(t[ve]={}),i=n.renderProxy=function(t){t.animationName===ye&&e()};H.each(_e,(function(e){Se(t,e,i)})),n.reflow=!!t.offsetParent,t.classList.add(xe)}(t,(function(){if(s.resizer){var e=t.parentNode;e&&e!==l.parentNode&&e.insertBefore(l,e.firstChild),l._reset()}}))}function Te(t){var e=t[ve]||{},n=e.resizer;delete e.resizer,function(t){var e=t[ve]||{},n=e.renderProxy;n&&(H.each(_e,(function(e){Ce(t,e,n)})),delete e.renderProxy),t.classList.remove(xe)}(t),n&&n.parentNode&&n.parentNode.removeChild(n)}var Ie={disableCSSInjection:!1,_enabled:"undefined"!=typeof window&&"undefined"!=typeof document,_ensureLoaded:function(t){if(!this.disableCSSInjection){var e=t.getRootNode?t.getRootNode():document;!function(t,e){var n=t[ve]||(t[ve]={});if(!n.containsStyles){n.containsStyles=!0,e="/* Chart.js */\n"+e;var i=document.createElement("style");i.setAttribute("type","text/css"),i.appendChild(document.createTextNode(e)),t.appendChild(i)}}(e.host?e:document.head,me)}},acquireContext:function(t,e){"string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas);var n=t&&t.getContext&&t.getContext("2d");return n&&n.canvas===t?(this._ensureLoaded(t),function(t,e){var n=t.style,i=t.getAttribute("height"),a=t.getAttribute("width");if(t[ve]={initial:{height:i,width:a,style:{display:n.display,height:n.height,width:n.width}}},n.display=n.display||"block",null===a||""===a){var r=we(t,"width");void 0!==r&&(t.width=r)}if(null===i||""===i)if(""===t.style.height)t.height=t.width/(e.options.aspectRatio||2);else{var o=we(t,"height");void 0!==r&&(t.height=o)}}(t,e),n):null},releaseContext:function(t){var e=t.canvas;if(e[ve]){var n=e[ve].initial;["height","width"].forEach((function(t){var i=n[t];H.isNullOrUndef(i)?e.removeAttribute(t):e.setAttribute(t,i)})),H.each(n.style||{},(function(t,n){e.style[n]=t})),e.width=e.width,delete e[ve]}},addEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=n[ve]||(n[ve]={});Se(i,e,(a.proxies||(a.proxies={}))[t.id+"_"+e]=function(e){n(function(t,e){var n=ke[t.type]||t.type,i=H.getRelativePosition(t,e);return Pe(n,e,i.x,i.y,t)}(e,t))})}else De(i,n,t)},removeEventListener:function(t,e,n){var i=t.canvas;if("resize"!==e){var a=((n[ve]||{}).proxies||{})[t.id+"_"+e];a&&Ce(i,e,a)}else Te(i)}};H.addEvent=Se,H.removeEvent=Ce;var Fe=Ie._enabled?Ie:{acquireContext:function(t){return t&&t.canvas&&(t=t.canvas),t&&t.getContext("2d")||null}},Oe=H.extend({initialize:function(){},acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},Fe);N._set("global",{plugins:{}});var Le={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach((function(t){-1===e.indexOf(t)&&e.push(t)})),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach((function(t){var n=e.indexOf(t);-1!==n&&e.splice(n,1)})),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length},getAll:function(){return this._plugins},notify:function(t,e,n){var i,a,r,o,s,l=this.descriptors(t),u=l.length;for(i=0;i<u;++i)if("function"==typeof(s=(r=(a=l[i]).plugin)[e])&&((o=[t].concat(n||[])).push(a.options),!1===s.apply(r,o)))return!1;return!0},descriptors:function(t){var e=t.$plugins||(t.$plugins={});if(e.id===this._cacheId)return e.descriptors;var n=[],i=[],a=t&&t.config||{},r=a.options&&a.options.plugins||{};return this._plugins.concat(a.plugins||[]).forEach((function(t){if(-1===n.indexOf(t)){var e=t.id,a=r[e];!1!==a&&(!0===a&&(a=H.clone(N.global.plugins[e])),n.push(t),i.push({plugin:t,options:a||{}}))}})),e.descriptors=i,e.id=this._cacheId,i},_invalidate:function(t){delete t.$plugins}},Re={constructors:{},defaults:{},registerScaleType:function(t,e,n){this.constructors[t]=e,this.defaults[t]=H.clone(n)},getScaleConstructor:function(t){return this.constructors.hasOwnProperty(t)?this.constructors[t]:void 0},getScaleDefaults:function(t){return this.defaults.hasOwnProperty(t)?H.merge(Object.create(null),[N.scale,this.defaults[t]]):{}},updateScaleDefaults:function(t,e){this.defaults.hasOwnProperty(t)&&(this.defaults[t]=H.extend(this.defaults[t],e))},addScalesToLayout:function(t){H.each(t.scales,(function(e){e.fullWidth=e.options.fullWidth,e.position=e.options.position,e.weight=e.options.weight,pe.addBox(t,e)}))}},ze=H.valueOrDefault,Ne=H.rtl.getRtlAdapter;N._set("global",{tooltips:{enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretPadding:2,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,borderColor:"rgba(0,0,0,0)",borderWidth:0,callbacks:{beforeTitle:H.noop,title:function(t,e){var n="",i=e.labels,a=i?i.length:0;if(t.length>0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index<a&&(n=i[r.index])}return n},afterTitle:H.noop,beforeBody:H.noop,beforeLabel:H.noop,label:function(t,e){var n=e.datasets[t.datasetIndex].label||"";return n&&(n+=": "),H.isNullOrUndef(t.value)?n+=t.yLabel:n+=t.value,n},labelColor:function(t,e){var n=e.getDatasetMeta(t.datasetIndex).data[t.index]._view;return{borderColor:n.borderColor,backgroundColor:n.backgroundColor}},labelTextColor:function(){return this._options.bodyFontColor},afterLabel:H.noop,afterBody:H.noop,beforeFooter:H.noop,footer:H.noop,afterFooter:H.noop}}});var Be={average:function(t){if(!t.length)return!1;var e,n,i=0,a=0,r=0;for(e=0,n=t.length;e<n;++e){var o=t[e];if(o&&o.hasValue()){var s=o.tooltipPosition();i+=s.x,a+=s.y,++r}}return{x:i/r,y:a/r}},nearest:function(t,e){var n,i,a,r=e.x,o=e.y,s=Number.POSITIVE_INFINITY;for(n=0,i=t.length;n<i;++n){var l=t[n];if(l&&l.hasValue()){var u=l.getCenterPoint(),d=H.distanceBetweenPoints(e,u);d<s&&(s=d,a=l)}}if(a){var h=a.tooltipPosition();r=h.x,o=h.y}return{x:r,y:o}}};function Ee(t,e){return e&&(H.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function We(t){return("string"==typeof t||t instanceof String)&&t.indexOf("\n")>-1?t.split("\n"):t}function Ve(t){var e=N.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:ze(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:ze(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:ze(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:ze(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:ze(t.titleFontStyle,e.defaultFontStyle),titleFontSize:ze(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:ze(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:ze(t.footerFontStyle,e.defaultFontStyle),footerFontSize:ze(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function He(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function je(t){return Ee([],We(t))}var qe=K.extend({initialize:function(){this._model=Ve(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=Ee(o,We(i)),o=Ee(o,We(a)),o=Ee(o,We(r))},getBeforeBody:function(){return je(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return H.each(t,(function(t){var r={before:[],lines:[],after:[]};Ee(r.before,We(i.beforeLabel.call(n,t,e))),Ee(r.lines,i.label.call(n,t,e)),Ee(r.after,We(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return je(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=Ee(r,We(n)),r=Ee(r,We(i)),r=Ee(r,We(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=Ve(c),p=h._active,m=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},x={width:f.width,height:f.height},y={x:f.caretX,y:f.caretY};if(p.length){g.opacity=1;var _=[],k=[];y=Be[c.position].call(h,p,h._eventPosition);var w=[];for(e=0,n=p.length;e<n;++e)w.push((i=p[e],a=void 0,r=void 0,o=void 0,s=void 0,l=void 0,u=void 0,d=void 0,a=i._xScale,r=i._yScale||i._scale,o=i._index,s=i._datasetIndex,l=i._chart.getDatasetMeta(s).controller,u=l._getIndexScale(),d=l._getValueScale(),{xLabel:a?a.getLabelForIndex(o,s):"",yLabel:r?r.getLabelForIndex(o,s):"",label:u?""+u.getLabelForIndex(o,s):"",value:d?""+d.getLabelForIndex(o,s):"",index:o,datasetIndex:s,x:i._model.x,y:i._model.y}));c.filter&&(w=w.filter((function(t){return c.filter(t,m)}))),c.itemSort&&(w=w.sort((function(t,e){return c.itemSort(t,e,m)}))),H.each(w,(function(t){_.push(c.callbacks.labelColor.call(h,t,h._chart)),k.push(c.callbacks.labelTextColor.call(h,t,h._chart))})),g.title=h.getTitle(w,m),g.beforeBody=h.getBeforeBody(w,m),g.body=h.getBody(w,m),g.afterBody=h.getAfterBody(w,m),g.footer=h.getFooter(w,m),g.x=y.x,g.y=y.y,g.caretPadding=c.caretPadding,g.labelColors=_,g.labelTextColors=k,g.dataPoints=w,x=function(t,e){var n=t._chart.ctx,i=2*e.yPadding,a=0,r=e.body,o=r.reduce((function(t,e){return t+e.before.length+e.lines.length+e.after.length}),0);o+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,l=e.footer.length,u=e.titleFontSize,d=e.bodyFontSize,h=e.footerFontSize;i+=s*u,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=o*d,i+=o?(o-1)*e.bodySpacing:0,i+=l?e.footerMarginTop:0,i+=l*h,i+=l?(l-1)*e.footerSpacing:0;var c=0,f=function(t){a=Math.max(a,n.measureText(t).width+c)};return n.font=H.fontString(u,e._titleFontStyle,e._titleFontFamily),H.each(e.title,f),n.font=H.fontString(d,e._bodyFontStyle,e._bodyFontFamily),H.each(e.beforeBody.concat(e.afterBody),f),c=e.displayColors?d+2:0,H.each(r,(function(t){H.each(t.before,f),H.each(t.lines,f),H.each(t.after,f)})),c=0,n.font=H.fontString(h,e._footerFontStyle,e._footerFontFamily),H.each(e.footer,f),{width:a+=2*e.xPadding,height:i}}(this,g),b=function(t,e,n,i){var a=t.x,r=t.y,o=t.caretSize,s=t.caretPadding,l=t.cornerRadius,u=n.xAlign,d=n.yAlign,h=o+s,c=l+s;return"right"===u?a-=e.width:"center"===u&&((a-=e.width/2)+e.width>i.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,x,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.y<e.height?h="top":s.y>l.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,x),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=x.width,g.height=x.height,g.caretX=y.x,g.caretY=y.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,p=e.width,m=e.height;if("center"===c)s=g+m/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+p)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+p-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+m)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=Ne(e.rtl,e.x,e.width);for(t.x=He(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=H.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r<s;++r)n.fillText(o[r],l.x(t.x),t.y+i/2),t.y+=i+a,r+1===s&&(t.y+=e.titleMarginBottom-a)}},drawBody:function(t,e,n){var i,a,r,o,s,l,u,d,h=e.bodyFontSize,c=e.bodySpacing,f=e._bodyAlign,g=e.body,p=e.displayColors,m=0,v=p?He(e,"left"):0,b=Ne(e.rtl,e.x,e.width),x=function(e){n.fillText(e,b.x(t.x+m),t.y+h/2),t.y+=h+c},y=b.textAlign(f);for(n.textAlign=f,n.textBaseline="middle",n.font=H.fontString(h,e._bodyFontStyle,e._bodyFontFamily),t.x=He(e,y),n.fillStyle=e.bodyFontColor,H.each(e.beforeBody,x),m=p&&"right"!==y?"center"===f?h/2+1:h+2:0,s=0,u=g.length;s<u;++s){for(i=g[s],a=e.labelTextColors[s],r=e.labelColors[s],n.fillStyle=a,H.each(i.before,x),l=0,d=(o=i.lines).length;l<d;++l){if(p){var _=b.x(v);n.fillStyle=e.legendColorBackground,n.fillRect(b.leftForLtr(_,h),t.y,h,h),n.lineWidth=1,n.strokeStyle=r.borderColor,n.strokeRect(b.leftForLtr(_,h),t.y,h,h),n.fillStyle=r.backgroundColor,n.fillRect(b.leftForLtr(b.xPlus(_,1),h-2),t.y+1,h-2,h-2),n.fillStyle=a}x(o[l])}H.each(i.after,x)}m=0,H.each(e.afterBody,x),t.y-=c},drawFooter:function(t,e,n){var i,a,r=e.footer,o=r.length;if(o){var s=Ne(e.rtl,e.x,e.width);for(t.x=He(e,e._footerAlign),t.y+=e.footerMarginTop,n.textAlign=s.textAlign(e._footerAlign),n.textBaseline="middle",i=e.footerFontSize,n.fillStyle=e.footerFontColor,n.font=H.fontString(i,e._footerFontStyle,e._footerFontFamily),a=0;a<o;++a)n.fillText(r[a],s.x(t.x),t.y+i/2),t.y+=i+e.footerSpacing}},drawBackground:function(t,e,n,i){n.fillStyle=e.backgroundColor,n.strokeStyle=e.borderColor,n.lineWidth=e.borderWidth;var a=e.xAlign,r=e.yAlign,o=t.x,s=t.y,l=i.width,u=i.height,d=e.cornerRadius;n.beginPath(),n.moveTo(o+d,s),"top"===r&&this.drawCaret(t,i),n.lineTo(o+l-d,s),n.quadraticCurveTo(o+l,s,o+l,s+d),"center"===r&&"right"===a&&this.drawCaret(t,i),n.lineTo(o+l,s+u-d),n.quadraticCurveTo(o+l,s+u,o+l-d,s+u),"bottom"===r&&this.drawCaret(t,i),n.lineTo(o+d,s+u),n.quadraticCurveTo(o,s+u,o,s+u-d),"center"===r&&"left"===a&&this.drawCaret(t,i),n.lineTo(o,s+d),n.quadraticCurveTo(o,s,o+d,s),n.closePath(),n.fill(),e.borderWidth>0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,H.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),H.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!H.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),Ue=Be,Ye=qe;Ye.positioners=Ue;var Ge=H.valueOrDefault;function Xe(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a<s;++a)o=n[t][a],r=Ge(o.type,"xAxes"===t?"category":"linear"),a>=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?H.merge(e[t][a],[Re.getScaleDefaults(r),o]):H.merge(e[t][a],o)}else H._merger(t,e,n,i)}})}function Ke(){return H.merge(Object.create(null),[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||Object.create(null),r=n[t];"scales"===t?e[t]=Xe(a,r):"scale"===t?e[t]=H.merge(a,[Re.getScaleDefaults(r.type),r]):H._merger(t,e,n,i)}})}function Ze(t){var e=t.options;H.each(t.scales,(function(e){pe.removeBox(t,e)})),e=Ke(N.global,N[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function $e(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(H.findIndex(t,a)>=0);return i}function Je(t){return"top"===t||"bottom"===t}function Qe(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}N._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var tn=function(t,e){return this.construct(t,e),this};H.extend(tn.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||Object.create(null)).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=Ke(N.global,N[t.type],t.options||{}),t}(e);var i=Oe.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=H.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,tn.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),H.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return H.canvas.clear(this),this},stop:function(){return J.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(H.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:H.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",H.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;H.each(e.xAxes,(function(t,n){t.id||(t.id=$e(e.xAxes,"x-axis-",n))})),H.each(e.yAxes,(function(t,n){t.id||(t.id=$e(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),H.each(i,(function(e){var i=e.options,r=i.id,o=Ge(i.type,e.dtype);Je(i.position)!==Je(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Re.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),H.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Re.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t<e;t++){var r=a[t],o=n.getDatasetMeta(t),s=r.type||n.config.type;if(o.type&&o.type!==s&&(n.destroyDatasetMeta(t),o=n.getDatasetMeta(t)),o.type=s,o.order=r.order||0,o.index=t,o.controller)o.controller.updateIndex(t),o.controller.linkScales();else{var l=Jt[o.type];if(void 0===l)throw new Error('"'+o.type+'" is not a chart type.');o.controller=new l(n,t),i.push(o.controller)}}return i},resetElements:function(){var t=this;H.each(t.data.datasets,(function(e,n){t.getDatasetMeta(n).controller.reset()}),t)},reset:function(){this.resetElements(),this.tooltip.initialize()},update:function(t){var e,n,i=this;if(t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]}),Ze(i),Le._invalidate(i),!1!==Le.notify(i,"beforeUpdate")){i.tooltip._data=i.data;var a=i.buildOrUpdateControllers();for(e=0,n=i.data.datasets.length;e<n;e++)i.getDatasetMeta(e).controller.buildOrUpdateElements();i.updateLayout(),i.options.animation&&i.options.animation.duration&&H.each(a,(function(t){t.reset()})),i.updateDatasets(),i.tooltip.initialize(),i.lastActive=[],Le.notify(i,"afterUpdate"),i._layers.sort(Qe("z","_idx")),i._bufferedRender?i._bufferedRequest={duration:t.duration,easing:t.easing,lazy:t.lazy}:i.render(t)}},updateLayout:function(){var t=this;!1!==Le.notify(t,"beforeLayout")&&(pe.update(this,this.width,this.height),t._layers=[],H.each(t.boxes,(function(e){e._configure&&e._configure(),t._layers.push.apply(t._layers,e._layers())}),t),t._layers.forEach((function(t,e){t._idx=e})),Le.notify(t,"afterScaleUpdate"),Le.notify(t,"afterLayout"))},updateDatasets:function(){if(!1!==Le.notify(this,"beforeDatasetsUpdate")){for(var t=0,e=this.data.datasets.length;t<e;++t)this.updateDataset(t);Le.notify(this,"afterDatasetsUpdate")}},updateDataset:function(t){var e=this.getDatasetMeta(t),n={meta:e,index:t};!1!==Le.notify(this,"beforeDatasetUpdate",[n])&&(e.controller._update(),Le.notify(this,"afterDatasetUpdate",[n]))},render:function(t){var e=this;t&&"object"==typeof t||(t={duration:t,lazy:arguments[1]});var n=e.options.animation,i=Ge(t.duration,n&&n.duration),a=t.lazy;if(!1!==Le.notify(e,"beforeRender")){var r=function(t){Le.notify(e,"afterRender"),H.callback(n&&n.onComplete,[t],e)};if(n&&i){var o=new $({numSteps:i/16.66,easing:t.easing||n.easing,render:function(t,e){var n=H.easing.effects[e.easing],i=e.currentStep,a=i/e.numSteps;t.draw(n(a),a,i)},onAnimationProgress:n.onProgress,onAnimationComplete:r});J.addAnimation(e,o,i,a)}else e.draw(),r(new $({numSteps:0,chart:e}));return e}},draw:function(t){var e,n,i=this;if(i.clear(),H.isNullOrUndef(t)&&(t=1),i.transition(t),!(i.width<=0||i.height<=0)&&!1!==Le.notify(i,"beforeDraw",[t])){for(n=i._layers,e=0;e<n.length&&n[e].z<=0;++e)n[e].draw(i.chartArea);for(i.drawDatasets(t);e<n.length;++e)n[e].draw(i.chartArea);i._drawTooltip(t),Le.notify(i,"afterDraw",[t])}},transition:function(t){for(var e=0,n=(this.data.datasets||[]).length;e<n;++e)this.isDatasetVisible(e)&&this.getDatasetMeta(e).controller.transition(t);this.tooltip.transition(t)},_getSortedDatasetMetas:function(t){var e,n,i=[];for(e=0,n=(this.data.datasets||[]).length;e<n;++e)t&&!this.isDatasetVisible(e)||i.push(this.getDatasetMeta(e));return i.sort(Qe("order","index")),i},_getSortedVisibleDatasetMetas:function(){return this._getSortedDatasetMetas(!0)},drawDatasets:function(t){var e,n;if(!1!==Le.notify(this,"beforeDatasetsDraw",[t])){for(n=(e=this._getSortedVisibleDatasetMetas()).length-1;n>=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return re.modes.single(this,t)},getElementsAtEvent:function(t){return re.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return re.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=re.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return re.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e<n;++e)this.isDatasetVisible(e)&&t++;return t},isDatasetVisible:function(t){var e=this.getDatasetMeta(t);return"boolean"==typeof e.hidden?!e.hidden:!this.data.datasets[t].hidden},generateLegend:function(){return this.options.legendCallback(this)},destroyDatasetMeta:function(t){var e=this.id,n=this.data.datasets[t],i=n._meta&&n._meta[e];i&&(i.controller.destroy(),delete n._meta[e])},destroy:function(){var t,e,n=this,i=n.canvas;for(n.stop(),t=0,e=n.data.datasets.length;t<e;++t)n.destroyDatasetMeta(t);i&&(n.unbindEvents(),H.canvas.clear(n),Oe.releaseContext(n.ctx),n.canvas=null,n.ctx=null),Le.notify(n,"destroy"),delete tn.instances[n.id]},toBase64Image:function(){return this.canvas.toDataURL.apply(this.canvas,arguments)},initToolTip:function(){var t=this;t.tooltip=new Ye({_chart:t,_chartInstance:t,_data:t.data,_options:t.options.tooltips},t)},bindEvents:function(){var t=this,e=t._listeners={},n=function(){t.eventHandler.apply(t,arguments)};H.each(t.options.events,(function(i){Oe.addEventListener(t,i,n),e[i]=n})),t.options.responsive&&(n=function(){t.resize()},Oe.addEventListener(t,"resize",n),e.resize=n)},unbindEvents:function(){var t=this,e=t._listeners;e&&(delete t._listeners,H.each(e,(function(e,n){Oe.removeEventListener(t,n,e)})))},updateHoverStyle:function(t,e,n){var i,a,r,o=n?"set":"remove";for(a=0,r=t.length;a<r;++a)(i=t[a])&&this.getDatasetMeta(i._datasetIndex).controller[o+"HoverStyle"](i);"dataset"===e&&this.getDatasetMeta(t[0]._datasetIndex).controller["_"+o+"DatasetHoverStyle"]()},eventHandler:function(t){var e=this,n=e.tooltip;if(!1!==Le.notify(e,"beforeEvent",[t])){e._bufferedRender=!0,e._bufferedRequest=null;var i=e.handleEvent(t);n&&(i=n._start?n.handleEvent(t):i|n.handleEvent(t)),Le.notify(e,"afterEvent",[t]);var a=e._bufferedRequest;return a?e.render(a):i&&!e.animating&&(e.stop(),e.render({duration:e.options.hover.animationDuration,lazy:!0})),e._bufferedRender=!1,e._bufferedRequest=null,e}},handleEvent:function(t){var e,n=this,i=n.options||{},a=i.hover;return n.lastActive=n.lastActive||[],"mouseout"===t.type?n.active=[]:n.active=n.getElementsAtEventForMode(t,a.mode,a),H.callback(i.onHover||i.hover.onHover,[t.native,n.active],n),"mouseup"!==t.type&&"click"!==t.type||i.onClick&&i.onClick.call(n,t.native,n.active),n.lastActive.length&&n.updateHoverStyle(n.lastActive,a.mode,!1),n.active.length&&a.mode&&n.updateHoverStyle(n.active,a.mode,!0),e=!H.arrayEquals(n.active,n.lastActive),n.lastActive=n.active,e}}),tn.instances={};var en=tn;tn.Controller=tn,tn.types={},H.configMerge=Ke,H.scaleMerge=Xe;function nn(){throw new Error("This method is not implemented: either no adapter can be found or an incomplete integration was provided.")}function an(t){this.options=t||{}}H.extend(an.prototype,{formats:nn,parse:nn,format:nn,add:nn,diff:nn,startOf:nn,endOf:nn,_create:function(t){return t}}),an.override=function(t){H.extend(an.prototype,t)};var rn={_date:an},on={formatters:{values:function(t){return H.isArray(t)?t:""+t},linear:function(t,e,n){var i=n.length>3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=H.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=H.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(H.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},sn=H.isArray,ln=H.isNullOrUndef,un=H.valueOrDefault,dn=H.valueAtIndexOrDefault;function hn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=r<e?i:-i)<s-1e-6||o>l+1e-6)))return o}function cn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,p,m,v=n.length,b=[],x=[],y=[],_=0,k=0;for(a=0;a<v;++a){if(s=n[a].label,l=n[a].major?e.major:e.minor,t.font=u=l.string,d=i[u]=i[u]||{data:{},gc:[]},h=l.lineHeight,c=f=0,ln(s)||sn(s)){if(sn(s))for(r=0,o=s.length;r<o;++r)g=s[r],ln(g)||sn(g)||(c=H.measureText(t,d.data,d.gc,c,g),f+=h)}else c=H.measureText(t,d.data,d.gc,c,s),f=h;b.push(c),x.push(f),y.push(h/2),_=Math.max(c,_),k=Math.max(f,k)}function w(t){return{width:b[t]||0,height:x[t]||0,offset:y[t]||0}}return function(t,e){H.each(t,(function(t){var n,i=t.gc,a=i.length/2;if(a>e){for(n=0;n<a;++n)delete t.data[i[n]];i.splice(0,a)}}))}(i,v),p=b.indexOf(_),m=x.indexOf(k),{first:w(0),last:w(v-1),widest:w(p),highest:w(m)}}function fn(t){return t.drawTicks?t.tickMarkLength:0}function gn(t){var e,n;return t.display?(e=H.options._parseFont(t),n=H.options.toPadding(t.padding),e.lineHeight+n.height):0}function pn(t,e){return H.extend(H.options._parseFont({fontFamily:un(e.fontFamily,t.fontFamily),fontSize:un(e.fontSize,t.fontSize),fontStyle:un(e.fontStyle,t.fontStyle),lineHeight:un(e.lineHeight,t.lineHeight)}),{color:H.options.resolve([e.fontColor,t.fontColor,N.global.defaultFontColor])})}function mn(t){var e=pn(t,t.minor);return{minor:e,major:t.major.enabled?pn(t,t.major):e}}function vn(t){var e,n,i,a=[];for(n=0,i=t.length;n<i;++n)void 0!==(e=t[n])._index&&a.push(e);return a}function bn(t,e,n,i){var a,r,o,s,l=un(n,0),u=Math.min(un(i,t.length),t.length),d=0;for(e=Math.ceil(e),i&&(e=(a=i-n)/Math.floor(a/e)),s=l;s<0;)d++,s=Math.round(l+d*e);for(r=Math.max(l,0);r<u;r++)o=t[r],r===s?(o._index=r,d++,s=Math.round(l+d*e)):delete o.label}N._set("scale",{display:!0,position:"left",offset:!1,gridLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,drawBorder:!0,drawOnChartArea:!0,drawTicks:!0,tickMarkLength:10,zeroLineWidth:1,zeroLineColor:"rgba(0,0,0,0.25)",zeroLineBorderDash:[],zeroLineBorderDashOffset:0,offsetGridLines:!1,borderDash:[],borderDashOffset:0},scaleLabel:{display:!1,labelString:"",padding:{top:4,bottom:4}},ticks:{beginAtZero:!1,minRotation:0,maxRotation:50,mirror:!1,padding:0,reverse:!1,display:!0,autoSkip:!0,autoSkipPadding:0,labelOffset:0,callback:on.formatters.values,minor:{},major:{}}});var xn=K.extend({zeroLineIndex:0,getPadding:function(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}},getTicks:function(){return this._ticks},_getLabels:function(){var t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]},mergeTicksOptions:function(){},beforeUpdate:function(){H.callback(this.options.beforeUpdate,[this])},update:function(t,e,n){var i,a,r,o,s,l=this,u=l.options.ticks,d=u.sampleSize;if(l.beforeUpdate(),l.maxWidth=t,l.maxHeight=e,l.margins=H.extend({left:0,right:0,top:0,bottom:0},n),l._ticks=null,l.ticks=null,l._labelSizes=null,l._maxLabelLines=0,l.longestLabelWidth=0,l.longestTextCache=l.longestTextCache||{},l._gridLineItems=null,l._labelItems=null,l.beforeSetDimensions(),l.setDimensions(),l.afterSetDimensions(),l.beforeDataLimits(),l.determineDataLimits(),l.afterDataLimits(),l.beforeBuildTicks(),o=l.buildTicks()||[],(!(o=l.afterBuildTicks(o)||o)||!o.length)&&l.ticks)for(o=[],i=0,a=l.ticks.length;i<a;++i)o.push({value:l.ticks[i],major:!1});return l._ticks=o,s=d<o.length,r=l._convertTicksToLabels(s?function(t,e){for(var n=[],i=t.length/e,a=0,r=t.length;a<r;a+=i)n.push(t[Math.floor(a)]);return n}(o,d):o),l._configure(),l.beforeCalculateTickRotation(),l.calculateTickRotation(),l.afterCalculateTickRotation(),l.beforeFit(),l.fit(),l.afterFit(),l._ticksToDraw=u.display&&(u.autoSkip||"auto"===u.source)?l._autoSkip(o):o,s&&(r=l._convertTicksToLabels(l._ticksToDraw)),l.ticks=r,l.afterUpdate(),l.minSize},_configure:function(){var t,e,n=this,i=n.options.ticks.reverse;n.isHorizontal()?(t=n.left,e=n.right):(t=n.top,e=n.bottom,i=!i),n._startPixel=t,n._endPixel=e,n._reversePixels=i,n._length=e-t},afterUpdate:function(){H.callback(this.options.afterUpdate,[this])},beforeSetDimensions:function(){H.callback(this.options.beforeSetDimensions,[this])},setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0},afterSetDimensions:function(){H.callback(this.options.afterSetDimensions,[this])},beforeDataLimits:function(){H.callback(this.options.beforeDataLimits,[this])},determineDataLimits:H.noop,afterDataLimits:function(){H.callback(this.options.afterDataLimits,[this])},beforeBuildTicks:function(){H.callback(this.options.beforeBuildTicks,[this])},buildTicks:H.noop,afterBuildTicks:function(t){var e=this;return sn(t)&&t.length?H.callback(e.options.afterBuildTicks,[e,t]):(e.ticks=H.callback(e.options.afterBuildTicks,[e,e.ticks])||e.ticks,t)},beforeTickToLabelConversion:function(){H.callback(this.options.beforeTickToLabelConversion,[this])},convertTicksToLabels:function(){var t=this.options.ticks;this.ticks=this.ticks.map(t.userCallback||t.callback,this)},afterTickToLabelConversion:function(){H.callback(this.options.afterTickToLabelConversion,[this])},beforeCalculateTickRotation:function(){H.callback(this.options.beforeCalculateTickRotation,[this])},calculateTickRotation:function(){var t,e,n,i,a,r,o,s=this,l=s.options,u=l.ticks,d=s.getTicks().length,h=u.minRotation||0,c=u.maxRotation,f=h;!s._isVisible()||!u.display||h>=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-fn(l.gridLines)-u.padding-gn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=H.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){H.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){H.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=fn(o)+gn(r)),u?s&&(e.height=fn(o)+gn(r)):e.height=t.maxHeight,a.display&&s){var d=mn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,p=h.highest,m=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,x=H.toRadians(t.labelRotation),y=Math.cos(x),_=Math.sin(x),k=_*g.width+y*(p.height-(b?p.offset:0))+(b?0:m);e.height=Math.min(t.maxHeight,e.height+k+v);var w,M,S=t.getPixelForTick(0)-t.left,C=t.right-t.getPixelForTick(t.getTicks().length-1);b?(w=l?y*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):y*f.width+_*f.offset):(w=c.width/2,M=f.width/2),t.paddingLeft=Math.max((w-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-C)*t.width/(t.width-C),0)+3}else{var P=a.mirror?0:g.width+v+m;e.width=Math.min(t.maxWidth,e.width+P),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){H.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(ln(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;n<i;++n)t[n].label=e[n];return e},_getLabelSizes:function(){var t=this,e=t._labelSizes;return e||(t._labelSizes=e=cn(t.ctx,mn(t.options.ticks),t.getTicks(),t.longestTextCache),t.longestLabelWidth=e.widest.width),e},_parseValue:function(t){var e,n,i,a;return sn(t)?(e=+this.getRightValue(t[0]),n=+this.getRightValue(t[1]),i=Math.min(e,n),a=Math.max(e,n)):(e=void 0,n=t=+this.getRightValue(t),i=t,a=t),{min:i,max:a,start:e,end:n}},_getScaleLabel:function(t){var e=this._parseValue(t);return void 0!==e.start?"["+e.start+", "+e.end+"]":+this.getRightValue(t)},getLabelForIndex:H.noop,getPixelForValue:H.noop,getValueForPixel:H.noop,getPixelForTick:function(t){var e=this.options.offset,n=this._ticks.length,i=1/Math.max(n-(e?0:1),1);return t<0||t>n-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;e<n;e++)t[e].major&&i.push(e);return i}(t):[],u=l.length,d=l[0],h=l[u-1];if(u>s)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;i<t.length;i++)a=t[i],i===o?(a._index=i,o=e[++r*n]):delete a.label}(t,l,u/s),vn(t);if(i=function(t,e,n,i){var a,r,o,s,l=function(t){var e,n,i=t.length;if(i<2)return!1;for(n=t[0],e=1;e<i;++e)if(t[e]-t[e-1]!==n)return!1;return n}(t),u=(e.length-1)/i;if(!l)return Math.max(u,1);for(o=0,s=(a=H.math._factorize(l)).length-1;o<s;o++)if((r=a[o])>u)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e<n;e++)bn(t,i,l[e],l[e+1]);return a=u>1?(h-d)/(u-1):null,bn(t,i,H.isNullOrUndef(a)?0:d-a,d),bn(t,i,h,H.isNullOrUndef(a)?t.length:h+a),vn(t)}return bn(t,i),vn(t)},_tickSize:function(){var t=this.options.ticks,e=H.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i<o*n?s/n:o/i},_isVisible:function(){var t,e,n,i=this.chart,a=this.options.display;if("auto"!==a)return!!a;for(t=0,e=i.data.datasets.length;t<e;++t)if(i.isDatasetVisible(t)&&((n=i.getDatasetMeta(t)).xAxisID===this.id||n.yAxisID===this.id))return!0;return!1},_computeGridLineItems:function(t){var e,n,i,a,r,o,s,l,u,d,h,c,f,g,p,m,v,b=this,x=b.chart,y=b.options,_=y.gridLines,k=y.position,w=_.offsetGridLines,M=b.isHorizontal(),S=b._ticksToDraw,C=S.length+(w?1:0),P=fn(_),A=[],D=_.drawBorder?dn(_.lineWidth,0,0):0,T=D/2,I=H._alignPixel,F=function(t){return I(x,t,D)};for("top"===k?(e=F(b.bottom),s=b.bottom-P,u=e-T,h=F(t.top)+T,f=t.bottom):"bottom"===k?(e=F(b.top),h=t.top,f=F(t.bottom)-T,s=e+T,u=b.top+P):"left"===k?(e=F(b.right),o=b.right-P,l=e-T,d=F(t.left)+T,c=t.right):(e=F(b.left),d=t.left,c=F(t.right)-T,o=e+T,l=b.left+P),n=0;n<C;++n)i=S[n]||{},ln(i.label)&&n<S.length||(n===b.zeroLineIndex&&y.offset===w?(g=_.zeroLineWidth,p=_.zeroLineColor,m=_.zeroLineBorderDash||[],v=_.zeroLineBorderDashOffset||0):(g=dn(_.lineWidth,n,1),p=dn(_.color,n,"rgba(0,0,0,0.1)"),m=_.borderDash||[],v=_.borderDashOffset||0),void 0!==(a=hn(b,i._index||n,w))&&(r=I(x,a,g),M?o=l=d=c=r:s=u=h=f=r,A.push({tx1:o,ty1:s,tx2:l,ty2:u,x1:d,y1:h,x2:c,y2:f,width:g,color:p,borderDash:m,borderDashOffset:v})));return A.ticksLength=C,A.borderValue=e,A},_computeLabelItems:function(){var t,e,n,i,a,r,o,s,l,u,d,h,c=this,f=c.options,g=f.ticks,p=f.position,m=g.mirror,v=c.isHorizontal(),b=c._ticksToDraw,x=mn(g),y=g.padding,_=fn(f.gridLines),k=-H.toRadians(c.labelRotation),w=[];for("top"===p?(r=c.bottom-_-y,o=k?"left":"center"):"bottom"===p?(r=c.top+_+y,o=k?"right":"center"):"left"===p?(a=c.right-(m?0:_)-y,o=m?"left":"right"):(a=c.left+(m?0:_)+y,o=m?"right":"left"),t=0,e=b.length;t<e;++t)i=(n=b[t]).label,ln(i)||(s=c.getPixelForTick(n._index||t)+g.labelOffset,u=(l=n.major?x.major:x.minor).lineHeight,d=sn(i)?i.length:1,v?(a=s,h="top"===p?((k?1:.5)-d)*u:(k?0:.5)*u):(r=s,h=(1-d)*u/2),w.push({x:a,y:r,rotation:k,label:i,font:l,textOffset:h,textAlign:o}));return w},_drawGrid:function(t){var e=this,n=e.options.gridLines;if(n.display){var i,a,r,o,s,l=e.ctx,u=e.chart,d=H._alignPixel,h=n.drawBorder?dn(n.lineWidth,0,0):0,c=e._gridLineItems||(e._gridLineItems=e._computeGridLineItems(t));for(r=0,o=c.length;r<o;++r)i=(s=c[r]).width,a=s.color,i&&a&&(l.save(),l.lineWidth=i,l.strokeStyle=a,l.setLineDash&&(l.setLineDash(s.borderDash),l.lineDashOffset=s.borderDashOffset),l.beginPath(),n.drawTicks&&(l.moveTo(s.tx1,s.ty1),l.lineTo(s.tx2,s.ty2)),n.drawOnChartArea&&(l.moveTo(s.x1,s.y1),l.lineTo(s.x2,s.y2)),l.stroke(),l.restore());if(h){var f,g,p,m,v=h,b=dn(n.lineWidth,c.ticksLength-1,1),x=c.borderValue;e.isHorizontal()?(f=d(u,e.left,v)-v/2,g=d(u,e.right,b)+b/2,p=m=x):(p=d(u,e.top,v)-v/2,m=d(u,e.bottom,b)+b/2,f=g=x),l.lineWidth=h,l.strokeStyle=dn(n.color,0),l.beginPath(),l.moveTo(f,p),l.lineTo(g,m),l.stroke()}}},_drawLabels:function(){var t=this;if(t.options.ticks.display){var e,n,i,a,r,o,s,l,u=t.ctx,d=t._labelItems||(t._labelItems=t._computeLabelItems());for(e=0,i=d.length;e<i;++e){if(o=(r=d[e]).font,u.save(),u.translate(r.x,r.y),u.rotate(r.rotation),u.font=o.string,u.fillStyle=o.color,u.textBaseline="middle",u.textAlign=r.textAlign,s=r.label,l=r.textOffset,sn(s))for(n=0,a=s.length;n<a;++n)u.fillText(""+s[n],0,l),l+=o.lineHeight;else u.fillText(s,0,l);u.restore()}}},_drawTitle:function(){var t=this,e=t.ctx,n=t.options,i=n.scaleLabel;if(i.display){var a,r,o=un(i.fontColor,N.global.defaultFontColor),s=H.options._parseFont(i),l=H.options.toPadding(i.padding),u=s.lineHeight/2,d=n.position,h=0;if(t.isHorizontal())a=t.left+t.width/2,r="bottom"===d?t.bottom-u-l.bottom:t.top+u+l.top;else{var c="left"===d;a=c?t.left+u+l.top:t.right-u-l.top,r=t.top+t.height/2,h=c?-.5*Math.PI:.5*Math.PI}e.save(),e.translate(a,r),e.rotate(h),e.textAlign="center",e.textBaseline="middle",e.fillStyle=o,e.font=s.string,e.fillText(i.labelString,0,0),e.restore()}},draw:function(t){this._isVisible()&&(this._drawGrid(t),this._drawTitle(),this._drawLabels())},_layers:function(){var t=this,e=t.options,n=e.ticks&&e.ticks.z||0,i=e.gridLines&&e.gridLines.z||0;return t._isVisible()&&n!==i&&t.draw===t._draw?[{z:i,draw:function(){t._drawGrid.apply(t,arguments),t._drawTitle.apply(t,arguments)}},{z:n,draw:function(){t._drawLabels.apply(t,arguments)}}]:[{z:n,draw:function(){t.draw.apply(t,arguments)}}]},_getMatchingVisibleMetas:function(t){var e=this,n=e.isHorizontal();return e.chart._getSortedVisibleDatasetMetas().filter((function(i){return(!t||i.type===t)&&(n?i.xAxisID===e.id:i.yAxisID===e.id)}))}});xn.prototype._draw=xn.prototype.draw;var yn=xn,_n=H.isNullOrUndef,kn=yn.extend({determineDataLimits:function(){var t,e=this,n=e._getLabels(),i=e.options.ticks,a=i.min,r=i.max,o=0,s=n.length-1;void 0!==a&&(t=n.indexOf(a))>=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;yn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return _n(e)||_n(n)||(t=o.chart.data.datasets[n].data[e]),_n(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=H.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),wn={position:"bottom"};kn._defaults=wn;var Mn=H.noop,Sn=H.isNullOrUndef;var Cn=yn.extend({getRightValue:function(t){return"string"==typeof t?+t:yn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=H.sign(t.min),i=H.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:Mn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:H.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,p=H.niceNum((g-f)/u/l)*l;if(p<1e-14&&Sn(d)&&Sn(h))return[f,g];(r=Math.ceil(g/p)-Math.floor(f/p))>u&&(p=H.niceNum(r*p/u/l)*l),s||Sn(c)?n=Math.pow(10,H._decimalPlaces(p)):(n=Math.pow(10,c),p=Math.ceil(p*n)/n),i=Math.floor(f/p)*p,a=Math.ceil(g/p)*p,s&&(!Sn(d)&&H.almostWhole(d/p,p/1e3)&&(i=d),!Sn(h)&&H.almostWhole(h/p,p/1e3)&&(a=h)),r=(a-i)/p,r=H.almostEquals(r,Math.round(r),p/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Sn(d)?i:d);for(var m=1;m<r;++m)o.push(Math.round((i+m*p)*n)/n);return o.push(Sn(h)?a:h),o}(i,t);t.handleDirectionalChanges(),t.max=H.max(a),t.min=H.min(a),e.reverse?(a.reverse(),t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max)},convertTicksToLabels:function(){var t=this;t.ticksAsNumbers=t.ticks.slice(),t.zeroLineIndex=t.ticks.indexOf(0),yn.prototype.convertTicksToLabels.call(t)},_configure:function(){var t,e=this,n=e.getTicks(),i=e.min,a=e.max;yn.prototype._configure.call(e),e.options.offset&&n.length&&(i-=t=(a-i)/Math.max(n.length-1,1)/2,a+=t),e._startValue=i,e._endValue=a,e._valueRange=a-i}}),Pn={position:"left",ticks:{callback:on.formatters.linear}};function An(t,e,n,i){var a,r,o=t.options,s=function(t,e,n){var i=[n.type,void 0===e&&void 0===n.stack?n.index:"",n.stack].join(".");return void 0===t[i]&&(t[i]={pos:[],neg:[]}),t[i]}(e,o.stacked,n),l=s.pos,u=s.neg,d=i.length;for(a=0;a<d;++a)r=t._parseValue(i[a]),isNaN(r.min)||isNaN(r.max)||n.data[a].hidden||(l[a]=l[a]||0,u[a]=u[a]||0,o.relativePoints?l[a]=100:r.min<0||r.max<0?u[a]+=r.min:l[a]+=r.max)}function Dn(t,e,n){var i,a,r=n.length;for(i=0;i<r;++i)a=t._parseValue(n[i]),isNaN(a.min)||isNaN(a.max)||e.data[i].hidden||(t.min=Math.min(t.min,a.min),t.max=Math.max(t.max,a.max))}var Tn=Cn.extend({determineDataLimits:function(){var t,e,n,i,a=this,r=a.options,o=a.chart.data.datasets,s=a._getMatchingVisibleMetas(),l=r.stacked,u={},d=s.length;if(a.min=Number.POSITIVE_INFINITY,a.max=Number.NEGATIVE_INFINITY,void 0===l)for(t=0;!l&&t<d;++t)l=void 0!==(e=s[t]).stack;for(t=0;t<d;++t)n=o[(e=s[t]).index].data,l?An(a,u,e,n):Dn(a,e,n);H.each(u,(function(t){i=t.pos.concat(t.neg),a.min=Math.min(a.min,H.min(i)),a.max=Math.max(a.max,H.max(i))})),a.min=H.isFinite(a.min)&&!isNaN(a.min)?a.min:0,a.max=H.isFinite(a.max)&&!isNaN(a.max)?a.max:1,a.handleTickRangeOptions()},_computeTickLimit:function(){var t;return this.isHorizontal()?Math.ceil(this.width/40):(t=H.options._parseFont(this.options.ticks),Math.ceil(this.height/t.lineHeight))},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return this._getScaleLabel(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){return this.getPixelForDecimal((+this.getRightValue(t)-this._startValue)/this._valueRange)},getValueForPixel:function(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange},getPixelForTick:function(t){var e=this.ticksAsNumbers;return t<0||t>e.length-1?null:this.getPixelForValue(e[t])}}),In=Pn;Tn._defaults=In;var Fn=H.valueOrDefault,On=H.math.log10;var Ln={position:"left",ticks:{callback:on.formatters.logarithmic}};function Rn(t,e){return H.isFinite(t)&&t>=0?t:e}var zn=yn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t<u.length;t++)if(e=l.getDatasetMeta(t),l.isDatasetVisible(t)&&h(e)&&void 0!==e.stack){c=!0;break}if(s.stacked||c){var f={};for(t=0;t<u.length;t++){var g=[(e=l.getDatasetMeta(t)).type,void 0===s.stacked&&void 0===e.stack?t:"",e.stack].join(".");if(l.isDatasetVisible(t)&&h(e))for(void 0===f[g]&&(f[g]=[]),a=0,r=(i=u[t].data).length;a<r;a++){var p=f[g];n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(p[a]=p[a]||0,p[a]+=n.max)}}H.each(f,(function(t){if(t.length>0){var e=H.min(t),n=H.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t<u.length;t++)if(e=l.getDatasetMeta(t),l.isDatasetVisible(t)&&h(e))for(a=0,r=(i=u[t].data).length;a<r;a++)n=o._parseValue(i[a]),isNaN(n.min)||isNaN(n.max)||e.data[a].hidden||n.min<0||n.max<0||(o.min=Math.min(n.min,o.min),o.max=Math.max(n.max,o.max),0!==n.min&&(o.minNotZero=Math.min(n.min,o.minNotZero)));o.min=H.isFinite(o.min)?o.min:null,o.max=H.isFinite(o.max)?o.max:null,o.minNotZero=H.isFinite(o.minNotZero)?o.minNotZero:null,this.handleTickRangeOptions()},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;t.min=Rn(e.min,t.min),t.max=Rn(e.max,t.max),t.min===t.max&&(0!==t.min&&null!==t.min?(t.min=Math.pow(10,Math.floor(On(t.min))-1),t.max=Math.pow(10,Math.floor(On(t.max))+1)):(t.min=1,t.max=10)),null===t.min&&(t.min=Math.pow(10,Math.floor(On(t.max))-1)),null===t.max&&(t.max=0!==t.min?Math.pow(10,Math.floor(On(t.min))+1):10),null===t.minNotZero&&(t.min>0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(On(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Rn(e.min),max:Rn(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=Fn(t.min,Math.pow(10,Math.floor(On(e.min)))),o=Math.floor(On(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(On(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(On(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(n<o||n===o&&i<s);var u=Fn(t.max,r);return a.push(u),a}(i,t);t.max=H.max(a),t.min=H.min(a),e.reverse?(n=!n,t.start=t.max,t.end=t.min):(t.start=t.min,t.end=t.max),n&&a.reverse()},convertTicksToLabels:function(){this.tickValues=this.ticks.slice(),yn.prototype.convertTicksToLabels.call(this)},getLabelForIndex:function(t,e){return this._getScaleLabel(this.chart.data.datasets[e].data[t])},getPixelForTick:function(t){var e=this.tickValues;return t<0||t>e.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(On(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;yn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=Fn(t.options.ticks.fontSize,N.global.defaultFontSize)/t._length),t._startValue=On(e),t._valueOffset=n,t._valueRange=(On(t.max)-On(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(On(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),Nn=Ln;zn._defaults=Nn;var Bn=H.valueOrDefault,En=H.valueAtIndexOrDefault,Wn=H.options.resolve,Vn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:on.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Hn(t){var e=t.ticks;return e.display&&t.display?Bn(e.fontSize,N.global.defaultFontSize)+2*e.backdropPaddingY:0}function jn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:t<i||t>a?{start:e-n,end:e}:{start:e,end:e+n}}function qn(t){return 0===t||180===t?"center":t<180?"left":"right"}function Un(t,e,n,i){var a,r,o=n.y+i/2;if(H.isArray(e))for(a=0,r=e.length;a<r;++a)t.fillText(e[a],n.x,o),o+=i;else t.fillText(e,n.x,o)}function Yn(t,e,n){90===t||270===t?n.y-=e.h/2:(t>270||t<90)&&(n.y-=e.h)}function Gn(t){return H.isNumber(t)?t:0}var Xn=Cn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Hn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;H.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);H.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Hn(this.options))},convertTicksToLabels:function(){var t=this;Cn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=H.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=H.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;e<d;e++){i=t.getPointPosition(e,t.drawingArea+5),s=t.ctx,l=a.lineHeight,u=t.pointLabels[e],n=H.isArray(u)?{w:H.longestText(s,s.font,u),h:u.length*l}:{w:s.measureText(u).width,h:l},t._pointLabelSizes[e]=n;var h=t.getIndexAngle(e),c=H.toDegrees(h)%360,f=jn(c,i.x,n.w,0,180),g=jn(c,i.y,n.h,90,270);f.start<r.l&&(r.l=f.start,o.l=h),f.end>r.r&&(r.r=f.end,o.r=h),g.start<r.t&&(r.t=g.start,o.t=h),g.end>r.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=Gn(a),r=Gn(r),o=Gn(o),s=Gn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(H.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Bn(s.lineWidth,o.lineWidth),u=Bn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Hn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=H.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=En(i.fontColor,s,N.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=H.toDegrees(h);e.textAlign=qn(c),Yn(c,t._pointLabelSizes[s],u),Un(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&H.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=En(e.color,i-1),u=En(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d<s;d++)a=t.getPointPosition(d,n),r.lineTo(a.x,a.y)}r.closePath(),r.stroke(),r.restore()}}(i,o,e,n))})),s.display&&l&&u){for(a.save(),a.lineWidth=l,a.strokeStyle=u,a.setLineDash&&(a.setLineDash(Wn([s.borderDash,o.borderDash,[]])),a.lineDashOffset=Wn([s.borderDashOffset,o.borderDashOffset,0])),t=i.chart.data.labels.length-1;t>=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=H.options._parseFont(n),s=Bn(n.fontColor,N.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",H.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:H.noop}),Kn=Vn;Xn._defaults=Kn;var Zn=H._deprecated,$n=H.options.resolve,Jn=H.valueOrDefault,Qn=Number.MIN_SAFE_INTEGER||-9007199254740991,ti=Number.MAX_SAFE_INTEGER||9007199254740991,ei={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ni=Object.keys(ei);function ii(t,e){return t-e}function ai(t){return H.valueOrDefault(t.time.min,t.ticks.min)}function ri(t){return H.valueOrDefault(t.time.max,t.ticks.max)}function oi(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]<n)o=i+1;else{if(!(a[e]>n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function si(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),H.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),H.isFinite(o)||(o=n.parse(o))),o)}function li(t,e){if(H.isNullOrUndef(e))return null;var n=t.options.time,i=si(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function ui(t,e,n,i){var a,r,o,s=ni.length;for(a=ni.indexOf(t);a<s-1;++a)if(o=(r=ei[ni[a]]).steps?r.steps:ti,r.common&&Math.ceil((n-e)/(o*r.size))<=i)return ni[a];return ni[s-1]}function di(t,e,n){var i,a,r=[],o={},s=e.length;for(i=0;i<s;++i)o[a=e[i]]=i,r.push({value:a,major:!1});return 0!==s&&n?function(t,e,n,i){var a,r,o=t._adapter,s=+o.startOf(e[0].value,i),l=e[e.length-1].value;for(a=s;a<=l;a=+o.add(a,1,i))(r=n[a])>=0&&(e[r].major=!0);return e}(t,r,o,n):r}var hi=yn.extend({initialize:function(){this.mergeTicksOptions(),yn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new rn._date(e.adapters.date);return Zn("time scale",n.format,"time.format","time.parser"),Zn("time scale",n.min,"time.min","ticks.min"),Zn("time scale",n.max,"time.max","ticks.max"),H.mergeIf(n.displayFormats,i.formats()),yn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),yn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=ti,f=Qn,g=[],p=[],m=[],v=s._getLabels();for(t=0,n=v.length;t<n;++t)m.push(li(s,v[t]));for(t=0,n=(l.data.datasets||[]).length;t<n;++t)if(l.isDatasetVisible(t))if(a=l.data.datasets[t].data,H.isObject(a[0]))for(p[t]=[],e=0,i=a.length;e<i;++e)r=li(s,a[e]),g.push(r),p[t][e]=r;else p[t]=m.slice(0),o||(g=g.concat(m),o=!0);else p[t]=[];m.length&&(c=Math.min(c,m[0]),f=Math.max(f,m[m.length-1])),g.length&&(g=n>1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e<n;++e)a[i=t[e]]||(a[i]=!0,r.push(i));return r}(g).sort(ii):g.sort(ii),c=Math.min(c,g[0]),f=Math.max(f,g[g.length-1])),c=li(s,ai(d))||c,f=li(s,ri(d))||f,c=c===ti?+u.startOf(Date.now(),h):c,f=f===Qn?+u.endOf(Date.now(),h)+1:f,s.min=Math.min(c,f),s.max=Math.max(c+1,f),s._table=[],s._timestamps={data:g,datasets:p,labels:m}},buildTicks:function(){var t,e,n,i=this,a=i.min,r=i.max,o=i.options,s=o.ticks,l=o.time,u=i._timestamps,d=[],h=i.getLabelCapacity(a),c=s.source,f=o.distribution;for(u="data"===c||"auto"===c&&"series"===f?u.data:"labels"===c?u.labels:function(t,e,n,i){var a,r=t._adapter,o=t.options,s=o.time,l=s.unit||ui(s.minUnit,e,n,i),u=$n([s.stepSize,s.unitStepSize,1]),d="week"===l&&s.isoWeekday,h=e,c=[];if(d&&(h=+r.startOf(h,"isoWeek",d)),h=+r.startOf(h,d?"day":l),r.diff(n,e,l)>1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a<n;a=+r.add(a,u,l))c.push(a);return a!==n&&"ticks"!==o.bounds||c.push(a),c}(i,a,r,h),"ticks"===o.bounds&&u.length&&(a=u[0],r=u[u.length-1]),a=li(i,ai(o))||a,r=li(i,ri(o))||r,t=0,e=u.length;t<e;++t)(n=u[t])>=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?ui(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ni.length-1;r>=ni.indexOf(n);r--)if(o=ni[r],ei[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ni[n?ni.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ni.indexOf(t)+1,n=ni.length;e<n;++e)if(ei[ni[e]].common)return ni[e]}(i._unit):void 0,i._table=function(t,e,n,i){if("linear"===i||!t.length)return[{time:e,pos:0},{time:n,pos:1}];var a,r,o,s,l,u=[],d=[e];for(a=0,r=t.length;a<r;++a)(s=t[a])>e&&s<n&&d.push(s);for(d.push(n),a=0,r=d.length;a<r;++a)l=d[a+1],o=d[a-1],s=d[a],void 0!==o&&void 0!==l&&Math.round((l+o)/2)===s||u.push({time:s,pos:a/(r-1)});return u}(i._timestamps.data,a,r,f),i._offsets=function(t,e,n,i,a){var r,o,s=0,l=0;return a.offset&&e.length&&(r=oi(t,"time",e[0],"pos"),s=1===e.length?1-r:(oi(t,"time",e[1],"pos")-r)/2,o=oi(t,"time",e[e.length-1],"pos"),l=1===e.length?o:(o-oi(t,"time",e[e.length-2],"pos"))/2),{start:s,end:l,factor:1/(s+1+l)}}(i._table,d,0,0,o),s.reverse&&d.reverse(),di(i,d,i._majorUnit)},getLabelForIndex:function(t,e){var n=this,i=n._adapter,a=n.chart.data,r=n.options.time,o=a.labels&&t<a.labels.length?a.labels[t]:"",s=a.datasets[e].data[t];return H.isObject(s)&&(o=n.getRightValue(s)),r.tooltipFormat?i.format(si(n,o),r.tooltipFormat):"string"==typeof o?o:i.format(si(n,o),r.displayFormats.datetime)},tickFormatFunction:function(t,e,n,i){var a=this._adapter,r=this.options,o=r.time.displayFormats,s=o[this._unit],l=this._majorUnit,u=o[l],d=n[e],h=r.ticks,c=l&&u&&d&&d.major,f=a.format(t,i||(c?u:s)),g=c?h.major:h.minor,p=$n([g.callback,g.userCallback,h.callback,h.userCallback]);return p?p(f,e,n):f},convertTicksToLabels:function(t){var e,n,i=[];for(e=0,n=t.length;e<n;++e)i.push(this.tickFormatFunction(t[e].value,e,t));return i},getPixelForOffset:function(t){var e=this._offsets,n=oi(this._table,"time",t,"pos");return this.getPixelForDecimal((e.start+n)*e.factor)},getPixelForValue:function(t,e,n){var i=null;if(void 0!==e&&void 0!==n&&(i=this._timestamps.datasets[n][e]),null===i&&(i=li(this,t)),null!==i)return this.getPixelForOffset(i)},getPixelForTick:function(t){var e=this.getTicks();return t>=0&&t<e.length?this.getPixelForOffset(e[t].value):null},getValueForPixel:function(t){var e=this._offsets,n=this.getDecimalForPixel(t)/e.factor-e.end,i=oi(this._table,"pos",n,"time");return this._adapter._create(i)},_getLabelSize:function(t){var e=this.options.ticks,n=this.ctx.measureText(t).width,i=H.toRadians(this.isHorizontal()?e.maxRotation:e.minRotation),a=Math.cos(i),r=Math.sin(i),o=Jn(e.fontSize,N.global.defaultFontSize);return{w:n*a+o*r,h:n*r+o*a}},getLabelWidth:function(t){return this._getLabelSize(t).w},getLabelCapacity:function(t){var e=this,n=e.options.time,i=n.displayFormats,a=i[n.unit]||i.millisecond,r=e.tickFormatFunction(t,0,di(e,[t],e._majorUnit),a),o=e._getLabelSize(r),s=Math.floor(e.isHorizontal()?e.width/o.w:e.height/o.h);return e.options.offset&&s--,s>0?s:1}}),ci={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};hi._defaults=ci;var fi={category:kn,linear:Tn,logarithmic:zn,radialLinear:Xn,time:hi},gi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};rn._date.override("function"==typeof t?{_id:"moment",formats:function(){return gi},parse:function(e,n){return"string"==typeof e&&"string"==typeof n?e=t(e,n):e instanceof t||(e=t(e)),e.isValid()?e.valueOf():null},format:function(e,n){return t(e).format(n)},add:function(e,n,i){return t(e).add(n,i).valueOf()},diff:function(e,n,i){return t(e).diff(t(n),i)},startOf:function(e,n,i){return e=t(e),"isoWeek"===n?e.isoWeekday(i).valueOf():e.startOf(n).valueOf()},endOf:function(e,n){return t(e).endOf(n).valueOf()},_create:function(e){return t(e)}}:{}),N._set("global",{plugins:{filler:{propagate:!0}}});var pi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e<r&&a[e]._view||null}:null},boundary:function(t){var e=t.boundary,n=e?e.x:null,i=e?e.y:null;return H.isArray(e)?function(t,n){return e[n]}:function(t){return{x:null===n?t.x:n,y:null===i?t.y:i}}}};function mi(t,e,n){var i,a=t._model||{},r=a.fill;if(void 0===r&&(r=!!a.backgroundColor),!1===r||null===r)return!1;if(!0===r)return"origin";if(i=parseFloat(r,10),isFinite(i)&&Math.floor(i)===i)return"-"!==r[0]&&"+"!==r[0]||(i=e+i),!(i===e||i<0||i>=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function vi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a<l;++a)r="start"===u||"end"===u?o.getPointPositionForValue(a,"start"===u?e:n):o.getBasePosition(a),s.gridLines.circular&&(r.cx=i.x,r.cy=i.y,r.angle=o.getIndexAngle(a)-Math.PI/2),d.push(r);return d}(t):function(t){var e,n=t.el._model||{},i=t.el._scale||{},a=t.fill,r=null;if(isFinite(a))return null;if("start"===a?r=void 0===n.scaleBottom?i.bottom:n.scaleBottom:"end"===a?r=void 0===n.scaleTop?i.top:n.scaleTop:void 0!==n.scaleZero?r=n.scaleZero:i.getBasePixel&&(r=i.getBasePixel()),null!=r){if(void 0!==r.x&&void 0!==r.y)return r;if(H.isFinite(r))return{x:(e=i.isHorizontal())?r:null,y:e?null:r}}return null}(t)}function bi(t,e,n){var i,a=t[e].fill,r=[e];if(!n)return a;for(;!1!==a&&-1===r.indexOf(a);){if(!isFinite(a))return a;if(!(i=t[a]))return!1;if(i.visible)return a;r.push(a),a=i.fill}return!1}function xi(t){var e=t.fill,n="dataset";return!1===e?null:(isFinite(e)||(n="boundary"),pi[n](t))}function yi(t){return t&&!t.skip}function _i(t,e,n,i,a){var r,o,s,l;if(i&&a){for(t.moveTo(e[0].x,e[0].y),r=1;r<i;++r)H.canvas.lineTo(t,e[r-1],e[r]);if(void 0===n[0].angle)for(t.lineTo(n[a-1].x,n[a-1].y),r=a-1;r>0;--r)H.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function ki(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,p=i.spanGaps,m=[],v=[],b=0,x=0;for(t.beginPath(),o=0,s=g;o<s;++o)d=n(u=e[l=o%g]._view,l,i),h=yi(u),c=yi(d),r&&void 0===f&&h&&(s=g+(f=o+1)),h&&c?(b=m.push(u),x=v.push(d)):b&&x&&(p?(h&&m.push(u),c&&v.push(d)):(_i(t,m,v,b,x),b=x=0,m=[],v=[]));_i(t,m,v,b,x),t.closePath(),t.fillStyle=a,t.fill()}var wi={id:"filler",afterDatasetsUpdate:function(t,e){var n,i,a,r,o=(t.data.datasets||[]).length,s=e.propagate,l=[];for(i=0;i<o;++i)r=null,(a=(n=t.getDatasetMeta(i)).dataset)&&a._model&&a instanceof kt.Line&&(r={visible:t.isDatasetVisible(i),fill:mi(a,i,o),chart:t,el:a}),n.$filler=r,l.push(r);for(i=0;i<o;++i)(r=l[i])&&(r.fill=bi(l,i,s),r.boundary=vi(r),r.mapper=xi(r))},beforeDatasetsDraw:function(t){var e,n,i,a,r,o,s,l=t._getSortedVisibleDatasetMetas(),u=t.ctx;for(n=l.length-1;n>=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||N.global.defaultColor,o&&s&&r.length&&(H.canvas.clipArea(u,t.chartArea),ki(u,r,o,a,s,i._loop),H.canvas.unclipArea(u)))}},Mi=H.rtl.getRtlAdapter,Si=H.noop,Ci=H.valueOrDefault;function Pi(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}N._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;e<n;e++)(i=a.appendChild(document.createElement("li"))).appendChild(document.createElement("span")).style.backgroundColor=r[e].backgroundColor,r[e].label&&i.appendChild(document.createTextNode(r[e].label));return a.outerHTML}});var Ai=K.extend({initialize:function(t){H.extend(this,t),this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1},beforeUpdate:Si,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Si,beforeSetDimensions:Si,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Si,beforeBuildLabels:Si,buildLabels:function(){var t=this,e=t.options.labels||{},n=H.callback(e.generateLabels,[t.chart],t)||[];e.filter&&(n=n.filter((function(n){return e.filter(n,t.chart.data)}))),t.options.reverse&&n.reverse(),t.legendItems=n},afterBuildLabels:Si,beforeFit:Si,fit:function(){var t=this,e=t.options,n=e.labels,i=e.display,a=t.ctx,r=H.options._parseFont(n),o=r.size,s=t.legendHitBoxes=[],l=t.minSize,u=t.isHorizontal();if(u?(l.width=t.maxWidth,l.height=i?10:0):(l.width=i?10:0,l.height=t.maxHeight),i){if(a.font=r.string,u){var d=t.lineWidths=[0],h=0;a.textAlign="left",a.textBaseline="middle",H.each(t.legendItems,(function(t,e){var i=Pi(n,o)+o/2+a.measureText(t.text).width;(0===e||d[d.length-1]+i+2*n.padding>l.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],p=n.padding,m=0,v=0;H.each(t.legendItems,(function(t,e){var i=Pi(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(p+=m+n.padding,f.push(m),g.push(v),m=0,v=0),m=Math.max(m,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),p+=m,f.push(m),g.push(v),l.width+=p}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Si,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=N.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=Mi(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Ci(n.fontColor,i.defaultFontColor),g=H.options._parseFont(n),p=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var m=Pi(n,p),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},x=t.isHorizontal();d=x?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},H.rtl.overrideTextDirection(t.ctx,e.textDirection);var y=p+n.padding;H.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=m+p/2+f,_=d.x,k=d.y;h.setWidth(t.minSize.width),x?i>0&&_+g+n.padding>t.left+t.minSize.width&&(k=d.y+=y,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&k+y>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,k=d.y=t.top+b(o,s[d.line]));var w=h.x(_);!function(t,e,i){if(!(isNaN(m)||m<=0)){c.save();var o=Ci(i.lineWidth,r.borderWidth);if(c.fillStyle=Ci(i.fillStyle,a),c.lineCap=Ci(i.lineCap,r.borderCapStyle),c.lineDashOffset=Ci(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Ci(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Ci(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Ci(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=m*Math.SQRT2/2,l=h.xPlus(t,m/2),u=e+p/2;H.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,m),e,m,p),0!==o&&c.strokeRect(h.leftForLtr(t,m),e,m,p);c.restore()}}(w,k,e),v[i].left=h.leftForLtr(w,v[i].width),v[i].top=k,function(t,e,n,i){var a=p/2,r=h.xPlus(t,m+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(w,k,e,f),x?d.x+=g+n.padding:d.y+=y})),H.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n<a.length;++n)if(t>=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Di(t,e){var n=new Ai({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.legend=n}var Ti={id:"legend",_element:Ai,beforeInit:function(t){var e=t.options.legend;e&&Di(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(H.mergeIf(e,N.global.legend),n?(pe.configure(t,n,e),n.options=e):Di(t,e)):n&&(pe.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Ii=H.noop;N._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Fi=K.extend({initialize:function(t){H.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Ii,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Ii,beforeSetDimensions:Ii,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Ii,beforeBuildLabels:Ii,buildLabels:Ii,afterBuildLabels:Ii,beforeFit:Ii,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(H.isArray(n.text)?n.text.length:1)*H.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Ii,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=H.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=H.valueOrDefault(n.fontColor,N.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(H.isArray(g))for(var p=0,m=0;m<g.length;++m)e.fillText(g[m],0,p,i),p+=s;else e.fillText(g,0,0,i);e.restore()}}});function Oi(t,e){var n=new Fi({ctx:t.ctx,options:e,chart:t});pe.configure(t,n,e),pe.addBox(t,n),t.titleBlock=n}var Li={},Ri=wi,zi=Ti,Ni={id:"title",_element:Fi,beforeInit:function(t){var e=t.options.title;e&&Oi(t,e)},beforeUpdate:function(t){var e=t.options.title,n=t.titleBlock;e?(H.mergeIf(e,N.global.title),n?(pe.configure(t,n,e),n.options=e):Oi(t,e)):n&&(pe.removeBox(t,n),delete t.titleBlock)}};for(var Bi in Li.filler=Ri,Li.legend=zi,Li.title=Ni,en.helpers=H,function(){function t(t,e,n){var i;return"string"==typeof t?(i=parseInt(t,10),-1!==t.indexOf("%")&&(i=i/100*e.parentNode[n])):i=t,i}function e(t){return null!=t&&"none"!==t}function n(n,i,a){var r=document.defaultView,o=H._getParentNode(n),s=r.getComputedStyle(n)[i],l=r.getComputedStyle(o)[i],u=e(s),d=e(l),h=Number.POSITIVE_INFINITY;return u||d?Math.min(u?t(s,n,a):h,d?t(l,o,a):h):"none"}H.where=function(t,e){if(H.isArray(t)&&Array.prototype.filter)return t.filter(e);var n=[];return H.each(t,(function(t){e(t)&&n.push(t)})),n},H.findIndex=Array.prototype.findIndex?function(t,e,n){return t.findIndex(e,n)}:function(t,e,n){n=void 0===n?t:n;for(var i=0,a=t.length;i<a;++i)if(e.call(n,t[i],i,t))return i;return-1},H.findNextWhere=function(t,e,n){H.isNullOrUndef(n)&&(n=-1);for(var i=n+1;i<t.length;i++){var a=t[i];if(e(a))return a}},H.findPreviousWhere=function(t,e,n){H.isNullOrUndef(n)&&(n=t.length);for(var i=n-1;i>=0;i--){var a=t[i];if(e(a))return a}},H.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},H.almostEquals=function(t,e,n){return Math.abs(t-e)<n},H.almostWhole=function(t,e){var n=Math.round(t);return n-e<=t&&n+e>=t},H.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},H.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},H.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},H.toRadians=function(t){return t*(Math.PI/180)},H.toDegrees=function(t){return t*(180/Math.PI)},H._decimalPlaces=function(t){if(H.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},H.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},H.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},H.aliasPixel=function(t){return t%2==0?0:.5},H._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},H.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},H.EPSILON=Number.EPSILON||1e-14,H.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e<h;++e)if(!(i=d[e]).model.skip){if(n=e>0?d[e-1]:null,(a=e<h-1?d[e+1]:null)&&!a.model.skip){var c=a.model.x-i.model.x;i.deltaK=0!==c?(a.model.y-i.model.y)/c:0}!n||n.model.skip?i.mK=i.deltaK:!a||a.model.skip?i.mK=n.deltaK:this.sign(n.deltaK)!==this.sign(i.deltaK)?i.mK=0:i.mK=(n.deltaK+i.deltaK)/2}for(e=0;e<h-1;++e)i=d[e],a=d[e+1],i.model.skip||a.model.skip||(H.almostEquals(i.deltaK,0,this.EPSILON)?i.mK=a.mK=0:(r=i.mK/i.deltaK,o=a.mK/i.deltaK,(l=Math.pow(r,2)+Math.pow(o,2))<=9||(s=3/Math.sqrt(l),i.mK=r*s*i.deltaK,a.mK=o*s*i.deltaK)));for(e=0;e<h;++e)(i=d[e]).model.skip||(n=e>0?d[e-1]:null,a=e<h-1?d[e+1]:null,n&&!n.model.skip&&(u=(i.model.x-n.model.x)/3,i.model.controlPointPreviousX=i.model.x-u,i.model.controlPointPreviousY=i.model.y-u*i.mK),a&&!a.model.skip&&(u=(a.model.x-i.model.x)/3,i.model.controlPointNextX=i.model.x+u,i.model.controlPointNextY=i.model.y+u*i.mK))},H.nextItem=function(t,e,n){return n?e>=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},H.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},H.niceNum=function(t,e){var n=Math.floor(H.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},H.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},H.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(H.getStyle(r,"padding-left")),u=parseFloat(H.getStyle(r,"padding-top")),d=parseFloat(H.getStyle(r,"padding-right")),h=parseFloat(H.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},H.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},H.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},H._calculatePadding=function(t,e,n){return(e=H.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},H._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},H.getMaximumWidth=function(t){var e=H._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-H._calculatePadding(e,"padding-left",n)-H._calculatePadding(e,"padding-right",n),a=H.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},H.getMaximumHeight=function(t){var e=H._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-H._calculatePadding(e,"padding-top",n)-H._calculatePadding(e,"padding-bottom",n),a=H.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},H.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},H.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},H.fontString=function(t,e,n){return e+" "+t+"px "+n},H.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;o<c;o++)if(null!=(u=n[o])&&!0!==H.isArray(u))h=H.measureText(t,a,r,h,u);else if(H.isArray(u))for(s=0,l=u.length;s<l;s++)null==(d=u[s])||H.isArray(d)||(h=H.measureText(t,a,r,h,d));var f=r.length/2;if(f>n.length){for(o=0;o<f;o++)delete a[r[o]];r.splice(0,f)}return h},H.measureText=function(t,e,n,i,a){var r=e[a];return r||(r=e[a]=t.measureText(a).width,n.push(a)),r>i&&(i=r),i},H.numberOfLabelLines=function(t){var e=1;return H.each(t,(function(t){H.isArray(t)&&t.length>e&&(e=t.length)})),e},H.color=_?function(t){return t instanceof CanvasGradient&&(t=N.global.defaultColor),_(t)}:function(t){return console.error("Color.js not found!"),t},H.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:H.color(t).saturate(.5).darken(.1).rgbString()}}(),en._adapters=rn,en.Animation=$,en.animationService=J,en.controllers=Jt,en.DatasetController=it,en.defaults=N,en.Element=K,en.elements=kt,en.Interaction=re,en.layouts=pe,en.platform=Oe,en.plugins=Le,en.Scale=yn,en.scaleService=Re,en.Ticks=on,en.Tooltip=Ye,en.helpers.each(fi,(function(t,e){en.scaleService.registerScaleType(e,t,t._defaults)})),Li)Li.hasOwnProperty(Bi)&&en.plugins.register(Li[Bi]);en.platform.initialize();var Ei=en;return"undefined"!=typeof window&&(window.Chart=en),en.Chart=en,en.Legend=Li.legend._element,en.Title=Li.title._element,en.pluginService=en.plugins,en.PluginBase=en.Element.extend({}),en.canvasHelpers=en.helpers.canvas,en.layoutService=en.layouts,en.LinearScaleBase=Cn,en.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){en[t]=function(e,n){return new en(e,en.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Ei}));
 
 
 
 
 
 
 
assets/js/wpp.js CHANGED
@@ -1,159 +1,159 @@
1
- var wpp_params = null;
2
- var WordPressPopularPosts = (function(){
3
-
4
- "use strict";
5
-
6
- var noop = function(){};
7
- var supportsShadowDOMV1 = !! HTMLElement.prototype.attachShadow;
8
-
9
- var get = function( url, params, callback ){
10
- callback = ( 'function' === typeof callback ) ? callback : noop;
11
- ajax( "GET", url, params, callback );
12
- };
13
-
14
- var post = function( url, params, callback ){
15
- callback = ( 'function' === typeof callback ) ? callback : noop;
16
- ajax( "POST", url, params, callback );
17
- };
18
-
19
- var ajax = function( method, url, params, callback ){
20
- /* Create XMLHttpRequest object and set variables */
21
- var xhr = new XMLHttpRequest(),
22
- target = url,
23
- args = params,
24
- valid_methods = ["GET", "POST"];
25
- method = -1 != valid_methods.indexOf( method ) ? method : "GET";
26
- /* Set request method and target URL */
27
- xhr.open( method, target + ( "GET" == method ? '?' + args : '' ), true );
28
- /* Set request headers */
29
- if ( "POST" == method ) {
30
- xhr.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
31
- }
32
- xhr.setRequestHeader( "X-Requested-With","XMLHttpRequest" );
33
- /* Hook into onreadystatechange */
34
- xhr.onreadystatechange = function() {
35
- if ( 4 === xhr.readyState && 200 <= xhr.status && 300 > xhr.status ) {
36
- if ( 'function' === typeof callback ) {
37
- callback.call( undefined, xhr.response );
38
- }
39
- }
40
- };
41
- /* Send request */
42
- xhr.send( ( "POST" == method ? args : null ) );
43
- };
44
-
45
- var theme = function(wpp_list) {
46
- if ( supportsShadowDOMV1 ) {
47
- let base_styles = document.createElement('style'),
48
- dummy_list = document.createElement('ul');
49
-
50
- dummy_list.innerHTML = '<li><a href="#"></a></li>';
51
- wpp_list.parentNode.appendChild(dummy_list);
52
-
53
- let dummy_list_item_styles = getComputedStyle(dummy_list.querySelector('li')),
54
- dummy_link_item_styles = getComputedStyle(dummy_list.querySelector('li a'));
55
-
56
- base_styles.innerHTML = '.wpp-list li {font-size: '+ dummy_list_item_styles.fontSize +'}';
57
- base_styles.innerHTML += '.wpp-list li a {color: '+ dummy_link_item_styles.color +'}';
58
-
59
- wpp_list.parentNode.removeChild(dummy_list);
60
-
61
- let wpp_list_sr = wpp_list.attachShadow({mode: "open"});
62
-
63
- wpp_list_sr.append(base_styles);
64
-
65
- while(wpp_list.firstElementChild) {
66
- wpp_list_sr.append(wpp_list.firstElementChild);
67
- }
68
- }
69
- };
70
-
71
- return {
72
- get: get,
73
- post: post,
74
- ajax: ajax,
75
- theme: theme
76
- };
77
-
78
- })();
79
-
80
- (function(){
81
- try {
82
- var wpp_json = document.querySelector("script#wpp-json"),
83
- do_request = true;
84
-
85
- wpp_params = JSON.parse(wpp_json.textContent);
86
-
87
- if ( wpp_params.ID ) {
88
- if ( '1' == wpp_params.sampling_active ) {
89
- var num = Math.floor(Math.random() * wpp_params.sampling_rate) + 1;
90
- do_request = ( 1 === num );
91
- }
92
-
93
- if ( do_request ) {
94
- WordPressPopularPosts.post(
95
- wpp_params.ajax_url,
96
- "_wpnonce=" + wpp_params.token + "&wpp_id=" + wpp_params.ID + "&sampling=" + wpp_params.sampling_active + "&sampling_rate=" + wpp_params.sampling_rate,
97
- function( response ) {
98
- wpp_params.debug&&window.console&&window.console.log&&window.console.log(JSON.parse(response));
99
- }
100
- );
101
- }
102
- }
103
- } catch (err) {
104
- console.error("WPP: Couldn't read JSON data");
105
- }
106
- })();
107
-
108
- document.addEventListener('DOMContentLoaded', function() {
109
- var widget_placeholders = document.querySelectorAll('.wpp-widget-placeholder');
110
-
111
- if ( widget_placeholders.length ) {
112
- for( var w = 0; w < widget_placeholders.length; w++ ) {
113
- fetchWidget(widget_placeholders[w]);
114
- }
115
- } else {
116
- var sr = document.querySelectorAll('.popular-posts-sr');
117
-
118
- if ( sr.length ) {
119
- for( var s = 0; s < sr.length; s++ ) {
120
- WordPressPopularPosts.theme(sr[s]);
121
- }
122
- }
123
- }
124
-
125
- function fetchWidget(widget_placeholder) {
126
- WordPressPopularPosts.get(
127
- wpp_params.ajax_url + '/widget/' + widget_placeholder.getAttribute('data-widget-id').split('-')[1],
128
- 'is_single=' + wpp_params.ID + ( wpp_params.lang ? '&lang=' + wpp_params.lang : '' ),
129
- function(response) {
130
- widget_placeholder.insertAdjacentHTML('afterend', JSON.parse(response).widget);
131
-
132
- let parent = widget_placeholder.parentNode,
133
- sr = parent.querySelector('.popular-posts-sr');
134
-
135
- parent.removeChild(widget_placeholder);
136
-
137
- if ( sr ) {
138
- WordPressPopularPosts.theme(sr);
139
- }
140
-
141
- let event = null;
142
-
143
- if ( 'function' === typeof(Event) ) {
144
- event = new Event("wpp-onload", {"bubbles": true, "cancelable": false});
145
- } /* Fallback for older browsers */
146
- else {
147
- if ( document.createEvent ) {
148
- event = document.createEvent('Event');
149
- event.initEvent("wpp-onload", true, false);
150
- }
151
- }
152
-
153
- if ( event ) {
154
- parent.dispatchEvent(event);
155
- }
156
- }
157
- );
158
- }
159
- });
1
+ var wpp_params = null;
2
+ var WordPressPopularPosts = (function(){
3
+
4
+ "use strict";
5
+
6
+ var noop = function(){};
7
+ var supportsShadowDOMV1 = !! HTMLElement.prototype.attachShadow;
8
+
9
+ var get = function( url, params, callback ){
10
+ callback = ( 'function' === typeof callback ) ? callback : noop;
11
+ ajax( "GET", url, params, callback );
12
+ };
13
+
14
+ var post = function( url, params, callback ){
15
+ callback = ( 'function' === typeof callback ) ? callback : noop;
16
+ ajax( "POST", url, params, callback );
17
+ };
18
+
19
+ var ajax = function( method, url, params, callback ){
20
+ /* Create XMLHttpRequest object and set variables */
21
+ var xhr = new XMLHttpRequest(),
22
+ target = url,
23
+ args = params,
24
+ valid_methods = ["GET", "POST"];
25
+ method = -1 != valid_methods.indexOf( method ) ? method : "GET";
26
+ /* Set request method and target URL */
27
+ xhr.open( method, target + ( "GET" == method ? '?' + args : '' ), true );
28
+ /* Set request headers */
29
+ if ( "POST" == method ) {
30
+ xhr.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
31
+ }
32
+ xhr.setRequestHeader( "X-Requested-With","XMLHttpRequest" );
33
+ /* Hook into onreadystatechange */
34
+ xhr.onreadystatechange = function() {
35
+ if ( 4 === xhr.readyState && 200 <= xhr.status && 300 > xhr.status ) {
36
+ if ( 'function' === typeof callback ) {
37
+ callback.call( undefined, xhr.response );
38
+ }
39
+ }
40
+ };
41
+ /* Send request */
42
+ xhr.send( ( "POST" == method ? args : null ) );
43
+ };
44
+
45
+ var theme = function(wpp_list) {
46
+ if ( supportsShadowDOMV1 ) {
47
+ let base_styles = document.createElement('style'),
48
+ dummy_list = document.createElement('ul');
49
+
50
+ dummy_list.innerHTML = '<li><a href="#"></a></li>';
51
+ wpp_list.parentNode.appendChild(dummy_list);
52
+
53
+ let dummy_list_item_styles = getComputedStyle(dummy_list.querySelector('li')),
54
+ dummy_link_item_styles = getComputedStyle(dummy_list.querySelector('li a'));
55
+
56
+ base_styles.innerHTML = '.wpp-list li {font-size: '+ dummy_list_item_styles.fontSize +'}';
57
+ base_styles.innerHTML += '.wpp-list li a {color: '+ dummy_link_item_styles.color +'}';
58
+
59
+ wpp_list.parentNode.removeChild(dummy_list);
60
+
61
+ let wpp_list_sr = wpp_list.attachShadow({mode: "open"});
62
+
63
+ wpp_list_sr.append(base_styles);
64
+
65
+ while(wpp_list.firstElementChild) {
66
+ wpp_list_sr.append(wpp_list.firstElementChild);
67
+ }
68
+ }
69
+ };
70
+
71
+ return {
72
+ get: get,
73
+ post: post,
74
+ ajax: ajax,
75
+ theme: theme
76
+ };
77
+
78
+ })();
79
+
80
+ (function(){
81
+ try {
82
+ var wpp_json = document.querySelector("script#wpp-json"),
83
+ do_request = true;
84
+
85
+ wpp_params = JSON.parse(wpp_json.textContent);
86
+
87
+ if ( wpp_params.ID ) {
88
+ if ( '1' == wpp_params.sampling_active ) {
89
+ var num = Math.floor(Math.random() * wpp_params.sampling_rate) + 1;
90
+ do_request = ( 1 === num );
91
+ }
92
+
93
+ if ( do_request ) {
94
+ WordPressPopularPosts.post(
95
+ wpp_params.ajax_url,
96
+ "_wpnonce=" + wpp_params.token + "&wpp_id=" + wpp_params.ID + "&sampling=" + wpp_params.sampling_active + "&sampling_rate=" + wpp_params.sampling_rate,
97
+ function( response ) {
98
+ wpp_params.debug&&window.console&&window.console.log&&window.console.log(JSON.parse(response));
99
+ }
100
+ );
101
+ }
102
+ }
103
+ } catch (err) {
104
+ console.error("WPP: Couldn't read JSON data");
105
+ }
106
+ })();
107
+
108
+ document.addEventListener('DOMContentLoaded', function() {
109
+ var widget_placeholders = document.querySelectorAll('.wpp-widget-placeholder');
110
+
111
+ if ( widget_placeholders.length ) {
112
+ for( var w = 0; w < widget_placeholders.length; w++ ) {
113
+ fetchWidget(widget_placeholders[w]);
114
+ }
115
+ } else {
116
+ var sr = document.querySelectorAll('.popular-posts-sr');
117
+
118
+ if ( sr.length ) {
119
+ for( var s = 0; s < sr.length; s++ ) {
120
+ WordPressPopularPosts.theme(sr[s]);
121
+ }
122
+ }
123
+ }
124
+
125
+ function fetchWidget(widget_placeholder) {
126
+ WordPressPopularPosts.get(
127
+ wpp_params.ajax_url + '/widget/' + widget_placeholder.getAttribute('data-widget-id').split('-')[1],
128
+ 'is_single=' + wpp_params.ID + ( wpp_params.lang ? '&lang=' + wpp_params.lang : '' ),
129
+ function(response) {
130
+ widget_placeholder.insertAdjacentHTML('afterend', JSON.parse(response).widget);
131
+
132
+ let parent = widget_placeholder.parentNode,
133
+ sr = parent.querySelector('.popular-posts-sr');
134
+
135
+ parent.removeChild(widget_placeholder);
136
+
137
+ if ( sr ) {
138
+ WordPressPopularPosts.theme(sr);
139
+ }
140
+
141
+ let event = null;
142
+
143
+ if ( 'function' === typeof(Event) ) {
144
+ event = new Event("wpp-onload", {"bubbles": true, "cancelable": false});
145
+ } /* Fallback for older browsers */
146
+ else {
147
+ if ( document.createEvent ) {
148
+ event = document.createEvent('Event');
149
+ event.initEvent("wpp-onload", true, false);
150
+ }
151
+ }
152
+
153
+ if ( event ) {
154
+ parent.dispatchEvent(event);
155
+ }
156
+ }
157
+ );
158
+ }
159
+ });
assets/themes/cards-compact/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Cards Compact",
3
- "description": "A compact card-style popular posts list.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": false,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": true,
25
- "build": "manual",
26
- "width": 75,
27
- "height": 75,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": true,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-cards-compact\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li>{thumb_img}<div class=\"wpp-item-data\"><div class=\"taxonomies\">{taxonomy}</div>{title}</div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Cards Compact",
3
+ "description": "A compact card-style popular posts list.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": false,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": true,
25
+ "build": "manual",
26
+ "width": 75,
27
+ "height": 75,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": true,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-cards-compact\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li>{thumb_img}<div class=\"wpp-item-data\"><div class=\"taxonomies\">{taxonomy}</div>{title}</div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/cards-compact/style.css CHANGED
@@ -1,64 +1,64 @@
1
- .wpp-cards-compact {
2
- margin-left: 0;
3
- margin-right: 0;
4
- padding: 0;
5
- }
6
-
7
- .wpp-cards-compact li {
8
- display: flex;
9
- align-items: center;
10
- list-style: none;
11
- margin: 0 0 1.2em 0;
12
- padding: 0 0 1em 0;
13
- border-bottom: #ddd 1px solid;
14
- }
15
-
16
- .wpp-cards-compact li:last-of-type,
17
- .wpp-cards-compact li:only-child {
18
- margin: 0;
19
- padding: 0;
20
- border-bottom: none;
21
- }
22
-
23
- .wpp-cards-compact li .wpp-thumbnail {
24
- overflow: hidden;
25
- display: inline-block;
26
- flex-grow: 0;
27
- flex-shrink: 0;
28
- margin-right: 1em;
29
- font-size: 0.8em;
30
- line-height: 1;
31
- background: #f0f0f0;
32
- border: none;
33
- }
34
-
35
- .wpp-cards-compact li a {
36
- text-decoration: none;
37
- }
38
-
39
- .wpp-cards-compact li a:hover {
40
- text-decoration: underline;
41
- }
42
-
43
- .wpp-cards-compact li .taxonomies,
44
- .wpp-cards-compact li .wpp-post-title {
45
- display: block;
46
- font-weight: bold;
47
- }
48
-
49
- .wpp-cards-compact li .taxonomies {
50
- margin-bottom: 0.25em;
51
- font-size: 0.7em;
52
- line-height: 1;
53
- }
54
-
55
- .wpp-cards-compact li .wpp-post-title {
56
- margin-bottom: 0.5em;
57
- font-size: 1.2em;
58
- line-height: 1.2;
59
- }
60
-
61
- .wpp-cards-compact li .wpp-excerpt {
62
- margin: 0;
63
- font-size: 0.8em;
64
  }
1
+ .wpp-cards-compact {
2
+ margin-left: 0;
3
+ margin-right: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ .wpp-cards-compact li {
8
+ display: flex;
9
+ align-items: center;
10
+ list-style: none;
11
+ margin: 0 0 1.2em 0;
12
+ padding: 0 0 1em 0;
13
+ border-bottom: #ddd 1px solid;
14
+ }
15
+
16
+ .wpp-cards-compact li:last-of-type,
17
+ .wpp-cards-compact li:only-child {
18
+ margin: 0;
19
+ padding: 0;
20
+ border-bottom: none;
21
+ }
22
+
23
+ .wpp-cards-compact li .wpp-thumbnail {
24
+ overflow: hidden;
25
+ display: inline-block;
26
+ flex-grow: 0;
27
+ flex-shrink: 0;
28
+ margin-right: 1em;
29
+ font-size: 0.8em;
30
+ line-height: 1;
31
+ background: #f0f0f0;
32
+ border: none;
33
+ }
34
+
35
+ .wpp-cards-compact li a {
36
+ text-decoration: none;
37
+ }
38
+
39
+ .wpp-cards-compact li a:hover {
40
+ text-decoration: underline;
41
+ }
42
+
43
+ .wpp-cards-compact li .taxonomies,
44
+ .wpp-cards-compact li .wpp-post-title {
45
+ display: block;
46
+ font-weight: bold;
47
+ }
48
+
49
+ .wpp-cards-compact li .taxonomies {
50
+ margin-bottom: 0.25em;
51
+ font-size: 0.7em;
52
+ line-height: 1;
53
+ }
54
+
55
+ .wpp-cards-compact li .wpp-post-title {
56
+ margin-bottom: 0.5em;
57
+ font-size: 1.2em;
58
+ line-height: 1.2;
59
+ }
60
+
61
+ .wpp-cards-compact li .wpp-excerpt {
62
+ margin: 0;
63
+ font-size: 0.8em;
64
  }
assets/themes/cards/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Cards",
3
- "description": "A card-style popular posts list.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": true,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": true,
25
- "build": "manual",
26
- "width": 75,
27
- "height": 75,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": true,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-cards\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li>{thumb_img} <div class=\"wpp-item-data\"><div class=\"taxonomies\">{taxonomy}</div>{title} <p class=\"wpp-excerpt\">{excerpt}</p></div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Cards",
3
+ "description": "A card-style popular posts list.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": true,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": true,
25
+ "build": "manual",
26
+ "width": 75,
27
+ "height": 75,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": true,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-cards\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li>{thumb_img} <div class=\"wpp-item-data\"><div class=\"taxonomies\">{taxonomy}</div>{title} <p class=\"wpp-excerpt\">{excerpt}</p></div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/cards/style.css CHANGED
@@ -1,64 +1,64 @@
1
- .wpp-cards {
2
- margin-left: 0;
3
- margin-right: 0;
4
- padding: 0;
5
- }
6
-
7
- .wpp-cards li {
8
- display: flex;
9
- list-style: none;
10
- margin: 0 0 1.2em 0;
11
- padding: 0 0 1em 0;
12
- border-bottom: #ddd 1px solid;
13
- }
14
-
15
- .wpp-cards li:last-of-type,
16
- .wpp-cards li:only-child {
17
- margin: 0;
18
- padding: 0;
19
- border-bottom: none;
20
- }
21
-
22
- .wpp-cards li .wpp-thumbnail {
23
- overflow: hidden;
24
- display: inline-block;
25
- align-self: flex-start;
26
- flex-grow: 0;
27
- flex-shrink: 0;
28
- margin-right: 1em;
29
- font-size: 0.8em;
30
- line-height: 1;
31
- background: #f0f0f0;
32
- border: none;
33
- }
34
-
35
- .wpp-cards li a {
36
- text-decoration: none;
37
- }
38
-
39
- .wpp-cards li a:hover {
40
- text-decoration: underline;
41
- }
42
-
43
- .wpp-cards li .taxonomies,
44
- .wpp-cards li .wpp-post-title {
45
- display: block;
46
- font-weight: bold;
47
- }
48
-
49
- .wpp-cards li .taxonomies {
50
- margin-bottom: 0.25em;
51
- font-size: 0.7em;
52
- line-height: 1;
53
- }
54
-
55
- .wpp-cards li .wpp-post-title {
56
- margin-bottom: 0.5em;
57
- font-size: 1.2em;
58
- line-height: 1.2;
59
- }
60
-
61
- .wpp-cards li .wpp-excerpt {
62
- margin: 0;
63
- font-size: 0.8em;
64
  }
1
+ .wpp-cards {
2
+ margin-left: 0;
3
+ margin-right: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ .wpp-cards li {
8
+ display: flex;
9
+ list-style: none;
10
+ margin: 0 0 1.2em 0;
11
+ padding: 0 0 1em 0;
12
+ border-bottom: #ddd 1px solid;
13
+ }
14
+
15
+ .wpp-cards li:last-of-type,
16
+ .wpp-cards li:only-child {
17
+ margin: 0;
18
+ padding: 0;
19
+ border-bottom: none;
20
+ }
21
+
22
+ .wpp-cards li .wpp-thumbnail {
23
+ overflow: hidden;
24
+ display: inline-block;
25
+ align-self: flex-start;
26
+ flex-grow: 0;
27
+ flex-shrink: 0;
28
+ margin-right: 1em;
29
+ font-size: 0.8em;
30
+ line-height: 1;
31
+ background: #f0f0f0;
32
+ border: none;
33
+ }
34
+
35
+ .wpp-cards li a {
36
+ text-decoration: none;
37
+ }
38
+
39
+ .wpp-cards li a:hover {
40
+ text-decoration: underline;
41
+ }
42
+
43
+ .wpp-cards li .taxonomies,
44
+ .wpp-cards li .wpp-post-title {
45
+ display: block;
46
+ font-weight: bold;
47
+ }
48
+
49
+ .wpp-cards li .taxonomies {
50
+ margin-bottom: 0.25em;
51
+ font-size: 0.7em;
52
+ line-height: 1;
53
+ }
54
+
55
+ .wpp-cards li .wpp-post-title {
56
+ margin-bottom: 0.5em;
57
+ font-size: 1.2em;
58
+ line-height: 1.2;
59
+ }
60
+
61
+ .wpp-cards li .wpp-excerpt {
62
+ margin: 0;
63
+ font-size: 0.8em;
64
  }
assets/themes/cardview-compact/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Cardview Compact",
3
- "description": "A compact cardview-style popular posts list.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": false,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": true,
25
- "build": "manual",
26
- "width": 320,
27
- "height": 165,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": true,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-cardview-compact\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li><div class=\"wpp-thumbnail-container\">{thumb}<div class=\"taxonomies\">{taxonomy}</div></div> <div class=\"wpp-item-data\">{title}</div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Cardview Compact",
3
+ "description": "A compact cardview-style popular posts list.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": false,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": true,
25
+ "build": "manual",
26
+ "width": 320,
27
+ "height": 165,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": true,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-cardview-compact\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li><div class=\"wpp-thumbnail-container\">{thumb}<div class=\"taxonomies\">{taxonomy}</div></div> <div class=\"wpp-item-data\">{title}</div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/cardview-compact/style.css CHANGED
@@ -1,72 +1,72 @@
1
- .wpp-cardview-compact {
2
- margin-left: 0;
3
- margin-right: 0;
4
- padding: 0;
5
- }
6
-
7
- .wpp-cardview-compact li {
8
- list-style: none;
9
- margin: 0 0 1.2em 0;
10
- padding: 0 0 1em 0;
11
- border-bottom: #ddd 1px solid;
12
- }
13
-
14
- .wpp-cardview-compact li:last-of-type,
15
- .wpp-cardview-compact li:only-child {
16
- margin: 0;
17
- padding: 0;
18
- border-bottom: none;
19
- }
20
-
21
- .wpp-cardview-compact .wpp-thumbnail-container {
22
- position: relative;
23
- margin-bottom: .8em;
24
- }
25
-
26
- .wpp-cardview-compact li .wpp-thumbnail {
27
- overflow: hidden;
28
- display: block;
29
- float: none;
30
- margin: 0;
31
- width: 100%;
32
- height: auto;
33
- font-size: 0.8em;
34
- line-height: 1;
35
- background: #f0f0f0;
36
- border: none;
37
- }
38
-
39
- .wpp-cardview-compact li a {
40
- text-decoration: none;
41
- }
42
-
43
- .wpp-cardview-compact li a:hover {
44
- text-decoration: underline;
45
- }
46
-
47
- .wpp-cardview-compact li .taxonomies,
48
- .wpp-cardview-compact li .wpp-post-title {
49
- display: block;
50
- font-weight: bold;
51
- }
52
-
53
- .wpp-cardview-compact li .taxonomies {
54
- position: absolute;
55
- bottom: 0;
56
- left: 0;
57
- padding: 1em;
58
- color: #aaa;
59
- font-size: 0.7em;
60
- line-height: 1;
61
- background: rgba(0, 0, 0, 0.5);
62
- }
63
-
64
- .wpp-cardview-compact li .taxonomies a {
65
- color: #fff;
66
- }
67
-
68
- .wpp-cardview-compact li .wpp-post-title {
69
- margin: 0 0 0.5em;
70
- font-size: 1.2em;
71
- line-height: 1.2;
72
- }
1
+ .wpp-cardview-compact {
2
+ margin-left: 0;
3
+ margin-right: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ .wpp-cardview-compact li {
8
+ list-style: none;
9
+ margin: 0 0 1.2em 0;
10
+ padding: 0 0 1em 0;
11
+ border-bottom: #ddd 1px solid;
12
+ }
13
+
14
+ .wpp-cardview-compact li:last-of-type,
15
+ .wpp-cardview-compact li:only-child {
16
+ margin: 0;
17
+ padding: 0;
18
+ border-bottom: none;
19
+ }
20
+
21
+ .wpp-cardview-compact .wpp-thumbnail-container {
22
+ position: relative;
23
+ margin-bottom: .8em;
24
+ }
25
+
26
+ .wpp-cardview-compact li .wpp-thumbnail {
27
+ overflow: hidden;
28
+ display: block;
29
+ float: none;
30
+ margin: 0;
31
+ width: 100%;
32
+ height: auto;
33
+ font-size: 0.8em;
34
+ line-height: 1;
35
+ background: #f0f0f0;
36
+ border: none;
37
+ }
38
+
39
+ .wpp-cardview-compact li a {
40
+ text-decoration: none;
41
+ }
42
+
43
+ .wpp-cardview-compact li a:hover {
44
+ text-decoration: underline;
45
+ }
46
+
47
+ .wpp-cardview-compact li .taxonomies,
48
+ .wpp-cardview-compact li .wpp-post-title {
49
+ display: block;
50
+ font-weight: bold;
51
+ }
52
+
53
+ .wpp-cardview-compact li .taxonomies {
54
+ position: absolute;
55
+ bottom: 0;
56
+ left: 0;
57
+ padding: 1em;
58
+ color: #aaa;
59
+ font-size: 0.7em;
60
+ line-height: 1;
61
+ background: rgba(0, 0, 0, 0.5);
62
+ }
63
+
64
+ .wpp-cardview-compact li .taxonomies a {
65
+ color: #fff;
66
+ }
67
+
68
+ .wpp-cardview-compact li .wpp-post-title {
69
+ margin: 0 0 0.5em;
70
+ font-size: 1.2em;
71
+ line-height: 1.2;
72
+ }
assets/themes/cardview/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Cardview",
3
- "description": "A cardview-style popular posts list.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": true,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": true,
25
- "build": "manual",
26
- "width": 320,
27
- "height": 165,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": true,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-cardview\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li><div class=\"wpp-thumbnail-container\">{thumb}<div class=\"taxonomies\">{taxonomy}</div></div> <div class=\"wpp-item-data\">{title} <p class=\"wpp-excerpt\">{excerpt}</p></div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Cardview",
3
+ "description": "A cardview-style popular posts list.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": true,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": true,
25
+ "build": "manual",
26
+ "width": 320,
27
+ "height": 165,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": true,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-cardview\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li><div class=\"wpp-thumbnail-container\">{thumb}<div class=\"taxonomies\">{taxonomy}</div></div> <div class=\"wpp-item-data\">{title} <p class=\"wpp-excerpt\">{excerpt}</p></div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/cardview/style.css CHANGED
@@ -1,77 +1,77 @@
1
- .wpp-cardview {
2
- margin-left: 0;
3
- margin-right: 0;
4
- padding: 0;
5
- }
6
-
7
- .wpp-cardview li {
8
- list-style: none;
9
- margin: 0 0 1.2em 0;
10
- padding: 0 0 1em 0;
11
- border-bottom: #ddd 1px solid;
12
- }
13
-
14
- .wpp-cardview li:last-of-type,
15
- .wpp-cardview li:only-child {
16
- margin: 0;
17
- padding: 0;
18
- border-bottom: none;
19
- }
20
-
21
- .wpp-cardview .wpp-thumbnail-container {
22
- position: relative;
23
- margin-bottom: .8em;
24
- }
25
-
26
- .wpp-cardview li .wpp-thumbnail {
27
- overflow: hidden;
28
- display: block;
29
- float: none;
30
- margin: 0;
31
- width: 100%;
32
- height: auto;
33
- font-size: 0.8em;
34
- line-height: 1;
35
- background: #f0f0f0;
36
- border: none;
37
- }
38
-
39
- .wpp-cardview li a {
40
- text-decoration: none;
41
- }
42
-
43
- .wpp-cardview li a:hover {
44
- text-decoration: underline;
45
- }
46
-
47
- .wpp-cardview li .taxonomies,
48
- .wpp-cardview li .wpp-post-title {
49
- display: block;
50
- font-weight: bold;
51
- }
52
-
53
- .wpp-cardview li .taxonomies {
54
- position: absolute;
55
- bottom: 0;
56
- left: 0;
57
- padding: 1em;
58
- color: #aaa;
59
- font-size: 0.7em;
60
- line-height: 1;
61
- background: rgba(0, 0, 0, 0.5);
62
- }
63
-
64
- .wpp-cardview li .taxonomies a {
65
- color: #fff;
66
- }
67
-
68
- .wpp-cardview li .wpp-post-title {
69
- margin: 0 0 0.5em;
70
- font-size: 1.2em;
71
- line-height: 1.2;
72
- }
73
-
74
- .wpp-cardview li .wpp-excerpt {
75
- margin: 0;
76
- font-size: 0.8em;
77
  }
1
+ .wpp-cardview {
2
+ margin-left: 0;
3
+ margin-right: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ .wpp-cardview li {
8
+ list-style: none;
9
+ margin: 0 0 1.2em 0;
10
+ padding: 0 0 1em 0;
11
+ border-bottom: #ddd 1px solid;
12
+ }
13
+
14
+ .wpp-cardview li:last-of-type,
15
+ .wpp-cardview li:only-child {
16
+ margin: 0;
17
+ padding: 0;
18
+ border-bottom: none;
19
+ }
20
+
21
+ .wpp-cardview .wpp-thumbnail-container {
22
+ position: relative;
23
+ margin-bottom: .8em;
24
+ }
25
+
26
+ .wpp-cardview li .wpp-thumbnail {
27
+ overflow: hidden;
28
+ display: block;
29
+ float: none;
30
+ margin: 0;
31
+ width: 100%;
32
+ height: auto;
33
+ font-size: 0.8em;
34
+ line-height: 1;
35
+ background: #f0f0f0;
36
+ border: none;
37
+ }
38
+
39
+ .wpp-cardview li a {
40
+ text-decoration: none;
41
+ }
42
+
43
+ .wpp-cardview li a:hover {
44
+ text-decoration: underline;
45
+ }
46
+
47
+ .wpp-cardview li .taxonomies,
48
+ .wpp-cardview li .wpp-post-title {
49
+ display: block;
50
+ font-weight: bold;
51
+ }
52
+
53
+ .wpp-cardview li .taxonomies {
54
+ position: absolute;
55
+ bottom: 0;
56
+ left: 0;
57
+ padding: 1em;
58
+ color: #aaa;
59
+ font-size: 0.7em;
60
+ line-height: 1;
61
+ background: rgba(0, 0, 0, 0.5);
62
+ }
63
+
64
+ .wpp-cardview li .taxonomies a {
65
+ color: #fff;
66
+ }
67
+
68
+ .wpp-cardview li .wpp-post-title {
69
+ margin: 0 0 0.5em;
70
+ font-size: 1.2em;
71
+ line-height: 1.2;
72
+ }
73
+
74
+ .wpp-cardview li .wpp-excerpt {
75
+ margin: 0;
76
+ font-size: 0.8em;
77
  }
assets/themes/evergreen/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Evergreen",
3
- "description": "A simple list of popular posts.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": false,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": false,
25
- "build": "manual",
26
- "width": 75,
27
- "height": 75,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": false,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-evergreen\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li style=\"--item-position: {item_position}; --total-items: {total_items};\"><div class=\"item-position\"></div> <div class=\"item-data\">{title}</div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Evergreen",
3
+ "description": "A simple list of popular posts.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": false,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": false,
25
+ "build": "manual",
26
+ "width": 75,
27
+ "height": 75,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": false,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-evergreen\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li style=\"--item-position: {item_position}; --total-items: {total_items};\"><div class=\"item-position\"></div> <div class=\"item-data\">{title}</div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/evergreen/style.css CHANGED
@@ -1,49 +1,49 @@
1
- .wpp-evergreen {
2
- counter-reset: wpp-counter;
3
- margin-left: 0;
4
- margin-right: 0;
5
- padding: 0;
6
- border-right: 6px solid rgb(49, 188, 7);
7
- box-sizing: border-box;
8
- }
9
-
10
- .wpp-evergreen li {
11
- position: relative;
12
- display: flex;
13
- align-items: center;
14
- counter-increment: wpp-counter;
15
- position: relative;
16
- list-style: none;
17
- margin: 0;
18
- padding: 15px 15px 15px 0;
19
- background: rgba(49, 188, 7, calc((((var(--total-items) - (var(--item-position) - 1)) * 100)/var(--total-items))/100));
20
- box-sizing: border-box;
21
- }
22
-
23
- .wpp-evergreen li .item-position::before {
24
- display: inline-block;
25
- flex: 1 0 0;
26
- content: counter(wpp-counter);
27
- color: rgba(0, 0, 0, 0.15);
28
- width: 40px;
29
- font-size: 18px;
30
- font-weight: 700;
31
- letter-spacing: -1px;
32
- text-align: center;
33
- }
34
-
35
- .wpp-evergreen li .item-data .wpp-post-title {
36
- display: block;
37
- font-size: 15px;
38
- font-weight: 700;
39
- line-height: 1.3;
40
- }
41
-
42
- .wpp-evergreen li .item-data a {
43
- color: #0f470e;
44
- text-decoration: none;
45
- }
46
-
47
- .wpp-evergreen li .item-data a:hover {
48
- text-decoration: underline;
49
  }
1
+ .wpp-evergreen {
2
+ counter-reset: wpp-counter;
3
+ margin-left: 0;
4
+ margin-right: 0;
5
+ padding: 0;
6
+ border-right: 6px solid rgb(49, 188, 7);
7
+ box-sizing: border-box;
8
+ }
9
+
10
+ .wpp-evergreen li {
11
+ position: relative;
12
+ display: flex;
13
+ align-items: center;
14
+ counter-increment: wpp-counter;
15
+ position: relative;
16
+ list-style: none;
17
+ margin: 0;
18
+ padding: 15px 15px 15px 0;
19
+ background: rgba(49, 188, 7, calc((((var(--total-items) - (var(--item-position) - 1)) * 100)/var(--total-items))/100));
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ .wpp-evergreen li .item-position::before {
24
+ display: inline-block;
25
+ flex: 1 0 0;
26
+ content: counter(wpp-counter);
27
+ color: rgba(0, 0, 0, 0.15);
28
+ width: 40px;
29
+ font-size: 18px;
30
+ font-weight: 700;
31
+ letter-spacing: -1px;
32
+ text-align: center;
33
+ }
34
+
35
+ .wpp-evergreen li .item-data .wpp-post-title {
36
+ display: block;
37
+ font-size: 15px;
38
+ font-weight: 700;
39
+ line-height: 1.3;
40
+ }
41
+
42
+ .wpp-evergreen li .item-data a {
43
+ color: #0f470e;
44
+ text-decoration: none;
45
+ }
46
+
47
+ .wpp-evergreen li .item-data a:hover {
48
+ text-decoration: underline;
49
  }
assets/themes/midnight/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Midnight",
3
- "description": "A simple list of popular posts.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": false,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": false,
25
- "build": "manual",
26
- "width": 75,
27
- "height": 75,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": false,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-midnight\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li style=\"--item-position: {item_position}; --total-items: {total_items};\"><div class=\"item-position\"></div> <div class=\"item-data\">{title}</div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Midnight",
3
+ "description": "A simple list of popular posts.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": false,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": false,
25
+ "build": "manual",
26
+ "width": 75,
27
+ "height": 75,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": false,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-midnight\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li style=\"--item-position: {item_position}; --total-items: {total_items};\"><div class=\"item-position\"></div> <div class=\"item-data\">{title}</div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/midnight/style.css CHANGED
@@ -1,49 +1,49 @@
1
- .wpp-midnight {
2
- counter-reset: wpp-counter;
3
- margin-left: 0;
4
- margin-right: 0;
5
- padding: 0;
6
- border-right: 6px solid rgb(0, 51, 51);
7
- box-sizing: border-box;
8
- }
9
-
10
- .wpp-midnight li {
11
- position: relative;
12
- display: flex;
13
- align-items: center;
14
- counter-increment: wpp-counter;
15
- position: relative;
16
- list-style: none;
17
- margin: 0;
18
- padding: 15px 15px 15px 0;
19
- background: rgba(0, 51, 51, calc((((var(--total-items) - (var(--item-position) - 1)) * 100)/var(--total-items))/100));
20
- box-sizing: border-box;
21
- }
22
-
23
- .wpp-midnight li .item-position::before {
24
- display: inline-block;
25
- flex: 1 0 0;
26
- content: counter(wpp-counter);
27
- color: rgba(255, 255, 255, 0.3);
28
- width: 40px;
29
- font-size: 18px;
30
- font-weight: 700;
31
- letter-spacing: -1px;
32
- text-align: center;
33
- }
34
-
35
- .wpp-midnight li .item-data .wpp-post-title {
36
- display: block;
37
- font-size: 15px;
38
- font-weight: 700;
39
- line-height: 1.3;
40
- }
41
-
42
- .wpp-midnight li .item-data a {
43
- color: #eee;
44
- text-decoration: none;
45
- }
46
-
47
- .wpp-midnight li .item-data a:hover {
48
- text-decoration: underline;
49
  }
1
+ .wpp-midnight {
2
+ counter-reset: wpp-counter;
3
+ margin-left: 0;
4
+ margin-right: 0;
5
+ padding: 0;
6
+ border-right: 6px solid rgb(0, 51, 51);
7
+ box-sizing: border-box;
8
+ }
9
+
10
+ .wpp-midnight li {
11
+ position: relative;
12
+ display: flex;
13
+ align-items: center;
14
+ counter-increment: wpp-counter;
15
+ position: relative;
16
+ list-style: none;
17
+ margin: 0;
18
+ padding: 15px 15px 15px 0;
19
+ background: rgba(0, 51, 51, calc((((var(--total-items) - (var(--item-position) - 1)) * 100)/var(--total-items))/100));
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ .wpp-midnight li .item-position::before {
24
+ display: inline-block;
25
+ flex: 1 0 0;
26
+ content: counter(wpp-counter);
27
+ color: rgba(255, 255, 255, 0.3);
28
+ width: 40px;
29
+ font-size: 18px;
30
+ font-weight: 700;
31
+ letter-spacing: -1px;
32
+ text-align: center;
33
+ }
34
+
35
+ .wpp-midnight li .item-data .wpp-post-title {
36
+ display: block;
37
+ font-size: 15px;
38
+ font-weight: 700;
39
+ line-height: 1.3;
40
+ }
41
+
42
+ .wpp-midnight li .item-data a {
43
+ color: #eee;
44
+ text-decoration: none;
45
+ }
46
+
47
+ .wpp-midnight li .item-data a:hover {
48
+ text-decoration: underline;
49
  }
assets/themes/sunrise/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Sunrise",
3
- "description": "A simple list of popular posts.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": false,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": false,
25
- "build": "manual",
26
- "width": 75,
27
- "height": 75,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": false,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-sunrise\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li style=\"--item-position: {item_position}; --total-items: {total_items};\"><div class=\"item-position\"></div> <div class=\"item-data\">{title}</div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Sunrise",
3
+ "description": "A simple list of popular posts.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": false,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": false,
25
+ "build": "manual",
26
+ "width": 75,
27
+ "height": 75,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": false,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-sunrise\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li style=\"--item-position: {item_position}; --total-items: {total_items};\"><div class=\"item-position\"></div> <div class=\"item-data\">{title}</div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/sunrise/style.css CHANGED
@@ -1,49 +1,49 @@
1
- .wpp-sunrise {
2
- counter-reset: wpp-counter;
3
- margin-left: 0;
4
- margin-right: 0;
5
- padding: 0;
6
- border-right: 6px solid rgb(255, 255, 124);
7
- box-sizing: border-box;
8
- }
9
-
10
- .wpp-sunrise li {
11
- position: relative;
12
- display: flex;
13
- align-items: center;
14
- counter-increment: wpp-counter;
15
- position: relative;
16
- list-style: none;
17
- margin: 0;
18
- padding: 15px 15px 15px 0;
19
- background: rgba(255, 255, 124, calc((((var(--total-items) - (var(--item-position) - 1)) * 100)/var(--total-items))/100));
20
- box-sizing: border-box;
21
- }
22
-
23
- .wpp-sunrise li .item-position::before {
24
- display: inline-block;
25
- flex: 1 0 0;
26
- content: counter(wpp-counter);
27
- color: rgba(0, 0, 0, 0.15);
28
- width: 40px;
29
- font-size: 18px;
30
- font-weight: 700;
31
- letter-spacing: -1px;
32
- text-align: center;
33
- }
34
-
35
- .wpp-sunrise li .item-data .wpp-post-title {
36
- display: block;
37
- font-size: 15px;
38
- font-weight: 700;
39
- line-height: 1.3;
40
- }
41
-
42
- .wpp-sunrise li .item-data a {
43
- color: #2b2b09;
44
- text-decoration: none;
45
- }
46
-
47
- .wpp-sunrise li .item-data a:hover {
48
- text-decoration: underline;
49
  }
1
+ .wpp-sunrise {
2
+ counter-reset: wpp-counter;
3
+ margin-left: 0;
4
+ margin-right: 0;
5
+ padding: 0;
6
+ border-right: 6px solid rgb(255, 255, 124);
7
+ box-sizing: border-box;
8
+ }
9
+
10
+ .wpp-sunrise li {
11
+ position: relative;
12
+ display: flex;
13
+ align-items: center;
14
+ counter-increment: wpp-counter;
15
+ position: relative;
16
+ list-style: none;
17
+ margin: 0;
18
+ padding: 15px 15px 15px 0;
19
+ background: rgba(255, 255, 124, calc((((var(--total-items) - (var(--item-position) - 1)) * 100)/var(--total-items))/100));
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ .wpp-sunrise li .item-position::before {
24
+ display: inline-block;
25
+ flex: 1 0 0;
26
+ content: counter(wpp-counter);
27
+ color: rgba(0, 0, 0, 0.15);
28
+ width: 40px;
29
+ font-size: 18px;
30
+ font-weight: 700;
31
+ letter-spacing: -1px;
32
+ text-align: center;
33
+ }
34
+
35
+ .wpp-sunrise li .item-data .wpp-post-title {
36
+ display: block;
37
+ font-size: 15px;
38
+ font-weight: 700;
39
+ line-height: 1.3;
40
+ }
41
+
42
+ .wpp-sunrise li .item-data a {
43
+ color: #2b2b09;
44
+ text-decoration: none;
45
+ }
46
+
47
+ .wpp-sunrise li .item-data a:hover {
48
+ text-decoration: underline;
49
  }
assets/themes/sunset/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Sunset",
3
- "description": "A simple list of popular posts.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": false,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": false,
25
- "build": "manual",
26
- "width": 75,
27
- "height": 75,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": false,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-sunset\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li style=\"--item-position: {item_position}; --total-items: {total_items};\"><div class=\"item-position\"></div> <div class=\"item-data\">{title}</div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Sunset",
3
+ "description": "A simple list of popular posts.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": false,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": false,
25
+ "build": "manual",
26
+ "width": 75,
27
+ "height": 75,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": false,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-sunset\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li style=\"--item-position: {item_position}; --total-items: {total_items};\"><div class=\"item-position\"></div> <div class=\"item-data\">{title}</div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/sunset/style.css CHANGED
@@ -1,49 +1,49 @@
1
- .wpp-sunset {
2
- counter-reset: wpp-counter;
3
- margin-left: 0;
4
- margin-right: 0;
5
- padding: 0;
6
- border-right: 6px solid rgb(234, 51, 51);
7
- box-sizing: border-box;
8
- }
9
-
10
- .wpp-sunset li {
11
- position: relative;
12
- display: flex;
13
- align-items: center;
14
- counter-increment: wpp-counter;
15
- position: relative;
16
- list-style: none;
17
- margin: 0;
18
- padding: 15px 15px 15px 0;
19
- background: rgba(234, 51, 51, calc((((var(--total-items) - (var(--item-position) - 1)) * 100)/var(--total-items))/100));
20
- box-sizing: border-box;
21
- }
22
-
23
- .wpp-sunset li .item-position::before {
24
- display: inline-block;
25
- flex: 1 0 0;
26
- content: counter(wpp-counter);
27
- color: rgba(0, 0, 0, 0.15);
28
- width: 40px;
29
- font-size: 18px;
30
- font-weight: 700;
31
- letter-spacing: -1px;
32
- text-align: center;
33
- }
34
-
35
- .wpp-sunset li .item-data .wpp-post-title {
36
- display: block;
37
- font-size: 15px;
38
- font-weight: 700;
39
- line-height: 1.3;
40
- }
41
-
42
- .wpp-sunset li .item-data a {
43
- color: #222;
44
- text-decoration: none;
45
- }
46
-
47
- .wpp-sunset li .item-data a:hover {
48
- text-decoration: underline;
49
  }
1
+ .wpp-sunset {
2
+ counter-reset: wpp-counter;
3
+ margin-left: 0;
4
+ margin-right: 0;
5
+ padding: 0;
6
+ border-right: 6px solid rgb(234, 51, 51);
7
+ box-sizing: border-box;
8
+ }
9
+
10
+ .wpp-sunset li {
11
+ position: relative;
12
+ display: flex;
13
+ align-items: center;
14
+ counter-increment: wpp-counter;
15
+ position: relative;
16
+ list-style: none;
17
+ margin: 0;
18
+ padding: 15px 15px 15px 0;
19
+ background: rgba(234, 51, 51, calc((((var(--total-items) - (var(--item-position) - 1)) * 100)/var(--total-items))/100));
20
+ box-sizing: border-box;
21
+ }
22
+
23
+ .wpp-sunset li .item-position::before {
24
+ display: inline-block;
25
+ flex: 1 0 0;
26
+ content: counter(wpp-counter);
27
+ color: rgba(0, 0, 0, 0.15);
28
+ width: 40px;
29
+ font-size: 18px;
30
+ font-weight: 700;
31
+ letter-spacing: -1px;
32
+ text-align: center;
33
+ }
34
+
35
+ .wpp-sunset li .item-data .wpp-post-title {
36
+ display: block;
37
+ font-size: 15px;
38
+ font-weight: 700;
39
+ line-height: 1.3;
40
+ }
41
+
42
+ .wpp-sunset li .item-data a {
43
+ color: #222;
44
+ text-decoration: none;
45
+ }
46
+
47
+ .wpp-sunset li .item-data a:hover {
48
+ text-decoration: underline;
49
  }
assets/themes/tiles/config.json CHANGED
@@ -1,50 +1,50 @@
1
- {
2
- "name": "Tiles",
3
- "description": "A Tile-styled popular posts list.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "shorten_title": {
13
- "active": false,
14
- "length": 25,
15
- "words": false
16
- },
17
- "post-excerpt": {
18
- "active": false,
19
- "length": 75,
20
- "keep_format": false,
21
- "words": false
22
- },
23
- "thumbnail": {
24
- "active": true,
25
- "build": "manual",
26
- "width": 320,
27
- "height": 160,
28
- "crop": true
29
- },
30
- "rating": false,
31
- "stats_tag": {
32
- "comment_count": false,
33
- "views": false,
34
- "author": false,
35
- "date": {
36
- "active": false,
37
- "format": "F j, Y"
38
- },
39
- "taxonomy": {
40
- "active": true,
41
- "name": "category"
42
- }
43
- },
44
- "markup": {
45
- "wpp-start": "<ul class=\"wpp-list wpp-tiles\">",
46
- "wpp-end": "</ul>",
47
- "post-html": "<li>{thumb}<div class=\"wpp-post-data\">{taxonomy} {title}</div></li>"
48
- }
49
- }
50
- }
1
+ {
2
+ "name": "Tiles",
3
+ "description": "A Tile-styled popular posts list.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "shorten_title": {
13
+ "active": false,
14
+ "length": 25,
15
+ "words": false
16
+ },
17
+ "post-excerpt": {
18
+ "active": false,
19
+ "length": 75,
20
+ "keep_format": false,
21
+ "words": false
22
+ },
23
+ "thumbnail": {
24
+ "active": true,
25
+ "build": "manual",
26
+ "width": 320,
27
+ "height": 160,
28
+ "crop": true
29
+ },
30
+ "rating": false,
31
+ "stats_tag": {
32
+ "comment_count": false,
33
+ "views": false,
34
+ "author": false,
35
+ "date": {
36
+ "active": false,
37
+ "format": "F j, Y"
38
+ },
39
+ "taxonomy": {
40
+ "active": true,
41
+ "name": "category"
42
+ }
43
+ },
44
+ "markup": {
45
+ "wpp-start": "<ul class=\"wpp-list wpp-tiles\">",
46
+ "wpp-end": "</ul>",
47
+ "post-html": "<li>{thumb}<div class=\"wpp-post-data\">{taxonomy} {title}</div></li>"
48
+ }
49
+ }
50
+ }
assets/themes/tiles/style.css CHANGED
@@ -1,65 +1,65 @@
1
- .wpp-tiles {
2
- margin-left: 0;
3
- margin-right: 0;
4
- padding: 0;
5
- }
6
-
7
- .wpp-tiles li {
8
- position: relative;
9
- list-style: none;
10
- margin: 0 0 1.2em 0;
11
- padding: 0;
12
- }
13
-
14
- .wpp-tiles li:last-of-type {
15
- margin: 0;
16
- }
17
-
18
- .wpp-tiles li .wpp-thumbnail {
19
- overflow: hidden;
20
- display: block;
21
- margin: 0;
22
- width: 100%;
23
- height: auto;
24
- font-size: 0.8em;
25
- line-height: 1;
26
- background: #f0f0f0;
27
- border: none;
28
- }
29
-
30
- .wpp-tiles li a {
31
- text-decoration: none;
32
- }
33
-
34
- .wpp-tiles li a:hover {
35
- text-decoration: underline;
36
- }
37
-
38
- .wpp-tiles li .wpp-post-data {
39
- position: absolute;
40
- left: 0;
41
- bottom: 0;
42
- padding: .75em 1em 1em;
43
- width: 100%;
44
- box-sizing: border-box;
45
- background: rgba(0, 0, 0, 0.5);
46
- }
47
-
48
- .wpp-tiles li .wpp-post-data .category,
49
- .wpp-tiles li .wpp-post-data .wpp-post-title {
50
- color: #fff;
51
- font-weight: bold;
52
- }
53
-
54
- .wpp-tiles li .wpp-post-data .category {
55
- margin: 0;
56
- font-size: 0.7em;
57
- line-height: 1;
58
- }
59
-
60
- .wpp-tiles li .wpp-post-data .wpp-post-title {
61
- display: block;
62
- margin: 0 0 0;
63
- font-size: 1em;
64
- line-height: 1.2;
65
  }
1
+ .wpp-tiles {
2
+ margin-left: 0;
3
+ margin-right: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ .wpp-tiles li {
8
+ position: relative;
9
+ list-style: none;
10
+ margin: 0 0 1.2em 0;
11
+ padding: 0;
12
+ }
13
+
14
+ .wpp-tiles li:last-of-type {
15
+ margin: 0;
16
+ }
17
+
18
+ .wpp-tiles li .wpp-thumbnail {
19
+ overflow: hidden;
20
+ display: block;
21
+ margin: 0;
22
+ width: 100%;
23
+ height: auto;
24
+ font-size: 0.8em;
25
+ line-height: 1;
26
+ background: #f0f0f0;
27
+ border: none;
28
+ }
29
+
30
+ .wpp-tiles li a {
31
+ text-decoration: none;
32
+ }
33
+
34
+ .wpp-tiles li a:hover {
35
+ text-decoration: underline;
36
+ }
37
+
38
+ .wpp-tiles li .wpp-post-data {
39
+ position: absolute;
40
+ left: 0;
41
+ bottom: 0;
42
+ padding: .75em 1em 1em;
43
+ width: 100%;
44
+ box-sizing: border-box;
45
+ background: rgba(0, 0, 0, 0.5);
46
+ }
47
+
48
+ .wpp-tiles li .wpp-post-data .category,
49
+ .wpp-tiles li .wpp-post-data .wpp-post-title {
50
+ color: #fff;
51
+ font-weight: bold;
52
+ }
53
+
54
+ .wpp-tiles li .wpp-post-data .category {
55
+ margin: 0;
56
+ font-size: 0.7em;
57
+ line-height: 1;
58
+ }
59
+
60
+ .wpp-tiles li .wpp-post-data .wpp-post-title {
61
+ display: block;
62
+ margin: 0 0 0;
63
+ font-size: 1em;
64
+ line-height: 1.2;
65
  }
assets/themes/tiny/config.json CHANGED
@@ -1,41 +1,41 @@
1
- {
2
- "name": "Tiny",
3
- "description": "A very compact popular posts list.",
4
- "authors": [
5
- {
6
- "name": "Hector Cabrera",
7
- "email": "me@cabrerahector.com",
8
- "role": "Creator / Main Developer"
9
- }
10
- ],
11
- "config": {
12
- "title" : "Trending",
13
- "shorten_title": {
14
- "active": false
15
- },
16
- "post-excerpt": {
17
- "active": false
18
- },
19
- "thumbnail": {
20
- "active": false
21
- },
22
- "rating": false,
23
- "stats_tag": {
24
- "comment_count": false,
25
- "views": false,
26
- "author": false,
27
- "date": {
28
- "active": false
29
- },
30
- "taxonomy": {
31
- "active": true,
32
- "name": "category"
33
- }
34
- },
35
- "markup": {
36
- "wpp-start": "<ul class=\"wpp-list wpp-tiny\">",
37
- "wpp-end": "</ul>",
38
- "post-html": "<li><div class=\"wpp-item-data\">{category}</div> {title}</li>"
39
- }
40
- }
41
- }
1
+ {
2
+ "name": "Tiny",
3
+ "description": "A very compact popular posts list.",
4
+ "authors": [
5
+ {
6
+ "name": "Hector Cabrera",
7
+ "email": "me@cabrerahector.com",
8
+ "role": "Creator / Main Developer"
9
+ }
10
+ ],
11
+ "config": {
12
+ "title" : "Trending",
13
+ "shorten_title": {
14
+ "active": false
15
+ },
16
+ "post-excerpt": {
17
+ "active": false
18
+ },
19
+ "thumbnail": {
20
+ "active": false
21
+ },
22
+ "rating": false,
23
+ "stats_tag": {
24
+ "comment_count": false,
25
+ "views": false,
26
+ "author": false,
27
+ "date": {
28
+ "active": false
29
+ },
30
+ "taxonomy": {
31
+ "active": true,
32
+ "name": "category"
33
+ }
34
+ },
35
+ "markup": {
36
+ "wpp-start": "<ul class=\"wpp-list wpp-tiny\">",
37
+ "wpp-end": "</ul>",
38
+ "post-html": "<li><div class=\"wpp-item-data\">{category}</div> {title}</li>"
39
+ }
40
+ }
41
+ }
assets/themes/tiny/style.css CHANGED
@@ -1,36 +1,36 @@
1
- .wpp-tiny {
2
- margin-left: 0;
3
- margin-right: 0;
4
- padding: 0;
5
- }
6
-
7
- .wpp-tiny li {
8
- list-style: none;
9
- margin: 0 0 1.2rem 0;
10
- padding: 0;
11
- }
12
-
13
- .wpp-tiny li:last-of-type {
14
- margin: 0;
15
- }
16
-
17
- .wpp-tiny li a {
18
- text-decoration: none;
19
- }
20
-
21
- .wpp-tiny li a:hover {
22
- text-decoration: underline;
23
- }
24
-
25
- .wpp-tiny li .wpp-post-title {
26
- font-size: 1.125rem;
27
- font-weight: 700;
28
- letter-spacing: -1px;
29
- line-height: 1.1;
30
- }
31
-
32
- .wpp-tiny li .wpp-item-data {
33
- opacity: 0.5;
34
- font-size: 0.65rem;
35
- text-transform: capitalize;
36
- }
1
+ .wpp-tiny {
2
+ margin-left: 0;
3
+ margin-right: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ .wpp-tiny li {
8
+ list-style: none;
9
+ margin: 0 0 1.2rem 0;
10
+ padding: 0;
11
+ }
12
+
13
+ .wpp-tiny li:last-of-type {
14
+ margin: 0;
15
+ }
16
+
17
+ .wpp-tiny li a {
18
+ text-decoration: none;
19
+ }
20
+
21
+ .wpp-tiny li a:hover {
22
+ text-decoration: underline;
23
+ }
24
+
25
+ .wpp-tiny li .wpp-post-title {
26
+ font-size: 1.125rem;
27
+ font-weight: 700;
28
+ letter-spacing: -1px;
29
+ line-height: 1.1;
30
+ }
31
+
32
+ .wpp-tiny li .wpp-item-data {
33
+ opacity: 0.5;
34
+ font-size: 0.65rem;
35
+ text-transform: capitalize;
36
+ }
i18n/wordpress-popular-posts.pot CHANGED
@@ -1,1225 +1,1225 @@
1
- # Copyright (C) 2014 Wordpress Popular Posts
2
- # This file is distributed under the same license as the Wordpress Popular Posts package.
3
- #, fuzzy
4
- msgid ""
5
- msgstr ""
6
- "Project-Id-Version: WordPress Popular Posts\n"
7
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/wordpress-popular-posts\n"
8
- "POT-Creation-Date: 2020-10-12 13:04-0400\n"
9
- "PO-Revision-Date: 2015-04-24 13:30-0430\n"
10
- "Last-Translator: Héctor Cabrera <hcabrerab@gmail.com>\n"
11
- "Language-Team: Héctor Cabrera <me@cabrerahector.com>\n"
12
- "Language: en\n"
13
- "MIME-Version: 1.0\n"
14
- "Content-Type: text/plain; charset=UTF-8\n"
15
- "Content-Transfer-Encoding: 8bit\n"
16
- "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
- "X-Generator: Poedit 2.4.1\n"
18
- "X-Poedit-KeywordsList: _e;__;__ngettext;__ngettext_noop;_n_noop;_x;_nx;_nx_noop;_ex;"
19
- "esc_attr__;esc_attr_e;esc_attr_x;esc_html__;esc_html_e;esc_html_x;_c;_nc;_n:1,2\n"
20
- "X-Poedit-Basepath: .\n"
21
- "X-Poedit-SourceCharset: UTF-8\n"
22
- "X-Poedit-SearchPath-0: .\n"
23
- "X-Poedit-SearchPath-1: ..\n"
24
-
25
- #: ../src/Admin/Admin.php:371
26
- #, php-format
27
- msgid "%s view in the last hour"
28
- msgid_plural "%s views in the last hour"
29
- msgstr[0] ""
30
- msgstr[1] ""
31
-
32
- #: ../src/Admin/Admin.php:405 ../src/Admin/admin-page.php:349
33
- msgid "Trending now"
34
- msgstr ""
35
-
36
- #: ../src/Admin/Admin.php:493
37
- msgid "View more"
38
- msgstr ""
39
-
40
- #: ../src/Admin/Admin.php:522
41
- msgid "Use this image"
42
- msgstr ""
43
-
44
- #: ../src/Admin/Admin.php:575
45
- msgid "Overview"
46
- msgstr ""
47
-
48
- #: ../src/Admin/Admin.php:576
49
- msgid ""
50
- "Welcome to WordPress Popular Posts' Dashboard! In this screen you will find statistics "
51
- "on what's popular on your site, tools to further tweak WPP to your needs, and more!"
52
- msgstr ""
53
-
54
- #: ../src/Admin/Admin.php:582
55
- msgid "Like this plugin?"
56
- msgstr ""
57
-
58
- #: ../src/Admin/Admin.php:584
59
- msgid ""
60
- "Each donation motivates me to keep releasing free stuff for the WordPress community!"
61
- msgstr ""
62
-
63
- #: ../src/Admin/Admin.php:591
64
- #, php-format
65
- msgid "You can <a href=\"%s\" target=\"_blank\">leave a review</a>, too!"
66
- msgstr ""
67
-
68
- #: ../src/Admin/Admin.php:598
69
- #, php-format
70
- msgid ""
71
- "<p><strong>For more information:</strong></p><ul><li><a href=\"%1$s\">Documentation</"
72
- "a></li><li><a href=\"%2$s\">Support</a></li></ul>"
73
- msgstr ""
74
-
75
- #: ../src/Admin/Admin.php:622
76
- msgid "Settings"
77
- msgstr ""
78
-
79
- #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1088 ../src/Admin/Admin.php:1092
80
- #: ../src/Output.php:757
81
- #, php-format
82
- msgid "%s view"
83
- msgid_plural "%s views"
84
- msgstr[0] ""
85
- msgstr[1] ""
86
-
87
- #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1090 ../src/Admin/Admin.php:1092
88
- #: ../src/Output.php:740
89
- #, php-format
90
- msgid "%s comment"
91
- msgid_plural "%s comments"
92
- msgstr[0] ""
93
- msgstr[1] ""
94
-
95
- #: ../src/Admin/Admin.php:720 ../src/Widget/form.php:21
96
- msgid "Comments"
97
- msgstr ""
98
-
99
- #: ../src/Admin/Admin.php:724
100
- msgid "Views"
101
- msgstr ""
102
-
103
- #: ../src/Admin/Admin.php:1094
104
- msgid "View"
105
- msgstr ""
106
-
107
- #: ../src/Admin/Admin.php:1094
108
- msgid "Edit"
109
- msgstr ""
110
-
111
- #: ../src/Admin/Admin.php:1105
112
- msgid ""
113
- "Looks like your site's activity is a little low right now. <br />Spread the word and "
114
- "come back later!"
115
- msgstr ""
116
-
117
- #: ../src/Admin/Admin.php:1367
118
- #, php-format
119
- msgid ""
120
- "<strong>WordPress Popular Posts:</strong> It seems your site is popular (great!) You "
121
- "may want to check <a href=\"%s\">these suggestions</a> to make sure your website's "
122
- "performance stays up to par."
123
- msgstr ""
124
-
125
- #: ../src/Admin/admin-page.php:6 ../src/Admin/admin-page.php:240
126
- msgid "Stats"
127
- msgstr ""
128
-
129
- #: ../src/Admin/admin-page.php:7 ../src/Admin/admin-page.php:241
130
- msgid "Tools"
131
- msgstr ""
132
-
133
- #: ../src/Admin/admin-page.php:8 ../src/Admin/admin-page.php:242
134
- msgid "Parameters"
135
- msgstr ""
136
-
137
- #: ../src/Admin/admin-page.php:30 ../src/Admin/admin-page.php:41
138
- #: ../src/Admin/admin-page.php:67 ../src/Admin/admin-page.php:103
139
- msgid "Settings saved."
140
- msgstr ""
141
-
142
- #: ../src/Admin/admin-page.php:52
143
- msgid "Please provide the name of your custom field."
144
- msgstr ""
145
-
146
- #: ../src/Admin/admin-page.php:121
147
- msgid ""
148
- "This operation will delete all entries from WordPress Popular Posts' cache table and "
149
- "cannot be undone."
150
- msgstr ""
151
-
152
- #: ../src/Admin/admin-page.php:121 ../src/Admin/admin-page.php:160
153
- #: ../src/Admin/admin-page.php:199
154
- msgid "Do you want to continue?"
155
- msgstr ""
156
-
157
- #: ../src/Admin/admin-page.php:133
158
- msgid "Success! The cache table has been cleared!"
159
- msgstr ""
160
-
161
- #: ../src/Admin/admin-page.php:137
162
- msgid "Error: cache table does not exist."
163
- msgstr ""
164
-
165
- #: ../src/Admin/admin-page.php:141 ../src/Admin/admin-page.php:149
166
- #: ../src/Admin/admin-page.php:180 ../src/Admin/admin-page.php:188
167
- #: ../src/Admin/admin-page.php:218 ../src/Admin/admin-page.php:226
168
- msgid "Invalid action."
169
- msgstr ""
170
-
171
- #: ../src/Admin/admin-page.php:145 ../src/Admin/admin-page.php:184
172
- #: ../src/Admin/admin-page.php:222
173
- msgid ""
174
- "Sorry, you do not have enough permissions to do this. Please contact the site "
175
- "administrator for support."
176
- msgstr ""
177
-
178
- #: ../src/Admin/admin-page.php:160
179
- msgid ""
180
- "This operation will delete all stored info from WordPress Popular Posts' data tables "
181
- "and cannot be undone."
182
- msgstr ""
183
-
184
- #: ../src/Admin/admin-page.php:172
185
- msgid "Success! All data have been cleared!"
186
- msgstr ""
187
-
188
- #: ../src/Admin/admin-page.php:176
189
- msgid "Error: one or both data tables are missing."
190
- msgstr ""
191
-
192
- #: ../src/Admin/admin-page.php:199
193
- msgid "This operation will delete all cached thumbnails and cannot be undone."
194
- msgstr ""
195
-
196
- #: ../src/Admin/admin-page.php:210
197
- msgid "Success! All files have been deleted!"
198
- msgstr ""
199
-
200
- #: ../src/Admin/admin-page.php:214
201
- msgid "The thumbnail cache is already empty!"
202
- msgstr ""
203
-
204
- #: ../src/Admin/admin-page.php:239
205
- msgid "Menu"
206
- msgstr ""
207
-
208
- #: ../src/Admin/admin-page.php:266
209
- msgid "Post type"
210
- msgstr ""
211
-
212
- #: ../src/Admin/admin-page.php:269
213
- msgid "Limit"
214
- msgstr ""
215
-
216
- #: ../src/Admin/admin-page.php:272 ../src/Widget/form.php:52
217
- msgid "Display only posts published within the selected Time Range"
218
- msgstr ""
219
-
220
- #: ../src/Admin/admin-page.php:278 ../src/Admin/admin-page.php:310
221
- #: ../src/Admin/admin-page.php:462 ../src/Admin/admin-page.php:569
222
- #: ../src/Admin/admin-page.php:609
223
- msgid "Apply"
224
- msgstr ""
225
-
226
- #: ../src/Admin/admin-page.php:279 ../src/Admin/admin-page.php:313
227
- msgid "Cancel"
228
- msgstr ""
229
-
230
- #: ../src/Admin/admin-page.php:288
231
- msgid "Custom Time Range"
232
- msgstr ""
233
-
234
- #: ../src/Admin/admin-page.php:289
235
- msgid "Date Range"
236
- msgstr ""
237
-
238
- #: ../src/Admin/admin-page.php:296 ../src/Admin/admin-page.php:535
239
- #: ../src/Widget/form.php:45
240
- msgid "Minute(s)"
241
- msgstr ""
242
-
243
- #: ../src/Admin/admin-page.php:297 ../src/Admin/admin-page.php:536
244
- #: ../src/Widget/form.php:46
245
- msgid "Hour(s)"
246
- msgstr ""
247
-
248
- #: ../src/Admin/admin-page.php:298 ../src/Admin/admin-page.php:537
249
- #: ../src/Widget/form.php:47
250
- msgid "Day(s)"
251
- msgstr ""
252
-
253
- #: ../src/Admin/admin-page.php:303
254
- msgid "Select a date..."
255
- msgstr ""
256
-
257
- #: ../src/Admin/admin-page.php:323
258
- msgid "Today"
259
- msgstr ""
260
-
261
- #: ../src/Admin/admin-page.php:324 ../src/Widget/form.php:34
262
- msgid "Last 24 hours"
263
- msgstr ""
264
-
265
- #: ../src/Admin/admin-page.php:325 ../src/Widget/form.php:35
266
- msgid "Last 7 days"
267
- msgstr ""
268
-
269
- #: ../src/Admin/admin-page.php:326 ../src/Widget/form.php:36
270
- msgid "Last 30 days"
271
- msgstr ""
272
-
273
- #: ../src/Admin/admin-page.php:327 ../src/Widget/form.php:38
274
- msgid "Custom"
275
- msgstr ""
276
-
277
- #: ../src/Admin/admin-page.php:331
278
- #, php-format
279
- msgid ""
280
- "Err... A nice little chart is supposed to be here, instead you are seeing this because "
281
- "your browser is too old. <br /> Please <a href=\"%s\" target=\"_blank\">get a better "
282
- "browser</a>."
283
- msgstr ""
284
-
285
- #: ../src/Admin/admin-page.php:347
286
- msgid "Most viewed"
287
- msgstr ""
288
-
289
- #: ../src/Admin/admin-page.php:348
290
- msgid "Most commented"
291
- msgstr ""
292
-
293
- #: ../src/Admin/admin-page.php:350
294
- msgid "Hall of Fame"
295
- msgstr ""
296
-
297
- #: ../src/Admin/admin-page.php:390
298
- msgid "Thumbnails"
299
- msgstr ""
300
-
301
- #: ../src/Admin/admin-page.php:396
302
- msgid "Default thumbnail"
303
- msgstr ""
304
-
305
- #: ../src/Admin/admin-page.php:402
306
- msgid "Change thumbnail"
307
- msgstr ""
308
-
309
- #: ../src/Admin/admin-page.php:405
310
- msgid "This image will be displayed when no thumbnail is available"
311
- msgstr ""
312
-
313
- #: ../src/Admin/admin-page.php:409
314
- msgid "Pick image from"
315
- msgstr ""
316
-
317
- #: ../src/Admin/admin-page.php:412
318
- msgid "Featured image"
319
- msgstr ""
320
-
321
- #: ../src/Admin/admin-page.php:413
322
- msgid "First image on post"
323
- msgstr ""
324
-
325
- #: ../src/Admin/admin-page.php:414
326
- msgid "First attachment"
327
- msgstr ""
328
-
329
- #: ../src/Admin/admin-page.php:415
330
- msgid "Custom field"
331
- msgstr ""
332
-
333
- #: ../src/Admin/admin-page.php:418
334
- msgid "Tell WordPress Popular Posts where it should get thumbnails from"
335
- msgstr ""
336
-
337
- #: ../src/Admin/admin-page.php:422
338
- msgid "Lazy load"
339
- msgstr ""
340
-
341
- #: ../src/Admin/admin-page.php:422 ../src/Admin/admin-page.php:519
342
- #: ../src/Admin/admin-page.php:547 ../src/Widget/form.php:7 ../src/Widget/form.php:54
343
- #: ../src/Widget/form.php:60 ../src/Widget/form.php:88 ../src/Widget/form.php:98
344
- #: ../src/Widget/form.php:190
345
- msgid "What is this?"
346
- msgstr ""
347
-
348
- #: ../src/Admin/admin-page.php:425
349
- msgid "No"
350
- msgstr ""
351
-
352
- #: ../src/Admin/admin-page.php:426 ../src/Admin/admin-page.php:441
353
- msgid "Yes"
354
- msgstr ""
355
-
356
- #: ../src/Admin/admin-page.php:431
357
- msgid "Custom field name"
358
- msgstr ""
359
-
360
- #: ../src/Admin/admin-page.php:437
361
- msgid "Resize image from Custom field?"
362
- msgstr ""
363
-
364
- #: ../src/Admin/admin-page.php:440
365
- msgid "No, use image as is"
366
- msgstr ""
367
-
368
- #: ../src/Admin/admin-page.php:452
369
- msgid "Empty image cache"
370
- msgstr ""
371
-
372
- #: ../src/Admin/admin-page.php:453
373
- msgid "Use this button to clear WPP's thumbnails cache"
374
- msgstr ""
375
-
376
- #: ../src/Admin/admin-page.php:473
377
- msgid "Data"
378
- msgstr ""
379
-
380
- #: ../src/Admin/admin-page.php:479
381
- msgid "Log views from"
382
- msgstr ""
383
-
384
- #: ../src/Admin/admin-page.php:482
385
- msgid "Visitors only"
386
- msgstr ""
387
-
388
- #: ../src/Admin/admin-page.php:483
389
- msgid "Logged-in users only"
390
- msgstr ""
391
-
392
- #: ../src/Admin/admin-page.php:484
393
- msgid "Everyone"
394
- msgstr ""
395
-
396
- #: ../src/Admin/admin-page.php:490
397
- msgid "Log limit"
398
- msgstr ""
399
-
400
- #: ../src/Admin/admin-page.php:493 ../src/Admin/admin-page.php:510
401
- #: ../src/Admin/admin-page.php:550 ../src/Admin/admin-page.php:600
402
- msgid "Disabled"
403
- msgstr ""
404
-
405
- #: ../src/Admin/admin-page.php:494
406
- msgid "Keep data for"
407
- msgstr ""
408
-
409
- #: ../src/Admin/admin-page.php:498
410
- msgid "day(s)"
411
- msgstr ""
412
-
413
- #: ../src/Admin/admin-page.php:501
414
- msgid "Data older than the specified time frame will be automatically discarded"
415
- msgstr ""
416
-
417
- #: ../src/Admin/admin-page.php:507
418
- msgid "Ajaxify widget"
419
- msgstr ""
420
-
421
- #: ../src/Admin/admin-page.php:511 ../src/Admin/admin-page.php:551
422
- #: ../src/Admin/admin-page.php:599
423
- msgid "Enabled"
424
- msgstr ""
425
-
426
- #: ../src/Admin/admin-page.php:515
427
- msgid ""
428
- "If you are using a caching plugin such as WP Super Cache, enabling this feature will "
429
- "keep the popular list from being cached by it"
430
- msgstr ""
431
-
432
- #: ../src/Admin/admin-page.php:519
433
- msgid "Data Caching"
434
- msgstr ""
435
-
436
- #: ../src/Admin/admin-page.php:522
437
- msgid "Never cache"
438
- msgstr ""
439
-
440
- #: ../src/Admin/admin-page.php:523
441
- msgid "Enable caching"
442
- msgstr ""
443
-
444
- #: ../src/Admin/admin-page.php:527
445
- msgid ""
446
- "WPP can cache the popular list for a specified amount of time. Recommended for large / "
447
- "high traffic sites"
448
- msgstr ""
449
-
450
- #: ../src/Admin/admin-page.php:531
451
- msgid "Refresh cache every"
452
- msgstr ""
453
-
454
- #: ../src/Admin/admin-page.php:538
455
- msgid "Week(s)"
456
- msgstr ""
457
-
458
- #: ../src/Admin/admin-page.php:539
459
- msgid "Month(s)"
460
- msgstr ""
461
-
462
- #: ../src/Admin/admin-page.php:540
463
- msgid "Year(s)"
464
- msgstr ""
465
-
466
- #: ../src/Admin/admin-page.php:543
467
- msgid "Really? That long?"
468
- msgstr ""
469
-
470
- #: ../src/Admin/admin-page.php:547
471
- msgid "Data Sampling"
472
- msgstr ""
473
-
474
- #: ../src/Admin/admin-page.php:555
475
- #, php-format
476
- msgid ""
477
- "By default, WordPress Popular Posts stores in database every single visit your site "
478
- "receives. For small / medium sites this is generally OK, but on large / high traffic "
479
- "sites the constant writing to the database may have an impact on performance. With <a "
480
- "href=\"%1$s\" target=\"_blank\">data sampling</a>, WordPress Popular Posts will store "
481
- "only a subset of your traffic and report on the tendencies detected in that sample set "
482
- "(for more, <a href=\"%2$s\" target=\"_blank\">please read here</a>)"
483
- msgstr ""
484
-
485
- #: ../src/Admin/admin-page.php:559
486
- msgid "Sample Rate"
487
- msgstr ""
488
-
489
- #: ../src/Admin/admin-page.php:563
490
- #, php-format
491
- msgid ""
492
- "A sampling rate of %d is recommended for large / high traffic sites. For lower traffic "
493
- "sites, you should lower the value"
494
- msgstr ""
495
-
496
- #: ../src/Admin/admin-page.php:580
497
- msgid "Miscellaneous"
498
- msgstr ""
499
-
500
- #: ../src/Admin/admin-page.php:586
501
- msgid "Open links in"
502
- msgstr ""
503
-
504
- #: ../src/Admin/admin-page.php:589
505
- msgid "Current window"
506
- msgstr ""
507
-
508
- #: ../src/Admin/admin-page.php:590
509
- msgid "New tab/window"
510
- msgstr ""
511
-
512
- #: ../src/Admin/admin-page.php:596
513
- msgid "Use plugin's stylesheet"
514
- msgstr ""
515
-
516
- #: ../src/Admin/admin-page.php:603
517
- msgid ""
518
- "By default, the plugin includes a stylesheet called wpp.css which you can use to style "
519
- "your popular posts listing. If you wish to use your own stylesheet or do not want it "
520
- "to have it included in the header section of your site, use this."
521
- msgstr ""
522
-
523
- #: ../src/Admin/admin-page.php:623
524
- msgid ""
525
- "WordPress Popular Posts maintains data in two separate tables: one for storing the "
526
- "most popular entries on a daily basis (from now on, \"cache\"), and another one to "
527
- "keep the All-time data (from now on, \"historical data\" or just \"data\"). If for "
528
- "some reason you need to clear the cache table, or even both historical and cache "
529
- "tables, please use the buttons below to do so."
530
- msgstr ""
531
-
532
- #: ../src/Admin/admin-page.php:624
533
- msgid "Empty cache"
534
- msgstr ""
535
-
536
- #: ../src/Admin/admin-page.php:624
537
- msgid "Use this button to manually clear entries from WPP cache only"
538
- msgstr ""
539
-
540
- #: ../src/Admin/admin-page.php:625
541
- msgid "Clear all data"
542
- msgstr ""
543
-
544
- #: ../src/Admin/admin-page.php:625
545
- msgid "Use this button to manually clear entries from all WPP data tables"
546
- msgstr ""
547
-
548
- #: ../src/Admin/admin-page.php:633
549
- #, php-format
550
- msgid ""
551
- "With the following parameters you can customize the popular posts list when using "
552
- "either the <a href=\"%1$s\">wpp_get_mostpopular() template tag</a> or the <a href="
553
- "\"%2$s\">[wpp] shortcode</a>."
554
- msgstr ""
555
-
556
- #: ../src/Admin/admin-page.php:643
557
- msgid "Parameter"
558
- msgstr ""
559
-
560
- #: ../src/Admin/admin-page.php:644
561
- msgid "What it does "
562
- msgstr ""
563
-
564
- #: ../src/Admin/admin-page.php:645
565
- msgid "Possible values"
566
- msgstr ""
567
-
568
- #: ../src/Admin/admin-page.php:646
569
- msgid "Defaults to"
570
- msgstr ""
571
-
572
- #: ../src/Admin/admin-page.php:647
573
- msgid "Example"
574
- msgstr ""
575
-
576
- #: ../src/Admin/admin-page.php:653
577
- msgid "Sets a heading for the list"
578
- msgstr ""
579
-
580
- #: ../src/Admin/admin-page.php:654 ../src/Admin/admin-page.php:661
581
- #: ../src/Admin/admin-page.php:668 ../src/Admin/admin-page.php:717
582
- #: ../src/Admin/admin-page.php:724 ../src/Admin/admin-page.php:731
583
- #: ../src/Admin/admin-page.php:738 ../src/Admin/admin-page.php:745
584
- #: ../src/Admin/admin-page.php:752 ../src/Admin/admin-page.php:843
585
- #: ../src/Admin/admin-page.php:864 ../src/Admin/admin-page.php:871
586
- msgid "Text string"
587
- msgstr ""
588
-
589
- #: ../src/Admin/admin-page.php:655 ../src/Admin/admin-page.php:725
590
- #: ../src/Admin/admin-page.php:732 ../src/Admin/admin-page.php:739
591
- #: ../src/Admin/admin-page.php:746 ../src/Admin/admin-page.php:753
592
- #: ../src/Widget/form.php:226
593
- msgid "None"
594
- msgstr ""
595
-
596
- #: ../src/Admin/admin-page.php:656 ../src/Admin/admin-page.php:663
597
- #: ../src/Admin/admin-page.php:670 ../src/Admin/admin-page.php:677
598
- #: ../src/Admin/admin-page.php:684 ../src/Admin/admin-page.php:691
599
- #: ../src/Admin/admin-page.php:698 ../src/Admin/admin-page.php:705
600
- #: ../src/Admin/admin-page.php:712 ../src/Admin/admin-page.php:719
601
- #: ../src/Admin/admin-page.php:726 ../src/Admin/admin-page.php:733
602
- #: ../src/Admin/admin-page.php:740 ../src/Admin/admin-page.php:747
603
- #: ../src/Admin/admin-page.php:754 ../src/Admin/admin-page.php:761
604
- #: ../src/Admin/admin-page.php:768 ../src/Admin/admin-page.php:775
605
- #: ../src/Admin/admin-page.php:782 ../src/Admin/admin-page.php:789
606
- #: ../src/Admin/admin-page.php:796 ../src/Admin/admin-page.php:803
607
- #: ../src/Admin/admin-page.php:810 ../src/Admin/admin-page.php:817
608
- #: ../src/Admin/admin-page.php:824 ../src/Admin/admin-page.php:831
609
- #: ../src/Admin/admin-page.php:838 ../src/Admin/admin-page.php:845
610
- #: ../src/Admin/admin-page.php:852 ../src/Admin/admin-page.php:859
611
- #: ../src/Admin/admin-page.php:866 ../src/Admin/admin-page.php:873
612
- #: ../src/Admin/admin-page.php:880
613
- msgid "With wpp_get_mostpopular():"
614
- msgstr ""
615
-
616
- #: ../src/Admin/admin-page.php:656 ../src/Admin/admin-page.php:663
617
- #: ../src/Admin/admin-page.php:670 ../src/Admin/admin-page.php:677
618
- #: ../src/Admin/admin-page.php:684 ../src/Admin/admin-page.php:691
619
- #: ../src/Admin/admin-page.php:698 ../src/Admin/admin-page.php:705
620
- #: ../src/Admin/admin-page.php:712 ../src/Admin/admin-page.php:719
621
- #: ../src/Admin/admin-page.php:726 ../src/Admin/admin-page.php:733
622
- #: ../src/Admin/admin-page.php:740 ../src/Admin/admin-page.php:747
623
- #: ../src/Admin/admin-page.php:754 ../src/Admin/admin-page.php:761
624
- #: ../src/Admin/admin-page.php:768 ../src/Admin/admin-page.php:775
625
- #: ../src/Admin/admin-page.php:782 ../src/Admin/admin-page.php:789
626
- #: ../src/Admin/admin-page.php:796 ../src/Admin/admin-page.php:803
627
- #: ../src/Admin/admin-page.php:810 ../src/Admin/admin-page.php:817
628
- #: ../src/Admin/admin-page.php:824 ../src/Admin/admin-page.php:831
629
- #: ../src/Admin/admin-page.php:838 ../src/Admin/admin-page.php:845
630
- #: ../src/Admin/admin-page.php:852 ../src/Admin/admin-page.php:859
631
- #: ../src/Admin/admin-page.php:866 ../src/Admin/admin-page.php:873
632
- #: ../src/Admin/admin-page.php:880
633
- msgid "With the [wpp] shortcode:"
634
- msgstr ""
635
-
636
- #: ../src/Admin/admin-page.php:660
637
- msgid "Set the opening tag for the heading of the list"
638
- msgstr ""
639
-
640
- #: ../src/Admin/admin-page.php:667
641
- msgid "Set the closing tag for the heading of the list"
642
- msgstr ""
643
-
644
- #: ../src/Admin/admin-page.php:674
645
- msgid "Sets the maximum number of popular posts to be shown on the listing"
646
- msgstr ""
647
-
648
- #: ../src/Admin/admin-page.php:675 ../src/Admin/admin-page.php:689
649
- #: ../src/Admin/admin-page.php:759 ../src/Admin/admin-page.php:773
650
- #: ../src/Admin/admin-page.php:794 ../src/Admin/admin-page.php:801
651
- msgid "Positive integer"
652
- msgstr ""
653
-
654
- #: ../src/Admin/admin-page.php:681
655
- msgid ""
656
- "Tells WordPress Popular Posts to retrieve the most popular entries within the time "
657
- "range specified by you"
658
- msgstr ""
659
-
660
- #: ../src/Admin/admin-page.php:688
661
- msgid "Especifies the number of time units of the custom time range"
662
- msgstr ""
663
-
664
- #: ../src/Admin/admin-page.php:695
665
- msgid "Especifies the time unit of the custom time range"
666
- msgstr ""
667
-
668
- #: ../src/Admin/admin-page.php:702
669
- msgid ""
670
- "Tells WordPress Popular Posts to retrieve the most popular entries published within "
671
- "the time range specified by you"
672
- msgstr ""
673
-
674
- #: ../src/Admin/admin-page.php:709
675
- msgid "Sets the sorting option of the popular posts"
676
- msgstr ""
677
-
678
- #: ../src/Admin/admin-page.php:710
679
- msgid "(for average views per day)"
680
- msgstr ""
681
-
682
- #: ../src/Admin/admin-page.php:716
683
- msgid "Defines the type of posts to show on the listing"
684
- msgstr ""
685
-
686
- #: ../src/Admin/admin-page.php:723
687
- msgid ""
688
- "If set, WordPress Popular Posts will exclude the specified post(s) ID(s) form the "
689
- "listing."
690
- msgstr ""
691
-
692
- #: ../src/Admin/admin-page.php:730
693
- msgid ""
694
- "If set, WordPress Popular Posts will retrieve all entries that belong to the specified "
695
- "category ID(s). If a minus sign is used, entries associated to the category will be "
696
- "excluded instead."
697
- msgstr ""
698
-
699
- #: ../src/Admin/admin-page.php:737
700
- msgid "If set, WordPress Popular Posts will filter posts by a given taxonomy."
701
- msgstr ""
702
-
703
- #: ../src/Admin/admin-page.php:744
704
- msgid ""
705
- "If set, WordPress Popular Posts will retrieve all entries that belong to the specified "
706
- "term ID(s). If a minus sign is used, entries associated to the term(s) will be "
707
- "excluded instead."
708
- msgstr ""
709
-
710
- #: ../src/Admin/admin-page.php:751
711
- msgid ""
712
- "If set, WordPress Popular Posts will retrieve all entries created by specified "
713
- "author(s) ID(s)."
714
- msgstr ""
715
-
716
- #: ../src/Admin/admin-page.php:758
717
- msgid ""
718
- "If set, WordPress Popular Posts will shorten each post title to \"n\" characters "
719
- "whenever possible"
720
- msgstr ""
721
-
722
- #: ../src/Admin/admin-page.php:765
723
- msgid ""
724
- "If set to 1, WordPress Popular Posts will shorten each post title to \"n\" words "
725
- "instead of characters"
726
- msgstr ""
727
-
728
- #: ../src/Admin/admin-page.php:772
729
- msgid ""
730
- "If set, WordPress Popular Posts will build and include an excerpt of \"n\" characters "
731
- "long from the content of each post listed as popular"
732
- msgstr ""
733
-
734
- #: ../src/Admin/admin-page.php:779
735
- msgid ""
736
- "If set, WordPress Popular Posts will maintaing all styling tags (strong, italic, etc) "
737
- "and hyperlinks found in the excerpt"
738
- msgstr ""
739
-
740
- #: ../src/Admin/admin-page.php:786
741
- msgid ""
742
- "If set to 1, WordPress Popular Posts will shorten the excerpt to \"n\" words instead "
743
- "of characters"
744
- msgstr ""
745
-
746
- #: ../src/Admin/admin-page.php:793
747
- msgid ""
748
- "If set, and if your current server configuration allows it, you will be able to "
749
- "display thumbnails of your posts. This attribute sets the width for thumbnails"
750
- msgstr ""
751
-
752
- #: ../src/Admin/admin-page.php:800
753
- msgid ""
754
- "If set, and if your current server configuration allows it, you will be able to "
755
- "display thumbnails of your posts. This attribute sets the height for thumbnails"
756
- msgstr ""
757
-
758
- #: ../src/Admin/admin-page.php:807
759
- msgid ""
760
- "If set, and if the WP-PostRatings plugin is installed and enabled on your blog, "
761
- "WordPress Popular Posts will show how your visitors are rating your entries"
762
- msgstr ""
763
-
764
- #: ../src/Admin/admin-page.php:814
765
- msgid ""
766
- "If set, WordPress Popular Posts will show how many comments each popular post has got "
767
- "during the specified time range"
768
- msgstr ""
769
-
770
- #: ../src/Admin/admin-page.php:821
771
- msgid ""
772
- "If set, WordPress Popular Posts will show how many views each popular post has got "
773
- "during the specified time range"
774
- msgstr ""
775
-
776
- #: ../src/Admin/admin-page.php:828
777
- msgid ""
778
- "If set, WordPress Popular Posts will show who published each popular post on the list"
779
- msgstr ""
780
-
781
- #: ../src/Admin/admin-page.php:835
782
- msgid ""
783
- "If set, WordPress Popular Posts will display the date when each popular post on the "
784
- "list was published"
785
- msgstr ""
786
-
787
- #: ../src/Admin/admin-page.php:842
788
- msgid "Sets the date format"
789
- msgstr ""
790
-
791
- #: ../src/Admin/admin-page.php:849
792
- msgid ""
793
- "If set, WordPress Popular Posts will display the categories associated to each entry"
794
- msgstr ""
795
-
796
- #: ../src/Admin/admin-page.php:856
797
- msgid ""
798
- "If set, WordPress Popular Posts will display the taxonomies associated to each entry"
799
- msgstr ""
800
-
801
- #: ../src/Admin/admin-page.php:863
802
- msgid "Sets the opening tag for the listing"
803
- msgstr ""
804
-
805
- #: ../src/Admin/admin-page.php:870
806
- msgid "Sets the closing tag for the listing"
807
- msgstr ""
808
-
809
- #: ../src/Admin/admin-page.php:877
810
- msgid "Sets the HTML structure of each post"
811
- msgstr ""
812
-
813
- #: ../src/Admin/admin-page.php:878
814
- msgid "Text string, custom HTML"
815
- msgstr ""
816
-
817
- #: ../src/Admin/admin-page.php:878
818
- msgid "Available Content Tags"
819
- msgstr ""
820
-
821
- #: ../src/Admin/admin-page.php:878
822
- msgid ""
823
- "returns thumbnail linked to post/page, requires thumbnail_width & thumbnail_height"
824
- msgstr ""
825
-
826
- #: ../src/Admin/admin-page.php:878
827
- msgid ""
828
- "returns thumbnail image without linking to post/page, requires thumbnail_width & "
829
- "thumbnail_height"
830
- msgstr ""
831
-
832
- #: ../src/Admin/admin-page.php:878
833
- msgid "returns thumbnail url, requires thumbnail_width & thumbnail_height"
834
- msgstr ""
835
-
836
- #: ../src/Admin/admin-page.php:878
837
- msgid "returns linked post/page title"
838
- msgstr ""
839
-
840
- #: ../src/Admin/admin-page.php:878
841
- msgid "returns the post/page ID"
842
- msgstr ""
843
-
844
- #: ../src/Admin/admin-page.php:878
845
- msgid "returns post/page excerpt, and requires excerpt_length to be greater than 0"
846
- msgstr ""
847
-
848
- #: ../src/Admin/admin-page.php:878
849
- msgid "returns the default stats tags"
850
- msgstr ""
851
-
852
- #: ../src/Admin/admin-page.php:878
853
- msgid "returns post/page current rating, requires WP-PostRatings installed and enabled"
854
- msgstr ""
855
-
856
- #: ../src/Admin/admin-page.php:878
857
- msgid ""
858
- "returns post/page current rating as an integer, requires WP-PostRatings installed and "
859
- "enabled"
860
- msgstr ""
861
-
862
- #: ../src/Admin/admin-page.php:878
863
- msgid "returns the URL of the post/page"
864
- msgstr ""
865
-
866
- #: ../src/Admin/admin-page.php:878
867
- msgid "returns post/page title, no link"
868
- msgstr ""
869
-
870
- #: ../src/Admin/admin-page.php:878
871
- msgid "similar to text_title, sanitized for use in title/alt attributes"
872
- msgstr ""
873
-
874
- #: ../src/Admin/admin-page.php:878
875
- msgid "returns linked author name, requires stats_author=1"
876
- msgstr ""
877
-
878
- #: ../src/Admin/admin-page.php:878
879
- msgid "returns linked author name with copy, requires stats_author=1"
880
- msgstr ""
881
-
882
- #: ../src/Admin/admin-page.php:878
883
- msgid "returns linked category name, requires stats_category=1"
884
- msgstr ""
885
-
886
- #: ../src/Admin/admin-page.php:878
887
- msgid "returns linked category name with copy, requires stats_category=1"
888
- msgstr ""
889
-
890
- #: ../src/Admin/admin-page.php:878
891
- msgid "returns linked taxonomy names, requires stats_taxonomy=1"
892
- msgstr ""
893
-
894
- #: ../src/Admin/admin-page.php:878
895
- msgid "returns linked taxonomy names with copy, requires stats_taxonomy=1"
896
- msgstr ""
897
-
898
- #: ../src/Admin/admin-page.php:878
899
- msgid "returns views count only, no text, requires stats_views=1"
900
- msgstr ""
901
-
902
- #: ../src/Admin/admin-page.php:878
903
- msgid "returns views count with copy, requires stats_views=1"
904
- msgstr ""
905
-
906
- #: ../src/Admin/admin-page.php:878
907
- msgid "returns comments count only, no text, requires stats_comments=1"
908
- msgstr ""
909
-
910
- #: ../src/Admin/admin-page.php:878
911
- msgid "returns comments count with copy, requires stats_comments=1"
912
- msgstr ""
913
-
914
- #: ../src/Admin/admin-page.php:878
915
- msgid "returns post/page date, requires stats_date=1"
916
- msgstr ""
917
-
918
- #: ../src/Admin/admin-page.php:878
919
- msgid "returns post/page date with copy, requires stats_date=1"
920
- msgstr ""
921
-
922
- #: ../src/Admin/admin-page.php:878
923
- msgid "outputs number of popular posts found"
924
- msgstr ""
925
-
926
- #: ../src/Admin/admin-page.php:878
927
- msgid "outputs the position of the post in the listing"
928
- msgstr ""
929
-
930
- #: ../src/Output.php:248
931
- msgid "Sorry. No data so far."
932
- msgstr ""
933
-
934
- #: ../src/Output.php:588
935
- #, php-format
936
- msgid "%s ago"
937
- msgstr ""
938
-
939
- #: ../src/Output.php:751
940
- #, php-format
941
- msgid "%s view per day"
942
- msgid_plural "%s views per day"
943
- msgstr[0] ""
944
- msgstr[1] ""
945
-
946
- #: ../src/Output.php:769
947
- #, php-format
948
- msgid "by %s"
949
- msgstr ""
950
-
951
- #: ../src/Output.php:774
952
- #, php-format
953
- msgid "posted %s"
954
- msgstr ""
955
-
956
- #: ../src/Output.php:774
957
- #, php-format
958
- msgid "posted on %s"
959
- msgstr ""
960
-
961
- #: ../src/Output.php:779
962
- #, php-format
963
- msgid "under %s"
964
- msgstr ""
965
-
966
- #: ../src/Rest/Controller.php:308
967
- msgid "Invalid Widget Instance ID"
968
- msgstr ""
969
-
970
- #: ../src/Rest/Controller.php:406
971
- msgid "Return popular posts from specified custom post type(s)."
972
- msgstr ""
973
-
974
- #: ../src/Rest/Controller.php:413
975
- msgid "The maximum number of popular posts to return."
976
- msgstr ""
977
-
978
- #: ../src/Rest/Controller.php:421
979
- msgid "Retrieve the most popular entries published within the specified time range."
980
- msgstr ""
981
-
982
- #: ../src/Rest/Controller.php:429
983
- msgid "An offset point for the collection."
984
- msgstr ""
985
-
986
- #: ../src/Rest/Controller.php:437
987
- msgid "Set the sorting option of the popular posts."
988
- msgstr ""
989
-
990
- #: ../src/Rest/Controller.php:445
991
- msgid "Return popular posts from a specified time range."
992
- msgstr ""
993
-
994
- #: ../src/Rest/Controller.php:453
995
- msgid "Specifies the time unit of the custom time range."
996
- msgstr ""
997
-
998
- #: ../src/Rest/Controller.php:461
999
- msgid "Specifies the number of time units of the custom time range."
1000
- msgstr ""
1001
-
1002
- #: ../src/Rest/Controller.php:469
1003
- msgid "Post IDs to exclude from the listing."
1004
- msgstr ""
1005
-
1006
- #: ../src/Rest/Controller.php:477
1007
- msgid "Include posts in a specified taxonomy."
1008
- msgstr ""
1009
-
1010
- #: ../src/Rest/Controller.php:485
1011
- msgid "Taxonomy IDs, separated by comma (prefix a minus sign to exclude)."
1012
- msgstr ""
1013
-
1014
- #: ../src/Rest/Controller.php:493
1015
- msgid "Include popular posts from author ID(s)."
1016
- msgstr ""
1017
-
1018
- #: ../src/Rest/Controller.php:514
1019
- msgid "Security nonce."
1020
- msgstr ""
1021
-
1022
- #: ../src/Rest/Controller.php:520
1023
- msgid "The post / page ID."
1024
- msgstr ""
1025
-
1026
- #: ../src/Rest/Controller.php:527
1027
- msgid "Enables Data Sampling."
1028
- msgstr ""
1029
-
1030
- #: ../src/Rest/Controller.php:534
1031
- msgid "Sets the Sampling Rate."
1032
- msgstr ""
1033
-
1034
- #: ../src/Widget/Widget.php:77
1035
- msgid "The most Popular Posts on your blog."
1036
- msgstr ""
1037
-
1038
- #: ../src/Widget/form.php:7
1039
- msgid "Title"
1040
- msgstr ""
1041
-
1042
- #: ../src/Widget/form.php:13
1043
- msgid "Show up to"
1044
- msgstr ""
1045
-
1046
- #: ../src/Widget/form.php:14
1047
- msgid "posts"
1048
- msgstr ""
1049
-
1050
- #: ../src/Widget/form.php:19
1051
- msgid "Sort posts by"
1052
- msgstr ""
1053
-
1054
- #: ../src/Widget/form.php:22
1055
- msgid "Total views"
1056
- msgstr ""
1057
-
1058
- #: ../src/Widget/form.php:23
1059
- msgid "Avg. daily views"
1060
- msgstr ""
1061
-
1062
- #: ../src/Widget/form.php:30
1063
- msgid "Filters"
1064
- msgstr ""
1065
-
1066
- #: ../src/Widget/form.php:32
1067
- msgid "Time Range"
1068
- msgstr ""
1069
-
1070
- #: ../src/Widget/form.php:37
1071
- msgid "All-time"
1072
- msgstr ""
1073
-
1074
- #: ../src/Widget/form.php:54
1075
- msgid "Post type(s)"
1076
- msgstr ""
1077
-
1078
- #: ../src/Widget/form.php:57
1079
- msgid "Post ID(s) to exclude"
1080
- msgstr ""
1081
-
1082
- #: ../src/Widget/form.php:60
1083
- msgid "Taxonomy"
1084
- msgstr ""
1085
-
1086
- #: ../src/Widget/form.php:82
1087
- #, php-format
1088
- msgid "%s IDs, separated by comma (prefix a minus sign to exclude)"
1089
- msgstr ""
1090
-
1091
- #: ../src/Widget/form.php:88
1092
- msgid "Author ID(s)"
1093
- msgstr ""
1094
-
1095
- #: ../src/Widget/form.php:94
1096
- msgid "Posts settings"
1097
- msgstr ""
1098
-
1099
- #: ../src/Widget/form.php:98
1100
- msgid "Display post rating"
1101
- msgstr ""
1102
-
1103
- #: ../src/Widget/form.php:101
1104
- msgid "Shorten title"
1105
- msgstr ""
1106
-
1107
- #: ../src/Widget/form.php:104
1108
- msgid "Shorten title to"
1109
- msgstr ""
1110
-
1111
- #: ../src/Widget/form.php:105 ../src/Widget/form.php:115
1112
- msgid "characters"
1113
- msgstr ""
1114
-
1115
- #: ../src/Widget/form.php:106 ../src/Widget/form.php:116
1116
- msgid "words"
1117
- msgstr ""
1118
-
1119
- #: ../src/Widget/form.php:109
1120
- msgid "Display post excerpt"
1121
- msgstr ""
1122
-
1123
- #: ../src/Widget/form.php:112
1124
- msgid "Keep text format and links"
1125
- msgstr ""
1126
-
1127
- #: ../src/Widget/form.php:113
1128
- msgid "Excerpt length"
1129
- msgstr ""
1130
-
1131
- #: ../src/Widget/form.php:119
1132
- msgid "Display post thumbnail"
1133
- msgstr ""
1134
-
1135
- #: ../src/Widget/form.php:122
1136
- msgid "Use predefined size"
1137
- msgstr ""
1138
-
1139
- #: ../src/Widget/form.php:134
1140
- msgid "Set size manually"
1141
- msgstr ""
1142
-
1143
- #: ../src/Widget/form.php:136
1144
- msgid "Width"
1145
- msgstr ""
1146
-
1147
- #: ../src/Widget/form.php:139
1148
- msgid "Height"
1149
- msgstr ""
1150
-
1151
- #: ../src/Widget/form.php:146
1152
- msgid "Stats Tag settings"
1153
- msgstr ""
1154
-
1155
- #: ../src/Widget/form.php:148
1156
- msgid "Display comment count"
1157
- msgstr ""
1158
-
1159
- #: ../src/Widget/form.php:150
1160
- msgid "Display views"
1161
- msgstr ""
1162
-
1163
- #: ../src/Widget/form.php:152
1164
- msgid "Display author"
1165
- msgstr ""
1166
-
1167
- #: ../src/Widget/form.php:154
1168
- msgid "Display date"
1169
- msgstr ""
1170
-
1171
- #: ../src/Widget/form.php:157
1172
- msgid "Date Format"
1173
- msgstr ""
1174
-
1175
- #: ../src/Widget/form.php:159
1176
- msgid "Relative"
1177
- msgstr ""
1178
-
1179
- #: ../src/Widget/form.php:160
1180
- msgid "WordPress Date Format"
1181
- msgstr ""
1182
-
1183
- #: ../src/Widget/form.php:167
1184
- msgid "Display taxonomy"
1185
- msgstr ""
1186
-
1187
- #: ../src/Widget/form.php:188
1188
- msgid "HTML Markup settings"
1189
- msgstr ""
1190
-
1191
- #: ../src/Widget/form.php:190
1192
- msgid "Use custom HTML Markup"
1193
- msgstr ""
1194
-
1195
- #: ../src/Widget/form.php:205
1196
- msgid "Before / after title"
1197
- msgstr ""
1198
-
1199
- #: ../src/Widget/form.php:208
1200
- msgid "Before / after Popular Posts"
1201
- msgstr ""
1202
-
1203
- #: ../src/Widget/form.php:211
1204
- msgid "Post HTML Markup"
1205
- msgstr ""
1206
-
1207
- #: ../src/Widget/form.php:218
1208
- msgid "Theme"
1209
- msgstr ""
1210
-
1211
- #: ../src/Widget/form.php:218
1212
- #, php-format
1213
- msgid "see a <a href=\"%s\">list of supported browsers</a>"
1214
- msgstr ""
1215
-
1216
- #: ../src/Widget/form.php:234
1217
- msgid "Please save this widget (or reload this page) to enable WPP themes."
1218
- msgstr ""
1219
-
1220
- #: ../wordpress-popular-posts.php:52
1221
- #, php-format
1222
- msgid ""
1223
- "WordPress Popular Posts requires at least PHP %1$s and WordPress %2$s to function "
1224
- "correctly. Your site uses PHP %3$s and WordPress %4$s."
1225
- msgstr ""
1
+ # Copyright (C) 2014 Wordpress Popular Posts
2
+ # This file is distributed under the same license as the Wordpress Popular Posts package.
3
+ #, fuzzy
4
+ msgid ""
5
+ msgstr ""
6
+ "Project-Id-Version: WordPress Popular Posts\n"
7
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/wordpress-popular-posts\n"
8
+ "POT-Creation-Date: 2020-10-12 13:04-0400\n"
9
+ "PO-Revision-Date: 2015-04-24 13:30-0430\n"
10
+ "Last-Translator: Héctor Cabrera <hcabrerab@gmail.com>\n"
11
+ "Language-Team: Héctor Cabrera <me@cabrerahector.com>\n"
12
+ "Language: en\n"
13
+ "MIME-Version: 1.0\n"
14
+ "Content-Type: text/plain; charset=UTF-8\n"
15
+ "Content-Transfer-Encoding: 8bit\n"
16
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
+ "X-Generator: Poedit 2.4.1\n"
18
+ "X-Poedit-KeywordsList: _e;__;__ngettext;__ngettext_noop;_n_noop;_x;_nx;_nx_noop;_ex;"
19
+ "esc_attr__;esc_attr_e;esc_attr_x;esc_html__;esc_html_e;esc_html_x;_c;_nc;_n:1,2\n"
20
+ "X-Poedit-Basepath: .\n"
21
+ "X-Poedit-SourceCharset: UTF-8\n"
22
+ "X-Poedit-SearchPath-0: .\n"
23
+ "X-Poedit-SearchPath-1: ..\n"
24
+
25
+ #: ../src/Admin/Admin.php:371
26
+ #, php-format
27
+ msgid "%s view in the last hour"
28
+ msgid_plural "%s views in the last hour"
29
+ msgstr[0] ""
30
+ msgstr[1] ""
31
+
32
+ #: ../src/Admin/Admin.php:405 ../src/Admin/admin-page.php:349
33
+ msgid "Trending now"
34
+ msgstr ""
35
+
36
+ #: ../src/Admin/Admin.php:493
37
+ msgid "View more"
38
+ msgstr ""
39
+
40
+ #: ../src/Admin/Admin.php:522
41
+ msgid "Use this image"
42
+ msgstr ""
43
+
44
+ #: ../src/Admin/Admin.php:575
45
+ msgid "Overview"
46
+ msgstr ""
47
+
48
+ #: ../src/Admin/Admin.php:576
49
+ msgid ""
50
+ "Welcome to WordPress Popular Posts' Dashboard! In this screen you will find statistics "
51
+ "on what's popular on your site, tools to further tweak WPP to your needs, and more!"
52
+ msgstr ""
53
+
54
+ #: ../src/Admin/Admin.php:582
55
+ msgid "Like this plugin?"
56
+ msgstr ""
57
+
58
+ #: ../src/Admin/Admin.php:584
59
+ msgid ""
60
+ "Each donation motivates me to keep releasing free stuff for the WordPress community!"
61
+ msgstr ""
62
+
63
+ #: ../src/Admin/Admin.php:591
64
+ #, php-format
65
+ msgid "You can <a href=\"%s\" target=\"_blank\">leave a review</a>, too!"
66
+ msgstr ""
67
+
68
+ #: ../src/Admin/Admin.php:598
69
+ #, php-format
70
+ msgid ""
71
+ "<p><strong>For more information:</strong></p><ul><li><a href=\"%1$s\">Documentation</"
72
+ "a></li><li><a href=\"%2$s\">Support</a></li></ul>"
73
+ msgstr ""
74
+
75
+ #: ../src/Admin/Admin.php:622
76
+ msgid "Settings"
77
+ msgstr ""
78
+
79
+ #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1088 ../src/Admin/Admin.php:1092
80
+ #: ../src/Output.php:757
81
+ #, php-format
82
+ msgid "%s view"
83
+ msgid_plural "%s views"
84
+ msgstr[0] ""
85
+ msgstr[1] ""
86
+
87
+ #: ../src/Admin/Admin.php:699 ../src/Admin/Admin.php:1090 ../src/Admin/Admin.php:1092
88
+ #: ../src/Output.php:740
89
+ #, php-format
90
+ msgid "%s comment"
91
+ msgid_plural "%s comments"
92
+ msgstr[0] ""
93
+ msgstr[1] ""
94
+
95
+ #: ../src/Admin/Admin.php:720 ../src/Widget/form.php:21
96
+ msgid "Comments"
97
+ msgstr ""
98
+
99
+ #: ../src/Admin/Admin.php:724
100
+ msgid "Views"
101
+ msgstr ""
102
+
103
+ #: ../src/Admin/Admin.php:1094
104
+ msgid "View"
105
+ msgstr ""
106
+
107
+ #: ../src/Admin/Admin.php:1094
108
+ msgid "Edit"
109
+ msgstr ""
110
+
111
+ #: ../src/Admin/Admin.php:1105
112
+ msgid ""
113
+ "Looks like your site's activity is a little low right now. <br />Spread the word and "
114
+ "come back later!"
115
+ msgstr ""
116
+
117
+ #: ../src/Admin/Admin.php:1367
118
+ #, php-format
119
+ msgid ""
120
+ "<strong>WordPress Popular Posts:</strong> It seems your site is popular (great!) You "
121
+ "may want to check <a href=\"%s\">these suggestions</a> to make sure your website's "
122
+ "performance stays up to par."
123
+ msgstr ""
124
+
125
+ #: ../src/Admin/admin-page.php:6 ../src/Admin/admin-page.php:240
126
+ msgid "Stats"
127
+ msgstr ""
128
+
129
+ #: ../src/Admin/admin-page.php:7 ../src/Admin/admin-page.php:241
130
+ msgid "Tools"
131
+ msgstr ""
132
+
133
+ #: ../src/Admin/admin-page.php:8 ../src/Admin/admin-page.php:242
134
+ msgid "Parameters"
135
+ msgstr ""
136
+
137
+ #: ../src/Admin/admin-page.php:30 ../src/Admin/admin-page.php:41
138
+ #: ../src/Admin/admin-page.php:67 ../src/Admin/admin-page.php:103
139
+ msgid "Settings saved."
140
+ msgstr ""
141
+
142
+ #: ../src/Admin/admin-page.php:52
143
+ msgid "Please provide the name of your custom field."
144
+ msgstr ""
145
+
146
+ #: ../src/Admin/admin-page.php:121
147
+ msgid ""
148
+ "This operation will delete all entries from WordPress Popular Posts' cache table and "
149
+ "cannot be undone."
150
+ msgstr ""
151
+
152
+ #: ../src/Admin/admin-page.php:121 ../src/Admin/admin-page.php:160
153
+ #: ../src/Admin/admin-page.php:199
154
+ msgid "Do you want to continue?"
155
+ msgstr ""
156
+
157
+ #: ../src/Admin/admin-page.php:133
158
+ msgid "Success! The cache table has been cleared!"
159
+ msgstr ""
160
+
161
+ #: ../src/Admin/admin-page.php:137
162
+ msgid "Error: cache table does not exist."
163
+ msgstr ""
164
+
165
+ #: ../src/Admin/admin-page.php:141 ../src/Admin/admin-page.php:149
166
+ #: ../src/Admin/admin-page.php:180 ../src/Admin/admin-page.php:188
167
+ #: ../src/Admin/admin-page.php:218 ../src/Admin/admin-page.php:226
168
+ msgid "Invalid action."
169
+ msgstr ""
170
+
171
+ #: ../src/Admin/admin-page.php:145 ../src/Admin/admin-page.php:184
172
+ #: ../src/Admin/admin-page.php:222
173
+ msgid ""
174
+ "Sorry, you do not have enough permissions to do this. Please contact the site "
175
+ "administrator for support."
176
+ msgstr ""
177
+
178
+ #: ../src/Admin/admin-page.php:160
179
+ msgid ""
180
+ "This operation will delete all stored info from WordPress Popular Posts' data tables "
181
+ "and cannot be undone."
182
+ msgstr ""
183
+
184
+ #: ../src/Admin/admin-page.php:172
185
+ msgid "Success! All data have been cleared!"
186
+ msgstr ""
187
+
188
+ #: ../src/Admin/admin-page.php:176
189
+ msgid "Error: one or both data tables are missing."
190
+ msgstr ""
191
+
192
+ #: ../src/Admin/admin-page.php:199
193
+ msgid "This operation will delete all cached thumbnails and cannot be undone."
194
+ msgstr ""
195
+
196
+ #: ../src/Admin/admin-page.php:210
197
+ msgid "Success! All files have been deleted!"
198
+ msgstr ""
199
+
200
+ #: ../src/Admin/admin-page.php:214
201
+ msgid "The thumbnail cache is already empty!"
202
+ msgstr ""
203
+
204
+ #: ../src/Admin/admin-page.php:239
205
+ msgid "Menu"
206
+ msgstr ""
207
+
208
+ #: ../src/Admin/admin-page.php:266
209
+ msgid "Post type"
210
+ msgstr ""
211
+
212
+ #: ../src/Admin/admin-page.php:269
213
+ msgid "Limit"
214
+ msgstr ""
215
+
216
+ #: ../src/Admin/admin-page.php:272 ../src/Widget/form.php:52
217
+ msgid "Display only posts published within the selected Time Range"
218
+ msgstr ""
219
+
220
+ #: ../src/Admin/admin-page.php:278 ../src/Admin/admin-page.php:310
221
+ #: ../src/Admin/admin-page.php:462 ../src/Admin/admin-page.php:569
222
+ #: ../src/Admin/admin-page.php:609
223
+ msgid "Apply"
224
+ msgstr ""
225
+
226
+ #: ../src/Admin/admin-page.php:279 ../src/Admin/admin-page.php:313
227
+ msgid "Cancel"
228
+ msgstr ""
229
+
230
+ #: ../src/Admin/admin-page.php:288
231
+ msgid "Custom Time Range"
232
+ msgstr ""
233
+
234
+ #: ../src/Admin/admin-page.php:289
235
+ msgid "Date Range"
236
+ msgstr ""
237
+
238
+ #: ../src/Admin/admin-page.php:296 ../src/Admin/admin-page.php:535
239
+ #: ../src/Widget/form.php:45
240
+ msgid "Minute(s)"
241
+ msgstr ""
242
+
243
+ #: ../src/Admin/admin-page.php:297 ../src/Admin/admin-page.php:536
244
+ #: ../src/Widget/form.php:46
245
+ msgid "Hour(s)"
246
+ msgstr ""
247
+
248
+ #: ../src/Admin/admin-page.php:298 ../src/Admin/admin-page.php:537
249
+ #: ../src/Widget/form.php:47
250
+ msgid "Day(s)"
251
+ msgstr ""
252
+
253
+ #: ../src/Admin/admin-page.php:303
254
+ msgid "Select a date..."
255
+ msgstr ""
256
+
257
+ #: ../src/Admin/admin-page.php:323
258
+ msgid "Today"
259
+ msgstr ""
260
+
261
+ #: ../src/Admin/admin-page.php:324 ../src/Widget/form.php:34
262
+ msgid "Last 24 hours"
263
+ msgstr ""
264
+
265
+ #: ../src/Admin/admin-page.php:325 ../src/Widget/form.php:35
266
+ msgid "Last 7 days"
267
+ msgstr ""
268
+
269
+ #: ../src/Admin/admin-page.php:326 ../src/Widget/form.php:36
270
+ msgid "Last 30 days"
271
+ msgstr ""
272
+
273
+ #: ../src/Admin/admin-page.php:327 ../src/Widget/form.php:38
274
+ msgid "Custom"
275
+ msgstr ""
276
+
277
+ #: ../src/Admin/admin-page.php:331
278
+ #, php-format
279
+ msgid ""
280
+ "Err... A nice little chart is supposed to be here, instead you are seeing this because "
281
+ "your browser is too old. <br /> Please <a href=\"%s\" target=\"_blank\">get a better "
282
+ "browser</a>."
283
+ msgstr ""
284
+
285
+ #: ../src/Admin/admin-page.php:347
286
+ msgid "Most viewed"
287
+ msgstr ""
288
+
289
+ #: ../src/Admin/admin-page.php:348
290
+ msgid "Most commented"
291
+ msgstr ""
292
+
293
+ #: ../src/Admin/admin-page.php:350
294
+ msgid "Hall of Fame"
295
+ msgstr ""
296
+
297
+ #: ../src/Admin/admin-page.php:390
298
+ msgid "Thumbnails"
299
+ msgstr ""
300
+
301
+ #: ../src/Admin/admin-page.php:396
302
+ msgid "Default thumbnail"
303
+ msgstr ""
304
+
305
+ #: ../src/Admin/admin-page.php:402
306
+ msgid "Change thumbnail"
307
+ msgstr ""
308
+
309
+ #: ../src/Admin/admin-page.php:405
310
+ msgid "This image will be displayed when no thumbnail is available"
311
+ msgstr ""
312
+
313
+ #: ../src/Admin/admin-page.php:409
314
+ msgid "Pick image from"
315
+ msgstr ""
316
+
317
+ #: ../src/Admin/admin-page.php:412
318
+ msgid "Featured image"
319
+ msgstr ""
320
+
321
+ #: ../src/Admin/admin-page.php:413
322
+ msgid "First image on post"
323
+ msgstr ""
324
+
325
+ #: ../src/Admin/admin-page.php:414
326
+ msgid "First attachment"
327
+ msgstr ""
328
+
329
+ #: ../src/Admin/admin-page.php:415
330
+ msgid "Custom field"
331
+ msgstr ""
332
+
333
+ #: ../src/Admin/admin-page.php:418
334
+ msgid "Tell WordPress Popular Posts where it should get thumbnails from"
335
+ msgstr ""
336
+
337
+ #: ../src/Admin/admin-page.php:422
338
+ msgid "Lazy load"
339
+ msgstr ""
340
+
341
+ #: ../src/Admin/admin-page.php:422 ../src/Admin/admin-page.php:519
342
+ #: ../src/Admin/admin-page.php:547 ../src/Widget/form.php:7 ../src/Widget/form.php:54
343
+ #: ../src/Widget/form.php:60 ../src/Widget/form.php:88 ../src/Widget/form.php:98
344
+ #: ../src/Widget/form.php:190
345
+ msgid "What is this?"
346
+ msgstr ""
347
+
348
+ #: ../src/Admin/admin-page.php:425
349
+ msgid "No"
350
+ msgstr ""
351
+
352
+ #: ../src/Admin/admin-page.php:426 ../src/Admin/admin-page.php:441
353
+ msgid "Yes"
354
+ msgstr ""
355
+
356
+ #: ../src/Admin/admin-page.php:431
357
+ msgid "Custom field name"
358
+ msgstr ""
359
+
360
+ #: ../src/Admin/admin-page.php:437
361
+ msgid "Resize image from Custom field?"
362
+ msgstr ""
363
+
364
+ #: ../src/Admin/admin-page.php:440
365
+ msgid "No, use image as is"
366
+ msgstr ""
367
+
368
+ #: ../src/Admin/admin-page.php:452
369
+ msgid "Empty image cache"
370
+ msgstr ""
371
+
372
+ #: ../src/Admin/admin-page.php:453
373
+ msgid "Use this button to clear WPP's thumbnails cache"
374
+ msgstr ""
375
+
376
+ #: ../src/Admin/admin-page.php:473
377
+ msgid "Data"
378
+ msgstr ""
379
+
380
+ #: ../src/Admin/admin-page.php:479
381
+ msgid "Log views from"
382
+ msgstr ""
383
+
384
+ #: ../src/Admin/admin-page.php:482
385
+ msgid "Visitors only"
386
+ msgstr ""
387
+
388
+ #: ../src/Admin/admin-page.php:483
389
+ msgid "Logged-in users only"
390
+ msgstr ""
391
+
392
+ #: ../src/Admin/admin-page.php:484
393
+ msgid "Everyone"
394
+ msgstr ""
395
+
396
+ #: ../src/Admin/admin-page.php:490
397
+ msgid "Log limit"
398
+ msgstr ""
399
+
400
+ #: ../src/Admin/admin-page.php:493 ../src/Admin/admin-page.php:510
401
+ #: ../src/Admin/admin-page.php:550 ../src/Admin/admin-page.php:600
402
+ msgid "Disabled"
403
+ msgstr ""
404
+
405
+ #: ../src/Admin/admin-page.php:494
406
+ msgid "Keep data for"
407
+ msgstr ""
408
+
409
+ #: ../src/Admin/admin-page.php:498
410
+ msgid "day(s)"
411
+ msgstr ""
412
+
413
+ #: ../src/Admin/admin-page.php:501
414
+ msgid "Data older than the specified time frame will be automatically discarded"
415
+ msgstr ""
416
+
417
+ #: ../src/Admin/admin-page.php:507
418
+ msgid "Ajaxify widget"
419
+ msgstr ""
420
+
421
+ #: ../src/Admin/admin-page.php:511 ../src/Admin/admin-page.php:551
422
+ #: ../src/Admin/admin-page.php:599
423
+ msgid "Enabled"
424
+ msgstr ""
425
+
426
+ #: ../src/Admin/admin-page.php:515
427
+ msgid ""
428
+ "If you are using a caching plugin such as WP Super Cache, enabling this feature will "
429
+ "keep the popular list from being cached by it"
430
+ msgstr ""
431
+
432
+ #: ../src/Admin/admin-page.php:519
433
+ msgid "Data Caching"
434
+ msgstr ""
435
+
436
+ #: ../src/Admin/admin-page.php:522
437
+ msgid "Never cache"
438
+ msgstr ""
439
+
440
+ #: ../src/Admin/admin-page.php:523
441
+ msgid "Enable caching"
442
+ msgstr ""
443
+
444
+ #: ../src/Admin/admin-page.php:527
445
+ msgid ""
446
+ "WPP can cache the popular list for a specified amount of time. Recommended for large / "
447
+ "high traffic sites"
448
+ msgstr ""
449
+
450
+ #: ../src/Admin/admin-page.php:531
451
+ msgid "Refresh cache every"
452
+ msgstr ""
453
+
454
+ #: ../src/Admin/admin-page.php:538
455
+ msgid "Week(s)"
456
+ msgstr ""
457
+
458
+ #: ../src/Admin/admin-page.php:539
459
+ msgid "Month(s)"
460
+ msgstr ""
461
+
462
+ #: ../src/Admin/admin-page.php:540
463
+ msgid "Year(s)"
464
+ msgstr ""
465
+
466
+ #: ../src/Admin/admin-page.php:543
467
+ msgid "Really? That long?"
468
+ msgstr ""
469
+
470
+ #: ../src/Admin/admin-page.php:547
471
+ msgid "Data Sampling"
472
+ msgstr ""
473
+
474
+ #: ../src/Admin/admin-page.php:555
475
+ #, php-format
476
+ msgid ""
477
+ "By default, WordPress Popular Posts stores in database every single visit your site "
478
+ "receives. For small / medium sites this is generally OK, but on large / high traffic "
479
+ "sites the constant writing to the database may have an impact on performance. With <a "
480
+ "href=\"%1$s\" target=\"_blank\">data sampling</a>, WordPress Popular Posts will store "
481
+ "only a subset of your traffic and report on the tendencies detected in that sample set "
482
+ "(for more, <a href=\"%2$s\" target=\"_blank\">please read here</a>)"
483
+ msgstr ""
484
+
485
+ #: ../src/Admin/admin-page.php:559
486
+ msgid "Sample Rate"
487
+ msgstr ""
488
+
489
+ #: ../src/Admin/admin-page.php:563
490
+ #, php-format
491
+ msgid ""
492
+ "A sampling rate of %d is recommended for large / high traffic sites. For lower traffic "
493
+ "sites, you should lower the value"
494
+ msgstr ""
495
+
496
+ #: ../src/Admin/admin-page.php:580
497
+ msgid "Miscellaneous"
498
+ msgstr ""
499
+
500
+ #: ../src/Admin/admin-page.php:586
501
+ msgid "Open links in"
502
+ msgstr ""
503
+
504
+ #: ../src/Admin/admin-page.php:589
505
+ msgid "Current window"
506
+ msgstr ""
507
+
508
+ #: ../src/Admin/admin-page.php:590
509
+ msgid "New tab/window"
510
+ msgstr ""
511
+
512
+ #: ../src/Admin/admin-page.php:596
513
+ msgid "Use plugin's stylesheet"
514
+ msgstr ""
515
+
516
+ #: ../src/Admin/admin-page.php:603
517
+ msgid ""
518
+ "By default, the plugin includes a stylesheet called wpp.css which you can use to style "
519
+ "your popular posts listing. If you wish to use your own stylesheet or do not want it "
520
+ "to have it included in the header section of your site, use this."
521
+ msgstr ""
522
+
523
+ #: ../src/Admin/admin-page.php:623
524
+ msgid ""
525
+ "WordPress Popular Posts maintains data in two separate tables: one for storing the "
526
+ "most popular entries on a daily basis (from now on, \"cache\"), and another one to "
527
+ "keep the All-time data (from now on, \"historical data\" or just \"data\"). If for "
528
+ "some reason you need to clear the cache table, or even both historical and cache "
529
+ "tables, please use the buttons below to do so."
530
+ msgstr ""
531
+
532
+ #: ../src/Admin/admin-page.php:624
533
+ msgid "Empty cache"
534
+ msgstr ""
535
+
536
+ #: ../src/Admin/admin-page.php:624
537
+ msgid "Use this button to manually clear entries from WPP cache only"
538
+ msgstr ""
539
+
540
+ #: ../src/Admin/admin-page.php:625
541
+ msgid "Clear all data"
542
+ msgstr ""
543
+
544
+ #: ../src/Admin/admin-page.php:625
545
+ msgid "Use this button to manually clear entries from all WPP data tables"
546
+ msgstr ""
547
+
548
+ #: ../src/Admin/admin-page.php:633
549
+ #, php-format
550
+ msgid ""
551
+ "With the following parameters you can customize the popular posts list when using "
552
+ "either the <a href=\"%1$s\">wpp_get_mostpopular() template tag</a> or the <a href="
553
+ "\"%2$s\">[wpp] shortcode</a>."
554
+ msgstr ""
555
+
556
+ #: ../src/Admin/admin-page.php:643
557
+ msgid "Parameter"
558
+ msgstr ""
559
+
560
+ #: ../src/Admin/admin-page.php:644
561
+ msgid "What it does "
562
+ msgstr ""
563
+
564
+ #: ../src/Admin/admin-page.php:645
565
+ msgid "Possible values"
566
+ msgstr ""
567
+
568
+ #: ../src/Admin/admin-page.php:646
569
+ msgid "Defaults to"
570
+ msgstr ""
571
+
572
+ #: ../src/Admin/admin-page.php:647
573
+ msgid "Example"
574
+ msgstr ""
575
+
576
+ #: ../src/Admin/admin-page.php:653
577
+ msgid "Sets a heading for the list"
578
+ msgstr ""
579
+
580
+ #: ../src/Admin/admin-page.php:654 ../src/Admin/admin-page.php:661
581
+ #: ../src/Admin/admin-page.php:668 ../src/Admin/admin-page.php:717
582
+ #: ../src/Admin/admin-page.php:724 ../src/Admin/admin-page.php:731
583
+ #: ../src/Admin/admin-page.php:738 ../src/Admin/admin-page.php:745
584
+ #: ../src/Admin/admin-page.php:752 ../src/Admin/admin-page.php:843
585
+ #: ../src/Admin/admin-page.php:864 ../src/Admin/admin-page.php:871
586
+ msgid "Text string"
587
+ msgstr ""
588
+
589
+ #: ../src/Admin/admin-page.php:655 ../src/Admin/admin-page.php:725
590
+ #: ../src/Admin/admin-page.php:732 ../src/Admin/admin-page.php:739
591
+ #: ../src/Admin/admin-page.php:746 ../src/Admin/admin-page.php:753
592
+ #: ../src/Widget/form.php:226
593
+ msgid "None"
594
+ msgstr ""
595
+
596
+ #: ../src/Admin/admin-page.php:656 ../src/Admin/admin-page.php:663
597
+ #: ../src/Admin/admin-page.php:670 ../src/Admin/admin-page.php:677
598
+ #: ../src/Admin/admin-page.php:684 ../src/Admin/admin-page.php:691
599
+ #: ../src/Admin/admin-page.php:698 ../src/Admin/admin-page.php:705
600
+ #: ../src/Admin/admin-page.php:712 ../src/Admin/admin-page.php:719
601
+ #: ../src/Admin/admin-page.php:726 ../src/Admin/admin-page.php:733
602
+ #: ../src/Admin/admin-page.php:740 ../src/Admin/admin-page.php:747
603
+ #: ../src/Admin/admin-page.php:754 ../src/Admin/admin-page.php:761
604
+ #: ../src/Admin/admin-page.php:768 ../src/Admin/admin-page.php:775
605
+ #: ../src/Admin/admin-page.php:782 ../src/Admin/admin-page.php:789
606
+ #: ../src/Admin/admin-page.php:796 ../src/Admin/admin-page.php:803
607
+ #: ../src/Admin/admin-page.php:810 ../src/Admin/admin-page.php:817
608
+ #: ../src/Admin/admin-page.php:824 ../src/Admin/admin-page.php:831
609
+ #: ../src/Admin/admin-page.php:838 ../src/Admin/admin-page.php:845
610
+ #: ../src/Admin/admin-page.php:852 ../src/Admin/admin-page.php:859
611
+ #: ../src/Admin/admin-page.php:866 ../src/Admin/admin-page.php:873
612
+ #: ../src/Admin/admin-page.php:880
613
+ msgid "With wpp_get_mostpopular():"
614
+ msgstr ""
615
+
616
+ #: ../src/Admin/admin-page.php:656 ../src/Admin/admin-page.php:663
617
+ #: ../src/Admin/admin-page.php:670 ../src/Admin/admin-page.php:677
618
+ #: ../src/Admin/admin-page.php:684 ../src/Admin/admin-page.php:691
619
+ #: ../src/Admin/admin-page.php:698 ../src/Admin/admin-page.php:705
620
+ #: ../src/Admin/admin-page.php:712 ../src/Admin/admin-page.php:719
621
+ #: ../src/Admin/admin-page.php:726 ../src/Admin/admin-page.php:733
622
+ #: ../src/Admin/admin-page.php:740 ../src/Admin/admin-page.php:747
623
+ #: ../src/Admin/admin-page.php:754 ../src/Admin/admin-page.php:761
624
+ #: ../src/Admin/admin-page.php:768 ../src/Admin/admin-page.php:775
625
+ #: ../src/Admin/admin-page.php:782 ../src/Admin/admin-page.php:789
626
+ #: ../src/Admin/admin-page.php:796 ../src/Admin/admin-page.php:803
627
+ #: ../src/Admin/admin-page.php:810 ../src/Admin/admin-page.php:817
628
+ #: ../src/Admin/admin-page.php:824 ../src/Admin/admin-page.php:831
629
+ #: ../src/Admin/admin-page.php:838 ../src/Admin/admin-page.php:845
630
+ #: ../src/Admin/admin-page.php:852 ../src/Admin/admin-page.php:859
631
+ #: ../src/Admin/admin-page.php:866 ../src/Admin/admin-page.php:873
632
+ #: ../src/Admin/admin-page.php:880
633
+ msgid "With the [wpp] shortcode:"
634
+ msgstr ""
635
+
636
+ #: ../src/Admin/admin-page.php:660
637
+ msgid "Set the opening tag for the heading of the list"
638
+ msgstr ""
639
+
640
+ #: ../src/Admin/admin-page.php:667
641
+ msgid "Set the closing tag for the heading of the list"
642
+ msgstr ""
643
+
644
+ #: ../src/Admin/admin-page.php:674
645
+ msgid "Sets the maximum number of popular posts to be shown on the listing"
646
+ msgstr ""
647
+
648
+ #: ../src/Admin/admin-page.php:675 ../src/Admin/admin-page.php:689
649
+ #: ../src/Admin/admin-page.php:759 ../src/Admin/admin-page.php:773
650
+ #: ../src/Admin/admin-page.php:794 ../src/Admin/admin-page.php:801
651
+ msgid "Positive integer"
652
+ msgstr ""
653
+
654
+ #: ../src/Admin/admin-page.php:681
655
+ msgid ""
656
+ "Tells WordPress Popular Posts to retrieve the most popular entries within the time "
657
+ "range specified by you"
658
+ msgstr ""
659
+
660
+ #: ../src/Admin/admin-page.php:688
661
+ msgid "Especifies the number of time units of the custom time range"
662
+ msgstr ""
663
+
664
+ #: ../src/Admin/admin-page.php:695
665
+ msgid "Especifies the time unit of the custom time range"
666
+ msgstr ""
667
+
668
+ #: ../src/Admin/admin-page.php:702
669
+ msgid ""
670
+ "Tells WordPress Popular Posts to retrieve the most popular entries published within "
671
+ "the time range specified by you"
672
+ msgstr ""
673
+
674
+ #: ../src/Admin/admin-page.php:709
675
+ msgid "Sets the sorting option of the popular posts"
676
+ msgstr ""
677
+
678
+ #: ../src/Admin/admin-page.php:710
679
+ msgid "(for average views per day)"
680
+ msgstr ""
681
+
682
+ #: ../src/Admin/admin-page.php:716
683
+ msgid "Defines the type of posts to show on the listing"
684
+ msgstr ""
685
+
686
+ #: ../src/Admin/admin-page.php:723
687
+ msgid ""
688
+ "If set, WordPress Popular Posts will exclude the specified post(s) ID(s) form the "
689
+ "listing."
690
+ msgstr ""
691
+
692
+ #: ../src/Admin/admin-page.php:730
693
+ msgid ""
694
+ "If set, WordPress Popular Posts will retrieve all entries that belong to the specified "
695
+ "category ID(s). If a minus sign is used, entries associated to the category will be "
696
+ "excluded instead."
697
+ msgstr ""
698
+
699
+ #: ../src/Admin/admin-page.php:737
700
+ msgid "If set, WordPress Popular Posts will filter posts by a given taxonomy."
701
+ msgstr ""
702
+
703
+ #: ../src/Admin/admin-page.php:744
704
+ msgid ""
705
+ "If set, WordPress Popular Posts will retrieve all entries that belong to the specified "
706
+ "term ID(s). If a minus sign is used, entries associated to the term(s) will be "
707
+ "excluded instead."
708
+ msgstr ""
709
+
710
+ #: ../src/Admin/admin-page.php:751
711
+ msgid ""
712
+ "If set, WordPress Popular Posts will retrieve all entries created by specified "
713
+ "author(s) ID(s)."
714
+ msgstr ""
715
+
716
+ #: ../src/Admin/admin-page.php:758
717
+ msgid ""
718
+ "If set, WordPress Popular Posts will shorten each post title to \"n\" characters "
719
+ "whenever possible"
720
+ msgstr ""
721
+
722
+ #: ../src/Admin/admin-page.php:765
723
+ msgid ""
724
+ "If set to 1, WordPress Popular Posts will shorten each post title to \"n\" words "
725
+ "instead of characters"
726
+ msgstr ""
727
+
728
+ #: ../src/Admin/admin-page.php:772
729
+ msgid ""
730
+ "If set, WordPress Popular Posts will build and include an excerpt of \"n\" characters "
731
+ "long from the content of each post listed as popular"
732
+ msgstr ""
733
+
734
+ #: ../src/Admin/admin-page.php:779
735
+ msgid ""
736
+ "If set, WordPress Popular Posts will maintaing all styling tags (strong, italic, etc) "
737
+ "and hyperlinks found in the excerpt"
738
+ msgstr ""
739
+
740
+ #: ../src/Admin/admin-page.php:786
741
+ msgid ""
742
+ "If set to 1, WordPress Popular Posts will shorten the excerpt to \"n\" words instead "
743
+ "of characters"
744
+ msgstr ""
745
+
746
+ #: ../src/Admin/admin-page.php:793
747
+ msgid ""
748
+ "If set, and if your current server configuration allows it, you will be able to "
749
+ "display thumbnails of your posts. This attribute sets the width for thumbnails"
750
+ msgstr ""
751
+
752
+ #: ../src/Admin/admin-page.php:800
753
+ msgid ""
754
+ "If set, and if your current server configuration allows it, you will be able to "
755
+ "display thumbnails of your posts. This attribute sets the height for thumbnails"
756
+ msgstr ""
757
+
758
+ #: ../src/Admin/admin-page.php:807
759
+ msgid ""
760
+ "If set, and if the WP-PostRatings plugin is installed and enabled on your blog, "
761
+ "WordPress Popular Posts will show how your visitors are rating your entries"
762
+ msgstr ""
763
+
764
+ #: ../src/Admin/admin-page.php:814
765
+ msgid ""
766
+ "If set, WordPress Popular Posts will show how many comments each popular post has got "
767
+ "during the specified time range"
768
+ msgstr ""
769
+
770
+ #: ../src/Admin/admin-page.php:821
771
+ msgid ""
772
+ "If set, WordPress Popular Posts will show how many views each popular post has got "
773
+ "during the specified time range"
774
+ msgstr ""
775
+
776
+ #: ../src/Admin/admin-page.php:828
777
+ msgid ""
778
+ "If set, WordPress Popular Posts will show who published each popular post on the list"
779
+ msgstr ""
780
+
781
+ #: ../src/Admin/admin-page.php:835
782
+ msgid ""
783
+ "If set, WordPress Popular Posts will display the date when each popular post on the "
784
+ "list was published"
785
+ msgstr ""
786
+
787
+ #: ../src/Admin/admin-page.php:842
788
+ msgid "Sets the date format"
789
+ msgstr ""
790
+
791
+ #: ../src/Admin/admin-page.php:849
792
+ msgid ""
793
+ "If set, WordPress Popular Posts will display the categories associated to each entry"
794
+ msgstr ""
795
+
796
+ #: ../src/Admin/admin-page.php:856
797
+ msgid ""
798
+ "If set, WordPress Popular Posts will display the taxonomies associated to each entry"
799
+ msgstr ""
800
+
801
+ #: ../src/Admin/admin-page.php:863
802
+ msgid "Sets the opening tag for the listing"
803
+ msgstr ""
804
+
805
+ #: ../src/Admin/admin-page.php:870
806
+ msgid "Sets the closing tag for the listing"
807
+ msgstr ""
808
+
809
+ #: ../src/Admin/admin-page.php:877
810
+ msgid "Sets the HTML structure of each post"
811
+ msgstr ""
812
+
813
+ #: ../src/Admin/admin-page.php:878
814
+ msgid "Text string, custom HTML"
815
+ msgstr ""
816
+
817
+ #: ../src/Admin/admin-page.php:878
818
+ msgid "Available Content Tags"
819
+ msgstr ""
820
+
821
+ #: ../src/Admin/admin-page.php:878
822
+ msgid ""
823
+ "returns thumbnail linked to post/page, requires thumbnail_width & thumbnail_height"
824
+ msgstr ""
825
+
826
+ #: ../src/Admin/admin-page.php:878
827
+ msgid ""
828
+ "returns thumbnail image without linking to post/page, requires thumbnail_width & "
829
+ "thumbnail_height"
830
+ msgstr ""
831
+
832
+ #: ../src/Admin/admin-page.php:878
833
+ msgid "returns thumbnail url, requires thumbnail_width & thumbnail_height"
834
+ msgstr ""
835
+
836
+ #: ../src/Admin/admin-page.php:878
837
+ msgid "returns linked post/page title"
838
+ msgstr ""
839
+
840
+ #: ../src/Admin/admin-page.php:878
841
+ msgid "returns the post/page ID"
842
+ msgstr ""
843
+
844
+ #: ../src/Admin/admin-page.php:878
845
+ msgid "returns post/page excerpt, and requires excerpt_length to be greater than 0"
846
+ msgstr ""
847
+
848
+ #: ../src/Admin/admin-page.php:878
849
+ msgid "returns the default stats tags"
850
+ msgstr ""
851
+
852
+ #: ../src/Admin/admin-page.php:878
853
+ msgid "returns post/page current rating, requires WP-PostRatings installed and enabled"
854
+ msgstr ""
855
+
856
+ #: ../src/Admin/admin-page.php:878
857
+ msgid ""
858
+ "returns post/page current rating as an integer, requires WP-PostRatings installed and "
859
+ "enabled"
860
+ msgstr ""
861
+
862
+ #: ../src/Admin/admin-page.php:878
863
+ msgid "returns the URL of the post/page"
864
+ msgstr ""
865
+
866
+ #: ../src/Admin/admin-page.php:878
867
+ msgid "returns post/page title, no link"
868
+ msgstr ""
869
+
870
+ #: ../src/Admin/admin-page.php:878
871
+ msgid "similar to text_title, sanitized for use in title/alt attributes"
872
+ msgstr ""
873
+
874
+ #: ../src/Admin/admin-page.php:878
875
+ msgid "returns linked author name, requires stats_author=1"
876
+ msgstr ""
877
+
878
+ #: ../src/Admin/admin-page.php:878
879
+ msgid "returns linked author name with copy, requires stats_author=1"
880
+ msgstr ""
881
+
882
+ #: ../src/Admin/admin-page.php:878
883
+ msgid "returns linked category name, requires stats_category=1"
884
+ msgstr ""
885
+
886
+ #: ../src/Admin/admin-page.php:878
887
+ msgid "returns linked category name with copy, requires stats_category=1"
888
+ msgstr ""
889
+
890
+ #: ../src/Admin/admin-page.php:878
891
+ msgid "returns linked taxonomy names, requires stats_taxonomy=1"
892
+ msgstr ""
893
+
894
+ #: ../src/Admin/admin-page.php:878
895
+ msgid "returns linked taxonomy names with copy, requires stats_taxonomy=1"
896
+ msgstr ""
897
+
898
+ #: ../src/Admin/admin-page.php:878
899
+ msgid "returns views count only, no text, requires stats_views=1"
900
+ msgstr ""
901
+
902
+ #: ../src/Admin/admin-page.php:878
903
+ msgid "returns views count with copy, requires stats_views=1"
904
+ msgstr ""
905
+
906
+ #: ../src/Admin/admin-page.php:878
907
+ msgid "returns comments count only, no text, requires stats_comments=1"
908
+ msgstr ""
909
+
910
+ #: ../src/Admin/admin-page.php:878
911
+ msgid "returns comments count with copy, requires stats_comments=1"
912
+ msgstr ""
913
+
914
+ #: ../src/Admin/admin-page.php:878
915
+ msgid "returns post/page date, requires stats_date=1"
916
+ msgstr ""
917
+
918
+ #: ../src/Admin/admin-page.php:878
919
+ msgid "returns post/page date with copy, requires stats_date=1"
920
+ msgstr ""
921
+
922
+ #: ../src/Admin/admin-page.php:878
923
+ msgid "outputs number of popular posts found"
924
+ msgstr ""
925
+
926
+ #: ../src/Admin/admin-page.php:878
927
+ msgid "outputs the position of the post in the listing"
928
+ msgstr ""
929
+
930
+ #: ../src/Output.php:248
931
+ msgid "Sorry. No data so far."
932
+ msgstr ""
933
+
934
+ #: ../src/Output.php:588
935
+ #, php-format
936
+ msgid "%s ago"
937
+ msgstr ""
938
+
939
+ #: ../src/Output.php:751
940
+ #, php-format
941
+ msgid "%s view per day"
942
+ msgid_plural "%s views per day"
943
+ msgstr[0] ""
944
+ msgstr[1] ""
945
+
946
+ #: ../src/Output.php:769
947
+ #, php-format
948
+ msgid "by %s"
949
+ msgstr ""
950
+
951
+ #: ../src/Output.php:774
952
+ #, php-format
953
+ msgid "posted %s"
954
+ msgstr ""
955
+
956
+ #: ../src/Output.php:774
957
+ #, php-format
958
+ msgid "posted on %s"
959
+ msgstr ""
960
+
961
+ #: ../src/Output.php:779
962
+ #, php-format
963
+ msgid "under %s"
964
+ msgstr ""
965
+
966
+ #: ../src/Rest/Controller.php:308
967
+ msgid "Invalid Widget Instance ID"
968
+ msgstr ""
969
+
970
+ #: ../src/Rest/Controller.php:406
971
+ msgid "Return popular posts from specified custom post type(s)."
972
+ msgstr ""
973
+
974
+ #: ../src/Rest/Controller.php:413
975
+ msgid "The maximum number of popular posts to return."
976
+ msgstr ""
977
+
978
+ #: ../src/Rest/Controller.php:421
979
+ msgid "Retrieve the most popular entries published within the specified time range."
980
+ msgstr ""
981
+
982
+ #: ../src/Rest/Controller.php:429
983
+ msgid "An offset point for the collection."
984
+ msgstr ""
985
+
986
+ #: ../src/Rest/Controller.php:437
987
+ msgid "Set the sorting option of the popular posts."
988
+ msgstr ""
989
+
990
+ #: ../src/Rest/Controller.php:445
991
+ msgid "Return popular posts from a specified time range."
992
+ msgstr ""
993
+
994
+ #: ../src/Rest/Controller.php:453
995
+ msgid "Specifies the time unit of the custom time range."
996
+ msgstr ""
997
+
998
+ #: ../src/Rest/Controller.php:461
999
+ msgid "Specifies the number of time units of the custom time range."
1000
+ msgstr ""
1001
+
1002
+ #: ../src/Rest/Controller.php:469
1003
+ msgid "Post IDs to exclude from the listing."
1004
+ msgstr ""
1005
+
1006
+ #: ../src/Rest/Controller.php:477
1007
+ msgid "Include posts in a specified taxonomy."
1008
+ msgstr ""
1009
+
1010
+ #: ../src/Rest/Controller.php:485
1011
+ msgid "Taxonomy IDs, separated by comma (prefix a minus sign to exclude)."
1012
+ msgstr ""
1013
+
1014
+ #: ../src/Rest/Controller.php:493
1015
+ msgid "Include popular posts from author ID(s)."
1016
+ msgstr ""
1017
+
1018
+ #: ../src/Rest/Controller.php:514
1019
+ msgid "Security nonce."
1020
+ msgstr ""
1021
+
1022
+ #: ../src/Rest/Controller.php:520
1023
+ msgid "The post / page ID."
1024
+ msgstr ""
1025
+
1026
+ #: ../src/Rest/Controller.php:527
1027
+ msgid "Enables Data Sampling."
1028
+ msgstr ""
1029
+
1030
+ #: ../src/Rest/Controller.php:534
1031
+ msgid "Sets the Sampling Rate."
1032
+ msgstr ""
1033
+
1034
+ #: ../src/Widget/Widget.php:77
1035
+ msgid "The most Popular Posts on your blog."
1036
+ msgstr ""
1037
+
1038
+ #: ../src/Widget/form.php:7
1039
+ msgid "Title"
1040
+ msgstr ""
1041
+
1042
+ #: ../src/Widget/form.php:13
1043
+ msgid "Show up to"
1044
+ msgstr ""
1045
+
1046
+ #: ../src/Widget/form.php:14
1047
+ msgid "posts"
1048
+ msgstr ""
1049
+
1050
+ #: ../src/Widget/form.php:19
1051
+ msgid "Sort posts by"
1052
+ msgstr ""
1053
+
1054
+ #: ../src/Widget/form.php:22
1055
+ msgid "Total views"
1056
+ msgstr ""
1057
+
1058
+ #: ../src/Widget/form.php:23
1059
+ msgid "Avg. daily views"
1060
+ msgstr ""
1061
+
1062
+ #: ../src/Widget/form.php:30
1063
+ msgid "Filters"
1064
+ msgstr ""
1065
+
1066
+ #: ../src/Widget/form.php:32
1067
+ msgid "Time Range"
1068
+ msgstr ""
1069
+
1070
+ #: ../src/Widget/form.php:37
1071
+ msgid "All-time"
1072
+ msgstr ""
1073
+
1074
+ #: ../src/Widget/form.php:54
1075
+ msgid "Post type(s)"
1076
+ msgstr ""
1077
+
1078
+ #: ../src/Widget/form.php:57
1079
+ msgid "Post ID(s) to exclude"
1080
+ msgstr ""
1081
+
1082
+ #: ../src/Widget/form.php:60
1083
+ msgid "Taxonomy"
1084
+ msgstr ""
1085
+
1086
+ #: ../src/Widget/form.php:82
1087
+ #, php-format
1088
+ msgid "%s IDs, separated by comma (prefix a minus sign to exclude)"
1089
+ msgstr ""
1090
+
1091
+ #: ../src/Widget/form.php:88
1092
+ msgid "Author ID(s)"
1093
+ msgstr ""
1094
+
1095
+ #: ../src/Widget/form.php:94
1096
+ msgid "Posts settings"
1097
+ msgstr ""
1098
+
1099
+ #: ../src/Widget/form.php:98
1100
+ msgid "Display post rating"
1101
+ msgstr ""
1102
+
1103
+ #: ../src/Widget/form.php:101
1104
+ msgid "Shorten title"
1105
+ msgstr ""
1106
+
1107
+ #: ../src/Widget/form.php:104
1108
+ msgid "Shorten title to"
1109
+ msgstr ""
1110
+
1111
+ #: ../src/Widget/form.php:105 ../src/Widget/form.php:115
1112
+ msgid "characters"
1113
+ msgstr ""
1114
+
1115
+ #: ../src/Widget/form.php:106 ../src/Widget/form.php:116
1116
+ msgid "words"
1117
+ msgstr ""
1118
+
1119
+ #: ../src/Widget/form.php:109
1120
+ msgid "Display post excerpt"
1121
+ msgstr ""
1122
+
1123
+ #: ../src/Widget/form.php:112
1124
+ msgid "Keep text format and links"
1125
+ msgstr ""
1126
+
1127
+ #: ../src/Widget/form.php:113
1128
+ msgid "Excerpt length"
1129
+ msgstr ""
1130
+
1131
+ #: ../src/Widget/form.php:119
1132
+ msgid "Display post thumbnail"
1133
+ msgstr ""
1134
+
1135
+ #: ../src/Widget/form.php:122
1136
+ msgid "Use predefined size"
1137
+ msgstr ""
1138
+
1139
+ #: ../src/Widget/form.php:134
1140
+ msgid "Set size manually"
1141
+ msgstr ""
1142
+
1143
+ #: ../src/Widget/form.php:136
1144
+ msgid "Width"
1145
+ msgstr ""
1146
+
1147
+ #: ../src/Widget/form.php:139
1148
+ msgid "Height"
1149
+ msgstr ""
1150
+
1151
+ #: ../src/Widget/form.php:146
1152
+ msgid "Stats Tag settings"
1153
+ msgstr ""
1154
+
1155
+ #: ../src/Widget/form.php:148
1156
+ msgid "Display comment count"
1157
+ msgstr ""
1158
+
1159
+ #: ../src/Widget/form.php:150
1160
+ msgid "Display views"
1161
+ msgstr ""
1162
+
1163
+ #: ../src/Widget/form.php:152
1164
+ msgid "Display author"
1165
+ msgstr ""
1166
+
1167
+ #: ../src/Widget/form.php:154
1168
+ msgid "Display date"
1169
+ msgstr ""
1170
+
1171
+ #: ../src/Widget/form.php:157
1172
+ msgid "Date Format"
1173
+ msgstr ""
1174
+
1175
+ #: ../src/Widget/form.php:159
1176
+ msgid "Relative"
1177
+ msgstr ""
1178
+
1179
+ #: ../src/Widget/form.php:160
1180
+ msgid "WordPress Date Format"
1181
+ msgstr ""
1182
+
1183
+ #: ../src/Widget/form.php:167
1184
+ msgid "Display taxonomy"
1185
+ msgstr ""
1186
+
1187
+ #: ../src/Widget/form.php:188
1188
+ msgid "HTML Markup settings"
1189
+ msgstr ""
1190
+
1191
+ #: ../src/Widget/form.php:190
1192
+ msgid "Use custom HTML Markup"
1193
+ msgstr ""
1194
+
1195
+ #: ../src/Widget/form.php:205
1196
+ msgid "Before / after title"
1197
+ msgstr ""
1198
+
1199
+ #: ../src/Widget/form.php:208
1200
+ msgid "Before / after Popular Posts"
1201
+ msgstr ""
1202
+
1203
+ #: ../src/Widget/form.php:211
1204
+ msgid "Post HTML Markup"
1205
+ msgstr ""
1206
+
1207
+ #: ../src/Widget/form.php:218
1208
+ msgid "Theme"
1209
+ msgstr ""
1210
+
1211
+ #: ../src/Widget/form.php:218
1212
+ #, php-format
1213
+ msgid "see a <a href=\"%s\">list of supported browsers</a>"
1214
+ msgstr ""
1215
+
1216
+ #: ../src/Widget/form.php:234
1217
+ msgid "Please save this widget (or reload this page) to enable WPP themes."
1218
+ msgstr ""
1219
+
1220
+ #: ../wordpress-popular-posts.php:52
1221
+ #, php-format
1222
+ msgid ""
1223
+ "WordPress Popular Posts requires at least PHP %1$s and WordPress %2$s to function "
1224
+ "correctly. Your site uses PHP %3$s and WordPress %4$s."
1225
+ msgstr ""
index.php CHANGED
@@ -1,2 +1,2 @@
1
- <?php
2
- // Silence is golden
1
+ <?php
2
+ // Silence is golden
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: hcabrera
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=hcabrerab%40gmail%2ecom&lc=GB&item_name=WordPress%20Popular%20Posts%20Plugin&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG_global%2egif%3aNonHosted
4
  Tags: popular, posts, widget, popularity, top
5
  Requires at least: 4.9
6
- Tested up to: 5.7.1
7
  Requires PHP: 5.4
8
- Stable tag: 5.3.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -40,7 +40,7 @@ WordPress Popular Posts is a highly customizable widget that displays your most
40
 
41
  If you'd like to support my work and efforts to creating and maintaining more open source projects your donations and messages of support mean a lot!
42
 
43
- [Buy me a coffee](https://ko-fi.com/cabrerahector) | [PayPal Me](https://paypal.me/cabrerahector)
44
 
45
  **WordPress Popular Posts** is now also on [GitHub](https://github.com/cabrerahector/wordpress-popular-posts)!
46
 
@@ -97,6 +97,18 @@ The FAQ section has been moved [here](https://github.com/cabrerahector/wordpress
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  = 5.3.2 =
101
 
102
  - `wpp_get_views()`: fixed an issue where the function would return 0 views under certain conditions (thanks to everyone who helped with this!)
@@ -125,103 +137,12 @@ The FAQ section has been moved [here](https://github.com/cabrerahector/wordpress
125
 
126
  [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-3-improved-php-8-support-retina-display-support-and-more/)
127
 
128
- = 5.2.4 =
129
-
130
- - Fixes PHP notices affecting Block Editor users on WordPress 5.5.
131
- - Fixes a rare PHP warning message that pops up randomly when the Pageviews Cache is enabled.
132
-
133
- [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-2-is-here#hotfixes-and-minor-updates)
134
-
135
- = 5.2.3 =
136
-
137
- **If you're using a caching plugin, flushing its cache right after installing / upgrading to this version is required.**
138
-
139
- - Fixes a compatibility issue with WordPress 5.5.
140
- - Widget themes: various fixes for better IE11 compatibility.
141
-
142
- [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-2-is-here#hotfixes-and-minor-updates)
143
-
144
- = 5.2.2 =
145
-
146
- **If you're using a caching plugin, flushing its cache right after installing / upgrading to this version is required.**
147
-
148
- - Fixes compatibility issue with plugins that minify HTML code.
149
- - Updates installation instructions.
150
- - Other minor improvements.
151
-
152
- [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-2-is-here#hotfixes-and-minor-updates)
153
-
154
- = 5.2.1 =
155
-
156
- **If you're using a caching plugin, flushing its cache right after installing / upgrading to this version is required.**
157
-
158
- - Fixes fatal PHP error triggered on some server setups.
159
- - Makes sure non-ajaxified themed widgets are properly moved into the ShadowRoot.
160
- - Fixes declaration of the wpp_params variable.
161
-
162
- [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-2-is-here#hotfixes-and-minor-updates)
163
-
164
- = 5.2.0 =
165
-
166
- **If you're using a caching plugin, flushing its cache right after installing / upgrading to this version is required.**
167
-
168
- - JavaScript based Lazy Loading superseded by Native Lazing Loading.
169
- - Improved Pageviews Cache.
170
- - Views/comments count will be prettified now!
171
- - Fixed a few layout issues found in widget themes.
172
- - Improved compatibility with Content Security Policy (CSP).
173
- - Added support for ACF images.
174
- - Other minor improvements and fixes.
175
-
176
- [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-2-is-here)
177
-
178
- = 5.1.0 =
179
-
180
- - The /popular-posts GET API endpoint is now being cached as well.
181
- - Added a new Content Tag: title_attr.
182
- - Added a new [filter hook to filter popular posts terms](https://github.com/cabrerahector/wordpress-popular-posts/wiki/3.-Filters#wpp_post_terms).
183
- - Minor code improvements.
184
-
185
- = 5.0.2 =
186
-
187
- - A performance notice will be displayed for mid/high traffic sites (see [#239](https://github.com/cabrerahector/wordpress-popular-posts/issues/239)).
188
- - Fixed an issue with text_title content tag not being shortened (see [#241](https://github.com/cabrerahector/wordpress-popular-posts/issues/241)).
189
- - Added a link to the Debug screen to the plugin's dashboard for ease of access.
190
- - Other minor improvements/changes.
191
-
192
- = 5.0.1 =
193
-
194
- **If you're using a caching plugin, flushing its cache right after installing / upgrading to this version is recommended.**
195
-
196
- - Fixed a compatibility issue with the newly introduced [widget themes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-0-multiple-taxonomy-support-themes-thumbnail-lazy-loading-and-more/#themes) feature. If you're using a theme with your popular posts widget you'll need to reapply it for it to get the latest changes (go to Appearance > Widgets > WordPress Popular Posts, select a different theme then hit Save, finally switch back to your preferred theme and hit Save again.)
197
- - Fixed two date related issues.
198
- - Minor styling improvements to widget themes Cards, Cards Compact, Cardview and Cardview Compact.
199
- - Removes bold styling from post title on the stock design (wpp.css).
200
- - Improves data caching logic.
201
-
202
- = 5.0.0 =
203
-
204
- **If you're using a caching plugin, flushing its cache right after installing / upgrading to this version is required.**
205
-
206
- - Code has been refactored to use more modern PHP practices! This will help make WordPress Popular Posts more maintainable and easier to extend.
207
- - WordPress Popular Posts now requires PHP 5.4 or newer and WordPress 4.7 or newer.
208
- - The `WPP_Query` class has been deprecated. Use `WordPressPopularPosts\Query` instead.
209
- - Added ability to filter posts by multiple taxonomies (thanks [blackWhitePanda](https://github.com/blackWhitePanda)!)
210
- - New Dashboard Widget: Trending Now.
211
- - Added 10 new themes for the widget!
212
- - Added ability to lazy load thumbnails (enabled by default).
213
- - Improved support for WPML and Polylang.
214
- - Authors and Editors can now access the Stats dashboard too!
215
- - Fixed translation issues affecting russian and similar languages.
216
- - New Content Tags: total_items and item_position.
217
- - Many minor bug fixes/improvements.
218
-
219
- [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-0-multiple-taxonomy-support-themes-thumbnail-lazy-loading-and-more/) | [Full Changelog](https://github.com/cabrerahector/wordpress-popular-posts/compare/4.2.2...5.0.0).
220
 
221
  == Credits ==
222
 
223
  * Flame graphic by freevector/Vecteezy.com.
224
 
225
  == Upgrade Notice ==
226
- = 5.3.1 =
227
- If you're using a caching plugin, flushing its cache after upgrading to this version is recommended.
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=hcabrerab%40gmail%2ecom&lc=GB&item_name=WordPress%20Popular%20Posts%20Plugin&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG_global%2egif%3aNonHosted
4
  Tags: popular, posts, widget, popularity, top
5
  Requires at least: 4.9
6
+ Tested up to: 5.7.2
7
  Requires PHP: 5.4
8
+ Stable tag: 5.3.3
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
40
 
41
  If you'd like to support my work and efforts to creating and maintaining more open source projects your donations and messages of support mean a lot!
42
 
43
+ [Ko-fi](https://ko-fi.com/cabrerahector) | [Buy me a coffee](https://www.buymeacoffee.com/cabrerahector) | [PayPal Me](https://paypal.me/cabrerahector)
44
 
45
  **WordPress Popular Posts** is now also on [GitHub](https://github.com/cabrerahector/wordpress-popular-posts)!
46
 
97
 
98
  == Changelog ==
99
 
100
+ = 5.3.3 =
101
+
102
+ - Fixes a potential XSS vulnerability (props to Yu Iwama of Secure Sky Technology Inc. and the JPCERT/CC Vulnerability Coordination Group).
103
+ - Fixes a potential code injection vulnerability (props to Jerome & NinTechNet).
104
+ - Fixes a srcset bug that affects specific PHP locales (props to @fredel).
105
+ - Fixes a srcset not loading images due to improper SSL/HTTPS configuration (props to @aj4h).
106
+ - Updates ChartJS to version 2.9.4.
107
+
108
+ If you're using a caching plugin flushing its cache after upgrading to this version is highly recommended.
109
+
110
+ [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-3-improved-php-8-support-retina-display-support-and-more/#minor-updates-and-hotfixes)
111
+
112
  = 5.3.2 =
113
 
114
  - `wpp_get_views()`: fixed an issue where the function would return 0 views under certain conditions (thanks to everyone who helped with this!)
137
 
138
  [Release notes](https://cabrerahector.com/wordpress/wordpress-popular-posts-5-3-improved-php-8-support-retina-display-support-and-more/)
139
 
140
+ [Full Changelog](https://github.com/cabrerahector/wordpress-popular-posts/blob/master/changelog.md)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
  == Credits ==
143
 
144
  * Flame graphic by freevector/Vecteezy.com.
145
 
146
  == Upgrade Notice ==
147
+ = 5.3.3 =
148
+ If you're using a caching plugin flushing its cache after upgrading to this version is highly recommended.
src/Activation/Activator.php CHANGED
@@ -1,129 +1,129 @@
1
- <?php
2
-
3
- /**
4
- * Fired during plugin activation
5
- *
6
- * @since 1.0.0
7
- * @package WordPressPopularPosts
8
- */
9
-
10
- /**
11
- * Fired during plugin activation.
12
- *
13
- * This class defines all code necessary to run during the plugin's activation.
14
- *
15
- * @since 1.0.0
16
- * @package WordPressPopularPosts
17
- * @author Hector Cabrera <me@cabrerahector.com>
18
- */
19
-
20
- namespace WordPressPopularPosts\Activation;
21
-
22
- class Activator {
23
- /**
24
- * Fired when the plugin is activated.
25
- *
26
- * @since 1.0.0
27
- * @param bool $network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is disabled or plugin is activated on an individual blog.
28
- * @global object $wpdb
29
- */
30
- public static function activate($network_wide)
31
- {
32
- global $wpdb;
33
-
34
- if ( function_exists('is_multisite') && \is_multisite() ) {
35
- // run activation for each blog in the network
36
- if ( $network_wide ) {
37
- $original_blog_id = \get_current_blog_id();
38
- $blogs_ids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->blogs}");
39
-
40
- foreach( $blogs_ids as $blog_id ) {
41
- \switch_to_blog($blog_id);
42
- self::plugin_activate();
43
- }
44
-
45
- // switch back to current blog
46
- \switch_to_blog($original_blog_id);
47
-
48
- return;
49
- }
50
- }
51
-
52
- self::plugin_activate();
53
- }
54
-
55
- /**
56
- * When a new MU site is added, generate its WPP DB tables.
57
- *
58
- * @since 1.0.0
59
- */
60
- public static function track_new_site()
61
- {
62
- self::plugin_activate();
63
- }
64
-
65
- /**
66
- * On plugin activation, checks that the WPP database tables are present.
67
- *
68
- * @since 1.0.0
69
- * @global object $wpdb
70
- */
71
- private static function plugin_activate()
72
- {
73
- $wpp_ver = \get_option('wpp_ver');
74
-
75
- if (
76
- ! $wpp_ver
77
- || version_compare($wpp_ver, WPP_VERSION, '<')
78
- ) {
79
- global $wpdb;
80
-
81
- $prefix = $wpdb->prefix . "popularposts";
82
- self::do_db_tables($prefix);
83
- }
84
- }
85
-
86
- /**
87
- * Creates/updates the database tables.
88
- *
89
- * @since 1.0.0
90
- * @param string $prefix
91
- * @global object $wpdb
92
- */
93
- private static function do_db_tables($prefix)
94
- {
95
- global $wpdb;
96
- $charset_collate = "";
97
-
98
- if ( !empty($wpdb->charset) )
99
- $charset_collate = "DEFAULT CHARACTER SET {$wpdb->charset} ";
100
-
101
- if ( !empty($wpdb->collate) )
102
- $charset_collate .= "COLLATE {$wpdb->collate}";
103
-
104
- $sql = "
105
- CREATE TABLE {$prefix}data (
106
- postid bigint(20) NOT NULL,
107
- day datetime NOT NULL,
108
- last_viewed datetime NOT NULL,
109
- pageviews bigint(20) DEFAULT 1,
110
- PRIMARY KEY (postid)
111
- ) {$charset_collate} ENGINE=InnoDB;
112
- CREATE TABLE {$prefix}summary (
113
- ID bigint(20) NOT NULL AUTO_INCREMENT,
114
- postid bigint(20) NOT NULL,
115
- pageviews bigint(20) NOT NULL DEFAULT 1,
116
- view_date date NOT NULL,
117
- view_datetime datetime NOT NULL,
118
- PRIMARY KEY (ID),
119
- KEY postid (postid),
120
- KEY view_date (view_date),
121
- KEY view_datetime (view_datetime)
122
- ) {$charset_collate} ENGINE=InnoDB;";
123
-
124
- require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
125
- \dbDelta($sql);
126
-
127
- \update_option('wpp_ver', WPP_VERSION);
128
- }
129
- }
1
+ <?php
2
+
3
+ /**
4
+ * Fired during plugin activation
5
+ *
6
+ * @since 1.0.0
7
+ * @package WordPressPopularPosts
8
+ */
9
+
10
+ /**
11
+ * Fired during plugin activation.
12
+ *
13
+ * This class defines all code necessary to run during the plugin's activation.
14
+ *
15
+ * @since 1.0.0
16
+ * @package WordPressPopularPosts
17
+ * @author Hector Cabrera <me@cabrerahector.com>
18
+ */
19
+
20
+ namespace WordPressPopularPosts\Activation;
21
+
22
+ class Activator {
23
+ /**
24
+ * Fired when the plugin is activated.
25
+ *
26
+ * @since 1.0.0
27
+ * @param bool $network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is disabled or plugin is activated on an individual blog.
28
+ * @global object $wpdb
29
+ */
30
+ public static function activate($network_wide)
31
+ {
32
+ global $wpdb;
33
+
34
+ if ( function_exists('is_multisite') && \is_multisite() ) {
35
+ // run activation for each blog in the network
36
+ if ( $network_wide ) {
37
+ $original_blog_id = \get_current_blog_id();
38
+ $blogs_ids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->blogs}");
39
+
40
+ foreach( $blogs_ids as $blog_id ) {
41
+ \switch_to_blog($blog_id);
42
+ self::plugin_activate();
43
+ }
44
+
45
+ // switch back to current blog
46
+ \switch_to_blog($original_blog_id);
47
+
48
+ return;
49
+ }
50
+ }
51
+
52
+ self::plugin_activate();
53
+ }
54
+
55
+ /**
56
+ * When a new MU site is added, generate its WPP DB tables.
57
+ *
58
+ * @since 1.0.0
59
+ */
60
+ public static function track_new_site()
61
+ {
62
+ self::plugin_activate();
63
+ }
64
+
65
+ /**
66
+ * On plugin activation, checks that the WPP database tables are present.
67
+ *
68
+ * @since 1.0.0
69
+ * @global object $wpdb
70
+ */
71
+ private static function plugin_activate()
72
+ {
73
+ $wpp_ver = \get_option('wpp_ver');
74
+
75
+ if (
76
+ ! $wpp_ver
77
+ || version_compare($wpp_ver, WPP_VERSION, '<')
78
+ ) {
79
+ global $wpdb;
80
+
81
+ $prefix = $wpdb->prefix . "popularposts";
82
+ self::do_db_tables($prefix);
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Creates/updates the database tables.
88
+ *
89
+ * @since 1.0.0
90
+ * @param string $prefix
91
+ * @global object $wpdb
92
+ */
93
+ private static function do_db_tables($prefix)
94
+ {
95
+ global $wpdb;
96
+ $charset_collate = "";
97
+
98
+ if ( !empty($wpdb->charset) )
99
+ $charset_collate = "DEFAULT CHARACTER SET {$wpdb->charset} ";
100
+
101
+ if ( !empty($wpdb->collate) )
102
+ $charset_collate .= "COLLATE {$wpdb->collate}";
103
+
104
+ $sql = "
105
+ CREATE TABLE {$prefix}data (
106
+ postid bigint(20) NOT NULL,
107
+ day datetime NOT NULL,
108
+ last_viewed datetime NOT NULL,
109
+ pageviews bigint(20) DEFAULT 1,
110
+ PRIMARY KEY (postid)
111
+ ) {$charset_collate} ENGINE=InnoDB;
112
+ CREATE TABLE {$prefix}summary (
113
+ ID bigint(20) NOT NULL AUTO_INCREMENT,
114
+ postid bigint(20) NOT NULL,
115
+ pageviews bigint(20) NOT NULL DEFAULT 1,
116
+ view_date date NOT NULL,
117
+ view_datetime datetime NOT NULL,
118
+ PRIMARY KEY (ID),
119
+ KEY postid (postid),
120
+ KEY view_date (view_date),
121
+ KEY view_datetime (view_datetime)
122
+ ) {$charset_collate} ENGINE=InnoDB;";
123
+
124
+ require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
125
+ \dbDelta($sql);
126
+
127
+ \update_option('wpp_ver', WPP_VERSION);
128
+ }
129
+ }
src/Activation/Deactivator.php CHANGED
@@ -1,66 +1,66 @@
1
- <?php
2
- /**
3
- * Fired during plugin deactivation
4
- *
5
- * @link https://cabrerahector.com
6
- * @since 4.0.0
7
- *
8
- * @package WordPressPopularPosts
9
- */
10
-
11
- /**
12
- * Fired during plugin deactivation.
13
- *
14
- * This class defines all code necessary to run during the plugin's deactivation.
15
- *
16
- * @since 4.0.0
17
- * @package WordPressPopularPosts
18
- * @author Hector Cabrera <me@cabrerahector.com>
19
- */
20
- namespace WordPressPopularPosts\Activation;
21
-
22
- class Deactivator {
23
- /**
24
- * Fired when the plugin is deactivated.
25
- *
26
- * @since 1.0.0
27
- * @global object wpbd
28
- * @param bool network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is disabled or plugin is activated on an individual blog
29
- */
30
- public static function deactivate($network_wide)
31
- {
32
- global $wpdb;
33
-
34
- if ( function_exists('is_multisite') && is_multisite() ) {
35
- // Run deactivation for each blog in the network
36
- if ( $network_wide ) {
37
- $original_blog_id = get_current_blog_id();
38
- $blogs_ids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->blogs}");
39
-
40
- foreach( $blogs_ids as $blog_id ) {
41
- switch_to_blog($blog_id);
42
- self::plugin_deactivate();
43
- }
44
-
45
- // Switch back to current blog
46
- switch_to_blog($original_blog_id);
47
-
48
- return;
49
- }
50
- }
51
-
52
- self::plugin_deactivate();
53
- }
54
-
55
- /**
56
- * On plugin deactivation, disables the shortcode and removes the scheduled task.
57
- *
58
- * @since 2.4.0
59
- */
60
- private static function plugin_deactivate()
61
- {
62
- remove_shortcode('wpp');
63
- wp_clear_scheduled_hook('wpp_cache_event');
64
- wp_clear_scheduled_hook('wpp_maybe_performance_nag');
65
- }
66
- }
1
+ <?php
2
+ /**
3
+ * Fired during plugin deactivation
4
+ *
5
+ * @link https://cabrerahector.com
6
+ * @since 4.0.0
7
+ *
8
+ * @package WordPressPopularPosts
9
+ */
10
+
11
+ /**
12
+ * Fired during plugin deactivation.
13
+ *
14
+ * This class defines all code necessary to run during the plugin's deactivation.
15
+ *
16
+ * @since 4.0.0
17
+ * @package WordPressPopularPosts
18
+ * @author Hector Cabrera <me@cabrerahector.com>
19
+ */
20
+ namespace WordPressPopularPosts\Activation;
21
+
22
+ class Deactivator {
23
+ /**
24
+ * Fired when the plugin is deactivated.
25
+ *
26
+ * @since 1.0.0
27
+ * @global object wpbd
28
+ * @param bool network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is disabled or plugin is activated on an individual blog
29
+ */
30
+ public static function deactivate($network_wide)
31
+ {
32
+ global $wpdb;
33
+
34
+ if ( function_exists('is_multisite') && is_multisite() ) {
35
+ // Run deactivation for each blog in the network
36
+ if ( $network_wide ) {
37
+ $original_blog_id = get_current_blog_id();
38
+ $blogs_ids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->blogs}");
39
+
40
+ foreach( $blogs_ids as $blog_id ) {
41
+ switch_to_blog($blog_id);
42
+ self::plugin_deactivate();
43
+ }
44
+
45
+ // Switch back to current blog
46
+ switch_to_blog($original_blog_id);
47
+
48
+ return;
49
+ }
50
+ }
51
+
52
+ self::plugin_deactivate();
53
+ }
54
+
55
+ /**
56
+ * On plugin deactivation, disables the shortcode and removes the scheduled task.
57
+ *
58
+ * @since 2.4.0
59
+ */
60
+ private static function plugin_deactivate()
61
+ {
62
+ remove_shortcode('wpp');
63
+ wp_clear_scheduled_hook('wpp_cache_event');
64
+ wp_clear_scheduled_hook('wpp_maybe_performance_nag');
65
+ }
66
+ }
src/Admin/Admin.php CHANGED
@@ -1,1383 +1,1383 @@
1
- <?php
2
- /**
3
- * The admin-facing functionality of the plugin.
4
- *
5
- * Defines hooks to enqueue the admin-specific stylesheet and JavaScript,
6
- * plugin settings and other admin stuff.
7
- *
8
- * @package WordPressPopularPosts
9
- * @subpackage WordPressPopularPosts/Admin
10
- * @author Hector Cabrera <me@cabrerahector.com>
11
- */
12
-
13
- namespace WordPressPopularPosts\Admin;
14
-
15
- use WordPressPopularPosts\Helper;
16
- use WordPressPopularPosts\Output;
17
- use WordPressPopularPosts\Query;
18
-
19
- class Admin {
20
-
21
- /**
22
- * Slug of the plugin screen.
23
- *
24
- * @since 3.0.0
25
- * @var string
26
- */
27
- protected $screen_hook_suffix = NULL;
28
-
29
- /**
30
- * Plugin options.
31
- *
32
- * @var array $config
33
- * @access private
34
- */
35
- private $config;
36
-
37
- /**
38
- * Image object
39
- *
40
- * @since 4.0.2
41
- * @var WordPressPopularPosts\Image
42
- */
43
- private $thumbnail;
44
-
45
- /**
46
- * Construct.
47
- *
48
- * @since 5.0.0
49
- * @param array $config Admin settings.
50
- * @param \WordPressPopularPosts\Image $thumbnail Image class.
51
- */
52
- public function __construct(array $config, \WordPressPopularPosts\Image $thumbnail)
53
- {
54
- $this->config = $config;
55
- $this->thumbnail = $thumbnail;
56
-
57
- // Delete old data on demand
58
- if ( 1 == $this->config['tools']['log']['limit'] ) {
59
- if ( ! wp_next_scheduled('wpp_cache_event') ) {
60
- $midnight = strtotime('midnight') - ( get_option('gmt_offset') * HOUR_IN_SECONDS ) + DAY_IN_SECONDS;
61
- wp_schedule_event($midnight, 'daily', 'wpp_cache_event');
62
- }
63
- } else {
64
- // Remove the scheduled event if exists
65
- if ( $timestamp = wp_next_scheduled('wpp_cache_event') ) {
66
- wp_unschedule_event($timestamp, 'wpp_cache_event');
67
- }
68
- }
69
-
70
- // Allow WP themers / coders to override data sampling status (active/inactive)
71
- $this->config['tools']['sampling']['active'] = apply_filters('wpp_data_sampling', $this->config['tools']['sampling']['active']);
72
-
73
- if (
74
- ! ( wp_using_ext_object_cache() && defined('WPP_CACHE_VIEWS') && WPP_CACHE_VIEWS ) // Not using a persistent object cache
75
- && ! $this->config['tools']['sampling']['active'] // Not using Data Sampling
76
- ) {
77
- // Schedule performance nag
78
- if ( ! wp_next_scheduled('wpp_maybe_performance_nag') ) {
79
- wp_schedule_event(time(), 'hourly', 'wpp_maybe_performance_nag');
80
- }
81
- } else {
82
- // Remove the scheduled performance nag if found
83
- if ( $timestamp = wp_next_scheduled('wpp_maybe_performance_nag') ) {
84
- wp_unschedule_event($timestamp, 'wpp_maybe_performance_nag');
85
- }
86
- }
87
- }
88
-
89
- /**
90
- * WordPress public-facing hooks.
91
- *
92
- * @since 5.0.0
93
- */
94
- public function hooks()
95
- {
96
- // Upgrade check
97
- add_action('init', [$this, 'upgrade_check']);
98
- // Hook fired when a new blog is activated on WP Multisite
99
- add_action('wpmu_new_blog', [$this, 'activate_new_site']);
100
- // Hook fired when a blog is deleted on WP Multisite
101
- add_filter('wpmu_drop_tables', [$this, 'delete_site_data'], 10, 2);
102
- // At-A-Glance
103
- add_filter('dashboard_glance_items', [$this, 'at_a_glance_stats']);
104
- add_action('admin_head', [$this, 'at_a_glance_stats_css']);
105
- // Dashboard Trending Now widget
106
- //if ( current_user_can('edit_published_posts') )
107
- add_action('wp_dashboard_setup', [$this, 'add_dashboard_widgets']);
108
- // Load WPP's admin styles and scripts
109
- add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']);
110
- // Add admin screen
111
- add_action('admin_menu', [$this, 'add_plugin_admin_menu']);
112
- // Contextual help
113
- add_action('admin_head', [$this, 'add_contextual_help']);
114
- // Add plugin settings link
115
- add_filter('plugin_action_links', [$this, 'add_plugin_settings_link'], 10, 2);
116
- // Update chart
117
- add_action('wp_ajax_wpp_update_chart', [$this, 'update_chart']);
118
- // Get lists
119
- add_action('wp_ajax_wpp_get_most_viewed', [$this, 'get_popular_items']);
120
- add_action('wp_ajax_wpp_get_most_commented', [$this, 'get_popular_items']);
121
- add_action('wp_ajax_wpp_get_trending', [$this, 'get_popular_items']);
122
- // Delete plugin data
123
- add_action('wp_ajax_wpp_clear_data', [$this, 'clear_data']);
124
- // Empty plugin's images cache
125
- add_action('wp_ajax_wpp_clear_thumbnail', [$this, 'clear_thumbnails']);
126
- // Flush cached thumbnail on featured image change/deletion
127
- add_action('updated_post_meta', [$this, 'updated_post_meta'], 10, 4);
128
- add_action('deleted_post_meta', [$this, 'deleted_post_meta'], 10, 4);
129
- // Purge post data on post/page deletion
130
- add_action('admin_init', [$this, 'purge_post_data']);
131
- // Purge old data on demand
132
- add_action('wpp_cache_event', [$this, 'purge_data']);
133
- // Maybe performance nag
134
- add_action('wpp_maybe_performance_nag', [$this, 'performance_check']);
135
- // Show notices
136
- add_action('admin_notices', [$this, 'notices']);
137
- }
138
-
139
- /**
140
- * Checks if an upgrade procedure is required.
141
- *
142
- * @since 2.4.0
143
- */
144
- public function upgrade_check()
145
- {
146
- $this->upgrade_site();
147
- }
148
-
149
- /**
150
- * Checks whether a performance tweak may be necessary.
151
- *
152
- * @since 5.0.2
153
- */
154
- public function performance_check()
155
- {
156
- $performance_nag = get_option('wpp_performance_nag');
157
-
158
- if ( ! $performance_nag ) {
159
- $performance_nag = [
160
- 'status' => 0,
161
- 'last_checked' => null
162
- ];
163
- add_option('wpp_performance_nag', $performance_nag);
164
- }
165
-
166
- if ( 3 != $performance_nag['status'] ) { // 0 = inactive, 1 = active, 2 = remind me later, 3 = dismissed
167
- global $wpdb;
168
-
169
- $views_count = $wpdb->get_var(
170
- $wpdb->prepare(
171
- "SELECT IFNULL(SUM(pageviews), 0) AS views FROM {$wpdb->prefix}popularpostssummary WHERE view_datetime > DATE_SUB(%s, INTERVAL 1 HOUR);",
172
- Helper::now()
173
- )
174
- );
175
-
176
- // This site is probably a mid/high traffic one,
177
- // display performance nag
178
- if ( $views_count >= 420 ) {
179
- if ( 0 == $performance_nag['status'] ) {
180
- $performance_nag['status'] = 1;
181
- $performance_nag['last_checked'] = Helper::timestamp();
182
- update_option('wpp_performance_nag', $performance_nag);
183
- }
184
- }
185
- }
186
- }
187
-
188
- /**
189
- * Upgrades single site.
190
- *
191
- * @since 4.0.7
192
- */
193
- private function upgrade_site()
194
- {
195
- // Get WPP version
196
- $wpp_ver = get_option('wpp_ver');
197
-
198
- if ( ! $wpp_ver ) {
199
- add_option('wpp_ver', WPP_VERSION);
200
- } elseif ( version_compare($wpp_ver, WPP_VERSION, '<') ) {
201
- $this->upgrade();
202
- }
203
- }
204
-
205
- /**
206
- * On plugin upgrade, performs a number of actions: update WPP database tables structures (if needed),
207
- * run the setup wizard (if needed), and some other checks.
208
- *
209
- * @since 2.4.0
210
- * @access private
211
- * @global object $wpdb
212
- */
213
- private function upgrade()
214
- {
215
- $now = Helper::now();
216
-
217
- // Keep the upgrade process from running too many times
218
- if ( $wpp_update = get_option('wpp_update') ) {
219
- $from_time = strtotime($wpp_update);
220
- $to_time = strtotime($now);
221
- $difference_in_minutes = round(abs($to_time - $from_time)/60, 2);
222
-
223
- // Upgrade flag is still valid, abort
224
- if ( $difference_in_minutes <= 15 )
225
- return;
226
- // Upgrade flag expired, delete it and continue
227
- delete_option('wpp_update');
228
- }
229
-
230
- global $wpdb;
231
-
232
- // Upgrade flag
233
- add_option('wpp_update', $now);
234
-
235
- // Set table name
236
- $prefix = $wpdb->prefix . "popularposts";
237
-
238
- // Update data table structure and indexes
239
- $dataFields = $wpdb->get_results("SHOW FIELDS FROM {$prefix}data;");
240
-
241
- foreach ( $dataFields as $column ) {
242
- if ( "day" == $column->Field ) {
243
- $wpdb->query("ALTER TABLE {$prefix}data ALTER COLUMN day DROP DEFAULT;");
244
- }
245
-
246
- if ( "last_viewed" == $column->Field ) {
247
- $wpdb->query("ALTER TABLE {$prefix}data ALTER COLUMN last_viewed DROP DEFAULT;");
248
- }
249
- }
250
-
251
- // Update summary table structure and indexes
252
- $summaryFields = $wpdb->get_results("SHOW FIELDS FROM {$prefix}summary;");
253
-
254
- foreach ( $summaryFields as $column ) {
255
- if ( "last_viewed" == $column->Field ) {
256
- $wpdb->query("ALTER TABLE {$prefix}summary CHANGE last_viewed view_datetime datetime NOT NULL, ADD KEY view_datetime (view_datetime);");
257
- }
258
-
259
- if ( "view_date" == $column->Field ) {
260
- $wpdb->query("ALTER TABLE {$prefix}summary ALTER COLUMN view_date DROP DEFAULT;");
261
- }
262
-
263
- if ( "view_datetime" == $column->Field ) {
264
- $wpdb->query("ALTER TABLE {$prefix}summary ALTER COLUMN view_datetime DROP DEFAULT;");
265
- }
266
- }
267
-
268
- $summaryIndexes = $wpdb->get_results("SHOW INDEX FROM {$prefix}summary;");
269
-
270
- foreach( $summaryIndexes as $index ) {
271
- if ( 'ID_date' == $index->Key_name ) {
272
- $wpdb->query("ALTER TABLE {$prefix}summary DROP INDEX ID_date;");
273
- }
274
-
275
- if ( 'last_viewed' == $index->Key_name ) {
276
- $wpdb->query("ALTER TABLE {$prefix}summary DROP INDEX last_viewed;");
277
- }
278
- }
279
-
280
- // Validate the structure of the tables, create missing tables / fields if necessary
281
- \WordPressPopularPosts\Activation\Activator::track_new_site();
282
-
283
- // Check storage engine
284
- $storage_engine_data = $wpdb->get_var("SELECT `ENGINE` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`='{$wpdb->dbname}' AND `TABLE_NAME`='{$prefix}data';");
285
-
286
- if ( 'InnoDB' != $storage_engine_data ) {
287
- $wpdb->query("ALTER TABLE {$prefix}data ENGINE=InnoDB;");
288
- }
289
-
290
- $storage_engine_summary = $wpdb->get_var("SELECT `ENGINE` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`='{$wpdb->dbname}' AND `TABLE_NAME`='{$prefix}summary';");
291
-
292
- if ( 'InnoDB' != $storage_engine_summary ) {
293
- $wpdb->query("ALTER TABLE {$prefix}summary ENGINE=InnoDB;");
294
- }
295
-
296
- // Update WPP version
297
- update_option('wpp_ver', WPP_VERSION);
298
- // Remove upgrade flag
299
- delete_option('wpp_update');
300
- }
301
-
302
- /**
303
- * Fired when a new blog is activated on WP Multisite.
304
- *
305
- * @since 3.0.0
306
- * @param int $blog_id New blog ID
307
- */
308
- public function activate_new_site($blog_id)
309
- {
310
- if ( 1 !== did_action('wpmu_new_blog') )
311
- return;
312
-
313
- // run activation for the new blog
314
- switch_to_blog($blog_id);
315
- \WordPressPopularPosts\Activation\Activator::track_new_site();
316
- // switch back to current blog
317
- restore_current_blog();
318
- }
319
-
320
- /**
321
- * Fired when a blog is deleted on WP Multisite.
322
- *
323
- * @since 4.0.0
324
- * @param array $tables
325
- * @param int $blog_id
326
- * @return array
327
- */
328
- public function delete_site_data($tables, $blog_id)
329
- {
330
- global $wpdb;
331
-
332
- $tables[] = $wpdb->prefix . 'popularpostsdata';
333
- $tables[] = $wpdb->prefix . 'popularpostssummary';
334
-
335
- return $tables;
336
- }
337
-
338
- /**
339
- * Display some statistics at the "At a Glance" box from the Dashboard.
340
- *
341
- * @since 4.1.0
342
- */
343
- public function at_a_glance_stats()
344
- {
345
- global $wpdb;
346
-
347
- $glances = [];
348
- $args = ['post', 'page'];
349
- $post_type_placeholders = '%s, %s';
350
-
351
- if (
352
- isset($this->config['stats']['post_type'])
353
- && ! empty($this->config['stats']['post_type'])
354
- ) {
355
- $args = array_map('trim', explode(',', $this->config['stats']['post_type']));
356
- $post_type_placeholders = implode(', ', array_fill(0, count($args), '%s'));
357
- }
358
-
359
- $args[] = Helper::now();
360
-
361
- $query = $wpdb->prepare(
362
- "SELECT SUM(pageviews) AS total
363
- FROM `{$wpdb->prefix}popularpostssummary` v LEFT JOIN `{$wpdb->prefix}posts` p ON v.postid = p.ID
364
- WHERE p.post_type IN({$post_type_placeholders}) AND p.post_status = 'publish' AND p.post_password = '' AND v.view_datetime > DATE_SUB(%s, INTERVAL 1 HOUR);"
365
- , $args
366
- );
367
-
368
- $total_views = $wpdb->get_var($query);
369
-
370
- $pageviews = sprintf(
371
- _n('%s view in the last hour', '%s views in the last hour', $total_views, 'wordpress-popular-posts'),
372
- number_format_i18n($total_views)
373
- );
374
-
375
- if ( current_user_can('edit_published_posts') ) {
376
- $glances[] = '<a class="wpp-views-count" href="' . admin_url('options-general.php?page=wordpress-popular-posts') . '">' . $pageviews . '</a>';
377
- }
378
- else {
379
- $glances[] = '<span class="wpp-views-count">' . $pageviews . '</a>';
380
- }
381
-
382
- return $glances;
383
- }
384
-
385
- /**
386
- * Add custom inline CSS styles for At a Glance stats.
387
- *
388
- * @since 4.1.0
389
- */
390
- public function at_a_glance_stats_css()
391
- {
392
- echo '<style>#dashboard_right_now a.wpp-views-count:before, #dashboard_right_now span.wpp-views-count:before {content: "\f177";}</style>';
393
- }
394
-
395
- /**
396
- * Adds a widget to the dashboard.
397
- *
398
- * @since 5.0.0
399
- */
400
- public function add_dashboard_widgets()
401
- {
402
- if ( current_user_can('edit_published_posts') ) {
403
- wp_add_dashboard_widget(
404
- 'wpp_trending_dashboard_widget',
405
- __('Trending now', 'wordpress-popular-posts'),
406
- [$this, 'trending_dashboard_widget']
407
- );
408
- }
409
- }
410
-
411
- /**
412
- * Outputs the contents of our Trending Dashboard Widget.
413
- *
414
- * @since 5.0.0
415
- */
416
- function trending_dashboard_widget()
417
- {
418
- ?>
419
- <style>
420
- #wpp_trending_dashboard_widget .inside {
421
- overflow: hidden;
422
- position: relative;
423
- min-height: 150px;
424
- padding-bottom: 22px;
425
- }
426
-
427
- #wpp_trending_dashboard_widget .inside::after {
428
- position: absolute;
429
- top: 0;
430
- left: 0;
431
- opacity: 0.2;
432
- display: block;
433
- content: '';
434
- width: 100%;
435
- height: 100%;
436
- z-index: 1;
437
- background-image: url('<?php echo plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/images/flame.png'; ?>');
438
- background-position: right bottom;
439
- background-repeat: no-repeat;
440
- background-size: 34% auto;
441
- }
442
-
443
- #wpp_trending_dashboard_widget .inside .no-data {
444
- position: absolute;
445
- top: calc(50% - 11px);
446
- left: 50%;
447
- z-index: 2;
448
- margin: 0;
449
- padding: 0;
450
- width: 96%;
451
- transform: translate(-50.0001%, -50.0001%);
452
- }
453
-
454
- #wpp_trending_dashboard_widget .inside .popular-posts-list,
455
- #wpp_trending_dashboard_widget .inside p#wpp_read_more {
456
- position: relative;
457
- z-index: 2;
458
- }
459
-
460
- #wpp_trending_dashboard_widget .inside .popular-posts-list {
461
- margin: 1em 0;
462
- }
463
-
464
- #wpp_trending_dashboard_widget .inside p#wpp_read_more {
465
- position: absolute;
466
- left: 0;
467
- bottom: 0;
468
- width: 100%;
469
- text-align: center;
470
- }
471
- </style>
472
- <?php
473
- $args = [
474
- 'range' => 'custom',
475
- 'time_quantity' => 1,
476
- 'time_unit' => 'HOUR',
477
- 'post_type' => $this->config['stats']['post_type'],
478
- 'limit' => 5,
479
- 'stats_tag' => [
480
- 'views' => 1,
481
- 'comment_count' => 1
482
- ]
483
- ];
484
- $options = apply_filters('wpp_trending_dashboard_widget_args', []);
485
-
486
- if ( is_array($options) && ! empty($options) )
487
- $args = Helper::merge_array_r($args, $options);
488
-
489
- $trending = new Query($args);
490
- $posts = $trending->get_posts();
491
-
492
- $this->render_list($posts, 'trending');
493
- echo '<p id="wpp_read_more"><a href="' . admin_url('options-general.php?page=wordpress-popular-posts') . '">' . __('View more', 'wordpress-popular-posts') . '</a><p>';
494
-
495
- }
496
-
497
- /**
498
- * Enqueues admin facing assets.
499
- *
500
- * @since 5.0.0
501
- */
502
- public function enqueue_assets()
503
- {
504
- $screen = get_current_screen();
505
-
506
- if ( isset($screen->id) ) {
507
- if ( $screen->id == $this->screen_hook_suffix ) {
508
- wp_enqueue_style('wpp-datepicker-theme', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/css/datepicker.css', [], WPP_VERSION, 'all');
509
-
510
- wp_enqueue_media();
511
- wp_enqueue_script('jquery-ui-datepicker');
512
- wp_enqueue_script('chartjs', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/js/vendor/Chart.min.js', [], WPP_VERSION);
513
-
514
- wp_register_script('wpp-chart', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/js/chart.js', ['chartjs'], WPP_VERSION);
515
- wp_localize_script('wpp-chart', 'wpp_chart_params', [
516
- 'colors' => $this->get_admin_color_scheme()
517
- ]);
518
- wp_enqueue_script('wpp-chart');
519
-
520
- wp_register_script('wordpress-popular-posts-admin-script', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/js/admin.js', ['jquery'], WPP_VERSION, true);
521
- wp_localize_script('wordpress-popular-posts-admin-script', 'wpp_admin_params', [
522
- 'label_media_upload_button' => __("Use this image", "wordpress-popular-posts"),
523
- 'nonce' => wp_create_nonce("wpp_admin_nonce")
524
- ]);
525
- wp_enqueue_script('wordpress-popular-posts-admin-script');
526
- }
527
-
528
- if ( $screen->id == $this->screen_hook_suffix || 'dashboard' == $screen->id ) {
529
- // Fontello icons
530
- wp_enqueue_style('wpp-fontello', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/css/fontello.css', [], WPP_VERSION, 'all');
531
- wp_enqueue_style('wordpress-popular-posts-admin-styles', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/css/admin.css', [], WPP_VERSION, 'all');
532
- }
533
- }
534
- }
535
-
536
- /**
537
- * Register the administration menu for this plugin into the WordPress Dashboard menu.
538
- *
539
- * @since 1.0.0
540
- */
541
- public function add_plugin_admin_menu()
542
- {
543
- $this->screen_hook_suffix = add_options_page(
544
- 'WordPress Popular Posts',
545
- 'WordPress Popular Posts',
546
- 'edit_published_posts',
547
- 'wordpress-popular-posts',
548
- [$this, 'display_plugin_admin_page']
549
- );
550
- }
551
-
552
- /**
553
- * Render the settings page for this plugin.
554
- *
555
- * @since 1.0.0
556
- */
557
- public function display_plugin_admin_page()
558
- {
559
- include_once plugin_dir_path(__FILE__) . 'admin-page.php';
560
- }
561
-
562
- /**
563
- * Adds contextual help menu.
564
- *
565
- * @since 4.0.0
566
- */
567
- public function add_contextual_help()
568
- {
569
- $screen = get_current_screen();
570
-
571
- if ( isset($screen->id) && $screen->id == $this->screen_hook_suffix ){
572
- $screen->add_help_tab(
573
- [
574
- 'id' => 'wpp_help_overview',
575
- 'title' => __('Overview', 'wordpress-popular-posts'),
576
- 'content' => "<p>" . __("Welcome to WordPress Popular Posts' Dashboard! In this screen you will find statistics on what's popular on your site, tools to further tweak WPP to your needs, and more!", "wordpress-popular-posts") . "</p>"
577
- ]
578
- );
579
- $screen->add_help_tab(
580
- [
581
- 'id' => 'wpp_help_donate',
582
- 'title' => __('Like this plugin?', 'wordpress-popular-posts'),
583
- 'content' => '
584
- <p style="text-align: center;">' . __('Each donation motivates me to keep releasing free stuff for the WordPress community!', 'wordpress-popular-posts') . '</p>
585
- <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" style="margin: 0; padding: 0; text-align: center;">
586
- <input type="hidden" name="cmd" value="_s-xclick">
587
- <input type="hidden" name="hosted_button_id" value="RP9SK8KVQHRKS">
588
- <input type="image" src="//www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" style="display: inline; margin: 0;">
589
- <img alt="" border="0" src="//www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
590
- </form>
591
- <p style="text-align: center;">' . sprintf(__('You can <a href="%s" target="_blank">leave a review</a>, too!', 'wordpress-popular-posts'), 'https://wordpress.org/support/view/plugin-reviews/wordpress-popular-posts?rate=5#postform') . '</p>'
592
- ]
593
- );
594
-
595
- // Help sidebar
596
- $screen->set_help_sidebar(
597
- sprintf(
598
- __('<p><strong>For more information:</strong></p><ul><li><a href="%1$s">Documentation</a></li><li><a href="%2$s">Support</a></li></ul>', 'wordpress-popular-posts'),
599
- "https://github.com/cabrerahector/wordpress-popular-posts/",
600
- "https://wordpress.org/support/plugin/wordpress-popular-posts/"
601
- )
602
- );
603
- }
604
- }
605
-
606
- /**
607
- * Registers Settings link on plugin description.
608
- *
609
- * @since 2.3.3
610
- * @param array $links
611
- * @param string $file
612
- * @return array
613
- */
614
- public function add_plugin_settings_link($links, $file)
615
- {
616
- $plugin_file = 'wordpress-popular-posts/wordpress-popular-posts.php';
617
-
618
- if (
619
- is_plugin_active($plugin_file)
620
- && $plugin_file == $file
621
- ) {
622
- array_unshift(
623
- $links,
624
- '<a href="' . admin_url('options-general.php?page=wordpress-popular-posts') . '">' . __('Settings') . '</a>',
625
- '<a href="https://wordpress.org/support/plugin/wordpress-popular-posts/">' . __('Support', 'wordpress-popular-posts') . '</a>'
626
- );
627
- }
628
-
629
- return $links;
630
- }
631
-
632
- /**
633
- * Gets current admin color scheme.
634
- *
635
- * @since 4.0.0
636
- * @return array
637
- */
638
- private function get_admin_color_scheme()
639
- {
640
- global $_wp_admin_css_colors;
641
-
642
- if (
643
- is_array($_wp_admin_css_colors)
644
- && count($_wp_admin_css_colors)
645
- ) {
646
- $current_user = wp_get_current_user();
647
- $color_scheme = get_user_option('admin_color', $current_user->ID);
648
-
649
- if (
650
- empty($color_scheme)
651
- || ! isset($_wp_admin_css_colors[ $color_scheme])
652
- ) {
653
- $color_scheme = 'fresh';
654
- }
655
-
656
- if ( isset($_wp_admin_css_colors[$color_scheme]) && isset($_wp_admin_css_colors[$color_scheme]->colors) ) {
657
- return $_wp_admin_css_colors[$color_scheme]->colors;
658
- }
659
-
660
- }
661
-
662
- // Fallback, just in case
663
- return ['#333', '#999', '#881111', '#a80000'];
664
- }
665
-
666
- /**
667
- * Fetches chart data.
668
- *
669
- * @since 4.0.0
670
- * @return string
671
- */
672
- public function get_chart_data($range = 'last7days', $time_unit = 'HOUR', $time_quantity = 24)
673
- {
674
- $dates = $this->get_dates($range, $time_unit, $time_quantity);
675
- $start_date = $dates[0];
676
- $end_date = $dates[count($dates) - 1];
677
- $date_range = Helper::get_date_range($start_date, $end_date, 'Y-m-d H:i:s');
678
- $views_data = $this->get_range_item_count($start_date, $end_date, 'views');
679
- $views = [];
680
- $comments_data = $this->get_range_item_count($start_date, $end_date, 'comments');
681
- $comments = [];
682
-
683
- if ( 'today' != $range ) {
684
- foreach($date_range as $date) {
685
- $key = date('Y-m-d', strtotime($date));
686
- $views[] = ( ! isset($views_data[$key]) ) ? 0 : $views_data[$key]->pageviews;
687
- $comments[] = ( ! isset($comments_data[$key]) ) ? 0 : $comments_data[$key]->comments;
688
- }
689
- } else {
690
- $key = date('Y-m-d', strtotime($dates[0]));
691
- $views[] = ( ! isset($views_data[$key]) ) ? 0 : $views_data[$key]->pageviews;
692
- $comments[] = ( ! isset($comments_data[$key]) ) ? 0 : $comments_data[$key]->comments;
693
- }
694
-
695
- if ( $start_date != $end_date )
696
- $label_date_range = date_i18n('M, D d', strtotime($start_date)) . ' &mdash; ' . date_i18n('M, D d', strtotime($end_date));
697
- else
698
- $label_date_range = date_i18n('M, D d', strtotime($start_date));
699
-
700
- $total_views = array_sum($views);
701
- $total_comments = array_sum($comments);
702
-
703
- $label_summary = sprintf(_n('%s view', '%s views', $total_views, 'wordpress-popular-posts'), '<strong>' . number_format_i18n($total_views) . '</strong>') . '<br style="display: none;" /> / ' . sprintf(_n('%s comment', '%s comments', $total_comments, 'wordpress-popular-posts'), '<strong>' . number_format_i18n($total_comments) . '</strong>');
704
-
705
- // Format labels
706
- if ( 'today' != $range ) {
707
- $date_range = array_map(function($d){
708
- return date_i18n('D d', strtotime($d));
709
- }, $date_range);
710
- } else {
711
- $date_range = [date_i18n('D d', strtotime($date_range[0]))];
712
- $comments = [array_sum($comments)];
713
- $views = [array_sum($views)];
714
- }
715
-
716
- $response = [
717
- 'totals' => [
718
- 'label_summary' => $label_summary,
719
- 'label_date_range' => $label_date_range,
720
- ],
721
- 'labels' => $date_range,
722
- 'datasets' => [
723
- [
724
- 'label' => __("Comments", "wordpress-popular-posts"),
725
- 'data' => $comments
726
- ],
727
- [
728
- 'label' => __("Views", "wordpress-popular-posts"),
729
- 'data' => $views
730
- ]
731
- ]
732
- ];
733
-
734
- return json_encode($response);
735
- }
736
-
737
- /**
738
- * Returns an array of dates.
739
- *
740
- * @since 5.0.0
741
- * @return array|bool
742
- */
743
- private function get_dates($range = 'last7days', $time_unit = 'HOUR', $time_quantity = 24)
744
- {
745
- $valid_ranges = ['today', 'daily', 'last24hours', 'weekly', 'last7days', 'monthly', 'last30days', 'all', 'custom'];
746
- $range = in_array($range, $valid_ranges) ? $range : 'last7days';
747
- $now = new \DateTime(Helper::now(), new \DateTimeZone(Helper::get_timezone()));
748
-
749
- // Determine time range
750
- switch( $range ){
751
- case "last24hours":
752
- case "daily":
753
- $end_date = $now->format('Y-m-d H:i:s');
754
- $start_date = $now->modify('-1 day')->format('Y-m-d H:i:s');
755
- break;
756
-
757
- case "today":
758
- $start_date = $now->format('Y-m-d') . ' 00:00:00';
759
- $end_date = $now->format('Y-m-d') . ' 23:59:59';
760
- break;
761
-
762
- case "last7days":
763
- case "weekly":
764
- $end_date = $now->format('Y-m-d') . ' 23:59:59';
765
- $start_date = $now->modify('-6 day')->format('Y-m-d') . ' 00:00:00';
766
- break;
767
-
768
- case "last30days":
769
- case "monthly":
770
- $end_date = $now->format('Y-m-d') . ' 23:59:59';
771
- $start_date = $now->modify('-29 day')->format('Y-m-d') . ' 00:00:00';
772
- break;
773
-
774
- case "custom":
775
- $end_date = $now->format('Y-m-d H:i:s');
776
-
777
- if (
778
- Helper::is_number($time_quantity)
779
- && $time_quantity >= 1
780
- ) {
781
- $end_date = $now->format('Y-m-d H:i:s');
782
- $time_unit = strtoupper($time_unit);
783
-
784
- if ( 'MINUTE' == $time_unit ) {
785
- $start_date = $now->sub(new \DateInterval('PT' . (60 * $time_quantity) . 'S'))->format('Y-m-d H:i:s');
786
- } elseif ( 'HOUR' == $time_unit ) {
787
- $start_date = $now->sub(new \DateInterval('PT' . ((60 * $time_quantity) - 1) . 'M59S'))->format('Y-m-d H:i:s');
788
- } else {
789
- $end_date = $now->format('Y-m-d') . ' 23:59:59';
790
- $start_date = $now->sub(new \DateInterval('P' . ($time_quantity - 1) . 'D'))->format('Y-m-d') . ' 00:00:00';
791
- }
792
- } // fallback to last 24 hours
793
- else {
794
- $start_date = $now->modify('-1 day')->format('Y-m-d H:i:s');
795
- }
796
-
797
- // Check if custom date range has been requested
798
- $dates = null;
799
-
800
- if ( isset($_GET['dates']) ) {
801
- $dates = explode(" ~ ", $_GET['dates']);
802
-
803
- if (
804
- ! is_array($dates)
805
- || empty($dates)
806
- || ! Helper::is_valid_date($dates[0])
807
- ) {
808
- $dates = null;
809
- } else {
810
- if (
811
- ! isset($dates[1])
812
- || ! Helper::is_valid_date($dates[1])
813
- ) {
814
- $dates[1] = $dates[0];
815
- }
816
-
817
- $start_date = $dates[0] . ' 00:00:00';
818
- $end_date = $dates[1] . ' 23:59:59';
819
- }
820
- }
821
-
822
- break;
823
-
824
- default:
825
- $end_date = $now->format('Y-m-d') . ' 23:59:59';
826
- $start_date = $now->modify('-6 day')->format('Y-m-d') . ' 00:00:00';
827
- break;
828
- }
829
-
830
- return [$start_date, $end_date];
831
- }
832
-
833
- /**
834
- * Returns an array of dates with views/comments count.
835
- *
836
- * @since 5.0.0
837
- * @param string $start_date
838
- * @param string $end_date
839
- * @param string $item
840
- * @return array
841
- */
842
- public function get_range_item_count($start_date, $end_date, $item = 'views')
843
- {
844
- global $wpdb;
845
-
846
- $args = array_map('trim', explode(',', $this->config['stats']['post_type']));
847
-
848
- if ( empty($args) ) {
849
- $args = ['post', 'page'];
850
- }
851
-
852
- $post_type_placeholders = array_fill(0, count($args), '%s');
853
-
854
- if ( $this->config['stats']['freshness'] ) {
855
- $args[] = $start_date;
856
- }
857
-
858
- // Append dates to arguments list
859
- array_unshift($args, $start_date, $end_date);
860
-
861
- if ( $item == 'comments' ) {
862
- $query = $wpdb->prepare(
863
- "SELECT DATE(`c`.`comment_date_gmt`) AS `c_date`, COUNT(*) AS `comments`
864
- FROM `{$wpdb->comments}` c INNER JOIN `{$wpdb->posts}` p ON `c`.`comment_post_ID` = `p`.`ID`
865
- WHERE (`c`.`comment_date_gmt` BETWEEN %s AND %s) AND `c`.`comment_approved` = '1' AND `p`.`post_type` IN (". implode(", ", $post_type_placeholders) . ") AND `p`.`post_status` = 'publish' AND `p`.`post_password` = ''
866
- " . ( $this->config['stats']['freshness'] ? " AND `p`.`post_date` >= %s" : "" ) . "
867
- GROUP BY `c_date` ORDER BY `c_date` DESC;",
868
- $args
869
- );
870
- } else {
871
- $query = $wpdb->prepare(
872
- "SELECT `v`.`view_date`, SUM(`v`.`pageviews`) AS `pageviews`
873
- FROM `{$wpdb->prefix}popularpostssummary` v INNER JOIN `{$wpdb->posts}` p ON `v`.`postid` = `p`.`ID`
874
- WHERE (`v`.`view_datetime` BETWEEN %s AND %s) AND `p`.`post_type` IN (". implode(", ", $post_type_placeholders) . ") AND `p`.`post_status` = 'publish' AND `p`.`post_password` = ''
875
- " . ( $this->config['stats']['freshness'] ? " AND `p`.`post_date` >= %s" : "" ) . "
876
- GROUP BY `v`.`view_date` ORDER BY `v`.`view_date` DESC;",
877
- $args
878
- );
879
-
880
- //error_log($query);
881
- }
882
-
883
- return $wpdb->get_results($query, OBJECT_K);
884
- }
885
-
886
- /**
887
- * Updates chart via AJAX.
888
- *
889
- * @since 4.0.0
890
- */
891
- public function update_chart()
892
- {
893
- $response = [
894
- 'status' => 'error'
895
- ];
896
- $nonce = isset($_GET['nonce']) ? $_GET['nonce'] : null;
897
-
898
- if ( wp_verify_nonce($nonce, 'wpp_admin_nonce') ) {
899
-
900
- $valid_ranges = ['today', 'daily', 'last24hours', 'weekly', 'last7days', 'monthly', 'last30days', 'all', 'custom'];
901
- $time_units = ["MINUTE", "HOUR", "DAY"];
902
-
903
- $range = ( isset($_GET['range']) && in_array($_GET['range'], $valid_ranges) ) ? $_GET['range'] : 'last7days';
904
- $time_quantity = ( isset($_GET['time_quantity']) && filter_var($_GET['time_quantity'], FILTER_VALIDATE_INT) ) ? $_GET['time_quantity'] : 24;
905
- $time_unit = ( isset($_GET['time_unit']) && in_array(strtoupper($_GET['time_unit']), $time_units) ) ? $_GET['time_unit'] : 'hour';
906
-
907
- $this->config['stats']['range'] = $range;
908
- $this->config['stats']['time_quantity'] = $time_quantity;
909
- $this->config['stats']['time_unit'] = $time_unit;
910
-
911
- update_option('wpp_settings_config', $this->config);
912
-
913
- $response = [
914
- 'status' => 'ok',
915
- 'data' => json_decode(
916
- $this->get_chart_data($this->config['stats']['range'], $this->config['stats']['time_unit'], $this->config['stats']['time_quantity']),
917
- true
918
- )
919
- ];
920
- }
921
-
922
- wp_send_json($response);
923
- }
924
-
925
- /**
926
- * Fetches most viewed/commented/trending posts via AJAX.
927
- *
928
- * @since 5.0.0
929
- */
930
- public function get_popular_items()
931
- {
932
- $items = isset($_GET['items']) ? $_GET['items'] : null;
933
- $nonce = isset($_GET['nonce']) ? $_GET['nonce'] : null;
934
-
935
- if ( wp_verify_nonce($nonce, 'wpp_admin_nonce') ) {
936
- $args = [
937
- 'range' => $this->config['stats']['range'],
938
- 'time_quantity' => $this->config['stats']['time_quantity'],
939
- 'time_unit' => $this->config['stats']['time_unit'],
940
- 'post_type' => $this->config['stats']['post_type'],
941
- 'freshness' => $this->config['stats']['freshness'],
942
- 'limit' => $this->config['stats']['limit'],
943
- 'stats_tag' => [
944
- 'date' => [
945
- 'active' => 1
946
- ]
947
- ]
948
- ];
949
-
950
- if ( 'most-commented' == $items ) {
951
- $args['order_by'] = 'comments';
952
- $args['stats_tag']['comment_count'] = 1;
953
- $args['stats_tag']['views'] = 0;
954
- } elseif ( 'trending' == $items ) {
955
- $args['range'] = 'custom';
956
- $args['time_quantity'] = 1;
957
- $args['time_unit'] = 'HOUR';
958
- $args['stats_tag']['comment_count'] = 1;
959
- $args['stats_tag']['views'] = 1;
960
- } else {
961
- $args['stats_tag']['comment_count'] = 0;
962
- $args['stats_tag']['views'] = 1;
963
- }
964
-
965
- if ( 'trending' != $items ) {
966
-
967
- add_filter('wpp_query_join', function($join, $options) use ($items)
968
- {
969
- global $wpdb;
970
- $dates = null;
971
-
972
- if ( isset($_GET['dates']) ) {
973
- $dates = explode(" ~ ", $_GET['dates']);
974
-
975
- if (
976
- ! is_array($dates)
977
- || empty($dates)
978
- || ! Helper::is_valid_date($dates[0])
979
- ) {
980
- $dates = null;
981
- } else {
982
- if (
983
- ! isset($dates[1])
984
- || ! Helper::is_valid_date($dates[1])
985
- ) {
986
- $dates[1] = $dates[0];
987
- }
988
-
989
- $start_date = $dates[0];
990
- $end_date = $dates[1];
991
- }
992
-
993
- }
994
-
995
- if ( $dates ) {
996
- if ( 'most-commented' == $items ) {
997
- return "INNER JOIN (SELECT comment_post_ID, COUNT(comment_post_ID) AS comment_count, comment_date_gmt FROM `{$wpdb->comments}` WHERE comment_date_gmt BETWEEN '{$dates[0]} 00:00:00' AND '{$dates[1]} 23:59:59' AND comment_approved = '1' GROUP BY comment_post_ID) c ON p.ID = c.comment_post_ID";
998
- }
999
-
1000
- return "INNER JOIN (SELECT SUM(pageviews) AS pageviews, view_date, postid FROM `{$wpdb->prefix}popularpostssummary` WHERE view_datetime BETWEEN '{$dates[0]} 00:00:00' AND '{$dates[1]} 23:59:59' GROUP BY postid) v ON p.ID = v.postid";
1001
- }
1002
-
1003
- $now = Helper::now();
1004
-
1005
- // Determine time range
1006
- switch( $options['range'] ){
1007
- case "last24hours":
1008
- case "daily":
1009
- $interval = "24 HOUR";
1010
- break;
1011
-
1012
- case "today":
1013
- $hours = date('H', strtotime($now));
1014
- $minutes = $hours * 60 + (int) date( 'i', strtotime($now) );
1015
- $interval = "{$minutes} MINUTE";
1016
- break;
1017
-
1018
- case "last7days":
1019
- case "weekly":
1020
- $interval = "6 DAY";
1021
- break;
1022
-
1023
- case "last30days":
1024
- case "monthly":
1025
- $interval = "29 DAY";
1026
- break;
1027
-
1028
- case "custom":
1029
- $time_units = ["MINUTE", "HOUR", "DAY"];
1030
- $interval = "24 HOUR";
1031
-
1032
- // Valid time unit
1033
- if (
1034
- isset($options['time_unit'])
1035
- && in_array(strtoupper($options['time_unit']), $time_units)
1036
- && isset($options['time_quantity'])
1037
- && filter_var($options['time_quantity'], FILTER_VALIDATE_INT)
1038
- && $options['time_quantity'] > 0
1039
- ) {
1040
- $interval = "{$options['time_quantity']} " . strtoupper($options['time_unit']);
1041
- }
1042
-
1043
- break;
1044
-
1045
- default:
1046
- $interval = "1 DAY";
1047
- break;
1048
- }
1049
-
1050
- if ( 'most-commented' == $items ) {
1051
- return "INNER JOIN (SELECT comment_post_ID, COUNT(comment_post_ID) AS comment_count, comment_date_gmt FROM `{$wpdb->comments}` WHERE comment_date_gmt > DATE_SUB('{$now}', INTERVAL {$interval}) AND comment_approved = '1' GROUP BY comment_post_ID) c ON p.ID = c.comment_post_ID";
1052
- }
1053
-
1054
- return "INNER JOIN (SELECT SUM(pageviews) AS pageviews, view_date, postid FROM `{$wpdb->prefix}popularpostssummary` WHERE view_datetime > DATE_SUB('{$now}', INTERVAL {$interval}) GROUP BY postid) v ON p.ID = v.postid";
1055
- }, 1, 2);
1056
-
1057
- }
1058
-
1059
- $popular_items = new \WordPressPopularPosts\Query($args);
1060
- $posts = $popular_items->get_posts();
1061
-
1062
- if ( 'trending' != $items ) {
1063
- remove_all_filters('wpp_query_join', 1);
1064
- }
1065
-
1066
- $this->render_list($posts, $items);
1067
- }
1068
-
1069
- wp_die();
1070
- }
1071
-
1072
- /**
1073
- * Renders popular posts lists.
1074
- *
1075
- * @since 5.0.0
1076
- * @param array
1077
- */
1078
- public function render_list($posts, $list = 'most-viewed')
1079
- {
1080
- if (
1081
- is_array($posts)
1082
- && ! empty($posts)
1083
- ) {
1084
- ?>
1085
- <ol class="popular-posts-list">
1086
- <?php
1087
- foreach( $posts as $post ) { ?>
1088
- <li>
1089
- <a href="<?php echo get_permalink($post->id); ?>" class="wpp-title"><?php echo sanitize_text_field(apply_filters('the_title', $post->title, $post->id)); ?></a>
1090
- <div>
1091
- <?php if ( 'most-viewed' == $list ) : ?>
1092
- <span><?php printf(_n('%s view', '%s views', $post->pageviews, 'wordpress-popular-posts' ), number_format_i18n($post->pageviews)); ?></span>
1093
- <?php elseif ( 'most-commented' == $list ) : ?>
1094
- <span><?php printf(_n('%s comment', '%s comments', $post->comment_count, 'wordpress-popular-posts'), number_format_i18n($post->comment_count)); ?></span>
1095
- <?php else : ?>
1096
- <span><?php printf(_n('%s view', '%s views', $post->pageviews, 'wordpress-popular-posts' ), number_format_i18n($post->pageviews)); ?></span>, <span><?php printf(_n('%s comment', '%s comments', $post->comment_count, 'wordpress-popular-posts'), number_format_i18n($post->comment_count)); ?></span>
1097
- <?php endif; ?>
1098
- <small> &mdash; <a href="<?php echo get_permalink($post->id); ?>"><?php _e("View"); ?></a><?php if ( current_user_can('edit_others_posts') ): ?> | <a href="<?php echo get_edit_post_link($post->id); ?>"><?php _e("Edit"); ?></a><?php endif; ?></small>
1099
- </div>
1100
- </li>
1101
- <?php
1102
- }
1103
- ?>
1104
- </ol>
1105
- <?php
1106
- }
1107
- else {
1108
- ?>
1109
- <p class="no-data" style="text-align: center;"><?php _e("Looks like your site's activity is a little low right now. <br />Spread the word and come back later!", "wordpress-popular-posts"); ?></p>
1110
- <?php
1111
- }
1112
- }
1113
-
1114
- /**
1115
- * Truncates data and cache on demand.
1116
- *
1117
- * @since 2.0.0
1118
- * @global object $wpdb
1119
- */
1120
- public function clear_data()
1121
- {
1122
- $token = $_POST['token'];
1123
- $clear = isset($_POST['clear']) ? $_POST['clear'] : null;
1124
- $key = get_option("wpp_rand");
1125
-
1126
- if (
1127
- current_user_can('manage_options')
1128
- && ( $token === $key )
1129
- && $clear
1130
- ) {
1131
- global $wpdb;
1132
-
1133
- // set table name
1134
- $prefix = $wpdb->prefix . "popularposts";
1135
-
1136
- if ( $clear == 'cache' ) {
1137
- if ( $wpdb->get_var("SHOW TABLES LIKE '{$prefix}summary'") ) {
1138
- $wpdb->query("TRUNCATE TABLE {$prefix}summary;");
1139
- $this->flush_transients();
1140
-
1141
- echo 1;
1142
- } else {
1143
- echo 2;
1144
- }
1145
- } elseif ( $clear == 'all' ) {
1146
- if ( $wpdb->get_var("SHOW TABLES LIKE '{$prefix}data'") && $wpdb->get_var("SHOW TABLES LIKE '{$prefix}summary'") ) {
1147
- $wpdb->query("TRUNCATE TABLE {$prefix}data;");
1148
- $wpdb->query("TRUNCATE TABLE {$prefix}summary;");
1149
- $this->flush_transients();
1150
-
1151
- echo 1;
1152
- } else {
1153
- echo 2;
1154
- }
1155
- } else {
1156
- echo 3;
1157
- }
1158
- } else {
1159
- echo 4;
1160
- }
1161
-
1162
- wp_die();
1163
- }
1164
-
1165
- /**
1166
- * Deletes cached (transient) data.
1167
- *
1168
- * @since 3.0.0
1169
- * @access private
1170
- */
1171
- private function flush_transients()
1172
- {
1173
- $wpp_transients = get_option('wpp_transients');
1174
-
1175
- if ( $wpp_transients && is_array($wpp_transients) && ! empty($wpp_transients) ) {
1176
- for ( $t=0; $t < count($wpp_transients); $t++ )
1177
- delete_transient($wpp_transients[$t]);
1178
-
1179
- update_option('wpp_transients', []);
1180
- }
1181
- }
1182
-
1183
- /**
1184
- * Truncates thumbnails cache on demand.
1185
- *
1186
- * @since 2.0.0
1187
- * @global object wpdb
1188
- */
1189
- public function clear_thumbnails()
1190
- {
1191
- $wpp_uploads_dir = $this->thumbnail->get_plugin_uploads_dir();
1192
-
1193
- if ( is_array($wpp_uploads_dir) && ! empty($wpp_uploads_dir) ) {
1194
- $token = isset($_POST['token']) ? $_POST['token'] : null;
1195
- $key = get_option("wpp_rand");
1196
-
1197
- if (
1198
- current_user_can('edit_published_posts')
1199
- && ( $token === $key )
1200
- ) {
1201
- if ( is_dir($wpp_uploads_dir['basedir']) ) {
1202
- $files = glob("{$wpp_uploads_dir['basedir']}/*"); // get all related images
1203
-
1204
- if ( is_array($files) && ! empty($files) ) {
1205
- foreach( $files as $file ){ // iterate files
1206
- if ( is_file($file) ) {
1207
- @unlink($file); // delete file
1208
- }
1209
- }
1210
- echo 1;
1211
- } else {
1212
- echo 2;
1213
- }
1214
- } else {
1215
- echo 3;
1216
- }
1217
- } else {
1218
- echo 4;
1219
- }
1220
- }
1221
-
1222
- wp_die();
1223
- }
1224
-
1225
- /**
1226
- * Fires immediately after deleting metadata of a post.
1227
- *
1228
- * @since 5.0.0
1229
- *
1230
- * @param int $meta_id Metadata ID.
1231
- * @param int $post_id Post ID.
1232
- * @param string $meta_key Meta key.
1233
- * @param mixed $meta_value Meta value.
1234
- */
1235
- public function updated_post_meta($meta_id, $post_id, $meta_key, $meta_value)
1236
- {
1237
- if ( '_thumbnail_id' == $meta_key ) {
1238
- $this->flush_post_thumbnail($post_id);
1239
- }
1240
- }
1241
-
1242
- /**
1243
- * Fires immediately after deleting metadata of a post.
1244
- *
1245
- * @since 5.0.0
1246
- *
1247
- * @param array $meta_ids An array of deleted metadata entry IDs.
1248
- * @param int $post_id Post ID.
1249
- * @param string $meta_key Meta key.
1250
- * @param mixed $meta_value Meta value.
1251
- */
1252
- public function deleted_post_meta($meta_ids, $post_id, $meta_key, $meta_value)
1253
- {
1254
- if ( '_thumbnail_id' == $meta_key ) {
1255
- $this->flush_post_thumbnail($post_id);
1256
- }
1257
- }
1258
-
1259
- /**
1260
- * Flushes post's cached thumbnail(s).
1261
- *
1262
- * @since 3.3.4
1263
- *
1264
- * @param integer $post_id Post ID
1265
- */
1266
- public function flush_post_thumbnail($post_id)
1267
- {
1268
- $wpp_uploads_dir = $this->thumbnail->get_plugin_uploads_dir();
1269
-
1270
- if ( is_array($wpp_uploads_dir) && ! empty($wpp_uploads_dir) ) {
1271
- $files = glob("{$wpp_uploads_dir['basedir']}/{$post_id}-*.*"); // get all related images
1272
-
1273
- if ( is_array($files) && ! empty($files) ) {
1274
- foreach( $files as $file ){ // iterate files
1275
- if ( is_file($file) ) {
1276
- @unlink($file); // delete file
1277
- }
1278
- }
1279
- }
1280
- }
1281
- }
1282
-
1283
- /**
1284
- * Purges post from data/summary tables.
1285
- *
1286
- * @since 3.3.0
1287
- */
1288
- public function purge_post_data()
1289
- {
1290
- if ( current_user_can('delete_posts') )
1291
- add_action('delete_post', [$this, 'purge_post']);
1292
- }
1293
-
1294
- /**
1295
- * Purges post from data/summary tables.
1296
- *
1297
- * @since 3.3.0
1298
- * @global object $wpdb
1299
- */
1300
- public function purge_post($post_ID)
1301
- {
1302
- global $wpdb;
1303
-
1304
- if ( $wpdb->get_var($wpdb->prepare("SELECT postid FROM {$wpdb->prefix}popularpostsdata WHERE postid = %d", $post_ID)) ) {
1305
- // Delete from data table
1306
- $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}popularpostsdata WHERE postid = %d;", $post_ID));
1307
- // Delete from summary table
1308
- $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}popularpostssummary WHERE postid = %d;", $post_ID));
1309
- }
1310
-
1311
- // Delete cached thumbnail(s) as well
1312
- $this->flush_post_thumbnail($post_ID);
1313
- }
1314
-
1315
- /**
1316
- * Purges old post data from summary table.
1317
- *
1318
- * @since 2.0.0
1319
- * @global object $wpdb
1320
- */
1321
- public function purge_data()
1322
- {
1323
- global $wpdb;
1324
- $wpdb->query("DELETE FROM {$wpdb->prefix}popularpostssummary WHERE view_date < DATE_SUB('" . Helper::curdate() . "', INTERVAL {$this->config['tools']['log']['expires_after']} DAY);");
1325
- }
1326
-
1327
- /**
1328
- * Displays admin notices.
1329
- *
1330
- * @since 5.0.2
1331
- */
1332
- public function notices()
1333
- {
1334
- /** Performance nag */
1335
- $performance_nag = get_option('wpp_performance_nag');
1336
-
1337
- if (
1338
- isset($performance_nag['status'])
1339
- && 3 != $performance_nag['status'] // 0 = inactive, 1 = active, 2 = remind me later, 3 = dismissed
1340
- ) {
1341
- $now = Helper::timestamp();
1342
-
1343
- if ( isset($_GET['wpp_dismiss_performance_notice']) || isset($_GET['wpp_remind_performance_notice']) ) {
1344
- // User dismissed the notice
1345
- if ( isset($_GET['wpp_dismiss_performance_notice']) ) {
1346
- $performance_nag['status'] = 3;
1347
- } // User asked us to remind them later
1348
- else {
1349
- $performance_nag['status'] = 2;
1350
- $performance_nag['last_checked'] = $now;
1351
- }
1352
-
1353
- update_option('wpp_performance_nag', $performance_nag);
1354
- echo '<script>window.location.replace("'. esc_url(remove_query_arg(['wpp_dismiss_performance_notice', 'wpp_remind_performance_notice'])) .'");</script>';
1355
- } // Maybe display the notice
1356
- else {
1357
- // How much time has passed since the notice was last displayed?
1358
- $last_checked = $performance_nag['last_checked'];
1359
-
1360
- if ( $last_checked ) {
1361
- $last_checked = ($now - $last_checked) / (60 * 60);
1362
- }
1363
-
1364
- if (
1365
- 1 == $performance_nag['status']
1366
- || ( 2 == $performance_nag['status'] && $last_checked && $last_checked >= 24 )
1367
- ) {
1368
- ?>
1369
- <div class="notice notice-warning">
1370
- <p><?php printf(
1371
- __("<strong>WordPress Popular Posts:</strong> It seems your site is popular (great!) You may want to check <a href=\"%s\">these suggestions</a> to make sure your website's performance stays up to par.", 'wordpress-popular-posts'),
1372
- 'https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance'
1373
- ) ?></p>
1374
- <?php if ( current_user_can('manage_options') ) : ?>
1375
- <p><a href="<?php echo add_query_arg('wpp_dismiss_performance_notice', '1'); ?>">Dismiss</a> | <a href="<?php echo add_query_arg('wpp_remind_performance_notice', '1'); ?>">Remind me later</a></p>
1376
- <?php endif; ?>
1377
- </div>
1378
- <?php
1379
- }
1380
- }
1381
- }
1382
- }
1383
- }
1
+ <?php
2
+ /**
3
+ * The admin-facing functionality of the plugin.
4
+ *
5
+ * Defines hooks to enqueue the admin-specific stylesheet and JavaScript,
6
+ * plugin settings and other admin stuff.
7
+ *
8
+ * @package WordPressPopularPosts
9
+ * @subpackage WordPressPopularPosts/Admin
10
+ * @author Hector Cabrera <me@cabrerahector.com>
11
+ */
12
+
13
+ namespace WordPressPopularPosts\Admin;
14
+
15
+ use WordPressPopularPosts\Helper;
16
+ use WordPressPopularPosts\Output;
17
+ use WordPressPopularPosts\Query;
18
+
19
+ class Admin {
20
+
21
+ /**
22
+ * Slug of the plugin screen.
23
+ *
24
+ * @since 3.0.0
25
+ * @var string
26
+ */
27
+ protected $screen_hook_suffix = NULL;
28
+
29
+ /**
30
+ * Plugin options.
31
+ *
32
+ * @var array $config
33
+ * @access private
34
+ */
35
+ private $config;
36
+
37
+ /**
38
+ * Image object
39
+ *
40
+ * @since 4.0.2
41
+ * @var WordPressPopularPosts\Image
42
+ */
43
+ private $thumbnail;
44
+
45
+ /**
46
+ * Construct.
47
+ *
48
+ * @since 5.0.0
49
+ * @param array $config Admin settings.
50
+ * @param \WordPressPopularPosts\Image $thumbnail Image class.
51
+ */
52
+ public function __construct(array $config, \WordPressPopularPosts\Image $thumbnail)
53
+ {
54
+ $this->config = $config;
55
+ $this->thumbnail = $thumbnail;
56
+
57
+ // Delete old data on demand
58
+ if ( 1 == $this->config['tools']['log']['limit'] ) {
59
+ if ( ! wp_next_scheduled('wpp_cache_event') ) {
60
+ $midnight = strtotime('midnight') - ( get_option('gmt_offset') * HOUR_IN_SECONDS ) + DAY_IN_SECONDS;
61
+ wp_schedule_event($midnight, 'daily', 'wpp_cache_event');
62
+ }
63
+ } else {
64
+ // Remove the scheduled event if exists
65
+ if ( $timestamp = wp_next_scheduled('wpp_cache_event') ) {
66
+ wp_unschedule_event($timestamp, 'wpp_cache_event');
67
+ }
68
+ }
69
+
70
+ // Allow WP themers / coders to override data sampling status (active/inactive)
71
+ $this->config['tools']['sampling']['active'] = apply_filters('wpp_data_sampling', $this->config['tools']['sampling']['active']);
72
+
73
+ if (
74
+ ! ( wp_using_ext_object_cache() && defined('WPP_CACHE_VIEWS') && WPP_CACHE_VIEWS ) // Not using a persistent object cache
75
+ && ! $this->config['tools']['sampling']['active'] // Not using Data Sampling
76
+ ) {
77
+ // Schedule performance nag
78
+ if ( ! wp_next_scheduled('wpp_maybe_performance_nag') ) {
79
+ wp_schedule_event(time(), 'hourly', 'wpp_maybe_performance_nag');
80
+ }
81
+ } else {
82
+ // Remove the scheduled performance nag if found
83
+ if ( $timestamp = wp_next_scheduled('wpp_maybe_performance_nag') ) {
84
+ wp_unschedule_event($timestamp, 'wpp_maybe_performance_nag');
85
+ }
86
+ }
87
+ }
88
+
89
+ /**
90
+ * WordPress public-facing hooks.
91
+ *
92
+ * @since 5.0.0
93
+ */
94
+ public function hooks()
95
+ {
96
+ // Upgrade check
97
+ add_action('init', [$this, 'upgrade_check']);
98
+ // Hook fired when a new blog is activated on WP Multisite
99
+ add_action('wpmu_new_blog', [$this, 'activate_new_site']);
100
+ // Hook fired when a blog is deleted on WP Multisite
101
+ add_filter('wpmu_drop_tables', [$this, 'delete_site_data'], 10, 2);
102
+ // At-A-Glance
103
+ add_filter('dashboard_glance_items', [$this, 'at_a_glance_stats']);
104
+ add_action('admin_head', [$this, 'at_a_glance_stats_css']);
105
+ // Dashboard Trending Now widget
106
+ //if ( current_user_can('edit_published_posts') )
107
+ add_action('wp_dashboard_setup', [$this, 'add_dashboard_widgets']);
108
+ // Load WPP's admin styles and scripts
109
+ add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']);
110
+ // Add admin screen
111
+ add_action('admin_menu', [$this, 'add_plugin_admin_menu']);
112
+ // Contextual help
113
+ add_action('admin_head', [$this, 'add_contextual_help']);
114
+ // Add plugin settings link
115
+ add_filter('plugin_action_links', [$this, 'add_plugin_settings_link'], 10, 2);
116
+ // Update chart
117
+ add_action('wp_ajax_wpp_update_chart', [$this, 'update_chart']);
118
+ // Get lists
119
+ add_action('wp_ajax_wpp_get_most_viewed', [$this, 'get_popular_items']);
120
+ add_action('wp_ajax_wpp_get_most_commented', [$this, 'get_popular_items']);
121
+ add_action('wp_ajax_wpp_get_trending', [$this, 'get_popular_items']);
122
+ // Delete plugin data
123
+ add_action('wp_ajax_wpp_clear_data', [$this, 'clear_data']);
124
+ // Empty plugin's images cache
125
+ add_action('wp_ajax_wpp_clear_thumbnail', [$this, 'clear_thumbnails']);
126
+ // Flush cached thumbnail on featured image change/deletion
127
+ add_action('updated_post_meta', [$this, 'updated_post_meta'], 10, 4);
128
+ add_action('deleted_post_meta', [$this, 'deleted_post_meta'], 10, 4);
129
+ // Purge post data on post/page deletion
130
+ add_action('admin_init', [$this, 'purge_post_data']);
131
+ // Purge old data on demand
132
+ add_action('wpp_cache_event', [$this, 'purge_data']);
133
+ // Maybe performance nag
134
+ add_action('wpp_maybe_performance_nag', [$this, 'performance_check']);
135
+ // Show notices
136
+ add_action('admin_notices', [$this, 'notices']);
137
+ }
138
+
139
+ /**
140
+ * Checks if an upgrade procedure is required.
141
+ *
142
+ * @since 2.4.0
143
+ */
144
+ public function upgrade_check()
145
+ {
146
+ $this->upgrade_site();
147
+ }
148
+
149
+ /**
150
+ * Checks whether a performance tweak may be necessary.
151
+ *
152
+ * @since 5.0.2
153
+ */
154
+ public function performance_check()
155
+ {
156
+ $performance_nag = get_option('wpp_performance_nag');
157
+
158
+ if ( ! $performance_nag ) {
159
+ $performance_nag = [
160
+ 'status' => 0,
161
+ 'last_checked' => null
162
+ ];
163
+ add_option('wpp_performance_nag', $performance_nag);
164
+ }
165
+
166
+ if ( 3 != $performance_nag['status'] ) { // 0 = inactive, 1 = active, 2 = remind me later, 3 = dismissed
167
+ global $wpdb;
168
+
169
+ $views_count = $wpdb->get_var(
170
+ $wpdb->prepare(
171
+ "SELECT IFNULL(SUM(pageviews), 0) AS views FROM {$wpdb->prefix}popularpostssummary WHERE view_datetime > DATE_SUB(%s, INTERVAL 1 HOUR);",
172
+ Helper::now()
173
+ )
174
+ );
175
+
176
+ // This site is probably a mid/high traffic one,
177
+ // display performance nag
178
+ if ( $views_count >= 420 ) {
179
+ if ( 0 == $performance_nag['status'] ) {
180
+ $performance_nag['status'] = 1;
181
+ $performance_nag['last_checked'] = Helper::timestamp();
182
+ update_option('wpp_performance_nag', $performance_nag);
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Upgrades single site.
190
+ *
191
+ * @since 4.0.7
192
+ */
193
+ private function upgrade_site()
194
+ {
195
+ // Get WPP version
196
+ $wpp_ver = get_option('wpp_ver');
197
+
198
+ if ( ! $wpp_ver ) {
199
+ add_option('wpp_ver', WPP_VERSION);
200
+ } elseif ( version_compare($wpp_ver, WPP_VERSION, '<') ) {
201
+ $this->upgrade();
202
+ }
203
+ }
204
+
205
+ /**
206
+ * On plugin upgrade, performs a number of actions: update WPP database tables structures (if needed),
207
+ * run the setup wizard (if needed), and some other checks.
208
+ *
209
+ * @since 2.4.0
210
+ * @access private
211
+ * @global object $wpdb
212
+ */
213
+ private function upgrade()
214
+ {
215
+ $now = Helper::now();
216
+
217
+ // Keep the upgrade process from running too many times
218
+ if ( $wpp_update = get_option('wpp_update') ) {
219
+ $from_time = strtotime($wpp_update);
220
+ $to_time = strtotime($now);
221
+ $difference_in_minutes = round(abs($to_time - $from_time)/60, 2);
222
+
223
+ // Upgrade flag is still valid, abort
224
+ if ( $difference_in_minutes <= 15 )
225
+ return;
226
+ // Upgrade flag expired, delete it and continue
227
+ delete_option('wpp_update');
228
+ }
229
+
230
+ global $wpdb;
231
+
232
+ // Upgrade flag
233
+ add_option('wpp_update', $now);
234
+
235
+ // Set table name
236
+ $prefix = $wpdb->prefix . "popularposts";
237
+
238
+ // Update data table structure and indexes
239
+ $dataFields = $wpdb->get_results("SHOW FIELDS FROM {$prefix}data;");
240
+
241
+ foreach ( $dataFields as $column ) {
242
+ if ( "day" == $column->Field ) {
243
+ $wpdb->query("ALTER TABLE {$prefix}data ALTER COLUMN day DROP DEFAULT;");
244
+ }
245
+
246
+ if ( "last_viewed" == $column->Field ) {
247
+ $wpdb->query("ALTER TABLE {$prefix}data ALTER COLUMN last_viewed DROP DEFAULT;");
248
+ }
249
+ }
250
+
251
+ // Update summary table structure and indexes
252
+ $summaryFields = $wpdb->get_results("SHOW FIELDS FROM {$prefix}summary;");
253
+
254
+ foreach ( $summaryFields as $column ) {
255
+ if ( "last_viewed" == $column->Field ) {
256
+ $wpdb->query("ALTER TABLE {$prefix}summary CHANGE last_viewed view_datetime datetime NOT NULL, ADD KEY view_datetime (view_datetime);");
257
+ }
258
+
259
+ if ( "view_date" == $column->Field ) {
260
+ $wpdb->query("ALTER TABLE {$prefix}summary ALTER COLUMN view_date DROP DEFAULT;");
261
+ }
262
+
263
+ if ( "view_datetime" == $column->Field ) {
264
+ $wpdb->query("ALTER TABLE {$prefix}summary ALTER COLUMN view_datetime DROP DEFAULT;");
265
+ }
266
+ }
267
+
268
+ $summaryIndexes = $wpdb->get_results("SHOW INDEX FROM {$prefix}summary;");
269
+
270
+ foreach( $summaryIndexes as $index ) {
271
+ if ( 'ID_date' == $index->Key_name ) {
272
+ $wpdb->query("ALTER TABLE {$prefix}summary DROP INDEX ID_date;");
273
+ }
274
+
275
+ if ( 'last_viewed' == $index->Key_name ) {
276
+ $wpdb->query("ALTER TABLE {$prefix}summary DROP INDEX last_viewed;");
277
+ }
278
+ }
279
+
280
+ // Validate the structure of the tables, create missing tables / fields if necessary
281
+ \WordPressPopularPosts\Activation\Activator::track_new_site();
282
+
283
+ // Check storage engine
284
+ $storage_engine_data = $wpdb->get_var("SELECT `ENGINE` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`='{$wpdb->dbname}' AND `TABLE_NAME`='{$prefix}data';");
285
+
286
+ if ( 'InnoDB' != $storage_engine_data ) {
287
+ $wpdb->query("ALTER TABLE {$prefix}data ENGINE=InnoDB;");
288
+ }
289
+
290
+ $storage_engine_summary = $wpdb->get_var("SELECT `ENGINE` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`='{$wpdb->dbname}' AND `TABLE_NAME`='{$prefix}summary';");
291
+
292
+ if ( 'InnoDB' != $storage_engine_summary ) {
293
+ $wpdb->query("ALTER TABLE {$prefix}summary ENGINE=InnoDB;");
294
+ }
295
+
296
+ // Update WPP version
297
+ update_option('wpp_ver', WPP_VERSION);
298
+ // Remove upgrade flag
299
+ delete_option('wpp_update');
300
+ }
301
+
302
+ /**
303
+ * Fired when a new blog is activated on WP Multisite.
304
+ *
305
+ * @since 3.0.0
306
+ * @param int $blog_id New blog ID
307
+ */
308
+ public function activate_new_site($blog_id)
309
+ {
310
+ if ( 1 !== did_action('wpmu_new_blog') )
311
+ return;
312
+
313
+ // run activation for the new blog
314
+ switch_to_blog($blog_id);
315
+ \WordPressPopularPosts\Activation\Activator::track_new_site();
316
+ // switch back to current blog
317
+ restore_current_blog();
318
+ }
319
+
320
+ /**
321
+ * Fired when a blog is deleted on WP Multisite.
322
+ *
323
+ * @since 4.0.0
324
+ * @param array $tables
325
+ * @param int $blog_id
326
+ * @return array
327
+ */
328
+ public function delete_site_data($tables, $blog_id)
329
+ {
330
+ global $wpdb;
331
+
332
+ $tables[] = $wpdb->prefix . 'popularpostsdata';
333
+ $tables[] = $wpdb->prefix . 'popularpostssummary';
334
+
335
+ return $tables;
336
+ }
337
+
338
+ /**
339
+ * Display some statistics at the "At a Glance" box from the Dashboard.
340
+ *
341
+ * @since 4.1.0
342
+ */
343
+ public function at_a_glance_stats()
344
+ {
345
+ global $wpdb;
346
+
347
+ $glances = [];
348
+ $args = ['post', 'page'];
349
+ $post_type_placeholders = '%s, %s';
350
+
351
+ if (
352
+ isset($this->config['stats']['post_type'])
353
+ && ! empty($this->config['stats']['post_type'])
354
+ ) {
355
+ $args = array_map('trim', explode(',', $this->config['stats']['post_type']));
356
+ $post_type_placeholders = implode(', ', array_fill(0, count($args), '%s'));
357
+ }
358
+
359
+ $args[] = Helper::now();
360
+
361
+ $query = $wpdb->prepare(
362
+ "SELECT SUM(pageviews) AS total
363
+ FROM `{$wpdb->prefix}popularpostssummary` v LEFT JOIN `{$wpdb->prefix}posts` p ON v.postid = p.ID
364
+ WHERE p.post_type IN({$post_type_placeholders}) AND p.post_status = 'publish' AND p.post_password = '' AND v.view_datetime > DATE_SUB(%s, INTERVAL 1 HOUR);"
365
+ , $args
366
+ );
367
+
368
+ $total_views = $wpdb->get_var($query);
369
+
370
+ $pageviews = sprintf(
371
+ _n('%s view in the last hour', '%s views in the last hour', $total_views, 'wordpress-popular-posts'),
372
+ number_format_i18n($total_views)
373
+ );
374
+
375
+ if ( current_user_can('edit_published_posts') ) {
376
+ $glances[] = '<a class="wpp-views-count" href="' . admin_url('options-general.php?page=wordpress-popular-posts') . '">' . $pageviews . '</a>';
377
+ }
378
+ else {
379
+ $glances[] = '<span class="wpp-views-count">' . $pageviews . '</a>';
380
+ }
381
+
382
+ return $glances;
383
+ }
384
+
385
+ /**
386
+ * Add custom inline CSS styles for At a Glance stats.
387
+ *
388
+ * @since 4.1.0
389
+ */
390
+ public function at_a_glance_stats_css()
391
+ {
392
+ echo '<style>#dashboard_right_now a.wpp-views-count:before, #dashboard_right_now span.wpp-views-count:before {content: "\f177";}</style>';
393
+ }
394
+
395
+ /**
396
+ * Adds a widget to the dashboard.
397
+ *
398
+ * @since 5.0.0
399
+ */
400
+ public function add_dashboard_widgets()
401
+ {
402
+ if ( current_user_can('edit_published_posts') ) {
403
+ wp_add_dashboard_widget(
404
+ 'wpp_trending_dashboard_widget',
405
+ __('Trending now', 'wordpress-popular-posts'),
406
+ [$this, 'trending_dashboard_widget']
407
+ );
408
+ }
409
+ }
410
+
411
+ /**
412
+ * Outputs the contents of our Trending Dashboard Widget.
413
+ *
414
+ * @since 5.0.0
415
+ */
416
+ function trending_dashboard_widget()
417
+ {
418
+ ?>
419
+ <style>
420
+ #wpp_trending_dashboard_widget .inside {
421
+ overflow: hidden;
422
+ position: relative;
423
+ min-height: 150px;
424
+ padding-bottom: 22px;
425
+ }
426
+
427
+ #wpp_trending_dashboard_widget .inside::after {
428
+ position: absolute;
429
+ top: 0;
430
+ left: 0;
431
+ opacity: 0.2;
432
+ display: block;
433
+ content: '';
434
+ width: 100%;
435
+ height: 100%;
436
+ z-index: 1;
437
+ background-image: url('<?php echo plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/images/flame.png'; ?>');
438
+ background-position: right bottom;
439
+ background-repeat: no-repeat;
440
+ background-size: 34% auto;
441
+ }
442
+
443
+ #wpp_trending_dashboard_widget .inside .no-data {
444
+ position: absolute;
445
+ top: calc(50% - 11px);
446
+ left: 50%;
447
+ z-index: 2;
448
+ margin: 0;
449
+ padding: 0;
450
+ width: 96%;
451
+ transform: translate(-50.0001%, -50.0001%);
452
+ }
453
+
454
+ #wpp_trending_dashboard_widget .inside .popular-posts-list,
455
+ #wpp_trending_dashboard_widget .inside p#wpp_read_more {
456
+ position: relative;
457
+ z-index: 2;
458
+ }
459
+
460
+ #wpp_trending_dashboard_widget .inside .popular-posts-list {
461
+ margin: 1em 0;
462
+ }
463
+
464
+ #wpp_trending_dashboard_widget .inside p#wpp_read_more {
465
+ position: absolute;
466
+ left: 0;
467
+ bottom: 0;
468
+ width: 100%;
469
+ text-align: center;
470
+ }
471
+ </style>
472
+ <?php
473
+ $args = [
474
+ 'range' => 'custom',
475
+ 'time_quantity' => 1,
476
+ 'time_unit' => 'HOUR',
477
+ 'post_type' => $this->config['stats']['post_type'],
478
+ 'limit' => 5,
479
+ 'stats_tag' => [
480
+ 'views' => 1,
481
+ 'comment_count' => 1
482
+ ]
483
+ ];
484
+ $options = apply_filters('wpp_trending_dashboard_widget_args', []);
485
+
486
+ if ( is_array($options) && ! empty($options) )
487
+ $args = Helper::merge_array_r($args, $options);
488
+
489
+ $trending = new Query($args);
490
+ $posts = $trending->get_posts();
491
+
492
+ $this->render_list($posts, 'trending');
493
+ echo '<p id="wpp_read_more"><a href="' . admin_url('options-general.php?page=wordpress-popular-posts') . '">' . __('View more', 'wordpress-popular-posts') . '</a><p>';
494
+
495
+ }
496
+
497
+ /**
498
+ * Enqueues admin facing assets.
499
+ *
500
+ * @since 5.0.0
501
+ */
502
+ public function enqueue_assets()
503
+ {
504
+ $screen = get_current_screen();
505
+
506
+ if ( isset($screen->id) ) {
507
+ if ( $screen->id == $this->screen_hook_suffix ) {
508
+ wp_enqueue_style('wpp-datepicker-theme', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/css/datepicker.css', [], WPP_VERSION, 'all');
509
+
510
+ wp_enqueue_media();
511
+ wp_enqueue_script('jquery-ui-datepicker');
512
+ wp_enqueue_script('chartjs', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/js/vendor/Chart.min.js', [], WPP_VERSION);
513
+
514
+ wp_register_script('wpp-chart', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/js/chart.js', ['chartjs'], WPP_VERSION);
515
+ wp_localize_script('wpp-chart', 'wpp_chart_params', [
516
+ 'colors' => $this->get_admin_color_scheme()
517
+ ]);
518
+ wp_enqueue_script('wpp-chart');
519
+
520
+ wp_register_script('wordpress-popular-posts-admin-script', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/js/admin.js', ['jquery'], WPP_VERSION, true);
521
+ wp_localize_script('wordpress-popular-posts-admin-script', 'wpp_admin_params', [
522
+ 'label_media_upload_button' => __("Use this image", "wordpress-popular-posts"),
523
+ 'nonce' => wp_create_nonce("wpp_admin_nonce")
524
+ ]);
525
+ wp_enqueue_script('wordpress-popular-posts-admin-script');
526
+ }
527
+
528
+ if ( $screen->id == $this->screen_hook_suffix || 'dashboard' == $screen->id ) {
529
+ // Fontello icons
530
+ wp_enqueue_style('wpp-fontello', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/css/fontello.css', [], WPP_VERSION, 'all');
531
+ wp_enqueue_style('wordpress-popular-posts-admin-styles', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/css/admin.css', [], WPP_VERSION, 'all');
532
+ }
533
+ }
534
+ }
535
+
536
+ /**
537
+ * Register the administration menu for this plugin into the WordPress Dashboard menu.
538
+ *
539
+ * @since 1.0.0
540
+ */
541
+ public function add_plugin_admin_menu()
542
+ {
543
+ $this->screen_hook_suffix = add_options_page(
544
+ 'WordPress Popular Posts',
545
+ 'WordPress Popular Posts',
546
+ 'edit_published_posts',
547
+ 'wordpress-popular-posts',
548
+ [$this, 'display_plugin_admin_page']
549
+ );
550
+ }
551
+
552
+ /**
553
+ * Render the settings page for this plugin.
554
+ *
555
+ * @since 1.0.0
556
+ */
557
+ public function display_plugin_admin_page()
558
+ {
559
+ include_once plugin_dir_path(__FILE__) . 'admin-page.php';
560
+ }
561
+
562
+ /**
563
+ * Adds contextual help menu.
564
+ *
565
+ * @since 4.0.0
566
+ */
567
+ public function add_contextual_help()
568
+ {
569
+ $screen = get_current_screen();
570
+
571
+ if ( isset($screen->id) && $screen->id == $this->screen_hook_suffix ){
572
+ $screen->add_help_tab(
573
+ [
574
+ 'id' => 'wpp_help_overview',
575
+ 'title' => __('Overview', 'wordpress-popular-posts'),
576
+ 'content' => "<p>" . __("Welcome to WordPress Popular Posts' Dashboard! In this screen you will find statistics on what's popular on your site, tools to further tweak WPP to your needs, and more!", "wordpress-popular-posts") . "</p>"
577
+ ]
578
+ );
579
+ $screen->add_help_tab(
580
+ [
581
+ 'id' => 'wpp_help_donate',
582
+ 'title' => __('Like this plugin?', 'wordpress-popular-posts'),
583
+ 'content' => '
584
+ <p style="text-align: center;">' . __('Each donation motivates me to keep releasing free stuff for the WordPress community!', 'wordpress-popular-posts') . '</p>
585
+ <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" style="margin: 0; padding: 0; text-align: center;">
586
+ <input type="hidden" name="cmd" value="_s-xclick">
587
+ <input type="hidden" name="hosted_button_id" value="RP9SK8KVQHRKS">
588
+ <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" style="display: inline; margin: 0;">
589
+ <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
590
+ </form>
591
+ <p style="text-align: center;">' . sprintf(__('You can <a href="%s" target="_blank">leave a review</a>, too!', 'wordpress-popular-posts'), 'https://wordpress.org/support/view/plugin-reviews/wordpress-popular-posts?rate=5#postform') . '</p>'
592
+ ]
593
+ );
594
+
595
+ // Help sidebar
596
+ $screen->set_help_sidebar(
597
+ sprintf(
598
+ __('<p><strong>For more information:</strong></p><ul><li><a href="%1$s">Documentation</a></li><li><a href="%2$s">Support</a></li></ul>', 'wordpress-popular-posts'),
599
+ "https://github.com/cabrerahector/wordpress-popular-posts/",
600
+ "https://wordpress.org/support/plugin/wordpress-popular-posts/"
601
+ )
602
+ );
603
+ }
604
+ }
605
+
606
+ /**
607
+ * Registers Settings link on plugin description.
608
+ *
609
+ * @since 2.3.3
610
+ * @param array $links
611
+ * @param string $file
612
+ * @return array
613
+ */
614
+ public function add_plugin_settings_link($links, $file)
615
+ {
616
+ $plugin_file = 'wordpress-popular-posts/wordpress-popular-posts.php';
617
+
618
+ if (
619
+ is_plugin_active($plugin_file)
620
+ && $plugin_file == $file
621
+ ) {
622
+ array_unshift(
623
+ $links,
624
+ '<a href="' . admin_url('options-general.php?page=wordpress-popular-posts') . '">' . __('Settings') . '</a>',
625
+ '<a href="https://wordpress.org/support/plugin/wordpress-popular-posts/">' . __('Support', 'wordpress-popular-posts') . '</a>'
626
+ );
627
+ }
628
+
629
+ return $links;
630
+ }
631
+
632
+ /**
633
+ * Gets current admin color scheme.
634
+ *
635
+ * @since 4.0.0
636
+ * @return array
637
+ */
638
+ private function get_admin_color_scheme()
639
+ {
640
+ global $_wp_admin_css_colors;
641
+
642
+ if (
643
+ is_array($_wp_admin_css_colors)
644
+ && count($_wp_admin_css_colors)
645
+ ) {
646
+ $current_user = wp_get_current_user();
647
+ $color_scheme = get_user_option('admin_color', $current_user->ID);
648
+
649
+ if (
650
+ empty($color_scheme)
651
+ || ! isset($_wp_admin_css_colors[ $color_scheme])
652
+ ) {
653
+ $color_scheme = 'fresh';
654
+ }
655
+
656
+ if ( isset($_wp_admin_css_colors[$color_scheme]) && isset($_wp_admin_css_colors[$color_scheme]->colors) ) {
657
+ return $_wp_admin_css_colors[$color_scheme]->colors;
658
+ }
659
+
660
+ }
661
+
662
+ // Fallback, just in case
663
+ return ['#333', '#999', '#881111', '#a80000'];
664
+ }
665
+
666
+ /**
667
+ * Fetches chart data.
668
+ *
669
+ * @since 4.0.0
670
+ * @return string
671
+ */
672
+ public function get_chart_data($range = 'last7days', $time_unit = 'HOUR', $time_quantity = 24)
673
+ {
674
+ $dates = $this->get_dates($range, $time_unit, $time_quantity);
675
+ $start_date = $dates[0];
676
+ $end_date = $dates[count($dates) - 1];
677
+ $date_range = Helper::get_date_range($start_date, $end_date, 'Y-m-d H:i:s');
678
+ $views_data = $this->get_range_item_count($start_date, $end_date, 'views');
679
+ $views = [];
680
+ $comments_data = $this->get_range_item_count($start_date, $end_date, 'comments');
681
+ $comments = [];
682
+
683
+ if ( 'today' != $range ) {
684
+ foreach($date_range as $date) {
685
+ $key = date('Y-m-d', strtotime($date));
686
+ $views[] = ( ! isset($views_data[$key]) ) ? 0 : $views_data[$key]->pageviews;
687
+ $comments[] = ( ! isset($comments_data[$key]) ) ? 0 : $comments_data[$key]->comments;
688
+ }
689
+ } else {
690
+ $key = date('Y-m-d', strtotime($dates[0]));
691
+ $views[] = ( ! isset($views_data[$key]) ) ? 0 : $views_data[$key]->pageviews;
692
+ $comments[] = ( ! isset($comments_data[$key]) ) ? 0 : $comments_data[$key]->comments;
693
+ }
694
+
695
+ if ( $start_date != $end_date )
696
+ $label_date_range = date_i18n('M, D d', strtotime($start_date)) . ' &mdash; ' . date_i18n('M, D d', strtotime($end_date));
697
+ else
698
+ $label_date_range = date_i18n('M, D d', strtotime($start_date));
699
+
700
+ $total_views = array_sum($views);
701
+ $total_comments = array_sum($comments);
702
+
703
+ $label_summary = sprintf(_n('%s view', '%s views', $total_views, 'wordpress-popular-posts'), '<strong>' . number_format_i18n($total_views) . '</strong>') . '<br style="display: none;" /> / ' . sprintf(_n('%s comment', '%s comments', $total_comments, 'wordpress-popular-posts'), '<strong>' . number_format_i18n($total_comments) . '</strong>');
704
+
705
+ // Format labels
706
+ if ( 'today' != $range ) {
707
+ $date_range = array_map(function($d){
708
+ return date_i18n('D d', strtotime($d));
709
+ }, $date_range);
710
+ } else {
711
+ $date_range = [date_i18n('D d', strtotime($date_range[0]))];
712
+ $comments = [array_sum($comments)];
713
+ $views = [array_sum($views)];
714
+ }
715
+
716
+ $response = [
717
+ 'totals' => [
718
+ 'label_summary' => $label_summary,
719
+ 'label_date_range' => $label_date_range,
720
+ ],
721
+ 'labels' => $date_range,
722
+ 'datasets' => [
723
+ [
724
+ 'label' => __("Comments", "wordpress-popular-posts"),
725
+ 'data' => $comments
726
+ ],
727
+ [
728
+ 'label' => __("Views", "wordpress-popular-posts"),
729
+ 'data' => $views
730
+ ]
731
+ ]
732
+ ];
733
+
734
+ return json_encode($response);
735
+ }
736
+
737
+ /**
738
+ * Returns an array of dates.
739
+ *
740
+ * @since 5.0.0
741
+ * @return array|bool
742
+ */
743
+ private function get_dates($range = 'last7days', $time_unit = 'HOUR', $time_quantity = 24)
744
+ {
745
+ $valid_ranges = ['today', 'daily', 'last24hours', 'weekly', 'last7days', 'monthly', 'last30days', 'all', 'custom'];
746
+ $range = in_array($range, $valid_ranges) ? $range : 'last7days';
747
+ $now = new \DateTime(Helper::now(), new \DateTimeZone(Helper::get_timezone()));
748
+
749
+ // Determine time range
750
+ switch( $range ){
751
+ case "last24hours":
752
+ case "daily":
753
+ $end_date = $now->format('Y-m-d H:i:s');
754
+ $start_date = $now->modify('-1 day')->format('Y-m-d H:i:s');
755
+ break;
756
+
757
+ case "today":
758
+ $start_date = $now->format('Y-m-d') . ' 00:00:00';
759
+ $end_date = $now->format('Y-m-d') . ' 23:59:59';
760
+ break;
761
+
762
+ case "last7days":
763
+ case "weekly":
764
+ $end_date = $now->format('Y-m-d') . ' 23:59:59';
765
+ $start_date = $now->modify('-6 day')->format('Y-m-d') . ' 00:00:00';
766
+ break;
767
+
768
+ case "last30days":
769
+ case "monthly":
770
+ $end_date = $now->format('Y-m-d') . ' 23:59:59';
771
+ $start_date = $now->modify('-29 day')->format('Y-m-d') . ' 00:00:00';
772
+ break;
773
+
774
+ case "custom":
775
+ $end_date = $now->format('Y-m-d H:i:s');
776
+
777
+ if (
778
+ Helper::is_number($time_quantity)
779
+ && $time_quantity >= 1
780
+ ) {
781
+ $end_date = $now->format('Y-m-d H:i:s');
782
+ $time_unit = strtoupper($time_unit);
783
+
784
+ if ( 'MINUTE' == $time_unit ) {
785
+ $start_date = $now->sub(new \DateInterval('PT' . (60 * $time_quantity) . 'S'))->format('Y-m-d H:i:s');
786
+ } elseif ( 'HOUR' == $time_unit ) {
787
+ $start_date = $now->sub(new \DateInterval('PT' . ((60 * $time_quantity) - 1) . 'M59S'))->format('Y-m-d H:i:s');
788
+ } else {
789
+ $end_date = $now->format('Y-m-d') . ' 23:59:59';
790
+ $start_date = $now->sub(new \DateInterval('P' . ($time_quantity - 1) . 'D'))->format('Y-m-d') . ' 00:00:00';
791
+ }
792
+ } // fallback to last 24 hours
793
+ else {
794
+ $start_date = $now->modify('-1 day')->format('Y-m-d H:i:s');
795
+ }
796
+
797
+ // Check if custom date range has been requested
798
+ $dates = null;
799
+
800
+ if ( isset($_GET['dates']) ) {
801
+ $dates = explode(" ~ ", $_GET['dates']);
802
+
803
+ if (
804
+ ! is_array($dates)
805
+ || empty($dates)
806
+ || ! Helper::is_valid_date($dates[0])
807
+ ) {
808
+ $dates = null;
809
+ } else {
810
+ if (
811
+ ! isset($dates[1])
812
+ || ! Helper::is_valid_date($dates[1])
813
+ ) {
814
+ $dates[1] = $dates[0];
815
+ }
816
+
817
+ $start_date = $dates[0] . ' 00:00:00';
818
+ $end_date = $dates[1] . ' 23:59:59';
819
+ }
820
+ }
821
+
822
+ break;
823
+
824
+ default:
825
+ $end_date = $now->format('Y-m-d') . ' 23:59:59';
826
+ $start_date = $now->modify('-6 day')->format('Y-m-d') . ' 00:00:00';
827
+ break;
828
+ }
829
+
830
+ return [$start_date, $end_date];
831
+ }
832
+
833
+ /**
834
+ * Returns an array of dates with views/comments count.
835
+ *
836
+ * @since 5.0.0
837
+ * @param string $start_date
838
+ * @param string $end_date
839
+ * @param string $item
840
+ * @return array
841
+ */
842
+ public function get_range_item_count($start_date, $end_date, $item = 'views')
843
+ {
844
+ global $wpdb;
845
+
846
+ $args = array_map('trim', explode(',', $this->config['stats']['post_type']));
847
+
848
+ if ( empty($args) ) {
849
+ $args = ['post', 'page'];
850
+ }
851
+
852
+ $post_type_placeholders = array_fill(0, count($args), '%s');
853
+
854
+ if ( $this->config['stats']['freshness'] ) {
855
+ $args[] = $start_date;
856
+ }
857
+
858
+ // Append dates to arguments list
859
+ array_unshift($args, $start_date, $end_date);
860
+
861
+ if ( $item == 'comments' ) {
862
+ $query = $wpdb->prepare(
863
+ "SELECT DATE(`c`.`comment_date_gmt`) AS `c_date`, COUNT(*) AS `comments`
864
+ FROM `{$wpdb->comments}` c INNER JOIN `{$wpdb->posts}` p ON `c`.`comment_post_ID` = `p`.`ID`
865
+ WHERE (`c`.`comment_date_gmt` BETWEEN %s AND %s) AND `c`.`comment_approved` = '1' AND `p`.`post_type` IN (". implode(", ", $post_type_placeholders) . ") AND `p`.`post_status` = 'publish' AND `p`.`post_password` = ''
866
+ " . ( $this->config['stats']['freshness'] ? " AND `p`.`post_date` >= %s" : "" ) . "
867
+ GROUP BY `c_date` ORDER BY `c_date` DESC;",
868
+ $args
869
+ );
870
+ } else {
871
+ $query = $wpdb->prepare(
872
+ "SELECT `v`.`view_date`, SUM(`v`.`pageviews`) AS `pageviews`
873
+ FROM `{$wpdb->prefix}popularpostssummary` v INNER JOIN `{$wpdb->posts}` p ON `v`.`postid` = `p`.`ID`
874
+ WHERE (`v`.`view_datetime` BETWEEN %s AND %s) AND `p`.`post_type` IN (". implode(", ", $post_type_placeholders) . ") AND `p`.`post_status` = 'publish' AND `p`.`post_password` = ''
875
+ " . ( $this->config['stats']['freshness'] ? " AND `p`.`post_date` >= %s" : "" ) . "
876
+ GROUP BY `v`.`view_date` ORDER BY `v`.`view_date` DESC;",
877
+ $args
878
+ );
879
+
880
+ //error_log($query);
881
+ }
882
+
883
+ return $wpdb->get_results($query, OBJECT_K);
884
+ }
885
+
886
+ /**
887
+ * Updates chart via AJAX.
888
+ *
889
+ * @since 4.0.0
890
+ */
891
+ public function update_chart()
892
+ {
893
+ $response = [
894
+ 'status' => 'error'
895
+ ];
896
+ $nonce = isset($_GET['nonce']) ? $_GET['nonce'] : null;
897
+
898
+ if ( wp_verify_nonce($nonce, 'wpp_admin_nonce') ) {
899
+
900
+ $valid_ranges = ['today', 'daily', 'last24hours', 'weekly', 'last7days', 'monthly', 'last30days', 'all', 'custom'];
901
+ $time_units = ["MINUTE", "HOUR", "DAY"];
902
+
903
+ $range = ( isset($_GET['range']) && in_array($_GET['range'], $valid_ranges) ) ? $_GET['range'] : 'last7days';
904
+ $time_quantity = ( isset($_GET['time_quantity']) && filter_var($_GET['time_quantity'], FILTER_VALIDATE_INT) ) ? $_GET['time_quantity'] : 24;
905
+ $time_unit = ( isset($_GET['time_unit']) && in_array(strtoupper($_GET['time_unit']), $time_units) ) ? $_GET['time_unit'] : 'hour';
906
+
907
+ $this->config['stats']['range'] = $range;
908
+ $this->config['stats']['time_quantity'] = $time_quantity;
909
+ $this->config['stats']['time_unit'] = $time_unit;
910
+
911
+ update_option('wpp_settings_config', $this->config);
912
+
913
+ $response = [
914
+ 'status' => 'ok',
915
+ 'data' => json_decode(
916
+ $this->get_chart_data($this->config['stats']['range'], $this->config['stats']['time_unit'], $this->config['stats']['time_quantity']),
917
+ true
918
+ )
919
+ ];
920
+ }
921
+
922
+ wp_send_json($response);
923
+ }
924
+
925
+ /**
926
+ * Fetches most viewed/commented/trending posts via AJAX.
927
+ *
928
+ * @since 5.0.0
929
+ */
930
+ public function get_popular_items()
931
+ {
932
+ $items = isset($_GET['items']) ? $_GET['items'] : null;
933
+ $nonce = isset($_GET['nonce']) ? $_GET['nonce'] : null;
934
+
935
+ if ( wp_verify_nonce($nonce, 'wpp_admin_nonce') ) {
936
+ $args = [
937
+ 'range' => $this->config['stats']['range'],
938
+ 'time_quantity' => $this->config['stats']['time_quantity'],
939
+ 'time_unit' => $this->config['stats']['time_unit'],
940
+ 'post_type' => $this->config['stats']['post_type'],
941
+ 'freshness' => $this->config['stats']['freshness'],
942
+ 'limit' => $this->config['stats']['limit'],
943
+ 'stats_tag' => [
944
+ 'date' => [
945
+ 'active' => 1
946
+ ]
947
+ ]
948
+ ];
949
+
950
+ if ( 'most-commented' == $items ) {
951
+ $args['order_by'] = 'comments';
952
+ $args['stats_tag']['comment_count'] = 1;
953
+ $args['stats_tag']['views'] = 0;
954
+ } elseif ( 'trending' == $items ) {
955
+ $args['range'] = 'custom';
956
+ $args['time_quantity'] = 1;
957
+ $args['time_unit'] = 'HOUR';
958
+ $args['stats_tag']['comment_count'] = 1;
959
+ $args['stats_tag']['views'] = 1;
960
+ } else {
961
+ $args['stats_tag']['comment_count'] = 0;
962
+ $args['stats_tag']['views'] = 1;
963
+ }
964
+
965
+ if ( 'trending' != $items ) {
966
+
967
+ add_filter('wpp_query_join', function($join, $options) use ($items)
968
+ {
969
+ global $wpdb;
970
+ $dates = null;
971
+
972
+ if ( isset($_GET['dates']) ) {
973
+ $dates = explode(" ~ ", $_GET['dates']);
974
+
975
+ if (
976
+ ! is_array($dates)
977
+ || empty($dates)
978
+ || ! Helper::is_valid_date($dates[0])
979
+ ) {
980
+ $dates = null;
981
+ } else {
982
+ if (
983
+ ! isset($dates[1])
984
+ || ! Helper::is_valid_date($dates[1])
985
+ ) {
986
+ $dates[1] = $dates[0];
987
+ }
988
+
989
+ $start_date = $dates[0];
990
+ $end_date = $dates[1];
991
+ }
992
+
993
+ }
994
+
995
+ if ( $dates ) {
996
+ if ( 'most-commented' == $items ) {
997
+ return "INNER JOIN (SELECT comment_post_ID, COUNT(comment_post_ID) AS comment_count, comment_date_gmt FROM `{$wpdb->comments}` WHERE comment_date_gmt BETWEEN '{$dates[0]} 00:00:00' AND '{$dates[1]} 23:59:59' AND comment_approved = '1' GROUP BY comment_post_ID) c ON p.ID = c.comment_post_ID";
998
+ }
999
+
1000
+ return "INNER JOIN (SELECT SUM(pageviews) AS pageviews, view_date, postid FROM `{$wpdb->prefix}popularpostssummary` WHERE view_datetime BETWEEN '{$dates[0]} 00:00:00' AND '{$dates[1]} 23:59:59' GROUP BY postid) v ON p.ID = v.postid";
1001
+ }
1002
+
1003
+ $now = Helper::now();
1004
+
1005
+ // Determine time range
1006
+ switch( $options['range'] ){
1007
+ case "last24hours":
1008
+ case "daily":
1009
+ $interval = "24 HOUR";
1010
+ break;
1011
+
1012
+ case "today":
1013
+ $hours = date('H', strtotime($now));
1014
+ $minutes = $hours * 60 + (int) date( 'i', strtotime($now) );
1015
+ $interval = "{$minutes} MINUTE";
1016
+ break;
1017
+
1018
+ case "last7days":
1019
+ case "weekly":
1020
+ $interval = "6 DAY";
1021
+ break;
1022
+
1023
+ case "last30days":
1024
+ case "monthly":
1025
+ $interval = "29 DAY";
1026
+ break;
1027
+
1028
+ case "custom":
1029
+ $time_units = ["MINUTE", "HOUR", "DAY"];
1030
+ $interval = "24 HOUR";
1031
+
1032
+ // Valid time unit
1033
+ if (
1034
+ isset($options['time_unit'])
1035
+ && in_array(strtoupper($options['time_unit']), $time_units)
1036
+ && isset($options['time_quantity'])
1037
+ && filter_var($options['time_quantity'], FILTER_VALIDATE_INT)
1038
+ && $options['time_quantity'] > 0
1039
+ ) {
1040
+ $interval = "{$options['time_quantity']} " . strtoupper($options['time_unit']);
1041
+ }
1042
+
1043
+ break;
1044
+
1045
+ default:
1046
+ $interval = "1 DAY";
1047
+ break;
1048
+ }
1049
+
1050
+ if ( 'most-commented' == $items ) {
1051
+ return "INNER JOIN (SELECT comment_post_ID, COUNT(comment_post_ID) AS comment_count, comment_date_gmt FROM `{$wpdb->comments}` WHERE comment_date_gmt > DATE_SUB('{$now}', INTERVAL {$interval}) AND comment_approved = '1' GROUP BY comment_post_ID) c ON p.ID = c.comment_post_ID";
1052
+ }
1053
+
1054
+ return "INNER JOIN (SELECT SUM(pageviews) AS pageviews, view_date, postid FROM `{$wpdb->prefix}popularpostssummary` WHERE view_datetime > DATE_SUB('{$now}', INTERVAL {$interval}) GROUP BY postid) v ON p.ID = v.postid";
1055
+ }, 1, 2);
1056
+
1057
+ }
1058
+
1059
+ $popular_items = new \WordPressPopularPosts\Query($args);
1060
+ $posts = $popular_items->get_posts();
1061
+
1062
+ if ( 'trending' != $items ) {
1063
+ remove_all_filters('wpp_query_join', 1);
1064
+ }
1065
+
1066
+ $this->render_list($posts, $items);
1067
+ }
1068
+
1069
+ wp_die();
1070
+ }
1071
+
1072
+ /**
1073
+ * Renders popular posts lists.
1074
+ *
1075
+ * @since 5.0.0
1076
+ * @param array
1077
+ */
1078
+ public function render_list($posts, $list = 'most-viewed')
1079
+ {
1080
+ if (
1081
+ is_array($posts)
1082
+ && ! empty($posts)
1083
+ ) {
1084
+ ?>
1085
+ <ol class="popular-posts-list">
1086
+ <?php
1087
+ foreach( $posts as $post ) { ?>
1088
+ <li>
1089
+ <a href="<?php echo get_permalink($post->id); ?>" class="wpp-title"><?php echo sanitize_text_field(apply_filters('the_title', $post->title, $post->id)); ?></a>
1090
+ <div>
1091
+ <?php if ( 'most-viewed' == $list ) : ?>
1092
+ <span><?php printf(_n('%s view', '%s views', $post->pageviews, 'wordpress-popular-posts' ), number_format_i18n($post->pageviews)); ?></span>
1093
+ <?php elseif ( 'most-commented' == $list ) : ?>
1094
+ <span><?php printf(_n('%s comment', '%s comments', $post->comment_count, 'wordpress-popular-posts'), number_format_i18n($post->comment_count)); ?></span>
1095
+ <?php else : ?>
1096
+ <span><?php printf(_n('%s view', '%s views', $post->pageviews, 'wordpress-popular-posts' ), number_format_i18n($post->pageviews)); ?></span>, <span><?php printf(_n('%s comment', '%s comments', $post->comment_count, 'wordpress-popular-posts'), number_format_i18n($post->comment_count)); ?></span>
1097
+ <?php endif; ?>
1098
+ <small> &mdash; <a href="<?php echo get_permalink($post->id); ?>"><?php _e("View"); ?></a><?php if ( current_user_can('edit_others_posts') ): ?> | <a href="<?php echo get_edit_post_link($post->id); ?>"><?php _e("Edit"); ?></a><?php endif; ?></small>
1099
+ </div>
1100
+ </li>
1101
+ <?php
1102
+ }
1103
+ ?>
1104
+ </ol>
1105
+ <?php
1106
+ }
1107
+ else {
1108
+ ?>
1109
+ <p class="no-data" style="text-align: center;"><?php _e("Looks like your site's activity is a little low right now. <br />Spread the word and come back later!", "wordpress-popular-posts"); ?></p>
1110
+ <?php
1111
+ }
1112
+ }
1113
+
1114
+ /**
1115
+ * Truncates data and cache on demand.
1116
+ *
1117
+ * @since 2.0.0
1118
+ * @global object $wpdb
1119
+ */
1120
+ public function clear_data()
1121
+ {
1122
+ $token = $_POST['token'];
1123
+ $clear = isset($_POST['clear']) ? $_POST['clear'] : null;
1124
+ $key = get_option("wpp_rand");
1125
+
1126
+ if (
1127
+ current_user_can('manage_options')
1128
+ && ( $token === $key )
1129
+ && $clear
1130
+ ) {
1131
+ global $wpdb;
1132
+
1133
+ // set table name
1134
+ $prefix = $wpdb->prefix . "popularposts";
1135
+
1136
+ if ( $clear == 'cache' ) {
1137
+ if ( $wpdb->get_var("SHOW TABLES LIKE '{$prefix}summary'") ) {
1138
+ $wpdb->query("TRUNCATE TABLE {$prefix}summary;");
1139
+ $this->flush_transients();
1140
+
1141
+ echo 1;
1142
+ } else {
1143
+ echo 2;
1144
+ }
1145
+ } elseif ( $clear == 'all' ) {
1146
+ if ( $wpdb->get_var("SHOW TABLES LIKE '{$prefix}data'") && $wpdb->get_var("SHOW TABLES LIKE '{$prefix}summary'") ) {
1147
+ $wpdb->query("TRUNCATE TABLE {$prefix}data;");
1148
+ $wpdb->query("TRUNCATE TABLE {$prefix}summary;");
1149
+ $this->flush_transients();
1150
+
1151
+ echo 1;
1152
+ } else {
1153
+ echo 2;
1154
+ }
1155
+ } else {
1156
+ echo 3;
1157
+ }
1158
+ } else {
1159
+ echo 4;
1160
+ }
1161
+
1162
+ wp_die();
1163
+ }
1164
+
1165
+ /**
1166
+ * Deletes cached (transient) data.
1167
+ *
1168
+ * @since 3.0.0
1169
+ * @access private
1170
+ */
1171
+ private function flush_transients()
1172
+ {
1173
+ $wpp_transients = get_option('wpp_transients');
1174
+
1175
+ if ( $wpp_transients && is_array($wpp_transients) && ! empty($wpp_transients) ) {
1176
+ for ( $t=0; $t < count($wpp_transients); $t++ )
1177
+ delete_transient($wpp_transients[$t]);
1178
+
1179
+ update_option('wpp_transients', []);
1180
+ }
1181
+ }
1182
+
1183
+ /**
1184
+ * Truncates thumbnails cache on demand.
1185
+ *
1186
+ * @since 2.0.0
1187
+ * @global object wpdb
1188
+ */
1189
+ public function clear_thumbnails()
1190
+ {
1191
+ $wpp_uploads_dir = $this->thumbnail->get_plugin_uploads_dir();
1192
+
1193
+ if ( is_array($wpp_uploads_dir) && ! empty($wpp_uploads_dir) ) {
1194
+ $token = isset($_POST['token']) ? $_POST['token'] : null;
1195
+ $key = get_option("wpp_rand");
1196
+
1197
+ if (
1198
+ current_user_can('edit_published_posts')
1199
+ && ( $token === $key )
1200
+ ) {
1201
+ if ( is_dir($wpp_uploads_dir['basedir']) ) {
1202
+ $files = glob("{$wpp_uploads_dir['basedir']}/*"); // get all related images
1203
+
1204
+ if ( is_array($files) && ! empty($files) ) {
1205
+ foreach( $files as $file ){ // iterate files
1206
+ if ( is_file($file) ) {
1207
+ @unlink($file); // delete file
1208
+ }
1209
+ }
1210
+ echo 1;
1211
+ } else {
1212
+ echo 2;
1213
+ }
1214
+ } else {
1215
+ echo 3;
1216
+ }
1217
+ } else {
1218
+ echo 4;
1219
+ }
1220
+ }
1221
+
1222
+ wp_die();
1223
+ }
1224
+
1225
+ /**
1226
+ * Fires immediately after deleting metadata of a post.
1227
+ *
1228
+ * @since 5.0.0
1229
+ *
1230
+ * @param int $meta_id Metadata ID.
1231
+ * @param int $post_id Post ID.
1232
+ * @param string $meta_key Meta key.
1233
+ * @param mixed $meta_value Meta value.
1234
+ */
1235
+ public function updated_post_meta($meta_id, $post_id, $meta_key, $meta_value)
1236
+ {
1237
+ if ( '_thumbnail_id' == $meta_key ) {
1238
+ $this->flush_post_thumbnail($post_id);
1239
+ }
1240
+ }
1241
+
1242
+ /**
1243
+ * Fires immediately after deleting metadata of a post.
1244
+ *
1245
+ * @since 5.0.0
1246
+ *
1247
+ * @param array $meta_ids An array of deleted metadata entry IDs.
1248
+ * @param int $post_id Post ID.
1249
+ * @param string $meta_key Meta key.
1250
+ * @param mixed $meta_value Meta value.
1251
+ */
1252
+ public function deleted_post_meta($meta_ids, $post_id, $meta_key, $meta_value)
1253
+ {
1254
+ if ( '_thumbnail_id' == $meta_key ) {
1255
+ $this->flush_post_thumbnail($post_id);
1256
+ }
1257
+ }
1258
+
1259
+ /**
1260
+ * Flushes post's cached thumbnail(s).
1261
+ *
1262
+ * @since 3.3.4
1263
+ *
1264
+ * @param integer $post_id Post ID
1265
+ */
1266
+ public function flush_post_thumbnail($post_id)
1267
+ {
1268
+ $wpp_uploads_dir = $this->thumbnail->get_plugin_uploads_dir();
1269
+
1270
+ if ( is_array($wpp_uploads_dir) && ! empty($wpp_uploads_dir) ) {
1271
+ $files = glob("{$wpp_uploads_dir['basedir']}/{$post_id}-*.*"); // get all related images
1272
+
1273
+ if ( is_array($files) && ! empty($files) ) {
1274
+ foreach( $files as $file ){ // iterate files
1275
+ if ( is_file($file) ) {
1276
+ @unlink($file); // delete file
1277
+ }
1278
+ }
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ /**
1284
+ * Purges post from data/summary tables.
1285
+ *
1286
+ * @since 3.3.0
1287
+ */
1288
+ public function purge_post_data()
1289
+ {
1290
+ if ( current_user_can('delete_posts') )
1291
+ add_action('delete_post', [$this, 'purge_post']);
1292
+ }
1293
+
1294
+ /**
1295
+ * Purges post from data/summary tables.
1296
+ *
1297
+ * @since 3.3.0
1298
+ * @global object $wpdb
1299
+ */
1300
+ public function purge_post($post_ID)
1301
+ {
1302
+ global $wpdb;
1303
+
1304
+ if ( $wpdb->get_var($wpdb->prepare("SELECT postid FROM {$wpdb->prefix}popularpostsdata WHERE postid = %d", $post_ID)) ) {
1305
+ // Delete from data table
1306
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}popularpostsdata WHERE postid = %d;", $post_ID));
1307
+ // Delete from summary table
1308
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->prefix}popularpostssummary WHERE postid = %d;", $post_ID));
1309
+ }
1310
+
1311
+ // Delete cached thumbnail(s) as well
1312
+ $this->flush_post_thumbnail($post_ID);
1313
+ }
1314
+
1315
+ /**
1316
+ * Purges old post data from summary table.
1317
+ *
1318
+ * @since 2.0.0
1319
+ * @global object $wpdb
1320
+ */
1321
+ public function purge_data()
1322
+ {
1323
+ global $wpdb;
1324
+ $wpdb->query("DELETE FROM {$wpdb->prefix}popularpostssummary WHERE view_date < DATE_SUB('" . Helper::curdate() . "', INTERVAL {$this->config['tools']['log']['expires_after']} DAY);");
1325
+ }
1326
+
1327
+ /**
1328
+ * Displays admin notices.
1329
+ *
1330
+ * @since 5.0.2
1331
+ */
1332
+ public function notices()
1333
+ {
1334
+ /** Performance nag */
1335
+ $performance_nag = get_option('wpp_performance_nag');
1336
+
1337
+ if (
1338
+ isset($performance_nag['status'])
1339
+ && 3 != $performance_nag['status'] // 0 = inactive, 1 = active, 2 = remind me later, 3 = dismissed
1340
+ ) {
1341
+ $now = Helper::timestamp();
1342
+
1343
+ if ( isset($_GET['wpp_dismiss_performance_notice']) || isset($_GET['wpp_remind_performance_notice']) ) {
1344
+ // User dismissed the notice
1345
+ if ( isset($_GET['wpp_dismiss_performance_notice']) ) {
1346
+ $performance_nag['status'] = 3;
1347
+ } // User asked us to remind them later
1348
+ else {
1349
+ $performance_nag['status'] = 2;
1350
+ $performance_nag['last_checked'] = $now;
1351
+ }
1352
+
1353
+ update_option('wpp_performance_nag', $performance_nag);
1354
+ echo '<script>window.location.replace("'. esc_url(remove_query_arg(['wpp_dismiss_performance_notice', 'wpp_remind_performance_notice'])) .'");</script>';
1355
+ } // Maybe display the notice
1356
+ else {
1357
+ // How much time has passed since the notice was last displayed?
1358
+ $last_checked = $performance_nag['last_checked'];
1359
+
1360
+ if ( $last_checked ) {
1361
+ $last_checked = ($now - $last_checked) / (60 * 60);
1362
+ }
1363
+
1364
+ if (
1365
+ 1 == $performance_nag['status']
1366
+ || ( 2 == $performance_nag['status'] && $last_checked && $last_checked >= 24 )
1367
+ ) {
1368
+ ?>
1369
+ <div class="notice notice-warning">
1370
+ <p><?php printf(
1371
+ __("<strong>WordPress Popular Posts:</strong> It seems your site is popular (great!) You may want to check <a href=\"%s\">these suggestions</a> to make sure your website's performance stays up to par.", 'wordpress-popular-posts'),
1372
+ 'https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance'
1373
+ ) ?></p>
1374
+ <?php if ( current_user_can('manage_options') ) : ?>
1375
+ <p><a href="<?php echo add_query_arg('wpp_dismiss_performance_notice', '1'); ?>">Dismiss</a> | <a href="<?php echo add_query_arg('wpp_remind_performance_notice', '1'); ?>">Remind me later</a></p>
1376
+ <?php endif; ?>
1377
+ </div>
1378
+ <?php
1379
+ }
1380
+ }
1381
+ }
1382
+ }
1383
+ }
src/Admin/admin-page.php CHANGED
@@ -1,952 +1,967 @@
1
- <?php
2
- if ( basename($_SERVER['SCRIPT_NAME']) == basename(__FILE__) )
3
- exit('Please do not load this page directly');
4
-
5
- $tabs = [
6
- 'stats' => __('Stats', 'wordpress-popular-posts'),
7
- 'tools' => __('Tools', 'wordpress-popular-posts'),
8
- 'params' => __('Parameters', 'wordpress-popular-posts'),
9
- 'debug' => 'Debug'
10
- ];
11
-
12
- // Set active tab
13
- if ( isset($_GET['tab'] ) && isset($tabs[$_GET['tab']] ) )
14
- $current = $_GET['tab'];
15
- else
16
- $current = 'stats';
17
-
18
- // Update options on form submission
19
- if ( isset($_POST['section']) ) {
20
-
21
- if ( "stats" == $_POST['section'] ) {
22
- $current = 'stats';
23
-
24
- if ( isset($_POST['wpp-admin-token']) && wp_verify_nonce($_POST['wpp-admin-token'], 'wpp-update-stats-options') ) {
25
- $this->config['stats']['limit'] = ( \WordPressPopularPosts\Helper::is_number($_POST['stats_limit']) && $_POST['stats_limit'] > 0 ) ? $_POST['stats_limit'] : 10;
26
- $this->config['stats']['post_type'] = empty($_POST['stats_type']) ? "post,page" : $_POST['stats_type'];
27
- $this->config['stats']['freshness'] = empty($_POST['stats_freshness']) ? false : $_POST['stats_freshness'];
28
-
29
- update_option('wpp_settings_config', $this->config);
30
- echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
31
- }
32
- }
33
- elseif ( "misc" == $_POST['section'] ) {
34
- $current = 'tools';
35
-
36
- if ( isset($_POST['wpp-admin-token'] ) && wp_verify_nonce($_POST['wpp-admin-token'], 'wpp-update-misc-options') ) {
37
- $this->config['tools']['link']['target'] = $_POST['link_target'];
38
- $this->config['tools']['css'] = $_POST['css'];
39
-
40
- update_option('wpp_settings_config', $this->config);
41
- echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
42
- }
43
- }
44
- elseif ( "thumb" == $_POST['section'] ) {
45
- $current = 'tools';
46
-
47
- if ( isset($_POST['wpp-admin-token']) && wp_verify_nonce($_POST['wpp-admin-token'], 'wpp-update-thumbnail-options') ) {
48
- if (
49
- $_POST['thumb_source'] == "custom_field"
50
- && ( ! isset($_POST['thumb_field']) || empty($_POST['thumb_field']) )
51
- ) {
52
- echo '<div id="wpp-message" class="error fade"><p>' . __('Please provide the name of your custom field.', 'wordpress-popular-posts') . '</p></div>';
53
- }
54
- else {
55
- // thumbnail settings changed, flush transients
56
- if ( $this->config['tools']['cache']['active'] ) {
57
- $this->flush_transients();
58
- }
59
-
60
- $this->config['tools']['thumbnail']['source'] = $_POST['thumb_source'];
61
- $this->config['tools']['thumbnail']['field'] = ( ! empty($_POST['thumb_field']) ) ? $_POST['thumb_field'] : "wpp_thumbnail";
62
- $this->config['tools']['thumbnail']['default'] = ( ! empty($_POST['upload_thumb_src']) ) ? $_POST['upload_thumb_src'] : "";
63
- $this->config['tools']['thumbnail']['resize'] = $_POST['thumb_field_resize'];
64
- $this->config['tools']['thumbnail']['lazyload'] = (bool) $_POST['thumb_lazy_load'];
65
-
66
- update_option('wpp_settings_config', $this->config );
67
- echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
68
- }
69
- }
70
- }
71
- elseif ( "data" == $_POST['section'] && current_user_can('manage_options') ) {
72
- $current = 'tools';
73
-
74
- if ( isset($_POST['wpp-admin-token'] ) && wp_verify_nonce($_POST['wpp-admin-token'], 'wpp-update-data-options') ) {
75
- $this->config['tools']['log']['level'] = $_POST['log_option'];
76
- $this->config['tools']['log']['limit'] = $_POST['log_limit'];
77
- $this->config['tools']['log']['expires_after'] = ( \WordPressPopularPosts\Helper::is_number($_POST['log_expire_time']) && $_POST['log_expire_time'] > 0 )
78
- ? $_POST['log_expire_time']
79
- : 180;
80
- $this->config['tools']['ajax'] = $_POST['ajax'];
81
-
82
- // if any of the caching settings was updated, destroy all transients created by the plugin
83
- if (
84
- $this->config['tools']['cache']['active'] != $_POST['cache']
85
- || $this->config['tools']['cache']['interval']['time'] != $_POST['cache_interval_time']
86
- || $this->config['tools']['cache']['interval']['value'] != $_POST['cache_interval_value']
87
- ) {
88
- $this->flush_transients();
89
- }
90
-
91
- $this->config['tools']['cache']['active'] = $_POST['cache'];
92
- $this->config['tools']['cache']['interval']['time'] = $_POST['cache_interval_time'];
93
- $this->config['tools']['cache']['interval']['value'] = ( isset($_POST['cache_interval_value']) && \WordPressPopularPosts\Helper::is_number($_POST['cache_interval_value']) && $_POST['cache_interval_value'] > 0 )
94
- ? $_POST['cache_interval_value']
95
- : 1;
96
-
97
- $this->config['tools']['sampling']['active'] = $_POST['sampling'];
98
- $this->config['tools']['sampling']['rate'] = ( isset($_POST['sample_rate']) && \WordPressPopularPosts\Helper::is_number($_POST['sample_rate']) && $_POST['sample_rate'] > 0 )
99
- ? $_POST['sample_rate']
100
- : 100;
101
-
102
- update_option('wpp_settings_config', $this->config);
103
- echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
104
- }
105
- }
106
-
107
- }
108
-
109
- $rand = md5(uniqid(rand(), true));
110
-
111
- if ( ! $wpp_rand = get_option("wpp_rand") ) {
112
- add_option("wpp_rand", $rand);
113
- } else {
114
- update_option("wpp_rand", $rand);
115
- }
116
-
117
- ?>
118
- <script type="text/javascript">
119
- // TOOLS
120
- function confirm_reset_cache() {
121
- if ( confirm("<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("This operation will delete all entries from WordPress Popular Posts' cache table and cannot be undone.", 'wordpress-popular-posts'); ?> \n\n" + "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("Do you want to continue?", 'wordpress-popular-posts'); ?>") ) {
122
- jQuery.post(
123
- ajaxurl,
124
- {
125
- action: 'wpp_clear_data',
126
- token: '<?php echo get_option("wpp_rand"); ?>',
127
- clear: 'cache'
128
- }, function(data){
129
- var response = "";
130
-
131
- switch( data ) {
132
- case "1":
133
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Success! The cache table has been cleared!', 'wordpress-popular-posts'); ?>";
134
- break;
135
-
136
- case "2":
137
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Error: cache table does not exist.', 'wordpress-popular-posts'); ?>";
138
- break;
139
-
140
- case "3":
141
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
142
- break;
143
-
144
- case "4":
145
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Sorry, you do not have enough permissions to do this. Please contact the site administrator for support.', 'wordpress-popular-posts'); ?>";
146
- break;
147
-
148
- default:
149
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
150
- break;
151
- }
152
-
153
- alert(response);
154
- }
155
- );
156
- }
157
- }
158
-
159
- function confirm_reset_all() {
160
- if ( confirm("<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("This operation will delete all stored info from WordPress Popular Posts' data tables and cannot be undone.", 'wordpress-popular-posts'); ?> \n\n" + "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("Do you want to continue?", 'wordpress-popular-posts'); ?>")) {
161
- jQuery.post(
162
- ajaxurl,
163
- {
164
- action: 'wpp_clear_data',
165
- token: '<?php echo get_option("wpp_rand"); ?>',
166
- clear: 'all'
167
- }, function(data){
168
- var response = "";
169
-
170
- switch( data ) {
171
- case "1":
172
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Success! All data have been cleared!', 'wordpress-popular-posts'); ?>";
173
- break;
174
-
175
- case "2":
176
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Error: one or both data tables are missing.', 'wordpress-popular-posts'); ?>";
177
- break;
178
-
179
- case "3":
180
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
181
- break;
182
-
183
- case "4":
184
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Sorry, you do not have enough permissions to do this. Please contact the site administrator for support.', 'wordpress-popular-posts'); ?>";
185
- break;
186
-
187
- default:
188
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
189
- break;
190
- }
191
-
192
- alert(response);
193
- }
194
- );
195
- }
196
- }
197
-
198
- function confirm_clear_image_cache() {
199
- if ( confirm("<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("This operation will delete all cached thumbnails and cannot be undone.", 'wordpress-popular-posts'); ?> \n\n" + "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("Do you want to continue?", 'wordpress-popular-posts'); ?>") ) {
200
- jQuery.post(
201
- ajaxurl,
202
- {
203
- action: 'wpp_clear_thumbnail',
204
- token: '<?php echo get_option("wpp_rand"); ?>'
205
- }, function(data){
206
- var response = "";
207
-
208
- switch( data ) {
209
- case "1":
210
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Success! All files have been deleted!', 'wordpress-popular-posts'); ?>";
211
- break;
212
-
213
- case "2":
214
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('The thumbnail cache is already empty!', 'wordpress-popular-posts'); ?>";
215
- break;
216
-
217
- case "3":
218
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
219
- break;
220
-
221
- case "4":
222
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Sorry, you do not have enough permissions to do this. Please contact the site administrator for support.', 'wordpress-popular-posts'); ?>";
223
- break;
224
-
225
- default:
226
- response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
227
- break;
228
- }
229
-
230
- alert(response);
231
- }
232
- );
233
- }
234
- }
235
- </script>
236
-
237
- <nav id="wpp-menu">
238
- <ul>
239
- <li><a href="#" title="<?php esc_attr_e('Menu'); ?>"><span><?php _e('Menu'); ?></span></a></li>
240
- <li <?php echo ('stats' == $current ) ? 'class="current"' : ''; ?>><a href="<?php echo admin_url('options-general.php?page=wordpress-popular-posts&tab=stats'); ?>" title="<?php esc_attr_e('Stats', 'wordpress-popular-posts'); ?>"><span><?php _e('Stats', 'wordpress-popular-posts'); ?></span></a></li>
241
- <li <?php echo ('tools' == $current ) ? 'class="current"' : ''; ?>><a href="<?php echo admin_url('options-general.php?page=wordpress-popular-posts&tab=tools'); ?>" title="<?php esc_attr_e('Tools', 'wordpress-popular-posts'); ?>"><span><?php _e('Tools', 'wordpress-popular-posts'); ?></span></a></li>
242
- <li <?php echo ('params' == $current ) ? 'class="current"' : ''; ?>><a href="<?php echo admin_url('options-general.php?page=wordpress-popular-posts&tab=params'); ?>" title="<?php esc_attr_e('Parameters', 'wordpress-popular-posts'); ?>"><span><?php _e('Parameters', 'wordpress-popular-posts'); ?></span></a></li>
243
- <li <?php echo ('debug' == $current ) ? 'class="current"' : ''; ?>><a href="<?php echo admin_url('options-general.php?page=wordpress-popular-posts&tab=debug'); ?>" title="Debug"><span>Debug</span></a></li>
244
- </ul>
245
- </nav>
246
-
247
- <div class="wpp-wrapper wpp-section-<?php echo $current; ?>">
248
- <div class="wpp-header">
249
- <h2>WordPress Popular Posts</h2>
250
- <h3><?php echo $tabs[$current]; ?></h3>
251
- </div>
252
-
253
- <?php
254
- // Stats chart
255
- if ( 'stats' == $current ) {
256
- $chart_data = json_decode(
257
- $this->get_chart_data($this->config['stats']['range'], strtoupper($this->config['stats']['time_unit']), $this->config['stats']['time_quantity']),
258
- true
259
- );
260
- ?>
261
-
262
- <a href="#" id="wpp-stats-config-btn" class="dashicons dashicons-admin-generic"></a>
263
-
264
- <div id="wpp-stats-config" class="wpp-lightbox">
265
- <form action="" method="post" id="wpp_stats_options" name="wpp_stats_options">
266
- <label for="stats_type"><?php _e("Post type", 'wordpress-popular-posts'); ?>:</label>
267
- <input type="text" name="stats_type" value="<?php echo esc_attr($this->config['stats']['post_type']); ?>" size="15">
268
-
269
- <label for="stats_limits"><?php _e("Limit", 'wordpress-popular-posts'); ?>:</label>
270
- <input type="text" name="stats_limit" value="<?php echo $this->config['stats']['limit']; ?>" size="5">
271
-
272
- <label for="stats_freshness"><input type="checkbox" class="checkbox" <?php echo ($this->config['stats']['freshness']) ? 'checked="checked"' : ''; ?> id="stats_freshness" name="stats_freshness"> <small><?php _e('Display only posts published within the selected Time Range', 'wordpress-popular-posts'); ?></small></label>
273
-
274
- <div class="clear"></div>
275
- <br /><br />
276
-
277
- <input type="hidden" name="section" value="stats">
278
- <button type="submit" class="button-primary action"><?php _e("Apply", 'wordpress-popular-posts'); ?></button>
279
- <button class="button-secondary action right"><?php _e("Cancel"); ?></button>
280
-
281
- <?php wp_nonce_field('wpp-update-stats-options', 'wpp-admin-token'); ?>
282
- </form>
283
- </div>
284
-
285
- <div id="wpp-stats-range" class="wpp-lightbox">
286
- <form action="" method="post">
287
- <ul class="wpp-lightbox-tabs">
288
- <li class="active"><a href="#"><?php _e('Custom Time Range', 'wordpress-popular-posts'); ?></a></li>
289
- <li><a href="#"><?php _e('Date Range', 'wordpress-popular-posts'); ?></a></li>
290
- </ul>
291
-
292
- <div class="wpp-lightbox-tab-content wpp-lightbox-tab-content-active" id="custom-time-range">
293
- <input type="text" id="stats_range_time_quantity" name="stats_range_time_quantity" value="<?php echo $this->config['stats']['time_quantity']; ?>">
294
-
295
- <select id="stats_range_time_unit" name="stats_range_time_unit">
296
- <option <?php if ($this->config['stats']['time_unit'] == "minute") { ?>selected="selected"<?php } ?> value="minute"><?php _e("Minute(s)", 'wordpress-popular-posts'); ?></option>
297
- <option <?php if ($this->config['stats']['time_unit'] == "hour") { ?>selected="selected"<?php } ?> value="hour"><?php _e("Hour(s)", 'wordpress-popular-posts'); ?></option>
298
- <option <?php if ($this->config['stats']['time_unit'] == "day") { ?>selected="selected"<?php } ?> value="day"><?php _e("Day(s)", 'wordpress-popular-posts'); ?></option>
299
- </select>
300
- </div>
301
-
302
- <div class="wpp-lightbox-tab-content" id="custom-date-range">
303
- <input type="text" id="stats_range_date" name="stats_range_date" value="" placeholder="<?php esc_attr_e('Select a date...', 'wordpress-popular-posts'); ?>" readonly>
304
- </div>
305
-
306
- <div class="clear"></div>
307
- <br />
308
-
309
- <button type="submit" class="button-primary action">
310
- <?php _e("Apply", 'wordpress-popular-posts'); ?>
311
- </button>
312
- <button class="button-secondary action right">
313
- <?php _e("Cancel"); ?>
314
- </button>
315
- </form>
316
- </div>
317
-
318
- <div id="wpp-chart-wrapper">
319
- <h4><?php echo $chart_data['totals']['label_summary']; ?></h4>
320
- <h5><?php echo $chart_data['totals']['label_date_range']; ?></h5>
321
-
322
- <ul class="wpp-header-nav" id="wpp-time-ranges">
323
- <li <?php echo ('daily' == $this->config['stats']['range'] || 'today' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="today" title="<?php esc_attr_e('Today', 'wordpress-popular-posts'); ?>"><?php _e('Today', 'wordpress-popular-posts'); ?></a></li>
324
- <li <?php echo ('daily' == $this->config['stats']['range'] || 'last24hours' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="last24hours" title="<?php esc_attr_e('Last 24 hours', 'wordpress-popular-posts'); ?>">24h</a></li>
325
- <li <?php echo ('weekly' == $this->config['stats']['range'] || 'last7days' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="last7days" title="<?php esc_attr_e('Last 7 days', 'wordpress-popular-posts'); ?>">7d</a></li>
326
- <li <?php echo ('monthly' == $this->config['stats']['range'] || 'last30days' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="last30days" title="<?php esc_attr_e('Last 30 days', 'wordpress-popular-posts'); ?>">30d</a></li>
327
- <li <?php echo ('custom' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="custom" title="<?php esc_attr_e('Custom', 'wordpress-popular-posts'); ?>"><?php _e('Custom', 'wordpress-popular-posts'); ?></a></li>
328
- </ul>
329
-
330
- <div id="wpp-chart">
331
- <p><?php echo sprintf( __('Err... A nice little chart is supposed to be here, instead you are seeing this because your browser is too old. <br /> Please <a href="%s" target="_blank">get a better browser</a>.', 'wordpress-popular-posts'), 'https://browsehappy.com/'); ?></p>
332
-
333
- <script>
334
- if ( WPPChart.canRender() ) {
335
- jQuery("#wpp-chart p").remove();
336
- WPPChart.init('wpp-chart');
337
- }
338
- </script>
339
- </div>
340
- </div>
341
- <?php
342
- } // End stats chart
343
- ?>
344
-
345
- <div id="wpp-listing" class="wpp-content"<?php echo ('stats' == $current ) ? '' : ' style="display: none;"'; ?>>
346
- <ul class="wpp-tabbed-nav">
347
- <li class="active"><a href="#" title="<?php esc_attr_e('Most viewed', 'wordpress-popular-posts'); ?>"><span class="wpp-icon-eye"></span><span><?php _e('Most viewed', 'wordpress-popular-posts'); ?></span></a></li>
348
- <li><a href="#" title="<?php esc_attr_e('Most commented', 'wordpress-popular-posts'); ?>"><span class="wpp-icon-comment"></span><span><?php _e('Most commented', 'wordpress-popular-posts'); ?></span></a></li>
349
- <li><a href="#" title="<?php esc_attr_e('Trending now', 'wordpress-popular-posts'); ?>"><span class="wpp-icon-rocket"></span><span><?php _e('Trending now', 'wordpress-popular-posts'); ?></span></a></li>
350
- <li><a href="#" title="<?php esc_attr_e('Hall of Fame', 'wordpress-popular-posts'); ?>"><span class="wpp-icon-award"></span><span><?php _e('Hall of Fame', 'wordpress-popular-posts'); ?></span></a></li>
351
- </ul>
352
-
353
- <div class="wpp-tab-content wpp-tab-content-active">
354
- <span class="spinner"></span>
355
- </div>
356
-
357
- <div class="wpp-tab-content">
358
- <span class="spinner"></span>
359
- </div>
360
-
361
- <div class="wpp-tab-content">
362
- <span class="spinner"></span>
363
- </div>
364
-
365
- <div class="wpp-tab-content">
366
- <?php
367
- $args = [
368
- 'range' => 'all',
369
- 'post_type' => $this->config['stats']['post_type'],
370
- 'order_by' => 'views',
371
- 'limit' => $this->config['stats']['limit'],
372
- 'stats_tag' => [
373
- 'comment_count' => 1,
374
- 'views' => 1,
375
- 'date' => [
376
- 'active' => 1
377
- ]
378
- ]
379
- ];
380
- $hof = new \WordPressPopularPosts\Query($args);
381
- $posts = $hof->get_posts();
382
-
383
- $this->render_list($posts, 'hof');
384
- ?>
385
- </div>
386
- </div>
387
-
388
- <!-- Start tools -->
389
- <div id="wpp_tools" <?php echo ( "tools" == $current ) ? '' : ' style="display: none;"'; ?>>
390
- <h3 class="wmpp-subtitle"><?php _e("Thumbnails", 'wordpress-popular-posts'); ?></h3>
391
-
392
- <form action="" method="post" id="wpp_thumbnail_options" name="wpp_thumbnail_options">
393
- <table class="form-table">
394
- <tbody>
395
- <tr valign="top">
396
- <th scope="row"><label for="thumb_default"><?php _e("Default thumbnail", 'wordpress-popular-posts'); ?>:</label></th>
397
- <td>
398
- <div id="thumb-review">
399
- <img src="<?php echo ($this->config['tools']['thumbnail']['default'] ) ? str_replace(parse_url($this->config['tools']['thumbnail']['default'], PHP_URL_SCHEME) . ':', '', $this->config['tools']['thumbnail']['default']) : plugins_url() . '/wordpress-popular-posts/assets/images/no_thumb.jpg'; ?>" alt="" />
400
- </div>
401
-
402
- <input id="upload_thumb_button" type="button" class="button" value="<?php _e("Change thumbnail", 'wordpress-popular-posts'); ?>">
403
- <input type="hidden" id="upload_thumb_src" name="upload_thumb_src" value="">
404
-
405
- <p class="description"><?php _e("This image will be displayed when no thumbnail is available", 'wordpress-popular-posts'); ?>.</p>
406
- </td>
407
- </tr>
408
- <tr valign="top">
409
- <th scope="row"><label for="thumb_source"><?php _e("Pick image from", 'wordpress-popular-posts'); ?>:</label></th>
410
- <td>
411
- <select name="thumb_source" id="thumb_source">
412
- <option <?php if ($this->config['tools']['thumbnail']['source'] == "featured") { ?>selected="selected"<?php } ?> value="featured"><?php _e("Featured image", 'wordpress-popular-posts'); ?></option>
413
- <option <?php if ($this->config['tools']['thumbnail']['source'] == "first_image") { ?>selected="selected"<?php } ?> value="first_image"><?php _e("First image on post", 'wordpress-popular-posts'); ?></option>
414
- <option <?php if ($this->config['tools']['thumbnail']['source'] == "first_attachment") { ?>selected="selected"<?php } ?> value="first_attachment"><?php _e("First attachment", 'wordpress-popular-posts'); ?></option>
415
- <option <?php if ($this->config['tools']['thumbnail']['source'] == "custom_field") { ?>selected="selected"<?php } ?> value="custom_field"><?php _e("Custom field", 'wordpress-popular-posts'); ?></option>
416
- </select>
417
- <br />
418
- <p class="description"><?php _e("Tell WordPress Popular Posts where it should get thumbnails from", 'wordpress-popular-posts'); ?>.</p>
419
- </td>
420
- </tr>
421
- <tr valign="top">
422
- <th scope="row"><label for="thumb_lazy_load"><?php _e("Lazy load", 'wordpress-popular-posts'); ?>:</label> <small>[<a href="https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance#lazy-loading" target="_blank" title="<?php _e('What is this?', 'wordpress-popular-posts'); ?>">?</a>]</small></th>
423
- <td>
424
- <select name="thumb_lazy_load" id="thumb_lazy_load">
425
- <option <?php if ( ! $this->config['tools']['thumbnail']['lazyload'] ) { ?>selected="selected"<?php } ?> value="0"><?php _e("No", 'wordpress-popular-posts'); ?></option>
426
- <option <?php if ( $this->config['tools']['thumbnail']['lazyload'] ) { ?>selected="selected"<?php } ?> value="1"><?php _e("Yes", 'wordpress-popular-posts'); ?></option>
427
- </select>
428
- </td>
429
- </tr>
430
- <tr valign="top" <?php if ($this->config['tools']['thumbnail']['source'] != "custom_field") { ?>style="display: none;"<?php } ?> id="row_custom_field">
431
- <th scope="row"><label for="thumb_field"><?php _e("Custom field name", 'wordpress-popular-posts'); ?>:</label></th>
432
- <td>
433
- <input type="text" id="thumb_field" name="thumb_field" value="<?php echo esc_attr($this->config['tools']['thumbnail']['field']); ?>" size="10" <?php if ($this->config['tools']['thumbnail']['source'] != "custom_field") { ?>style="display: none;"<?php } ?> />
434
- </td>
435
- </tr>
436
- <tr valign="top" <?php if ($this->config['tools']['thumbnail']['source'] != "custom_field") { ?>style="display: none;"<?php } ?> id="row_custom_field_resize">
437
- <th scope="row"><label for="thumb_field_resize"><?php _e("Resize image from Custom field?", 'wordpress-popular-posts'); ?>:</label></th>
438
- <td>
439
- <select name="thumb_field_resize" id="thumb_field_resize">
440
- <option <?php if ( !$this->config['tools']['thumbnail']['resize'] ) { ?>selected="selected"<?php } ?> value="0"><?php _e("No, use image as is", 'wordpress-popular-posts'); ?></option>
441
- <option <?php if ($this->config['tools']['thumbnail']['resize'] == 1 ) { ?>selected="selected"<?php } ?> value="1"><?php _e("Yes", 'wordpress-popular-posts'); ?></option>
442
- </select>
443
- </td>
444
- </tr>
445
- <?php
446
- $wp_upload_dir = wp_get_upload_dir();
447
- if ( is_dir($wp_upload_dir['basedir'] . "/" . 'wordpress-popular-posts') ) :
448
- ?>
449
- <tr valign="top">
450
- <th scope="row"></th>
451
- <td>
452
- <input type="button" name="wpp-reset-cache" id="wpp-reset-cache" class="button-secondary" value="<?php _e("Empty image cache", 'wordpress-popular-posts'); ?>" onclick="confirm_clear_image_cache()">
453
- <p class="description"><?php _e("Use this button to clear WPP's thumbnails cache", 'wordpress-popular-posts'); ?>.</p>
454
- </td>
455
- </tr>
456
- <?php
457
- endif;
458
- ?>
459
- <tr valign="top">
460
- <td colspan="2">
461
- <input type="hidden" name="section" value="thumb">
462
- <input type="submit" class="button-primary action" id="btn_th_ops" value="<?php _e("Apply", 'wordpress-popular-posts'); ?>" name="">
463
- </td>
464
- </tr>
465
- </tbody>
466
- </table>
467
-
468
- <?php wp_nonce_field('wpp-update-thumbnail-options', 'wpp-admin-token'); ?>
469
- </form>
470
- <br />
471
- <p style="display: <?php echo ( current_user_can('manage_options') ) ? 'block' : 'none'; ?>; float:none; clear:both;">&nbsp;</p>
472
-
473
- <h3 class="wmpp-subtitle" style="display: <?php echo ( current_user_can('manage_options') ) ? 'block' : 'none'; ?>"><?php _e("Data", 'wordpress-popular-posts'); ?></h3>
474
-
475
- <form action="" method="post" id="wpp_ajax_options" name="wpp_ajax_options" style="display: <?php echo ( current_user_can('manage_options') ) ? 'block' : 'none'; ?>">
476
- <table class="form-table">
477
- <tbody>
478
- <tr valign="top">
479
- <th scope="row"><label for="log_option"><?php _e("Log views from", 'wordpress-popular-posts'); ?>:</label></th>
480
- <td>
481
- <select name="log_option" id="log_option">
482
- <option <?php if ($this->config['tools']['log']['level'] == 0) { ?>selected="selected"<?php } ?> value="0"><?php _e("Visitors only", 'wordpress-popular-posts'); ?></option>
483
- <option <?php if ($this->config['tools']['log']['level'] == 2) { ?>selected="selected"<?php } ?> value="2"><?php _e("Logged-in users only", 'wordpress-popular-posts'); ?></option>
484
- <option <?php if ($this->config['tools']['log']['level'] == 1) { ?>selected="selected"<?php } ?> value="1"><?php _e("Everyone", 'wordpress-popular-posts'); ?></option>
485
- </select>
486
- <br />
487
- </td>
488
- </tr>
489
- <tr valign="top">
490
- <th scope="row"><label for="log_limit"><?php _e("Log limit", 'wordpress-popular-posts'); ?>:</label></th>
491
- <td>
492
- <select name="log_limit" id="log_limit">
493
- <option <?php if ($this->config['tools']['log']['limit'] == 0) { ?>selected="selected"<?php } ?> value="0"><?php _e("Disabled", 'wordpress-popular-posts'); ?></option>
494
- <option <?php if ($this->config['tools']['log']['limit'] == 1) { ?>selected="selected"<?php } ?> value="1"><?php _e("Keep data for", 'wordpress-popular-posts'); ?></option>
495
- </select>
496
-
497
- <label for="log_expire_time"<?php echo ($this->config['tools']['log']['limit'] == 0) ? ' style="display: none;"' : ''; ?>>
498
- <input type="text" id="log_expire_time" name="log_expire_time" value="<?php echo esc_attr($this->config['tools']['log']['expires_after']); ?>" size="3"> <?php _e("day(s)", 'wordpress-popular-posts'); ?>
499
- </label>
500
-
501
- <p class="description"<?php echo ($this->config['tools']['log']['limit'] == 0) ? ' style="display: none;"' : ''; ?>><?php _e("Data older than the specified time frame will be automatically discarded", 'wordpress-popular-posts'); ?>.</p>
502
-
503
- <br <?php echo (1 == $this->config['tools']['log']['limit']) ? 'style="display: none;"' : ''; ?>/>
504
- </td>
505
- </tr>
506
- <tr valign="top">
507
- <th scope="row"><label for="ajax"><?php _e("Ajaxify widget", 'wordpress-popular-posts'); ?>:</label></th>
508
- <td>
509
- <select name="ajax" id="ajax">
510
- <option <?php if (! $this->config['tools']['ajax']) { ?>selected="selected"<?php } ?> value="0"><?php _e("Disabled", 'wordpress-popular-posts'); ?></option>
511
- <option <?php if ($this->config['tools']['ajax']) { ?>selected="selected"<?php } ?> value="1"><?php _e("Enabled", 'wordpress-popular-posts'); ?></option>
512
- </select>
513
-
514
- <br />
515
- <p class="description"><?php _e("If you are using a caching plugin such as WP Super Cache, enabling this feature will keep the popular list from being cached by it", 'wordpress-popular-posts'); ?>.</p>
516
- </td>
517
- </tr>
518
- <tr valign="top">
519
- <th scope="row"><label for="cache"><?php _e("Data Caching", 'wordpress-popular-posts'); ?>:</label> <small>[<a href="https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance#caching-db-queries-results" target="_blank" title="<?php _e('What is this?', 'wordpress-popular-posts'); ?>">?</a>]</small></th>
520
- <td>
521
- <select name="cache" id="cache">
522
- <option <?php if ( ! $this->config['tools']['cache']['active'] ) { ?>selected="selected"<?php } ?> value="0"><?php _e("Never cache", 'wordpress-popular-posts'); ?></option>
523
- <option <?php if ( $this->config['tools']['cache']['active'] ) { ?>selected="selected"<?php } ?> value="1"><?php _e("Enable caching", 'wordpress-popular-posts'); ?></option>
524
- </select>
525
-
526
- <br />
527
- <p class="description"><?php _e("WPP can cache the popular list for a specified amount of time. Recommended for large / high traffic sites", 'wordpress-popular-posts'); ?>.</p>
528
- </td>
529
- </tr>
530
- <tr valign="top" <?php if ( ! $this->config['tools']['cache']['active'] ) { ?>style="display: none;"<?php } ?> id="cache_refresh_interval">
531
- <th scope="row"><label for="cache_interval_value"><?php _e("Refresh cache every", 'wordpress-popular-posts'); ?>:</label></th>
532
- <td>
533
- <input name="cache_interval_value" type="text" id="cache_interval_value" value="<?php echo ( isset($this->config['tools']['cache']['interval']['value']) ) ? (int) $this->config['tools']['cache']['interval']['value'] : 1; ?>" class="small-text">
534
- <select name="cache_interval_time" id="cache_interval_time">
535
- <option <?php if ($this->config['tools']['cache']['interval']['time'] == "minute") { ?>selected="selected"<?php } ?> value="minute"><?php _e("Minute(s)", 'wordpress-popular-posts'); ?></option>
536
- <option <?php if ($this->config['tools']['cache']['interval']['time'] == "hour") { ?>selected="selected"<?php } ?> value="hour"><?php _e("Hour(s)", 'wordpress-popular-posts'); ?></option>
537
- <option <?php if ($this->config['tools']['cache']['interval']['time'] == "day") { ?>selected="selected"<?php } ?> value="day"><?php _e("Day(s)", 'wordpress-popular-posts'); ?></option>
538
- <option <?php if ($this->config['tools']['cache']['interval']['time'] == "week") { ?>selected="selected"<?php } ?> value="week"><?php _e("Week(s)", 'wordpress-popular-posts'); ?></option>
539
- <option <?php if ($this->config['tools']['cache']['interval']['time'] == "month") { ?>selected="selected"<?php } ?> value="month"><?php _e("Month(s)", 'wordpress-popular-posts'); ?></option>
540
- <option <?php if ($this->config['tools']['cache']['interval']['time'] == "year") { ?>selected="selected"<?php } ?> value="month"><?php _e("Year(s)", 'wordpress-popular-posts'); ?></option>
541
- </select>
542
- <br />
543
- <p class="description" style="display: none;" id="cache_too_long"><?php _e("Really? That long?", 'wordpress-popular-posts'); ?></p>
544
- </td>
545
- </tr>
546
- <tr valign="top">
547
- <th scope="row"><label for="sampling"><?php _e("Data Sampling", 'wordpress-popular-posts'); ?>:</label> <small>[<a href="https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance#data-sampling" target="_blank" title="<?php _e('What is this?', 'wordpress-popular-posts'); ?>">?</a>]</small></th>
548
- <td>
549
- <select name="sampling" id="sampling">
550
- <option <?php if ( !$this->config['tools']['sampling']['active'] ) { ?>selected="selected"<?php } ?> value="0"><?php _e("Disabled", 'wordpress-popular-posts'); ?></option>
551
- <option <?php if ( $this->config['tools']['sampling']['active'] ) { ?>selected="selected"<?php } ?> value="1"><?php _e("Enabled", 'wordpress-popular-posts'); ?></option>
552
- </select>
553
-
554
- <br />
555
- <p class="description"><?php echo sprintf( __('By default, WordPress Popular Posts stores in database every single visit your site receives. For small / medium sites this is generally OK, but on large / high traffic sites the constant writing to the database may have an impact on performance. With <a href="%1$s" target="_blank">data sampling</a>, WordPress Popular Posts will store only a subset of your traffic and report on the tendencies detected in that sample set (for more, <a href="%2$s" target="_blank">please read here</a>)', 'wordpress-popular-posts'), 'http://en.wikipedia.org/wiki/Sample_%28statistics%29', 'https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance#data-sampling'); ?>.</p>
556
- </td>
557
- </tr>
558
- <tr valign="top" <?php if ( ! $this->config['tools']['sampling']['active'] ) { ?>style="display: none;"<?php } ?>>
559
- <th scope="row"><label for="sample_rate"><?php _e("Sample Rate", 'wordpress-popular-posts'); ?>:</label></th>
560
- <td>
561
- <input name="sample_rate" type="text" id="sample_rate" value="<?php echo ( isset($this->config['tools']['sampling']['rate']) ) ? (int) $this->config['tools']['sampling']['rate'] : 100; ?>" class="small-text">
562
- <br />
563
- <p class="description"><?php echo sprintf(__("A sampling rate of %d is recommended for large / high traffic sites. For lower traffic sites, you should lower the value", 'wordpress-popular-posts'), 100); ?>.</p>
564
- </td>
565
- </tr>
566
- <tr valign="top">
567
- <td colspan="2">
568
- <input type="hidden" name="section" value="data">
569
- <input type="submit" class="button-primary action" id="btn_ajax_ops" value="<?php _e("Apply", 'wordpress-popular-posts'); ?>" name="">
570
- </td>
571
- </tr>
572
- </tbody>
573
- </table>
574
-
575
- <?php wp_nonce_field('wpp-update-data-options', 'wpp-admin-token'); ?>
576
- </form>
577
- <br />
578
- <p style="display: block; float:none; clear: both;">&nbsp;</p>
579
-
580
- <h3 class="wmpp-subtitle"><?php _e("Miscellaneous", 'wordpress-popular-posts'); ?></h3>
581
-
582
- <form action="" method="post" id="wpp_link_options" name="wpp_link_options">
583
- <table class="form-table">
584
- <tbody>
585
- <tr valign="top">
586
- <th scope="row"><label for="link_target"><?php _e("Open links in", 'wordpress-popular-posts'); ?>:</label></th>
587
- <td>
588
- <select name="link_target" id="link_target">
589
- <option <?php if ($this->config['tools']['link']['target'] == '_self') { ?>selected="selected"<?php } ?> value="_self"><?php _e("Current window", 'wordpress-popular-posts'); ?></option>
590
- <option <?php if ($this->config['tools']['link']['target'] == '_blank') { ?>selected="selected"<?php } ?> value="_blank"><?php _e("New tab/window", 'wordpress-popular-posts'); ?></option>
591
- </select>
592
- <br />
593
- </td>
594
- </tr>
595
- <tr valign="top">
596
- <th scope="row"><label for="css"><?php _e("Use plugin's stylesheet", 'wordpress-popular-posts'); ?>:</label></th>
597
- <td>
598
- <select name="css" id="css">
599
- <option <?php if ($this->config['tools']['css']) { ?>selected="selected"<?php } ?> value="1"><?php _e("Enabled", 'wordpress-popular-posts'); ?></option>
600
- <option <?php if (!$this->config['tools']['css']) { ?>selected="selected"<?php } ?> value="0"><?php _e("Disabled", 'wordpress-popular-posts'); ?></option>
601
- </select>
602
- <br />
603
- <p class="description"><?php _e("By default, the plugin includes a stylesheet called wpp.css which you can use to style your popular posts listing. If you wish to use your own stylesheet or do not want it to have it included in the header section of your site, use this.", 'wordpress-popular-posts'); ?></p>
604
- </td>
605
- </tr>
606
- <tr valign="top">
607
- <td colspan="2">
608
- <input type="hidden" name="section" value="misc">
609
- <input type="submit" class="button-primary action" value="<?php _e("Apply", 'wordpress-popular-posts'); ?>" name="">
610
- </td>
611
- </tr>
612
- </tbody>
613
- </table>
614
-
615
- <?php wp_nonce_field('wpp-update-misc-options', 'wpp-admin-token'); ?>
616
- </form>
617
- <br />
618
- <p style="display: block; float: none; clear: both;">&nbsp;</p>
619
-
620
- <div style="display: <?php echo ( current_user_can('manage_options') ) ? 'block' : 'none'; ?>">
621
- <br /><br />
622
-
623
- <p><?php _e('WordPress Popular Posts maintains data in two separate tables: one for storing the most popular entries on a daily basis (from now on, "cache"), and another one to keep the All-time data (from now on, "historical data" or just "data"). If for some reason you need to clear the cache table, or even both historical and cache tables, please use the buttons below to do so.', 'wordpress-popular-posts') ?></p>
624
- <p><input type="button" name="wpp-reset-cache" id="wpp-reset-cache" class="button-secondary" value="<?php _e("Empty cache", 'wordpress-popular-posts'); ?>" onclick="confirm_reset_cache()"> <label for="wpp-reset-cache"><small><?php _e('Use this button to manually clear entries from WPP cache only', 'wordpress-popular-posts'); ?></small></label></p>
625
- <p><input type="button" name="wpp-reset-all" id="wpp-reset-all" class="button-secondary" value="<?php _e("Clear all data", 'wordpress-popular-posts'); ?>" onclick="confirm_reset_all()"> <label for="wpp-reset-all"><small><?php _e('Use this button to manually clear entries from all WPP data tables', 'wordpress-popular-posts'); ?></small></label></p>
626
- </div>
627
- </div>
628
- <!-- End tools -->
629
-
630
- <!-- Start params -->
631
- <div id="wpp_params" <?php echo ( "params" == $current ) ? '' : ' style="display: none;"'; ?>>
632
- <div>
633
- <p><?php printf( __('With the following parameters you can customize the popular posts list when using either the <a href="%1$s">wpp_get_mostpopular() template tag</a> or the <a href="%2$s">[wpp] shortcode</a>.', 'wordpress-popular-posts'),
634
- 'https://github.com/cabrerahector/wordpress-popular-posts/wiki/2.-Template-tags#wpp_get_mostpopular',
635
- 'https://github.com/cabrerahector/wordpress-popular-posts/wiki/1.-Using-WPP-on-posts-&-pages'
636
- ); ?></p>
637
- <br />
638
-
639
- <div style="overflow-x: auto;">
640
- <table cellspacing="0" class="wp-list-table">
641
- <thead>
642
- <tr>
643
- <th class="manage-column column-title"><?php _e('Parameter', 'wordpress-popular-posts'); ?></th>
644
- <th class="manage-column column-title"><?php _e('What it does ', 'wordpress-popular-posts'); ?></th>
645
- <th class="manage-column column-title"><?php _e('Possible values', 'wordpress-popular-posts'); ?></th>
646
- <th class="manage-column column-title"><?php _e('Defaults to', 'wordpress-popular-posts'); ?></th>
647
- <th class="manage-column column-title"><?php _e('Example', 'wordpress-popular-posts'); ?></th>
648
- </tr>
649
- </thead>
650
- <tbody>
651
- <tr>
652
- <td><strong>header</strong></td>
653
- <td><?php _e('Sets a heading for the list', 'wordpress-popular-posts'); ?></td>
654
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
655
- <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
656
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'header' => 'Popular Posts'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp header='Popular Posts']<br /><br /></td>
657
- </tr>
658
- <tr class="alternate">
659
- <td><strong>header_start</strong></td>
660
- <td><?php _e('Set the opening tag for the heading of the list', 'wordpress-popular-posts'); ?></td>
661
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
662
- <td>&lt;h2&gt;</td>
663
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'header' => 'Popular Posts', <br />&nbsp;&nbsp;&nbsp;&nbsp;'header_start' => '&lt;h3 class="title"&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'header_end' => '&lt;/h3&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp header='Popular Posts' header_start='&lt;h3 class="title"&gt;' header_end='&lt;/h3&gt;']<br /><br /></td>
664
- </tr>
665
- <tr>
666
- <td><strong>header_end</strong></td>
667
- <td><?php _e('Set the closing tag for the heading of the list', 'wordpress-popular-posts'); ?></td>
668
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
669
- <td>&lt;/h2&gt;</td>
670
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'header' => 'Popular Posts', <br />&nbsp;&nbsp;&nbsp;&nbsp;'header_start' => '&lt;h3 class="title"&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'header_end' => '&lt;/h3&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp header='Popular Posts' header_start='&lt;h3 class="title"&gt;' header_end='&lt;/h3&gt;']<br /><br /></td>
671
- </tr>
672
- <tr class="alternate">
673
- <td><strong>limit</strong></td>
674
- <td><?php _e('Sets the maximum number of popular posts to be shown on the listing', 'wordpress-popular-posts'); ?></td>
675
- <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
676
- <td>10</td>
677
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'limit' => 5<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp limit=5]<br /><br /></td>
678
- </tr>
679
- <tr>
680
- <td><strong>range</strong></td>
681
- <td><?php _e('Tells WordPress Popular Posts to retrieve the most popular entries within the time range specified by you', 'wordpress-popular-posts'); ?></td>
682
- <td>"last24hours", "last7days", "last30days", "all", "custom"</td>
683
- <td>last24hours</td>
684
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'range' => 'last7days'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp range='last7days']<br /><br /></td>
685
- </tr>
686
- <tr class="alternate">
687
- <td><strong>time_quantity</strong></td>
688
- <td><?php _e('Especifies the number of time units of the custom time range', 'wordpress-popular-posts'); ?></td>
689
- <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
690
- <td>24</td>
691
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'range' => 'custom',<br />&nbsp;&nbsp;&nbsp;&nbsp;'time_quantity' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'time_unit' => 'hour'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp range='custom' time_quantity=1 time_unit='hour']<br /><br /></td>
692
- </tr>
693
- <tr>
694
- <td><strong>time_unit</strong></td>
695
- <td><?php _e('Especifies the time unit of the custom time range', 'wordpress-popular-posts'); ?></td>
696
- <td>minute, hour, day, week, month</td>
697
- <td>hour</td>
698
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'range' => 'custom',<br />&nbsp;&nbsp;&nbsp;&nbsp;'time_quantity' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'time_unit' => 'hour'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp range='custom' time_quantity=1 time_unit='hour']<br /><br /></td>
699
- </tr>
700
- <tr class="alternate">
701
- <td><strong>freshness</strong></td>
702
- <td><?php _e('Tells WordPress Popular Posts to retrieve the most popular entries published within the time range specified by you', 'wordpress-popular-posts'); ?></td>
703
- <td>1 (true), 0 (false)</td>
704
- <td>0</td>
705
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'range' => 'weekly',<br />&nbsp;&nbsp;&nbsp;&nbsp;'freshness' => 1<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp range='last7days' freshness=1]<br /><br /></td>
706
- </tr>
707
- <tr>
708
- <td><strong>order_by</strong></td>
709
- <td><?php _e('Sets the sorting option of the popular posts', 'wordpress-popular-posts'); ?></td>
710
- <td>"comments", "views", "avg" <?php _e('(for average views per day)', 'wordpress-popular-posts'); ?></td>
711
- <td>views</td>
712
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'order_by' => 'comments'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp order_by='comments']<br /><br /></td>
713
- </tr>
714
- <tr class="alternate">
715
- <td><strong>post_type</strong></td>
716
- <td><?php _e('Defines the type of posts to show on the listing', 'wordpress-popular-posts'); ?></td>
717
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
718
- <td>post</td>
719
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_type' => 'post,page,your-custom-post-type'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp post_type='post,page,your-custom-post-type']<br /><br /></td>
720
- </tr>
721
- <tr>
722
- <td><strong>pid</strong></td>
723
- <td><?php _e('If set, WordPress Popular Posts will exclude the specified post(s) ID(s) form the listing.', 'wordpress-popular-posts'); ?></td>
724
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
725
- <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
726
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'pid' => '60,25,31'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp pid='60,25,31']<br /><br /></td>
727
- </tr>
728
- <tr class="alternate">
729
- <td><strong>cat</strong></td>
730
- <td><?php _e('If set, WordPress Popular Posts will retrieve all entries that belong to the specified category ID(s). If a minus sign is used, entries associated to the category will be excluded instead.', 'wordpress-popular-posts'); ?></td>
731
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
732
- <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
733
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'cat' => '1,55,-74'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp cat='1,55,-74']<br /><br /></td>
734
- </tr>
735
- <tr>
736
- <td><strong>taxonomy</strong></td>
737
- <td><?php _e('If set, WordPress Popular Posts will filter posts by a given taxonomy.', 'wordpress-popular-posts'); ?></td>
738
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
739
- <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
740
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'taxonomy' => 'post_tag',<br />&nbsp;&nbsp;&nbsp;&nbsp;'term_id' => '118,75,15'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'taxonomy' => 'category; post_tag',<br />&nbsp;&nbsp;&nbsp;&nbsp;'term_id' => '1,55,-74; 118,75,15'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp taxonomy='post_tag' term_id='118,75,15']<br /><br />[wpp taxonomy='category; post_tag' term_id='1,55,-74; 118,75,15']<br /><br /></td>
741
- </tr>
742
- <tr class="alternate">
743
- <td><strong>term_id</strong></td>
744
- <td><?php _e('If set, WordPress Popular Posts will retrieve all entries that belong to the specified term ID(s). If a minus sign is used, entries associated to the term(s) will be excluded instead.', 'wordpress-popular-posts'); ?></td>
745
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
746
- <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
747
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'taxonomy' => 'post_tag',<br />&nbsp;&nbsp;&nbsp;&nbsp;'term_id' => '118,75,15'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp taxonomy='post_tag' term_id='118,75,15']<br /><br /></td>
748
- </tr>
749
- <tr>
750
- <td><strong>author</strong></td>
751
- <td><?php _e('If set, WordPress Popular Posts will retrieve all entries created by specified author(s) ID(s).', 'wordpress-popular-posts'); ?></td>
752
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
753
- <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
754
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'author' => '75,8,120'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp author='75,8,120']<br /><br /></td>
755
- </tr>
756
- <tr class="alternate">
757
- <td><strong>title_length</strong></td>
758
- <td><?php _e('If set, WordPress Popular Posts will shorten each post title to "n" characters whenever possible', 'wordpress-popular-posts'); ?></td>
759
- <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
760
- <td>25</td>
761
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'title_length' => 25<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp title_length=25]<br /><br /></td>
762
- </tr>
763
- <tr>
764
- <td><strong>title_by_words</strong></td>
765
- <td><?php _e('If set to 1, WordPress Popular Posts will shorten each post title to "n" words instead of characters', 'wordpress-popular-posts'); ?></td>
766
- <td>1 (true), (0) false</td>
767
- <td>0</td>
768
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'title_by_words' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'title_length' => 25<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp title_by_words=1 title_length=25]<br /><br /></td>
769
- </tr>
770
- <tr class="alternate">
771
- <td><strong>excerpt_length</strong></td>
772
- <td><?php _e('If set, WordPress Popular Posts will build and include an excerpt of "n" characters long from the content of each post listed as popular', 'wordpress-popular-posts'); ?></td>
773
- <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
774
- <td>0</td>
775
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_length' => 55,<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp excerpt_length=25 post_html='&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;']<br /><br /></td>
776
- </tr>
777
- <tr>
778
- <td><strong>excerpt_format</strong></td>
779
- <td><?php _e('If set, WordPress Popular Posts will maintaing all styling tags (strong, italic, etc) and hyperlinks found in the excerpt', 'wordpress-popular-posts'); ?></td>
780
- <td>1 (true), (0) false</td>
781
- <td>0</td>
782
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_format' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_length' => 55,<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp excerpt_format=1 excerpt_length=25 post_html='&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;']<br /><br /></td>
783
- </tr>
784
- <tr class="alternate">
785
- <td><strong>excerpt_by_words</strong></td>
786
- <td><?php _e('If set to 1, WordPress Popular Posts will shorten the excerpt to "n" words instead of characters', 'wordpress-popular-posts'); ?></td>
787
- <td>1 (true), (0) false</td>
788
- <td>0</td>
789
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_by_words' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_length' => 55,<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp excerpt_by_words=1 excerpt_length=55 post_html='&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;']<br /><br /></td>
790
- </tr>
791
- <tr>
792
- <td><strong>thumbnail_width</strong></td>
793
- <td><?php _e('If set, and if your current server configuration allows it, you will be able to display thumbnails of your posts. This attribute sets the width for thumbnails', 'wordpress-popular-posts'); ?></td>
794
- <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
795
- <td>0</td>
796
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_width' => 30,<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_height' => 30<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp thumbnail_width=30 thumbnail_height=30]<br /><br /></td>
797
- </tr>
798
- <tr class="alternate">
799
- <td><strong>thumbnail_height</strong></td>
800
- <td><?php _e('If set, and if your current server configuration allows it, you will be able to display thumbnails of your posts. This attribute sets the height for thumbnails', 'wordpress-popular-posts'); ?></td>
801
- <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
802
- <td>0</td>
803
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_width' => 30,<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_height' => 30<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp thumbnail_width=30 thumbnail_height=30]<br /><br /></td>
804
- </tr>
805
- <tr>
806
- <td><strong>rating</strong></td>
807
- <td><?php _e('If set, and if the WP-PostRatings plugin is installed and enabled on your blog, WordPress Popular Posts will show how your visitors are rating your entries', 'wordpress-popular-posts'); ?></td>
808
- <td>1 (true), (0) false</td>
809
- <td>0</td>
810
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'rating' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{title} {rating}&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp rating=1 post_html='&lt;li&gt;{title} {rating}&lt;/li&gt;']<br /><br /></td>
811
- </tr>
812
- <tr class="alternate">
813
- <td><strong>stats_comments</strong></td>
814
- <td><?php _e('If set, WordPress Popular Posts will show how many comments each popular post has got during the specified time range', 'wordpress-popular-posts'); ?></td>
815
- <td>1 (true), 0 (false)</td>
816
- <td>0</td>
817
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_comments' => 1<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_comments=1]<br /><br /></td>
818
- </tr>
819
- <tr>
820
- <td><strong>stats_views</strong></td>
821
- <td><?php _e('If set, WordPress Popular Posts will show how many views each popular post has got during the specified time range', 'wordpress-popular-posts'); ?></td>
822
- <td>1 (true), (0) false</td>
823
- <td>1</td>
824
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_views' => 0<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_views=0]<br /><br /></td>
825
- </tr>
826
- <tr class="alternate">
827
- <td><strong>stats_author</strong></td>
828
- <td><?php _e('If set, WordPress Popular Posts will show who published each popular post on the list', 'wordpress-popular-posts'); ?></td>
829
- <td>1 (true), (0) false</td>
830
- <td>0</td>
831
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_author' => 1<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_author=1]<br /><br /></td>
832
- </tr>
833
- <tr>
834
- <td><strong>stats_date</strong></td>
835
- <td><?php _e('If set, WordPress Popular Posts will display the date when each popular post on the list was published', 'wordpress-popular-posts'); ?></td>
836
- <td>1 (true), (0) false</td>
837
- <td>0</td>
838
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_date' => 1<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_date=1]<br /><br /></td>
839
- </tr>
840
- <tr class="alternate">
841
- <td><strong>stats_date_format</strong></td>
842
- <td><?php _e('Sets the date format', 'wordpress-popular-posts'); ?></td>
843
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
844
- <td>0</td>
845
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_date' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_date_format' => 'F j, Y'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_date=1 stats_date_format='F j, Y']<br /><br /></td>
846
- </tr>
847
- <tr>
848
- <td><strong>stats_category</strong></td>
849
- <td><?php _e('If set, WordPress Popular Posts will display the categories associated to each entry', 'wordpress-popular-posts'); ?></td>
850
- <td>1 (true), (0) false</td>
851
- <td>0</td>
852
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_category' => 1, <br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;&lt;a href="{url}"&gt;{text_title}&lt;/a&gt; {category}&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_taxonomy=1 post_html='&lt;li&gt;&lt;a href="{url}"&gt;{text_title}&lt;/a&gt; {category}&lt;/li&gt;']<br /><br /></td>
853
- </tr>
854
- <tr class="alternate">
855
- <td><strong>stats_taxonomy</strong></td>
856
- <td><?php _e('If set, WordPress Popular Posts will display the taxonomies associated to each entry', 'wordpress-popular-posts'); ?></td>
857
- <td>1 (true), (0) false</td>
858
- <td>0</td>
859
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_taxonomy' => 1, <br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;&lt;a href="{url}"&gt;{text_title}&lt;/a&gt; {taxonomy}&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_taxonomy=1 post_html='&lt;li&gt;&lt;a href="{url}"&gt;{text_title}&lt;/a&gt; {taxonomy}&lt;/li&gt;']<br /><br /></td>
860
- </tr>
861
- <tr>
862
- <td><strong>wpp_start</strong></td>
863
- <td><?php _e('Sets the opening tag for the listing', 'wordpress-popular-posts'); ?></td>
864
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
865
- <td>&lt;ul&gt;</td>
866
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'wpp_start' => '&lt;ol&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'wpp_end' => '&lt;/ol&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp wpp_start='&lt;ol&gt;' wpp_end='&lt;/ol&gt;']<br /><br /></td>
867
- </tr>
868
- <tr class="alternate">
869
- <td><strong>wpp_end</strong></td>
870
- <td><?php _e('Sets the closing tag for the listing', 'wordpress-popular-posts'); ?></td>
871
- <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
872
- <td>&lt;/ul&gt;</td>
873
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'wpp_start' => '&lt;ol&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'wpp_end' => '&lt;/ol&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp wpp_start='&lt;ol&gt;' wpp_end='&lt;/ol&gt;']<br /><br /></td>
874
- </tr>
875
- <tr>
876
- <td><strong>post_html</strong></td>
877
- <td><?php _e('Sets the HTML structure of each post', 'wordpress-popular-posts'); ?></td>
878
- <td><?php _e('Text string, custom HTML', 'wordpress-popular-posts'); ?>.<br /><br /><strong><?php _e('Available Content Tags', 'wordpress-popular-posts'); ?>:</strong> <br /><br /><em>{thumb}</em> (<?php _e('returns thumbnail linked to post/page, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{thumb_img}</em> (<?php _e('returns thumbnail image without linking to post/page, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{thumb_url}</em> (<?php _e('returns thumbnail url, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{title}</em> (<?php _e('returns linked post/page title', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{pid}</em> (<?php _e('returns the post/page ID', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{summary}</em> (<?php _e('returns post/page excerpt, and requires excerpt_length to be greater than 0', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{stats}</em> (<?php _e('returns the default stats tags', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{rating}</em> (<?php _e('returns post/page current rating, requires WP-PostRatings installed and enabled', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{score}</em> (<?php _e('returns post/page current rating as an integer, requires WP-PostRatings installed and enabled', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{url}</em> (<?php _e('returns the URL of the post/page', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{text_title}</em> (<?php _e('returns post/page title, no link', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{title_attr}</em> (<?php _e('similar to text_title, sanitized for use in title/alt attributes', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{author}</em> (<?php _e('returns linked author name, requires stats_author=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{author_copy}</em> (<?php _e('returns linked author name with copy, requires stats_author=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{category}</em> (<?php _e('returns linked category name, requires stats_category=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{category_copy}</em> (<?php _e('returns linked category name with copy, requires stats_category=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{taxonomy}</em> (<?php _e('returns linked taxonomy names, requires stats_taxonomy=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{taxonomy_copy}</em> (<?php _e('returns linked taxonomy names with copy, requires stats_taxonomy=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{views}</em> (<?php _e('returns views count only, no text, requires stats_views=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{views_copy}</em> (<?php _e('returns views count with copy, requires stats_views=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{comments}</em> (<?php _e('returns comments count only, no text, requires stats_comments=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{comments_copy}</em> (<?php _e('returns comments count with copy, requires stats_comments=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{date}</em> (<?php _e('returns post/page date, requires stats_date=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{date_copy}</em> (<?php _e('returns post/page date with copy, requires stats_date=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{total_items}</em> (<?php _e('outputs number of popular posts found', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{item_position}</em> (<?php _e('outputs the position of the post in the listing', 'wordpress-popular-posts'); ?>)</td>
879
- <td>&lt;li&gt;{thumb} {title} &lt;span class="wpp-meta post-stats"&gt;{stats}&lt;/span&gt;&lt;/li&gt;</td>
880
- <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{thumb} &lt;a href="{url}"&gt;{text_title}&lt;/a&gt;&lt;/li&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_width' => 100,<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_height' => 75<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp thumbnail_width=100 thumbnail_height=75 post_html='&lt;li&gt;{thumb} &lt;a href="{url}"&gt;{text_title}&lt;/a&gt;&lt;/li&gt;']<br /><br /></td>
881
- </tr>
882
- </tbody>
883
- </table>
884
- </div>
885
- </div>
886
- </div>
887
- <!-- End params -->
888
-
889
- <!-- Start debug -->
890
- <?php
891
- global $wpdb, $wp_version;
892
-
893
- $my_theme = wp_get_theme();
894
- $site_plugins = get_plugins();
895
- $plugin_names = [];
896
- $performance_nag = get_option('wpp_performance_nag');
897
-
898
- if ( ! $performance_nag ) {
899
- $performance_nag = [
900
- 'status' => 0,
901
- 'last_checked' => null
902
- ];
903
- }
904
-
905
- switch($performance_nag['status']) {
906
- case 0:
907
- $performance_nag_status = 'Inactive';
908
- break;
909
- case 1:
910
- $performance_nag_status = 'Active';
911
- break;
912
- case 2:
913
- $performance_nag_status = 'Remind me later';
914
- break;
915
- case 3:
916
- $performance_nag_status = 'Dismissed';
917
- break;
918
- default:
919
- $performance_nag_status = 'Inactive';
920
- break;
921
- }
922
-
923
- foreach( $site_plugins as $main_file => $plugin_meta ) :
924
- if ( ! is_plugin_active($main_file) )
925
- continue;
926
- $plugin_names[] = sanitize_text_field($plugin_meta['Name'] . ' ' . $plugin_meta['Version']);
927
- endforeach;
928
- ?>
929
- <div id="wpp_debug" <?php echo ( "debug" == $current ) ? '' : ' style="display: none;"'; ?>>
930
- <h3>Plugin Configuration</h3>
931
- <p><strong>Performance Nag:</strong> <?php echo $performance_nag_status; ?></p>
932
- <p><strong>Log Limit:</strong> <?php echo ( $this->config['tools']['log']['limit'] ) ? 'Yes, keep data for ' . $this->config['tools']['log']['expires_after'] . ' days' : 'No'; ?></p>
933
- <p><strong>Log Views From:</strong> <?php echo ( 0 == $this->config['tools']['log']['level'] ) ? 'Visitors only' : ( (2 == $this->config['tools']['log']['level']) ? 'Logged-in users only' : 'Everyone' ); ?></p>
934
- <p><strong>Data Caching:</strong> <?php echo ( $this->config['tools']['cache']['active'] ) ? 'Yes, ' . $this->config['tools']['cache']['interval']['value'] . ' ' . $this->config['tools']['cache']['interval']['time'] : 'No'; ?></p>
935
- <p><strong>Data Sampling:</strong> <?php echo ( $this->config['tools']['sampling']['active'] ) ? 'Yes, with a rate of ' . $this->config['tools']['sampling']['rate'] : 'No'; ?></p>
936
- <p><strong>External object cache:</strong> <?php echo ( wp_using_ext_object_cache() ) ? 'Yes' : 'No'; ?></p>
937
- <p><strong>WPP_CACHE_VIEWS:</strong> <?php echo ( defined('WPP_CACHE_VIEWS') && WPP_CACHE_VIEWS ) ? 'Yes' : 'No'; ?></p>
938
-
939
- <br />
940
-
941
- <h3>System Info</h3>
942
- <p><strong>PHP version:</strong> <?php echo phpversion(); ?></p>
943
- <p><strong>PHP extensions:</strong> <?php echo implode(', ', get_loaded_extensions()); ?></p>
944
- <p><strong>Database version:</strong> <?php echo $wpdb->get_var("SELECT VERSION();"); ?></p>
945
- <p><strong>InnoDB availability:</strong> <?php echo $wpdb->get_var("SELECT SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE = 'InnoDB';"); ?></p>
946
- <p><strong>WordPress version:</strong> <?php echo $wp_version; ?></p>
947
- <p><strong>Multisite:</strong> <?php echo ( function_exists('is_multisite') && is_multisite() ) ? 'Yes' : 'No'; ?></p>
948
- <p><strong>Active plugins:</strong> <?php echo implode(', ', $plugin_names); ?></p>
949
- <p><strong>Theme:</strong> <?php echo $my_theme->get('Name') . ' (' . $my_theme->get('Version') . ') by ' . $my_theme->get('Author'); ?></p>
950
- </div>
951
- <!-- End debug -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
952
  </div>
1
+ <?php
2
+ if ( basename($_SERVER['SCRIPT_NAME']) == basename(__FILE__) )
3
+ exit('Please do not load this page directly');
4
+
5
+ $tabs = [
6
+ 'stats' => __('Stats', 'wordpress-popular-posts'),
7
+ 'tools' => __('Tools', 'wordpress-popular-posts'),
8
+ 'params' => __('Parameters', 'wordpress-popular-posts'),
9
+ 'debug' => 'Debug'
10
+ ];
11
+
12
+ // Set active tab
13
+ if ( isset($_GET['tab'] ) && isset($tabs[$_GET['tab']] ) )
14
+ $current = $_GET['tab'];
15
+ else
16
+ $current = 'stats';
17
+
18
+ // Update options on form submission
19
+ if ( isset($_POST['section']) ) {
20
+
21
+ if ( "stats" == $_POST['section'] ) {
22
+ $current = 'stats';
23
+
24
+ if ( isset($_POST['wpp-update-stats-options-token']) && wp_verify_nonce($_POST['wpp-update-stats-options-token'], 'wpp-update-stats-options') ) {
25
+ $this->config['stats']['limit'] = ( \WordPressPopularPosts\Helper::is_number($_POST['stats_limit']) && $_POST['stats_limit'] > 0 ) ? $_POST['stats_limit'] : 10;
26
+ $this->config['stats']['post_type'] = empty($_POST['stats_type']) ? "post,page" : $_POST['stats_type'];
27
+ $this->config['stats']['freshness'] = empty($_POST['stats_freshness']) ? false : $_POST['stats_freshness'];
28
+
29
+ update_option('wpp_settings_config', $this->config);
30
+ echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
31
+ }
32
+ }
33
+ elseif ( "misc" == $_POST['section'] ) {
34
+ $current = 'tools';
35
+
36
+ if ( isset($_POST['wpp-update-misc-options-token'] ) && wp_verify_nonce($_POST['wpp-update-misc-options-token'], 'wpp-update-misc-options') ) {
37
+ $this->config['tools']['link']['target'] = $_POST['link_target'];
38
+ $this->config['tools']['css'] = $_POST['css'];
39
+
40
+ update_option('wpp_settings_config', $this->config);
41
+ echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
42
+ }
43
+ }
44
+ elseif ( "thumb" == $_POST['section'] ) {
45
+ $current = 'tools';
46
+
47
+ if ( isset($_POST['wpp-update-thumbnail-options-token']) && wp_verify_nonce($_POST['wpp-update-thumbnail-options-token'], 'wpp-update-thumbnail-options') ) {
48
+ if (
49
+ $_POST['thumb_source'] == "custom_field"
50
+ && ( ! isset($_POST['thumb_field']) || empty($_POST['thumb_field']) )
51
+ ) {
52
+ echo '<div id="wpp-message" class="error fade"><p>' . __('Please provide the name of your custom field.', 'wordpress-popular-posts') . '</p></div>';
53
+ }
54
+ else {
55
+ // thumbnail settings changed, flush transients
56
+ if ( $this->config['tools']['cache']['active'] ) {
57
+ $this->flush_transients();
58
+ }
59
+
60
+ $this->config['tools']['thumbnail']['source'] = $_POST['thumb_source'];
61
+ $this->config['tools']['thumbnail']['field'] = ( ! empty($_POST['thumb_field']) ) ? $_POST['thumb_field'] : "wpp_thumbnail";
62
+ $this->config['tools']['thumbnail']['default'] = ( ! empty($_POST['upload_thumb_src']) ) ? $_POST['upload_thumb_src'] : "";
63
+ $this->config['tools']['thumbnail']['resize'] = $_POST['thumb_field_resize'];
64
+ $this->config['tools']['thumbnail']['lazyload'] = (bool) $_POST['thumb_lazy_load'];
65
+
66
+ update_option('wpp_settings_config', $this->config );
67
+ echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
68
+ }
69
+ }
70
+ }
71
+ elseif ( "data" == $_POST['section'] && current_user_can('manage_options') ) {
72
+ $current = 'tools';
73
+
74
+ if ( isset($_POST['wpp-update-data-options-token'] ) && wp_verify_nonce($_POST['wpp-update-data-options-token'], 'wpp-update-data-options') ) {
75
+ $this->config['tools']['log']['level'] = $_POST['log_option'];
76
+ $this->config['tools']['log']['limit'] = $_POST['log_limit'];
77
+ $this->config['tools']['log']['expires_after'] = ( \WordPressPopularPosts\Helper::is_number($_POST['log_expire_time']) && $_POST['log_expire_time'] > 0 )
78
+ ? $_POST['log_expire_time']
79
+ : 180;
80
+ $this->config['tools']['ajax'] = $_POST['ajax'];
81
+
82
+ // if any of the caching settings was updated, destroy all transients created by the plugin
83
+ if (
84
+ $this->config['tools']['cache']['active'] != $_POST['cache']
85
+ || $this->config['tools']['cache']['interval']['time'] != $_POST['cache_interval_time']
86
+ || $this->config['tools']['cache']['interval']['value'] != $_POST['cache_interval_value']
87
+ ) {
88
+ $this->flush_transients();
89
+ }
90
+
91
+ $this->config['tools']['cache']['active'] = $_POST['cache'];
92
+ $this->config['tools']['cache']['interval']['time'] = $_POST['cache_interval_time'];
93
+ $this->config['tools']['cache']['interval']['value'] = ( isset($_POST['cache_interval_value']) && \WordPressPopularPosts\Helper::is_number($_POST['cache_interval_value']) && $_POST['cache_interval_value'] > 0 )
94
+ ? $_POST['cache_interval_value']
95
+ : 1;
96
+
97
+ $this->config['tools']['sampling']['active'] = $_POST['sampling'];
98
+ $this->config['tools']['sampling']['rate'] = ( isset($_POST['sample_rate']) && \WordPressPopularPosts\Helper::is_number($_POST['sample_rate']) && $_POST['sample_rate'] > 0 )
99
+ ? $_POST['sample_rate']
100
+ : 100;
101
+
102
+ update_option('wpp_settings_config', $this->config);
103
+ echo "<div class=\"notice notice-success is-dismissible\"><p><strong>" . __('Settings saved.', 'wordpress-popular-posts') . "</strong></p></div>";
104
+ }
105
+ }
106
+
107
+ }
108
+
109
+ $rand = md5(uniqid(rand(), true));
110
+
111
+ if ( ! $wpp_rand = get_option("wpp_rand") ) {
112
+ add_option("wpp_rand", $rand);
113
+ } else {
114
+ update_option("wpp_rand", $rand);
115
+ }
116
+
117
+ ?>
118
+ <script type="text/javascript">
119
+ // TOOLS
120
+ function confirm_reset_cache() {
121
+ if ( confirm("<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("This operation will delete all entries from WordPress Popular Posts' cache table and cannot be undone.", 'wordpress-popular-posts'); ?> \n\n" + "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("Do you want to continue?", 'wordpress-popular-posts'); ?>") ) {
122
+ jQuery.post(
123
+ ajaxurl,
124
+ {
125
+ action: 'wpp_clear_data',
126
+ token: '<?php echo get_option("wpp_rand"); ?>',
127
+ clear: 'cache'
128
+ }, function(data){
129
+ var response = "";
130
+
131
+ switch( data ) {
132
+ case "1":
133
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Success! The cache table has been cleared!', 'wordpress-popular-posts'); ?>";
134
+ break;
135
+
136
+ case "2":
137
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Error: cache table does not exist.', 'wordpress-popular-posts'); ?>";
138
+ break;
139
+
140
+ case "3":
141
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
142
+ break;
143
+
144
+ case "4":
145
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Sorry, you do not have enough permissions to do this. Please contact the site administrator for support.', 'wordpress-popular-posts'); ?>";
146
+ break;
147
+
148
+ default:
149
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
150
+ break;
151
+ }
152
+
153
+ alert(response);
154
+ }
155
+ );
156
+ }
157
+ }
158
+
159
+ function confirm_reset_all() {
160
+ if ( confirm("<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("This operation will delete all stored info from WordPress Popular Posts' data tables and cannot be undone.", 'wordpress-popular-posts'); ?> \n\n" + "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("Do you want to continue?", 'wordpress-popular-posts'); ?>")) {
161
+ jQuery.post(
162
+ ajaxurl,
163
+ {
164
+ action: 'wpp_clear_data',
165
+ token: '<?php echo get_option("wpp_rand"); ?>',
166
+ clear: 'all'
167
+ }, function(data){
168
+ var response = "";
169
+
170
+ switch( data ) {
171
+ case "1":
172
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Success! All data have been cleared!', 'wordpress-popular-posts'); ?>";
173
+ break;
174
+
175
+ case "2":
176
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Error: one or both data tables are missing.', 'wordpress-popular-posts'); ?>";
177
+ break;
178
+
179
+ case "3":
180
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
181
+ break;
182
+
183
+ case "4":
184
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Sorry, you do not have enough permissions to do this. Please contact the site administrator for support.', 'wordpress-popular-posts'); ?>";
185
+ break;
186
+
187
+ default:
188
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
189
+ break;
190
+ }
191
+
192
+ alert(response);
193
+ }
194
+ );
195
+ }
196
+ }
197
+
198
+ function confirm_clear_image_cache() {
199
+ if ( confirm("<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("This operation will delete all cached thumbnails and cannot be undone.", 'wordpress-popular-posts'); ?> \n\n" + "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e("Do you want to continue?", 'wordpress-popular-posts'); ?>") ) {
200
+ jQuery.post(
201
+ ajaxurl,
202
+ {
203
+ action: 'wpp_clear_thumbnail',
204
+ token: '<?php echo get_option("wpp_rand"); ?>'
205
+ }, function(data){
206
+ var response = "";
207
+
208
+ switch( data ) {
209
+ case "1":
210
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Success! All files have been deleted!', 'wordpress-popular-posts'); ?>";
211
+ break;
212
+
213
+ case "2":
214
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('The thumbnail cache is already empty!', 'wordpress-popular-posts'); ?>";
215
+ break;
216
+
217
+ case "3":
218
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
219
+ break;
220
+
221
+ case "4":
222
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Sorry, you do not have enough permissions to do this. Please contact the site administrator for support.', 'wordpress-popular-posts'); ?>";
223
+ break;
224
+
225
+ default:
226
+ response = "<?php /*translators: Special characters (such as accents) must be replaced with Javascript Octal codes (eg. \341 is the Octal code for small a with acute accent) */ _e('Invalid action.', 'wordpress-popular-posts'); ?>";
227
+ break;
228
+ }
229
+
230
+ alert(response);
231
+ }
232
+ );
233
+ }
234
+ }
235
+ </script>
236
+
237
+ <nav id="wpp-menu">
238
+ <ul>
239
+ <li><a href="#" title="<?php esc_attr_e('Menu'); ?>"><span><?php _e('Menu'); ?></span></a></li>
240
+ <li <?php echo ('stats' == $current ) ? 'class="current"' : ''; ?>><a href="<?php echo admin_url('options-general.php?page=wordpress-popular-posts&tab=stats'); ?>" title="<?php esc_attr_e('Stats', 'wordpress-popular-posts'); ?>"><span><?php _e('Stats', 'wordpress-popular-posts'); ?></span></a></li>
241
+ <li <?php echo ('tools' == $current ) ? 'class="current"' : ''; ?>><a href="<?php echo admin_url('options-general.php?page=wordpress-popular-posts&tab=tools'); ?>" title="<?php esc_attr_e('Tools', 'wordpress-popular-posts'); ?>"><span><?php _e('Tools', 'wordpress-popular-posts'); ?></span></a></li>
242
+ <li <?php echo ('params' == $current ) ? 'class="current"' : ''; ?>><a href="<?php echo admin_url('options-general.php?page=wordpress-popular-posts&tab=params'); ?>" title="<?php esc_attr_e('Parameters', 'wordpress-popular-posts'); ?>"><span><?php _e('Parameters', 'wordpress-popular-posts'); ?></span></a></li>
243
+ <li <?php echo ('debug' == $current ) ? 'class="current"' : ''; ?>><a href="<?php echo admin_url('options-general.php?page=wordpress-popular-posts&tab=debug'); ?>" title="Debug"><span>Debug</span></a></li>
244
+ </ul>
245
+ </nav>
246
+
247
+ <div class="wpp-wrapper wpp-section-<?php echo $current; ?>">
248
+ <div class="wpp-header">
249
+ <h2>WordPress Popular Posts</h2>
250
+ <h3><?php echo $tabs[$current]; ?></h3>
251
+ </div>
252
+
253
+ <?php
254
+ // Stats chart
255
+ if ( 'stats' == $current ) {
256
+ $chart_data = json_decode(
257
+ $this->get_chart_data($this->config['stats']['range'], strtoupper($this->config['stats']['time_unit']), $this->config['stats']['time_quantity']),
258
+ true
259
+ );
260
+ ?>
261
+
262
+ <a href="#" id="wpp-stats-config-btn" class="dashicons dashicons-admin-generic"></a>
263
+
264
+ <div id="wpp-stats-config" class="wpp-lightbox">
265
+ <form action="" method="post" id="wpp_stats_options" name="wpp_stats_options">
266
+ <label for="stats_type"><?php _e("Post type", 'wordpress-popular-posts'); ?>:</label>
267
+ <input type="text" name="stats_type" value="<?php echo esc_attr($this->config['stats']['post_type']); ?>" size="15">
268
+
269
+ <label for="stats_limits"><?php _e("Limit", 'wordpress-popular-posts'); ?>:</label>
270
+ <input type="text" name="stats_limit" value="<?php echo $this->config['stats']['limit']; ?>" size="5">
271
+
272
+ <label for="stats_freshness"><input type="checkbox" class="checkbox" <?php echo ($this->config['stats']['freshness']) ? 'checked="checked"' : ''; ?> id="stats_freshness" name="stats_freshness"> <small><?php _e('Display only posts published within the selected Time Range', 'wordpress-popular-posts'); ?></small></label>
273
+
274
+ <div class="clear"></div>
275
+ <br /><br />
276
+
277
+ <input type="hidden" name="section" value="stats">
278
+ <button type="submit" class="button-primary action"><?php _e("Apply", 'wordpress-popular-posts'); ?></button>
279
+ <button class="button-secondary action right"><?php _e("Cancel"); ?></button>
280
+
281
+ <?php wp_nonce_field('wpp-update-stats-options', 'wpp-update-stats-options-token'); ?>
282
+ </form>
283
+ </div>
284
+
285
+ <div id="wpp-stats-range" class="wpp-lightbox">
286
+ <form action="" method="post">
287
+ <ul class="wpp-lightbox-tabs">
288
+ <li class="active"><a href="#"><?php _e('Custom Time Range', 'wordpress-popular-posts'); ?></a></li>
289
+ <li><a href="#"><?php _e('Date Range', 'wordpress-popular-posts'); ?></a></li>
290
+ </ul>
291
+
292
+ <div class="wpp-lightbox-tab-content wpp-lightbox-tab-content-active" id="custom-time-range">
293
+ <input type="text" id="stats_range_time_quantity" name="stats_range_time_quantity" value="<?php echo $this->config['stats']['time_quantity']; ?>">
294
+
295
+ <select id="stats_range_time_unit" name="stats_range_time_unit">
296
+ <option <?php if ($this->config['stats']['time_unit'] == "minute") { ?>selected="selected"<?php } ?> value="minute"><?php _e("Minute(s)", 'wordpress-popular-posts'); ?></option>
297
+ <option <?php if ($this->config['stats']['time_unit'] == "hour") { ?>selected="selected"<?php } ?> value="hour"><?php _e("Hour(s)", 'wordpress-popular-posts'); ?></option>
298
+ <option <?php if ($this->config['stats']['time_unit'] == "day") { ?>selected="selected"<?php } ?> value="day"><?php _e("Day(s)", 'wordpress-popular-posts'); ?></option>
299
+ </select>
300
+ </div>
301
+
302
+ <div class="wpp-lightbox-tab-content" id="custom-date-range">
303
+ <input type="text" id="stats_range_date" name="stats_range_date" value="" placeholder="<?php esc_attr_e('Select a date...', 'wordpress-popular-posts'); ?>" readonly>
304
+ </div>
305
+
306
+ <div class="clear"></div>
307
+ <br />
308
+
309
+ <button type="submit" class="button-primary action">
310
+ <?php _e("Apply", 'wordpress-popular-posts'); ?>
311
+ </button>
312
+ <button class="button-secondary action right">
313
+ <?php _e("Cancel"); ?>
314
+ </button>
315
+ </form>
316
+ </div>
317
+
318
+ <div id="wpp-chart-wrapper">
319
+ <h4><?php echo $chart_data['totals']['label_summary']; ?></h4>
320
+ <h5><?php echo $chart_data['totals']['label_date_range']; ?></h5>
321
+
322
+ <ul class="wpp-header-nav" id="wpp-time-ranges">
323
+ <li <?php echo ('daily' == $this->config['stats']['range'] || 'today' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="today" title="<?php esc_attr_e('Today', 'wordpress-popular-posts'); ?>"><?php _e('Today', 'wordpress-popular-posts'); ?></a></li>
324
+ <li <?php echo ('daily' == $this->config['stats']['range'] || 'last24hours' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="last24hours" title="<?php esc_attr_e('Last 24 hours', 'wordpress-popular-posts'); ?>">24h</a></li>
325
+ <li <?php echo ('weekly' == $this->config['stats']['range'] || 'last7days' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="last7days" title="<?php esc_attr_e('Last 7 days', 'wordpress-popular-posts'); ?>">7d</a></li>
326
+ <li <?php echo ('monthly' == $this->config['stats']['range'] || 'last30days' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="last30days" title="<?php esc_attr_e('Last 30 days', 'wordpress-popular-posts'); ?>">30d</a></li>
327
+ <li <?php echo ('custom' == $this->config['stats']['range'] ) ? ' class="current"' : ''; ?>><a href="#" data-range="custom" title="<?php esc_attr_e('Custom', 'wordpress-popular-posts'); ?>"><?php _e('Custom', 'wordpress-popular-posts'); ?></a></li>
328
+ </ul>
329
+
330
+ <div id="wpp-chart">
331
+ <p><?php echo sprintf( __('Err... A nice little chart is supposed to be here, instead you are seeing this because your browser is too old. <br /> Please <a href="%s" target="_blank">get a better browser</a>.', 'wordpress-popular-posts'), 'https://browsehappy.com/'); ?></p>
332
+
333
+ <script>
334
+ if ( WPPChart.canRender() ) {
335
+ jQuery("#wpp-chart p").remove();
336
+ WPPChart.init('wpp-chart');
337
+ }
338
+ </script>
339
+ </div>
340
+ </div>
341
+ <?php
342
+ } // End stats chart
343
+ ?>
344
+
345
+ <div id="wpp-listing" class="wpp-content"<?php echo ('stats' == $current ) ? '' : ' style="display: none;"'; ?>>
346
+ <ul class="wpp-tabbed-nav">
347
+ <li class="active"><a href="#" title="<?php esc_attr_e('Most viewed', 'wordpress-popular-posts'); ?>"><span class="wpp-icon-eye"></span><span><?php _e('Most viewed', 'wordpress-popular-posts'); ?></span></a></li>
348
+ <li><a href="#" title="<?php esc_attr_e('Most commented', 'wordpress-popular-posts'); ?>"><span class="wpp-icon-comment"></span><span><?php _e('Most commented', 'wordpress-popular-posts'); ?></span></a></li>
349
+ <li><a href="#" title="<?php esc_attr_e('Trending now', 'wordpress-popular-posts'); ?>"><span class="wpp-icon-rocket"></span><span><?php _e('Trending now', 'wordpress-popular-posts'); ?></span></a></li>
350
+ <li><a href="#" title="<?php esc_attr_e('Hall of Fame', 'wordpress-popular-posts'); ?>"><span class="wpp-icon-award"></span><span><?php _e('Hall of Fame', 'wordpress-popular-posts'); ?></span></a></li>
351
+ </ul>
352
+
353
+ <div class="wpp-tab-content wpp-tab-content-active">
354
+ <span class="spinner"></span>
355
+ </div>
356
+
357
+ <div class="wpp-tab-content">
358
+ <span class="spinner"></span>
359
+ </div>
360
+
361
+ <div class="wpp-tab-content">
362
+ <span class="spinner"></span>
363
+ </div>
364
+
365
+ <div class="wpp-tab-content">
366
+ <?php
367
+ $args = [
368
+ 'range' => 'all',
369
+ 'post_type' => $this->config['stats']['post_type'],
370
+ 'order_by' => 'views',
371
+ 'limit' => $this->config['stats']['limit'],
372
+ 'stats_tag' => [
373
+ 'comment_count' => 1,
374
+ 'views' => 1,
375
+ 'date' => [
376
+ 'active' => 1
377
+ ]
378
+ ]
379
+ ];
380
+ $hof = new \WordPressPopularPosts\Query($args);
381
+ $posts = $hof->get_posts();
382
+
383
+ $this->render_list($posts, 'hof');
384
+ ?>
385
+ </div>
386
+ </div>
387
+
388
+ <!-- Start tools -->
389
+ <div id="wpp_tools" <?php echo ( "tools" == $current ) ? '' : ' style="display: none;"'; ?>>
390
+ <h3 class="wmpp-subtitle"><?php _e("Thumbnails", 'wordpress-popular-posts'); ?></h3>
391
+
392
+ <form action="" method="post" id="wpp_thumbnail_options" name="wpp_thumbnail_options">
393
+ <table class="form-table">
394
+ <tbody>
395
+ <tr valign="top">
396
+ <th scope="row"><label for="thumb_default"><?php _e("Default thumbnail", 'wordpress-popular-posts'); ?>:</label></th>
397
+ <td>
398
+ <?php
399
+ $fallback_thumbnail_url = trim($this->config['tools']['thumbnail']['default']);
400
+
401
+ if ( ! $fallback_thumbnail_url )
402
+ $fallback_thumbnail_url = $this->thumbnail->get_default_url();
403
+
404
+ $fallback_thumbnail_url = str_replace(
405
+ parse_url(
406
+ $fallback_thumbnail_url
407
+ , PHP_URL_SCHEME
408
+ ) . ':',
409
+ '',
410
+ $fallback_thumbnail_url
411
+ );
412
+ ?>
413
+ <div id="thumb-review">
414
+ <img src="<?php echo esc_url($fallback_thumbnail_url); ?>" alt="" />
415
+ </div>
416
+
417
+ <input id="upload_thumb_button" type="button" class="button" value="<?php _e("Change thumbnail", 'wordpress-popular-posts'); ?>">
418
+ <input type="hidden" id="upload_thumb_src" name="upload_thumb_src" value="">
419
+
420
+ <p class="description"><?php _e("This image will be displayed when no thumbnail is available", 'wordpress-popular-posts'); ?>.</p>
421
+ </td>
422
+ </tr>
423
+ <tr valign="top">
424
+ <th scope="row"><label for="thumb_source"><?php _e("Pick image from", 'wordpress-popular-posts'); ?>:</label></th>
425
+ <td>
426
+ <select name="thumb_source" id="thumb_source">
427
+ <option <?php if ($this->config['tools']['thumbnail']['source'] == "featured") { ?>selected="selected"<?php } ?> value="featured"><?php _e("Featured image", 'wordpress-popular-posts'); ?></option>
428
+ <option <?php if ($this->config['tools']['thumbnail']['source'] == "first_image") { ?>selected="selected"<?php } ?> value="first_image"><?php _e("First image on post", 'wordpress-popular-posts'); ?></option>
429
+ <option <?php if ($this->config['tools']['thumbnail']['source'] == "first_attachment") { ?>selected="selected"<?php } ?> value="first_attachment"><?php _e("First attachment", 'wordpress-popular-posts'); ?></option>
430
+ <option <?php if ($this->config['tools']['thumbnail']['source'] == "custom_field") { ?>selected="selected"<?php } ?> value="custom_field"><?php _e("Custom field", 'wordpress-popular-posts'); ?></option>
431
+ </select>
432
+ <br />
433
+ <p class="description"><?php _e("Tell WordPress Popular Posts where it should get thumbnails from", 'wordpress-popular-posts'); ?>.</p>
434
+ </td>
435
+ </tr>
436
+ <tr valign="top">
437
+ <th scope="row"><label for="thumb_lazy_load"><?php _e("Lazy load", 'wordpress-popular-posts'); ?>:</label> <small>[<a href="https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance#lazy-loading" target="_blank" title="<?php _e('What is this?', 'wordpress-popular-posts'); ?>">?</a>]</small></th>
438
+ <td>
439
+ <select name="thumb_lazy_load" id="thumb_lazy_load">
440
+ <option <?php if ( ! $this->config['tools']['thumbnail']['lazyload'] ) { ?>selected="selected"<?php } ?> value="0"><?php _e("No", 'wordpress-popular-posts'); ?></option>
441
+ <option <?php if ( $this->config['tools']['thumbnail']['lazyload'] ) { ?>selected="selected"<?php } ?> value="1"><?php _e("Yes", 'wordpress-popular-posts'); ?></option>
442
+ </select>
443
+ </td>
444
+ </tr>
445
+ <tr valign="top" <?php if ($this->config['tools']['thumbnail']['source'] != "custom_field") { ?>style="display: none;"<?php } ?> id="row_custom_field">
446
+ <th scope="row"><label for="thumb_field"><?php _e("Custom field name", 'wordpress-popular-posts'); ?>:</label></th>
447
+ <td>
448
+ <input type="text" id="thumb_field" name="thumb_field" value="<?php echo esc_attr($this->config['tools']['thumbnail']['field']); ?>" size="10" <?php if ($this->config['tools']['thumbnail']['source'] != "custom_field") { ?>style="display: none;"<?php } ?> />
449
+ </td>
450
+ </tr>
451
+ <tr valign="top" <?php if ($this->config['tools']['thumbnail']['source'] != "custom_field") { ?>style="display: none;"<?php } ?> id="row_custom_field_resize">
452
+ <th scope="row"><label for="thumb_field_resize"><?php _e("Resize image from Custom field?", 'wordpress-popular-posts'); ?>:</label></th>
453
+ <td>
454
+ <select name="thumb_field_resize" id="thumb_field_resize">
455
+ <option <?php if ( !$this->config['tools']['thumbnail']['resize'] ) { ?>selected="selected"<?php } ?> value="0"><?php _e("No, use image as is", 'wordpress-popular-posts'); ?></option>
456
+ <option <?php if ($this->config['tools']['thumbnail']['resize'] == 1 ) { ?>selected="selected"<?php } ?> value="1"><?php _e("Yes", 'wordpress-popular-posts'); ?></option>
457
+ </select>
458
+ </td>
459
+ </tr>
460
+ <?php
461
+ $wp_upload_dir = wp_get_upload_dir();
462
+ if ( is_dir($wp_upload_dir['basedir'] . "/" . 'wordpress-popular-posts') ) :
463
+ ?>
464
+ <tr valign="top">
465
+ <th scope="row"></th>
466
+ <td>
467
+ <input type="button" name="wpp-reset-cache" id="wpp-reset-cache" class="button-secondary" value="<?php _e("Empty image cache", 'wordpress-popular-posts'); ?>" onclick="confirm_clear_image_cache()">
468
+ <p class="description"><?php _e("Use this button to clear WPP's thumbnails cache", 'wordpress-popular-posts'); ?>.</p>
469
+ </td>
470
+ </tr>
471
+ <?php
472
+ endif;
473
+ ?>
474
+ <tr valign="top">
475
+ <td colspan="2">
476
+ <input type="hidden" name="section" value="thumb">
477
+ <input type="submit" class="button-primary action" id="btn_th_ops" value="<?php _e("Apply", 'wordpress-popular-posts'); ?>" name="">
478
+ </td>
479
+ </tr>
480
+ </tbody>
481
+ </table>
482
+
483
+ <?php wp_nonce_field('wpp-update-thumbnail-options', 'wpp-update-thumbnail-options-token'); ?>
484
+ </form>
485
+ <br />
486
+ <p style="display: <?php echo ( current_user_can('manage_options') ) ? 'block' : 'none'; ?>; float:none; clear:both;">&nbsp;</p>
487
+
488
+ <h3 class="wmpp-subtitle" style="display: <?php echo ( current_user_can('manage_options') ) ? 'block' : 'none'; ?>"><?php _e("Data", 'wordpress-popular-posts'); ?></h3>
489
+
490
+ <form action="" method="post" id="wpp_ajax_options" name="wpp_ajax_options" style="display: <?php echo ( current_user_can('manage_options') ) ? 'block' : 'none'; ?>">
491
+ <table class="form-table">
492
+ <tbody>
493
+ <tr valign="top">
494
+ <th scope="row"><label for="log_option"><?php _e("Log views from", 'wordpress-popular-posts'); ?>:</label></th>
495
+ <td>
496
+ <select name="log_option" id="log_option">
497
+ <option <?php if ($this->config['tools']['log']['level'] == 0) { ?>selected="selected"<?php } ?> value="0"><?php _e("Visitors only", 'wordpress-popular-posts'); ?></option>
498
+ <option <?php if ($this->config['tools']['log']['level'] == 2) { ?>selected="selected"<?php } ?> value="2"><?php _e("Logged-in users only", 'wordpress-popular-posts'); ?></option>
499
+ <option <?php if ($this->config['tools']['log']['level'] == 1) { ?>selected="selected"<?php } ?> value="1"><?php _e("Everyone", 'wordpress-popular-posts'); ?></option>
500
+ </select>
501
+ <br />
502
+ </td>
503
+ </tr>
504
+ <tr valign="top">
505
+ <th scope="row"><label for="log_limit"><?php _e("Log limit", 'wordpress-popular-posts'); ?>:</label></th>
506
+ <td>
507
+ <select name="log_limit" id="log_limit">
508
+ <option <?php if ($this->config['tools']['log']['limit'] == 0) { ?>selected="selected"<?php } ?> value="0"><?php _e("Disabled", 'wordpress-popular-posts'); ?></option>
509
+ <option <?php if ($this->config['tools']['log']['limit'] == 1) { ?>selected="selected"<?php } ?> value="1"><?php _e("Keep data for", 'wordpress-popular-posts'); ?></option>
510
+ </select>
511
+
512
+ <label for="log_expire_time"<?php echo ($this->config['tools']['log']['limit'] == 0) ? ' style="display: none;"' : ''; ?>>
513
+ <input type="text" id="log_expire_time" name="log_expire_time" value="<?php echo esc_attr($this->config['tools']['log']['expires_after']); ?>" size="3"> <?php _e("day(s)", 'wordpress-popular-posts'); ?>
514
+ </label>
515
+
516
+ <p class="description"<?php echo ($this->config['tools']['log']['limit'] == 0) ? ' style="display: none;"' : ''; ?>><?php _e("Data older than the specified time frame will be automatically discarded", 'wordpress-popular-posts'); ?>.</p>
517
+
518
+ <br <?php echo (1 == $this->config['tools']['log']['limit']) ? 'style="display: none;"' : ''; ?>/>
519
+ </td>
520
+ </tr>
521
+ <tr valign="top">
522
+ <th scope="row"><label for="ajax"><?php _e("Ajaxify widget", 'wordpress-popular-posts'); ?>:</label></th>
523
+ <td>
524
+ <select name="ajax" id="ajax">
525
+ <option <?php if (! $this->config['tools']['ajax']) { ?>selected="selected"<?php } ?> value="0"><?php _e("Disabled", 'wordpress-popular-posts'); ?></option>
526
+ <option <?php if ($this->config['tools']['ajax']) { ?>selected="selected"<?php } ?> value="1"><?php _e("Enabled", 'wordpress-popular-posts'); ?></option>
527
+ </select>
528
+
529
+ <br />
530
+ <p class="description"><?php _e("If you are using a caching plugin such as WP Super Cache, enabling this feature will keep the popular list from being cached by it", 'wordpress-popular-posts'); ?>.</p>
531
+ </td>
532
+ </tr>
533
+ <tr valign="top">
534
+ <th scope="row"><label for="cache"><?php _e("Data Caching", 'wordpress-popular-posts'); ?>:</label> <small>[<a href="https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance#caching-db-queries-results" target="_blank" title="<?php _e('What is this?', 'wordpress-popular-posts'); ?>">?</a>]</small></th>
535
+ <td>
536
+ <select name="cache" id="cache">
537
+ <option <?php if ( ! $this->config['tools']['cache']['active'] ) { ?>selected="selected"<?php } ?> value="0"><?php _e("Never cache", 'wordpress-popular-posts'); ?></option>
538
+ <option <?php if ( $this->config['tools']['cache']['active'] ) { ?>selected="selected"<?php } ?> value="1"><?php _e("Enable caching", 'wordpress-popular-posts'); ?></option>
539
+ </select>
540
+
541
+ <br />
542
+ <p class="description"><?php _e("WPP can cache the popular list for a specified amount of time. Recommended for large / high traffic sites", 'wordpress-popular-posts'); ?>.</p>
543
+ </td>
544
+ </tr>
545
+ <tr valign="top" <?php if ( ! $this->config['tools']['cache']['active'] ) { ?>style="display: none;"<?php } ?> id="cache_refresh_interval">
546
+ <th scope="row"><label for="cache_interval_value"><?php _e("Refresh cache every", 'wordpress-popular-posts'); ?>:</label></th>
547
+ <td>
548
+ <input name="cache_interval_value" type="text" id="cache_interval_value" value="<?php echo ( isset($this->config['tools']['cache']['interval']['value']) ) ? (int) $this->config['tools']['cache']['interval']['value'] : 1; ?>" class="small-text">
549
+ <select name="cache_interval_time" id="cache_interval_time">
550
+ <option <?php if ($this->config['tools']['cache']['interval']['time'] == "minute") { ?>selected="selected"<?php } ?> value="minute"><?php _e("Minute(s)", 'wordpress-popular-posts'); ?></option>
551
+ <option <?php if ($this->config['tools']['cache']['interval']['time'] == "hour") { ?>selected="selected"<?php } ?> value="hour"><?php _e("Hour(s)", 'wordpress-popular-posts'); ?></option>
552
+ <option <?php if ($this->config['tools']['cache']['interval']['time'] == "day") { ?>selected="selected"<?php } ?> value="day"><?php _e("Day(s)", 'wordpress-popular-posts'); ?></option>
553
+ <option <?php if ($this->config['tools']['cache']['interval']['time'] == "week") { ?>selected="selected"<?php } ?> value="week"><?php _e("Week(s)", 'wordpress-popular-posts'); ?></option>
554
+ <option <?php if ($this->config['tools']['cache']['interval']['time'] == "month") { ?>selected="selected"<?php } ?> value="month"><?php _e("Month(s)", 'wordpress-popular-posts'); ?></option>
555
+ <option <?php if ($this->config['tools']['cache']['interval']['time'] == "year") { ?>selected="selected"<?php } ?> value="month"><?php _e("Year(s)", 'wordpress-popular-posts'); ?></option>
556
+ </select>
557
+ <br />
558
+ <p class="description" style="display: none;" id="cache_too_long"><?php _e("Really? That long?", 'wordpress-popular-posts'); ?></p>
559
+ </td>
560
+ </tr>
561
+ <tr valign="top">
562
+ <th scope="row"><label for="sampling"><?php _e("Data Sampling", 'wordpress-popular-posts'); ?>:</label> <small>[<a href="https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance#data-sampling" target="_blank" title="<?php _e('What is this?', 'wordpress-popular-posts'); ?>">?</a>]</small></th>
563
+ <td>
564
+ <select name="sampling" id="sampling">
565
+ <option <?php if ( !$this->config['tools']['sampling']['active'] ) { ?>selected="selected"<?php } ?> value="0"><?php _e("Disabled", 'wordpress-popular-posts'); ?></option>
566
+ <option <?php if ( $this->config['tools']['sampling']['active'] ) { ?>selected="selected"<?php } ?> value="1"><?php _e("Enabled", 'wordpress-popular-posts'); ?></option>
567
+ </select>
568
+
569
+ <br />
570
+ <p class="description"><?php echo sprintf( __('By default, WordPress Popular Posts stores in database every single visit your site receives. For small / medium sites this is generally OK, but on large / high traffic sites the constant writing to the database may have an impact on performance. With <a href="%1$s" target="_blank">data sampling</a>, WordPress Popular Posts will store only a subset of your traffic and report on the tendencies detected in that sample set (for more, <a href="%2$s" target="_blank">please read here</a>)', 'wordpress-popular-posts'), 'http://en.wikipedia.org/wiki/Sample_%28statistics%29', 'https://github.com/cabrerahector/wordpress-popular-posts/wiki/7.-Performance#data-sampling'); ?>.</p>
571
+ </td>
572
+ </tr>
573
+ <tr valign="top" <?php if ( ! $this->config['tools']['sampling']['active'] ) { ?>style="display: none;"<?php } ?>>
574
+ <th scope="row"><label for="sample_rate"><?php _e("Sample Rate", 'wordpress-popular-posts'); ?>:</label></th>
575
+ <td>
576
+ <input name="sample_rate" type="text" id="sample_rate" value="<?php echo ( isset($this->config['tools']['sampling']['rate']) ) ? (int) $this->config['tools']['sampling']['rate'] : 100; ?>" class="small-text">
577
+ <br />
578
+ <p class="description"><?php echo sprintf(__("A sampling rate of %d is recommended for large / high traffic sites. For lower traffic sites, you should lower the value", 'wordpress-popular-posts'), 100); ?>.</p>
579
+ </td>
580
+ </tr>
581
+ <tr valign="top">
582
+ <td colspan="2">
583
+ <input type="hidden" name="section" value="data">
584
+ <input type="submit" class="button-primary action" id="btn_ajax_ops" value="<?php _e("Apply", 'wordpress-popular-posts'); ?>" name="">
585
+ </td>
586
+ </tr>
587
+ </tbody>
588
+ </table>
589
+
590
+ <?php wp_nonce_field('wpp-update-data-options', 'wpp-update-data-options-token'); ?>
591
+ </form>
592
+ <br />
593
+ <p style="display: block; float:none; clear: both;">&nbsp;</p>
594
+
595
+ <h3 class="wmpp-subtitle"><?php _e("Miscellaneous", 'wordpress-popular-posts'); ?></h3>
596
+
597
+ <form action="" method="post" id="wpp_link_options" name="wpp_link_options">
598
+ <table class="form-table">
599
+ <tbody>
600
+ <tr valign="top">
601
+ <th scope="row"><label for="link_target"><?php _e("Open links in", 'wordpress-popular-posts'); ?>:</label></th>
602
+ <td>
603
+ <select name="link_target" id="link_target">
604
+ <option <?php if ($this->config['tools']['link']['target'] == '_self') { ?>selected="selected"<?php } ?> value="_self"><?php _e("Current window", 'wordpress-popular-posts'); ?></option>
605
+ <option <?php if ($this->config['tools']['link']['target'] == '_blank') { ?>selected="selected"<?php } ?> value="_blank"><?php _e("New tab/window", 'wordpress-popular-posts'); ?></option>
606
+ </select>
607
+ <br />
608
+ </td>
609
+ </tr>
610
+ <tr valign="top">
611
+ <th scope="row"><label for="css"><?php _e("Use plugin's stylesheet", 'wordpress-popular-posts'); ?>:</label></th>
612
+ <td>
613
+ <select name="css" id="css">
614
+ <option <?php if ($this->config['tools']['css']) { ?>selected="selected"<?php } ?> value="1"><?php _e("Enabled", 'wordpress-popular-posts'); ?></option>
615
+ <option <?php if (!$this->config['tools']['css']) { ?>selected="selected"<?php } ?> value="0"><?php _e("Disabled", 'wordpress-popular-posts'); ?></option>
616
+ </select>
617
+ <br />
618
+ <p class="description"><?php _e("By default, the plugin includes a stylesheet called wpp.css which you can use to style your popular posts listing. If you wish to use your own stylesheet or do not want it to have it included in the header section of your site, use this.", 'wordpress-popular-posts'); ?></p>
619
+ </td>
620
+ </tr>
621
+ <tr valign="top">
622
+ <td colspan="2">
623
+ <input type="hidden" name="section" value="misc">
624
+ <input type="submit" class="button-primary action" value="<?php _e("Apply", 'wordpress-popular-posts'); ?>" name="">
625
+ </td>
626
+ </tr>
627
+ </tbody>
628
+ </table>
629
+
630
+ <?php wp_nonce_field('wpp-update-misc-options', 'wpp-update-misc-options-token'); ?>
631
+ </form>
632
+ <br />
633
+ <p style="display: block; float: none; clear: both;">&nbsp;</p>
634
+
635
+ <div style="display: <?php echo ( current_user_can('manage_options') ) ? 'block' : 'none'; ?>">
636
+ <br /><br />
637
+
638
+ <p><?php _e('WordPress Popular Posts maintains data in two separate tables: one for storing the most popular entries on a daily basis (from now on, "cache"), and another one to keep the All-time data (from now on, "historical data" or just "data"). If for some reason you need to clear the cache table, or even both historical and cache tables, please use the buttons below to do so.', 'wordpress-popular-posts') ?></p>
639
+ <p><input type="button" name="wpp-reset-cache" id="wpp-reset-cache" class="button-secondary" value="<?php _e("Empty cache", 'wordpress-popular-posts'); ?>" onclick="confirm_reset_cache()"> <label for="wpp-reset-cache"><small><?php _e('Use this button to manually clear entries from WPP cache only', 'wordpress-popular-posts'); ?></small></label></p>
640
+ <p><input type="button" name="wpp-reset-all" id="wpp-reset-all" class="button-secondary" value="<?php _e("Clear all data", 'wordpress-popular-posts'); ?>" onclick="confirm_reset_all()"> <label for="wpp-reset-all"><small><?php _e('Use this button to manually clear entries from all WPP data tables', 'wordpress-popular-posts'); ?></small></label></p>
641
+ </div>
642
+ </div>
643
+ <!-- End tools -->
644
+
645
+ <!-- Start params -->
646
+ <div id="wpp_params" <?php echo ( "params" == $current ) ? '' : ' style="display: none;"'; ?>>
647
+ <div>
648
+ <p><?php printf( __('With the following parameters you can customize the popular posts list when using either the <a href="%1$s">wpp_get_mostpopular() template tag</a> or the <a href="%2$s">[wpp] shortcode</a>.', 'wordpress-popular-posts'),
649
+ 'https://github.com/cabrerahector/wordpress-popular-posts/wiki/2.-Template-tags#wpp_get_mostpopular',
650
+ 'https://github.com/cabrerahector/wordpress-popular-posts/wiki/1.-Using-WPP-on-posts-&-pages'
651
+ ); ?></p>
652
+ <br />
653
+
654
+ <div style="overflow-x: auto;">
655
+ <table cellspacing="0" class="wp-list-table">
656
+ <thead>
657
+ <tr>
658
+ <th class="manage-column column-title"><?php _e('Parameter', 'wordpress-popular-posts'); ?></th>
659
+ <th class="manage-column column-title"><?php _e('What it does ', 'wordpress-popular-posts'); ?></th>
660
+ <th class="manage-column column-title"><?php _e('Possible values', 'wordpress-popular-posts'); ?></th>
661
+ <th class="manage-column column-title"><?php _e('Defaults to', 'wordpress-popular-posts'); ?></th>
662
+ <th class="manage-column column-title"><?php _e('Example', 'wordpress-popular-posts'); ?></th>
663
+ </tr>
664
+ </thead>
665
+ <tbody>
666
+ <tr>
667
+ <td><strong>header</strong></td>
668
+ <td><?php _e('Sets a heading for the list', 'wordpress-popular-posts'); ?></td>
669
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
670
+ <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
671
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'header' => 'Popular Posts'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp header='Popular Posts']<br /><br /></td>
672
+ </tr>
673
+ <tr class="alternate">
674
+ <td><strong>header_start</strong></td>
675
+ <td><?php _e('Set the opening tag for the heading of the list', 'wordpress-popular-posts'); ?></td>
676
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
677
+ <td>&lt;h2&gt;</td>
678
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'header' => 'Popular Posts', <br />&nbsp;&nbsp;&nbsp;&nbsp;'header_start' => '&lt;h3 class="title"&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'header_end' => '&lt;/h3&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp header='Popular Posts' header_start='&lt;h3 class="title"&gt;' header_end='&lt;/h3&gt;']<br /><br /></td>
679
+ </tr>
680
+ <tr>
681
+ <td><strong>header_end</strong></td>
682
+ <td><?php _e('Set the closing tag for the heading of the list', 'wordpress-popular-posts'); ?></td>
683
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
684
+ <td>&lt;/h2&gt;</td>
685
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'header' => 'Popular Posts', <br />&nbsp;&nbsp;&nbsp;&nbsp;'header_start' => '&lt;h3 class="title"&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'header_end' => '&lt;/h3&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp header='Popular Posts' header_start='&lt;h3 class="title"&gt;' header_end='&lt;/h3&gt;']<br /><br /></td>
686
+ </tr>
687
+ <tr class="alternate">
688
+ <td><strong>limit</strong></td>
689
+ <td><?php _e('Sets the maximum number of popular posts to be shown on the listing', 'wordpress-popular-posts'); ?></td>
690
+ <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
691
+ <td>10</td>
692
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'limit' => 5<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp limit=5]<br /><br /></td>
693
+ </tr>
694
+ <tr>
695
+ <td><strong>range</strong></td>
696
+ <td><?php _e('Tells WordPress Popular Posts to retrieve the most popular entries within the time range specified by you', 'wordpress-popular-posts'); ?></td>
697
+ <td>"last24hours", "last7days", "last30days", "all", "custom"</td>
698
+ <td>last24hours</td>
699
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'range' => 'last7days'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp range='last7days']<br /><br /></td>
700
+ </tr>
701
+ <tr class="alternate">
702
+ <td><strong>time_quantity</strong></td>
703
+ <td><?php _e('Especifies the number of time units of the custom time range', 'wordpress-popular-posts'); ?></td>
704
+ <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
705
+ <td>24</td>
706
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'range' => 'custom',<br />&nbsp;&nbsp;&nbsp;&nbsp;'time_quantity' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'time_unit' => 'hour'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp range='custom' time_quantity=1 time_unit='hour']<br /><br /></td>
707
+ </tr>
708
+ <tr>
709
+ <td><strong>time_unit</strong></td>
710
+ <td><?php _e('Especifies the time unit of the custom time range', 'wordpress-popular-posts'); ?></td>
711
+ <td>minute, hour, day, week, month</td>
712
+ <td>hour</td>
713
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'range' => 'custom',<br />&nbsp;&nbsp;&nbsp;&nbsp;'time_quantity' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'time_unit' => 'hour'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp range='custom' time_quantity=1 time_unit='hour']<br /><br /></td>
714
+ </tr>
715
+ <tr class="alternate">
716
+ <td><strong>freshness</strong></td>
717
+ <td><?php _e('Tells WordPress Popular Posts to retrieve the most popular entries published within the time range specified by you', 'wordpress-popular-posts'); ?></td>
718
+ <td>1 (true), 0 (false)</td>
719
+ <td>0</td>
720
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'range' => 'weekly',<br />&nbsp;&nbsp;&nbsp;&nbsp;'freshness' => 1<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp range='last7days' freshness=1]<br /><br /></td>
721
+ </tr>
722
+ <tr>
723
+ <td><strong>order_by</strong></td>
724
+ <td><?php _e('Sets the sorting option of the popular posts', 'wordpress-popular-posts'); ?></td>
725
+ <td>"comments", "views", "avg" <?php _e('(for average views per day)', 'wordpress-popular-posts'); ?></td>
726
+ <td>views</td>
727
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'order_by' => 'comments'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp order_by='comments']<br /><br /></td>
728
+ </tr>
729
+ <tr class="alternate">
730
+ <td><strong>post_type</strong></td>
731
+ <td><?php _e('Defines the type of posts to show on the listing', 'wordpress-popular-posts'); ?></td>
732
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
733
+ <td>post</td>
734
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_type' => 'post,page,your-custom-post-type'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp post_type='post,page,your-custom-post-type']<br /><br /></td>
735
+ </tr>
736
+ <tr>
737
+ <td><strong>pid</strong></td>
738
+ <td><?php _e('If set, WordPress Popular Posts will exclude the specified post(s) ID(s) form the listing.', 'wordpress-popular-posts'); ?></td>
739
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
740
+ <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
741
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'pid' => '60,25,31'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp pid='60,25,31']<br /><br /></td>
742
+ </tr>
743
+ <tr class="alternate">
744
+ <td><strong>cat</strong></td>
745
+ <td><?php _e('If set, WordPress Popular Posts will retrieve all entries that belong to the specified category ID(s). If a minus sign is used, entries associated to the category will be excluded instead.', 'wordpress-popular-posts'); ?></td>
746
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
747
+ <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
748
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'cat' => '1,55,-74'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp cat='1,55,-74']<br /><br /></td>
749
+ </tr>
750
+ <tr>
751
+ <td><strong>taxonomy</strong></td>
752
+ <td><?php _e('If set, WordPress Popular Posts will filter posts by a given taxonomy.', 'wordpress-popular-posts'); ?></td>
753
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
754
+ <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
755
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'taxonomy' => 'post_tag',<br />&nbsp;&nbsp;&nbsp;&nbsp;'term_id' => '118,75,15'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'taxonomy' => 'category; post_tag',<br />&nbsp;&nbsp;&nbsp;&nbsp;'term_id' => '1,55,-74; 118,75,15'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp taxonomy='post_tag' term_id='118,75,15']<br /><br />[wpp taxonomy='category; post_tag' term_id='1,55,-74; 118,75,15']<br /><br /></td>
756
+ </tr>
757
+ <tr class="alternate">
758
+ <td><strong>term_id</strong></td>
759
+ <td><?php _e('If set, WordPress Popular Posts will retrieve all entries that belong to the specified term ID(s). If a minus sign is used, entries associated to the term(s) will be excluded instead.', 'wordpress-popular-posts'); ?></td>
760
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
761
+ <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
762
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'taxonomy' => 'post_tag',<br />&nbsp;&nbsp;&nbsp;&nbsp;'term_id' => '118,75,15'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp taxonomy='post_tag' term_id='118,75,15']<br /><br /></td>
763
+ </tr>
764
+ <tr>
765
+ <td><strong>author</strong></td>
766
+ <td><?php _e('If set, WordPress Popular Posts will retrieve all entries created by specified author(s) ID(s).', 'wordpress-popular-posts'); ?></td>
767
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
768
+ <td><?php _e('None', 'wordpress-popular-posts'); ?></td>
769
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'author' => '75,8,120'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp author='75,8,120']<br /><br /></td>
770
+ </tr>
771
+ <tr class="alternate">
772
+ <td><strong>title_length</strong></td>
773
+ <td><?php _e('If set, WordPress Popular Posts will shorten each post title to "n" characters whenever possible', 'wordpress-popular-posts'); ?></td>
774
+ <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
775
+ <td>25</td>
776
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'title_length' => 25<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp title_length=25]<br /><br /></td>
777
+ </tr>
778
+ <tr>
779
+ <td><strong>title_by_words</strong></td>
780
+ <td><?php _e('If set to 1, WordPress Popular Posts will shorten each post title to "n" words instead of characters', 'wordpress-popular-posts'); ?></td>
781
+ <td>1 (true), (0) false</td>
782
+ <td>0</td>
783
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'title_by_words' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'title_length' => 25<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp title_by_words=1 title_length=25]<br /><br /></td>
784
+ </tr>
785
+ <tr class="alternate">
786
+ <td><strong>excerpt_length</strong></td>
787
+ <td><?php _e('If set, WordPress Popular Posts will build and include an excerpt of "n" characters long from the content of each post listed as popular', 'wordpress-popular-posts'); ?></td>
788
+ <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
789
+ <td>0</td>
790
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_length' => 55,<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp excerpt_length=25 post_html='&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;']<br /><br /></td>
791
+ </tr>
792
+ <tr>
793
+ <td><strong>excerpt_format</strong></td>
794
+ <td><?php _e('If set, WordPress Popular Posts will maintaing all styling tags (strong, italic, etc) and hyperlinks found in the excerpt', 'wordpress-popular-posts'); ?></td>
795
+ <td>1 (true), (0) false</td>
796
+ <td>0</td>
797
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_format' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_length' => 55,<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp excerpt_format=1 excerpt_length=25 post_html='&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;']<br /><br /></td>
798
+ </tr>
799
+ <tr class="alternate">
800
+ <td><strong>excerpt_by_words</strong></td>
801
+ <td><?php _e('If set to 1, WordPress Popular Posts will shorten the excerpt to "n" words instead of characters', 'wordpress-popular-posts'); ?></td>
802
+ <td>1 (true), (0) false</td>
803
+ <td>0</td>
804
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_by_words' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'excerpt_length' => 55,<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp excerpt_by_words=1 excerpt_length=55 post_html='&lt;li&gt;{title} &lt;span class="wpp-excerpt"&gt;{summary}&lt;/span&gt;&lt;/li&gt;']<br /><br /></td>
805
+ </tr>
806
+ <tr>
807
+ <td><strong>thumbnail_width</strong></td>
808
+ <td><?php _e('If set, and if your current server configuration allows it, you will be able to display thumbnails of your posts. This attribute sets the width for thumbnails', 'wordpress-popular-posts'); ?></td>
809
+ <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
810
+ <td>0</td>
811
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_width' => 30,<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_height' => 30<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp thumbnail_width=30 thumbnail_height=30]<br /><br /></td>
812
+ </tr>
813
+ <tr class="alternate">
814
+ <td><strong>thumbnail_height</strong></td>
815
+ <td><?php _e('If set, and if your current server configuration allows it, you will be able to display thumbnails of your posts. This attribute sets the height for thumbnails', 'wordpress-popular-posts'); ?></td>
816
+ <td><?php _e('Positive integer', 'wordpress-popular-posts'); ?></td>
817
+ <td>0</td>
818
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_width' => 30,<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_height' => 30<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp thumbnail_width=30 thumbnail_height=30]<br /><br /></td>
819
+ </tr>
820
+ <tr>
821
+ <td><strong>rating</strong></td>
822
+ <td><?php _e('If set, and if the WP-PostRatings plugin is installed and enabled on your blog, WordPress Popular Posts will show how your visitors are rating your entries', 'wordpress-popular-posts'); ?></td>
823
+ <td>1 (true), (0) false</td>
824
+ <td>0</td>
825
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'rating' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{title} {rating}&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp rating=1 post_html='&lt;li&gt;{title} {rating}&lt;/li&gt;']<br /><br /></td>
826
+ </tr>
827
+ <tr class="alternate">
828
+ <td><strong>stats_comments</strong></td>
829
+ <td><?php _e('If set, WordPress Popular Posts will show how many comments each popular post has got during the specified time range', 'wordpress-popular-posts'); ?></td>
830
+ <td>1 (true), 0 (false)</td>
831
+ <td>0</td>
832
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_comments' => 1<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_comments=1]<br /><br /></td>
833
+ </tr>
834
+ <tr>
835
+ <td><strong>stats_views</strong></td>
836
+ <td><?php _e('If set, WordPress Popular Posts will show how many views each popular post has got during the specified time range', 'wordpress-popular-posts'); ?></td>
837
+ <td>1 (true), (0) false</td>
838
+ <td>1</td>
839
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_views' => 0<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_views=0]<br /><br /></td>
840
+ </tr>
841
+ <tr class="alternate">
842
+ <td><strong>stats_author</strong></td>
843
+ <td><?php _e('If set, WordPress Popular Posts will show who published each popular post on the list', 'wordpress-popular-posts'); ?></td>
844
+ <td>1 (true), (0) false</td>
845
+ <td>0</td>
846
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_author' => 1<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_author=1]<br /><br /></td>
847
+ </tr>
848
+ <tr>
849
+ <td><strong>stats_date</strong></td>
850
+ <td><?php _e('If set, WordPress Popular Posts will display the date when each popular post on the list was published', 'wordpress-popular-posts'); ?></td>
851
+ <td>1 (true), (0) false</td>
852
+ <td>0</td>
853
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_date' => 1<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_date=1]<br /><br /></td>
854
+ </tr>
855
+ <tr class="alternate">
856
+ <td><strong>stats_date_format</strong></td>
857
+ <td><?php _e('Sets the date format', 'wordpress-popular-posts'); ?></td>
858
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
859
+ <td>0</td>
860
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_date' => 1,<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_date_format' => 'F j, Y'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_date=1 stats_date_format='F j, Y']<br /><br /></td>
861
+ </tr>
862
+ <tr>
863
+ <td><strong>stats_category</strong></td>
864
+ <td><?php _e('If set, WordPress Popular Posts will display the categories associated to each entry', 'wordpress-popular-posts'); ?></td>
865
+ <td>1 (true), (0) false</td>
866
+ <td>0</td>
867
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_category' => 1, <br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;&lt;a href="{url}"&gt;{text_title}&lt;/a&gt; {category}&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_taxonomy=1 post_html='&lt;li&gt;&lt;a href="{url}"&gt;{text_title}&lt;/a&gt; {category}&lt;/li&gt;']<br /><br /></td>
868
+ </tr>
869
+ <tr class="alternate">
870
+ <td><strong>stats_taxonomy</strong></td>
871
+ <td><?php _e('If set, WordPress Popular Posts will display the taxonomies associated to each entry', 'wordpress-popular-posts'); ?></td>
872
+ <td>1 (true), (0) false</td>
873
+ <td>0</td>
874
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'stats_taxonomy' => 1, <br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;&lt;a href="{url}"&gt;{text_title}&lt;/a&gt; {taxonomy}&lt;/li&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp stats_taxonomy=1 post_html='&lt;li&gt;&lt;a href="{url}"&gt;{text_title}&lt;/a&gt; {taxonomy}&lt;/li&gt;']<br /><br /></td>
875
+ </tr>
876
+ <tr>
877
+ <td><strong>wpp_start</strong></td>
878
+ <td><?php _e('Sets the opening tag for the listing', 'wordpress-popular-posts'); ?></td>
879
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
880
+ <td>&lt;ul&gt;</td>
881
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'wpp_start' => '&lt;ol&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'wpp_end' => '&lt;/ol&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp wpp_start='&lt;ol&gt;' wpp_end='&lt;/ol&gt;']<br /><br /></td>
882
+ </tr>
883
+ <tr class="alternate">
884
+ <td><strong>wpp_end</strong></td>
885
+ <td><?php _e('Sets the closing tag for the listing', 'wordpress-popular-posts'); ?></td>
886
+ <td><?php _e('Text string', 'wordpress-popular-posts'); ?></td>
887
+ <td>&lt;/ul&gt;</td>
888
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'wpp_start' => '&lt;ol&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'wpp_end' => '&lt;/ol&gt;'<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp wpp_start='&lt;ol&gt;' wpp_end='&lt;/ol&gt;']<br /><br /></td>
889
+ </tr>
890
+ <tr>
891
+ <td><strong>post_html</strong></td>
892
+ <td><?php _e('Sets the HTML structure of each post', 'wordpress-popular-posts'); ?></td>
893
+ <td><?php _e('Text string, custom HTML', 'wordpress-popular-posts'); ?>.<br /><br /><strong><?php _e('Available Content Tags', 'wordpress-popular-posts'); ?>:</strong> <br /><br /><em>{thumb}</em> (<?php _e('returns thumbnail linked to post/page, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{thumb_img}</em> (<?php _e('returns thumbnail image without linking to post/page, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{thumb_url}</em> (<?php _e('returns thumbnail url, requires thumbnail_width & thumbnail_height', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{title}</em> (<?php _e('returns linked post/page title', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{pid}</em> (<?php _e('returns the post/page ID', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{summary}</em> (<?php _e('returns post/page excerpt, and requires excerpt_length to be greater than 0', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{stats}</em> (<?php _e('returns the default stats tags', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{rating}</em> (<?php _e('returns post/page current rating, requires WP-PostRatings installed and enabled', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{score}</em> (<?php _e('returns post/page current rating as an integer, requires WP-PostRatings installed and enabled', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{url}</em> (<?php _e('returns the URL of the post/page', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{text_title}</em> (<?php _e('returns post/page title, no link', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{title_attr}</em> (<?php _e('similar to text_title, sanitized for use in title/alt attributes', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{author}</em> (<?php _e('returns linked author name, requires stats_author=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{author_copy}</em> (<?php _e('returns linked author name with copy, requires stats_author=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{category}</em> (<?php _e('returns linked category name, requires stats_category=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{category_copy}</em> (<?php _e('returns linked category name with copy, requires stats_category=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{taxonomy}</em> (<?php _e('returns linked taxonomy names, requires stats_taxonomy=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{taxonomy_copy}</em> (<?php _e('returns linked taxonomy names with copy, requires stats_taxonomy=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{views}</em> (<?php _e('returns views count only, no text, requires stats_views=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{views_copy}</em> (<?php _e('returns views count with copy, requires stats_views=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{comments}</em> (<?php _e('returns comments count only, no text, requires stats_comments=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{comments_copy}</em> (<?php _e('returns comments count with copy, requires stats_comments=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{date}</em> (<?php _e('returns post/page date, requires stats_date=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{date_copy}</em> (<?php _e('returns post/page date with copy, requires stats_date=1', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{total_items}</em> (<?php _e('outputs number of popular posts found', 'wordpress-popular-posts'); ?>)<br /><br /> <em>{item_position}</em> (<?php _e('outputs the position of the post in the listing', 'wordpress-popular-posts'); ?>)</td>
894
+ <td>&lt;li&gt;{thumb} {title} &lt;span class="wpp-meta post-stats"&gt;{stats}&lt;/span&gt;&lt;/li&gt;</td>
895
+ <td><strong><?php _e('With wpp_get_mostpopular():', 'wordpress-popular-posts'); ?></strong><br /><br />&lt;?php<br />$args = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;'post_html' => '&lt;li&gt;{thumb} &lt;a href="{url}"&gt;{text_title}&lt;/a&gt;&lt;/li&gt;',<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_width' => 100,<br />&nbsp;&nbsp;&nbsp;&nbsp;'thumbnail_height' => 75<br />);<br /><br />wpp_get_mostpopular($args);<br />?&gt;<br /><br /><hr /><br /><strong><?php _e('With the [wpp] shortcode:', 'wordpress-popular-posts'); ?></strong><br /><br />[wpp thumbnail_width=100 thumbnail_height=75 post_html='&lt;li&gt;{thumb} &lt;a href="{url}"&gt;{text_title}&lt;/a&gt;&lt;/li&gt;']<br /><br /></td>
896
+ </tr>
897
+ </tbody>
898
+ </table>
899
+ </div>
900
+ </div>
901
+ </div>
902
+ <!-- End params -->
903
+
904
+ <!-- Start debug -->
905
+ <?php
906
+ global $wpdb, $wp_version;
907
+
908
+ $my_theme = wp_get_theme();
909
+ $site_plugins = get_plugins();
910
+ $plugin_names = [];
911
+ $performance_nag = get_option('wpp_performance_nag');
912
+
913
+ if ( ! $performance_nag ) {
914
+ $performance_nag = [
915
+ 'status' => 0,
916
+ 'last_checked' => null
917
+ ];
918
+ }
919
+
920
+ switch($performance_nag['status']) {
921
+ case 0:
922
+ $performance_nag_status = 'Inactive';
923
+ break;
924
+ case 1:
925
+ $performance_nag_status = 'Active';
926
+ break;
927
+ case 2:
928
+ $performance_nag_status = 'Remind me later';
929
+ break;
930
+ case 3:
931
+ $performance_nag_status = 'Dismissed';
932
+ break;
933
+ default:
934
+ $performance_nag_status = 'Inactive';
935
+ break;
936
+ }
937
+
938
+ foreach( $site_plugins as $main_file => $plugin_meta ) :
939
+ if ( ! is_plugin_active($main_file) )
940
+ continue;
941
+ $plugin_names[] = sanitize_text_field($plugin_meta['Name'] . ' ' . $plugin_meta['Version']);
942
+ endforeach;
943
+ ?>
944
+ <div id="wpp_debug" <?php echo ( "debug" == $current ) ? '' : ' style="display: none;"'; ?>>
945
+ <h3>Plugin Configuration</h3>
946
+ <p><strong>Performance Nag:</strong> <?php echo $performance_nag_status; ?></p>
947
+ <p><strong>Log Limit:</strong> <?php echo ( $this->config['tools']['log']['limit'] ) ? 'Yes, keep data for ' . $this->config['tools']['log']['expires_after'] . ' days' : 'No'; ?></p>
948
+ <p><strong>Log Views From:</strong> <?php echo ( 0 == $this->config['tools']['log']['level'] ) ? 'Visitors only' : ( (2 == $this->config['tools']['log']['level']) ? 'Logged-in users only' : 'Everyone' ); ?></p>
949
+ <p><strong>Data Caching:</strong> <?php echo ( $this->config['tools']['cache']['active'] ) ? 'Yes, ' . $this->config['tools']['cache']['interval']['value'] . ' ' . $this->config['tools']['cache']['interval']['time'] : 'No'; ?></p>
950
+ <p><strong>Data Sampling:</strong> <?php echo ( $this->config['tools']['sampling']['active'] ) ? 'Yes, with a rate of ' . $this->config['tools']['sampling']['rate'] : 'No'; ?></p>
951
+ <p><strong>External object cache:</strong> <?php echo ( wp_using_ext_object_cache() ) ? 'Yes' : 'No'; ?></p>
952
+ <p><strong>WPP_CACHE_VIEWS:</strong> <?php echo ( defined('WPP_CACHE_VIEWS') && WPP_CACHE_VIEWS ) ? 'Yes' : 'No'; ?></p>
953
+
954
+ <br />
955
+
956
+ <h3>System Info</h3>
957
+ <p><strong>PHP version:</strong> <?php echo phpversion(); ?></p>
958
+ <p><strong>PHP extensions:</strong> <?php echo implode(', ', get_loaded_extensions()); ?></p>
959
+ <p><strong>Database version:</strong> <?php echo $wpdb->get_var("SELECT VERSION();"); ?></p>
960
+ <p><strong>InnoDB availability:</strong> <?php echo $wpdb->get_var("SELECT SUPPORT FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE = 'InnoDB';"); ?></p>
961
+ <p><strong>WordPress version:</strong> <?php echo $wp_version; ?></p>
962
+ <p><strong>Multisite:</strong> <?php echo ( function_exists('is_multisite') && is_multisite() ) ? 'Yes' : 'No'; ?></p>
963
+ <p><strong>Active plugins:</strong> <?php echo implode(', ', $plugin_names); ?></p>
964
+ <p><strong>Theme:</strong> <?php echo $my_theme->get('Name') . ' (' . $my_theme->get('Version') . ') by ' . $my_theme->get('Author'); ?></p>
965
+ </div>
966
+ <!-- End debug -->
967
  </div>
src/Bootstrap.php CHANGED
@@ -1,25 +1,25 @@
1
- <?php
2
- /**
3
- * Plugin bootstrap file.
4
- */
5
- namespace WordPressPopularPosts;
6
-
7
- /** Composer autoloder */
8
- require __DIR__ . '/../vendor/autoload.php';
9
-
10
- register_activation_hook($wpp_main_plugin_file, [__NAMESPACE__ . '\Activation\Activator', 'activate']);
11
- register_deactivation_hook($wpp_main_plugin_file, [__NAMESPACE__ . '\Activation\Deactivator', 'deactivate']);
12
-
13
- $container = new Container\Container();
14
- $container->configure([
15
- new Container\WordPressPopularPostsConfiguration()
16
- ]);
17
-
18
- $WordPressPopularPosts = $container['wpp'];
19
- add_action('plugins_loaded', [$WordPressPopularPosts, 'init']);
20
-
21
- // WPP's template tags
22
- require __DIR__ . '/template-tags.php';
23
-
24
- // Deprecated functions/classes
25
- require __DIR__ . '/deprecated.php';
1
+ <?php
2
+ /**
3
+ * Plugin bootstrap file.
4
+ */
5
+ namespace WordPressPopularPosts;
6
+
7
+ /** Composer autoloder */
8
+ require __DIR__ . '/../vendor/autoload.php';
9
+
10
+ register_activation_hook($wpp_main_plugin_file, [__NAMESPACE__ . '\Activation\Activator', 'activate']);
11
+ register_deactivation_hook($wpp_main_plugin_file, [__NAMESPACE__ . '\Activation\Deactivator', 'deactivate']);
12
+
13
+ $container = new Container\Container();
14
+ $container->configure([
15
+ new Container\WordPressPopularPostsConfiguration()
16
+ ]);
17
+
18
+ $WordPressPopularPosts = $container['wpp'];
19
+ add_action('plugins_loaded', [$WordPressPopularPosts, 'init']);
20
+
21
+ // WPP's template tags
22
+ require __DIR__ . '/template-tags.php';
23
+
24
+ // Deprecated functions/classes
25
+ require __DIR__ . '/deprecated.php';
src/Cache.php CHANGED
@@ -1,112 +1,112 @@
1
- <?php
2
-
3
- /**
4
- * Helper class to store data in cache for a fixed amount of time.
5
- *
6
- * @link https://cabrerahector.com
7
- * @since 4.1.2
8
- *
9
- * @package WordPressPopularPosts
10
- * @subpackage WordPressPopularPosts/includes
11
- */
12
-
13
- /**
14
- * Helper class to store data in cache for a fixed amount of time.
15
- *
16
- * Stores data in cache via WordPress Transients (or any other available
17
- * method in the future) for a fixed amount of time to reduce the number
18
- * of database calls.
19
- *
20
- * @package WordPressPopularPosts
21
- * @subpackage WordPressPopularPosts/includes
22
- * @author Hector Cabrera <me@cabrerahector.com>
23
- */
24
-
25
- namespace WordPressPopularPosts;
26
-
27
- class Cache {
28
-
29
- /**
30
- * Retrieves cached data.
31
- *
32
- * @since 4.1.2
33
- * @access public
34
- * @param string $key The name of the cached data.
35
- * @return mixed
36
- */
37
- public static function get($key)
38
- {
39
- return get_transient($key);
40
- }
41
-
42
- /**
43
- * Retrieves cached data.
44
- *
45
- * @since 4.1.2
46
- * @access public
47
- * @param string $key The name of the cached data.
48
- * @param mixed $data The data being stored.
49
- */
50
- public static function set($key = null, $data = [], $time_value = 1, $time_unit = 'minute')
51
- {
52
- if ( !$key )
53
- return false;
54
-
55
- if (
56
- false === filter_var($time_value, FILTER_VALIDATE_INT)
57
- || $time_value <= 0
58
- ) {
59
- $time_value = 1;
60
- }
61
-
62
- switch( $time_unit ){
63
-
64
- case 'minute':
65
- $time = 60;
66
- break;
67
-
68
- case 'hour':
69
- $time = 60 * 60;
70
- break;
71
-
72
- case 'day':
73
- $time = 60 * 60 * 24;
74
- break;
75
-
76
- case 'week':
77
- $time = 60 * 60 * 24 * 7;
78
- break;
79
-
80
- case 'month':
81
- $time = 60 * 60 * 24 * 30;
82
- break;
83
-
84
- case 'year':
85
- $time = 60 * 60 * 24 * 365;
86
- break;
87
-
88
- default:
89
- $time = 60;
90
- break;
91
-
92
- }
93
-
94
- $expiration = $time * $time_value;
95
-
96
- // Store transient
97
- set_transient($key, $data, $expiration);
98
-
99
- // Store transient in WPP transients array for garbage collection
100
- $wpp_transients = get_option('wpp_transients');
101
-
102
- if ( !$wpp_transients ) {
103
- $wpp_transients = [$key];
104
- add_option('wpp_transients', $wpp_transients);
105
- } else {
106
- if ( !in_array($key, $wpp_transients) ) {
107
- $wpp_transients[] = $key;
108
- update_option('wpp_transients', $wpp_transients);
109
- }
110
- }
111
- }
112
  }
1
+ <?php
2
+
3
+ /**
4
+ * Helper class to store data in cache for a fixed amount of time.
5
+ *
6
+ * @link https://cabrerahector.com
7
+ * @since 4.1.2
8
+ *
9
+ * @package WordPressPopularPosts
10
+ * @subpackage WordPressPopularPosts/includes
11
+ */
12
+
13
+ /**
14
+ * Helper class to store data in cache for a fixed amount of time.
15
+ *
16
+ * Stores data in cache via WordPress Transients (or any other available
17
+ * method in the future) for a fixed amount of time to reduce the number
18
+ * of database calls.
19
+ *
20
+ * @package WordPressPopularPosts
21
+ * @subpackage WordPressPopularPosts/includes
22
+ * @author Hector Cabrera <me@cabrerahector.com>
23
+ */
24
+
25
+ namespace WordPressPopularPosts;
26
+
27
+ class Cache {
28
+
29
+ /**
30
+ * Retrieves cached data.
31
+ *
32
+ * @since 4.1.2
33
+ * @access public
34
+ * @param string $key The name of the cached data.
35
+ * @return mixed
36
+ */
37
+ public static function get($key)
38
+ {
39
+ return get_transient($key);
40
+ }
41
+
42
+ /**
43
+ * Retrieves cached data.
44
+ *
45
+ * @since 4.1.2
46
+ * @access public
47
+ * @param string $key The name of the cached data.
48
+ * @param mixed $data The data being stored.
49
+ */
50
+ public static function set($key = null, $data = [], $time_value = 1, $time_unit = 'minute')
51
+ {
52
+ if ( !$key )
53
+ return false;
54
+
55
+ if (
56
+ false === filter_var($time_value, FILTER_VALIDATE_INT)
57
+ || $time_value <= 0
58
+ ) {
59
+ $time_value = 1;
60
+ }
61
+
62
+ switch( $time_unit ){
63
+
64
+ case 'minute':
65
+ $time = 60;
66
+ break;
67
+
68
+ case 'hour':
69
+ $time = 60 * 60;
70
+ break;
71
+
72
+ case 'day':
73
+ $time = 60 * 60 * 24;
74
+ break;
75
+
76
+ case 'week':
77
+ $time = 60 * 60 * 24 * 7;
78
+ break;
79
+
80
+ case 'month':
81
+ $time = 60 * 60 * 24 * 30;
82
+ break;
83
+
84
+ case 'year':
85
+ $time = 60 * 60 * 24 * 365;
86
+ break;
87
+
88
+ default:
89
+ $time = 60;
90
+ break;
91
+
92
+ }
93
+
94
+ $expiration = $time * $time_value;
95
+
96
+ // Store transient
97
+ set_transient($key, $data, $expiration);
98
+
99
+ // Store transient in WPP transients array for garbage collection
100
+ $wpp_transients = get_option('wpp_transients');
101
+
102
+ if ( !$wpp_transients ) {
103
+ $wpp_transients = [$key];
104
+ add_option('wpp_transients', $wpp_transients);
105
+ } else {
106
+ if ( !in_array($key, $wpp_transients) ) {
107
+ $wpp_transients[] = $key;
108
+ update_option('wpp_transients', $wpp_transients);
109
+ }
110
+ }
111
+ }
112
  }
src/Container/Container.php CHANGED
@@ -1,110 +1,110 @@
1
- <?php
2
- /**
3
- * A Simple Dependency Injector Container (DIC).
4
- *
5
- * Largely based on Carl Alexander's Dependency Injection Container.
6
- * @link https://carlalexander.ca/dependency-injection-wordpress/
7
- */
8
-
9
- namespace WordPressPopularPosts\Container;
10
-
11
- class Container implements \ArrayAccess
12
- {
13
- /**
14
- * Values stored inside the container.
15
- *
16
- * @var array
17
- */
18
- private $values;
19
-
20
- /**
21
- * Constructor.
22
- *
23
- * @param array $values
24
- */
25
- public function __construct(array $values = [])
26
- {
27
- $this->values = $values;
28
- }
29
-
30
- /**
31
- * Configure the container using the given container configuration objects.
32
- *
33
- * @param array $configurations
34
- */
35
- public function configure(array $configurations)
36
- {
37
- foreach ($configurations as $configuration) {
38
- if ( $configuration instanceof ContainerConfigurationInterface )
39
- $configuration->modify($this);
40
- }
41
- }
42
-
43
- /**
44
- * Checks if there's a value in the container for the given key.
45
- *
46
- * @param mixed $key
47
- *
48
- * @return bool
49
- */
50
- public function offsetExists($key)
51
- {
52
- return array_key_exists($key, $this->values);
53
- }
54
-
55
- /**
56
- * Sets a value inside of the container.
57
- *
58
- * @param mixed $key
59
- * @param mixed $value
60
- */
61
- public function offsetSet($key, $value)
62
- {
63
- $this->values[$key] = $value;
64
- }
65
-
66
- /**
67
- * Unset the value in the container for the given key.
68
- *
69
- * @param mixed $key
70
- */
71
- public function offsetUnset($key)
72
- {
73
- unset($this->values[$key]);
74
- }
75
-
76
- /**
77
- * Get a value from the container.
78
- *
79
- * @param mixed $key
80
- *
81
- * @return mixed
82
- */
83
- public function offsetGet($key)
84
- {
85
- if ( ! $this->offsetExists($key) ) {
86
- throw new \InvalidArgumentException(sprintf('Container doesn\'t have a value stored for the "%s" key.', $key));
87
- }
88
- return $this->values[$key] instanceof \Closure ? $this->values[$key]($this) : $this->values[$key];
89
- }
90
-
91
- /**
92
- * Creates a closure used for creating a service using the given callable.
93
- *
94
- * @param \Closure $closure
95
- *
96
- * @return \Closure
97
- */
98
- public function service(\Closure $closure)
99
- {
100
- return function(Container $container) use ($closure) {
101
- static $object;
102
-
103
- if ( null === $object ) {
104
- $object = $closure($container);
105
- }
106
-
107
- return $object;
108
- };
109
- }
110
- }
1
+ <?php
2
+ /**
3
+ * A Simple Dependency Injector Container (DIC).
4
+ *
5
+ * Largely based on Carl Alexander's Dependency Injection Container.
6
+ * @link https://carlalexander.ca/dependency-injection-wordpress/
7
+ */
8
+
9
+ namespace WordPressPopularPosts\Container;
10
+
11
+ class Container implements \ArrayAccess
12
+ {
13
+ /**
14
+ * Values stored inside the container.
15
+ *
16
+ * @var array
17
+ */
18
+ private $values;
19
+
20
+ /**
21
+ * Constructor.
22
+ *
23
+ * @param array $values
24
+ */
25
+ public function __construct(array $values = [])
26
+ {
27
+ $this->values = $values;
28
+ }
29
+
30
+ /**
31
+ * Configure the container using the given container configuration objects.
32
+ *
33
+ * @param array $configurations
34
+ */
35
+ public function configure(array $configurations)
36
+ {
37
+ foreach ($configurations as $configuration) {
38
+ if ( $configuration instanceof ContainerConfigurationInterface )
39
+ $configuration->modify($this);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Checks if there's a value in the container for the given key.
45
+ *
46
+ * @param mixed $key
47
+ *
48
+ * @return bool
49
+ */
50
+ public function offsetExists($key)
51
+ {
52
+ return array_key_exists($key, $this->values);
53
+ }
54
+
55
+ /**
56
+ * Sets a value inside of the container.
57
+ *
58
+ * @param mixed $key
59
+ * @param mixed $value
60
+ */
61
+ public function offsetSet($key, $value)
62
+ {
63
+ $this->values[$key] = $value;
64
+ }
65
+
66
+ /**
67
+ * Unset the value in the container for the given key.
68
+ *
69
+ * @param mixed $key
70
+ */
71
+ public function offsetUnset($key)
72
+ {
73
+ unset($this->values[$key]);
74
+ }
75
+
76
+ /**
77
+ * Get a value from the container.
78
+ *
79
+ * @param mixed $key
80
+ *
81
+ * @return mixed
82
+ */
83
+ public function offsetGet($key)
84
+ {
85
+ if ( ! $this->offsetExists($key) ) {
86
+ throw new \InvalidArgumentException(sprintf('Container doesn\'t have a value stored for the "%s" key.', $key));
87
+ }
88
+ return $this->values[$key] instanceof \Closure ? $this->values[$key]($this) : $this->values[$key];
89
+ }
90
+
91
+ /**
92
+ * Creates a closure used for creating a service using the given callable.
93
+ *
94
+ * @param \Closure $closure
95
+ *
96
+ * @return \Closure
97
+ */
98
+ public function service(\Closure $closure)
99
+ {
100
+ return function(Container $container) use ($closure) {
101
+ static $object;
102
+
103
+ if ( null === $object ) {
104
+ $object = $closure($container);
105
+ }
106
+
107
+ return $object;
108
+ };
109
+ }
110
+ }
src/Container/ContainerConfigurationInterface.php CHANGED
@@ -1,17 +1,17 @@
1
- <?php
2
- /**
3
- * Contract to modify the DIC.
4
- */
5
-
6
- namespace WordPressPopularPosts\Container;
7
-
8
- interface ContainerConfigurationInterface
9
- {
10
- /**
11
- * Modifies the given dependency injection container.
12
- *
13
- * @since 5.0.0
14
- * @param Container $container
15
- */
16
- public function modify(Container $container);
17
- }
1
+ <?php
2
+ /**
3
+ * Contract to modify the DIC.
4
+ */
5
+
6
+ namespace WordPressPopularPosts\Container;
7
+
8
+ interface ContainerConfigurationInterface
9
+ {
10
+ /**
11
+ * Modifies the given dependency injection container.
12
+ *
13
+ * @since 5.0.0
14
+ * @param Container $container
15
+ */
16
+ public function modify(Container $container);
17
+ }
src/Container/WordPressPopularPostsConfiguration.php CHANGED
@@ -1,71 +1,71 @@
1
- <?php
2
- namespace WordPressPopularPosts\Container;
3
-
4
- use WordPressPopularPosts\Settings;
5
-
6
- class WordPressPopularPostsConfiguration implements ContainerConfigurationInterface
7
- {
8
- /**
9
- * Modifies the given dependency injection container.
10
- *
11
- * @since 5.0.0
12
- * @param Container $container
13
- */
14
- public function modify(Container $container)
15
- {
16
- $container['admin_options'] = Settings::get('admin_options');
17
- $container['widget_options'] = Settings::get('widget_options');
18
-
19
- $container['i18n'] = $container->service(function(Container $container) {
20
- return new \WordPressPopularPosts\I18N($container['admin_options']);
21
- });
22
-
23
- $container['translate'] = $container->service(function(Container $container) {
24
- return new \WordPressPopularPosts\Translate();
25
- });
26
-
27
- $container['image'] = $container->service(function(Container $container) {
28
- return new \WordPressPopularPosts\Image($container['admin_options']);
29
- });
30
-
31
- $container['themer'] = $container->service(function(Container $container) {
32
- return new \WordPressPopularPosts\Themer();
33
- });
34
-
35
- $container['output'] = $container->service(function(Container $container) {
36
- return new \WordPressPopularPosts\Output($container['widget_options'], $container['admin_options'], $container['image'], $container['translate'], $container['themer']);
37
- });
38
-
39
- $container['widget'] = $container->service(function(Container $container) {
40
- return new \WordPressPopularPosts\Widget\Widget($container['widget_options'], $container['admin_options'], $container['output'], $container['image'], $container['translate'], $container['themer']);
41
- });
42
-
43
- $container['posts_endpoint'] = $container->service(function(Container $container) {
44
- return new \WordPressPopularPosts\Rest\PostsEndpoint($container['admin_options'], $container['translate']);
45
- });
46
-
47
- $container['view_logger_endpoint'] = $container->service(function(Container $container) {
48
- return new \WordPressPopularPosts\Rest\ViewLoggerEndpoint($container['admin_options'], $container['translate']);
49
- });
50
-
51
- $container['widget_endpoint'] = $container->service(function(Container $container) {
52
- return new \WordPressPopularPosts\Rest\WidgetEndpoint($container['admin_options'], $container['translate'], $container['output']);
53
- });
54
-
55
- $container['rest'] = $container->service(function(Container $container) {
56
- return new \WordPressPopularPosts\Rest\Controller($container['posts_endpoint'], $container['view_logger_endpoint'], $container['widget_endpoint']);
57
- });
58
-
59
- $container['admin'] = $container->service(function(Container $container) {
60
- return new \WordPressPopularPosts\Admin\Admin($container['admin_options'], $container['image']);
61
- });
62
-
63
- $container['front'] = $container->service(function(Container $container) {
64
- return new \WordPressPopularPosts\Front\Front($container['admin_options'], $container['translate'], $container['output']);
65
- });
66
-
67
- $container['wpp'] = $container->service(function(Container $container) {
68
- return new \WordPressPopularPosts\WordPressPopularPosts($container['i18n'], $container['rest'], $container['admin'], $container['front'], $container['widget']);
69
- });
70
- }
71
- }
1
+ <?php
2
+ namespace WordPressPopularPosts\Container;
3
+
4
+ use WordPressPopularPosts\Settings;
5
+
6
+ class WordPressPopularPostsConfiguration implements ContainerConfigurationInterface
7
+ {
8
+ /**
9
+ * Modifies the given dependency injection container.
10
+ *
11
+ * @since 5.0.0
12
+ * @param Container $container
13
+ */
14
+ public function modify(Container $container)
15
+ {
16
+ $container['admin_options'] = Settings::get('admin_options');
17
+ $container['widget_options'] = Settings::get('widget_options');
18
+
19
+ $container['i18n'] = $container->service(function(Container $container) {
20
+ return new \WordPressPopularPosts\I18N($container['admin_options']);
21
+ });
22
+
23
+ $container['translate'] = $container->service(function(Container $container) {
24
+ return new \WordPressPopularPosts\Translate();
25
+ });
26
+
27
+ $container['image'] = $container->service(function(Container $container) {
28
+ return new \WordPressPopularPosts\Image($container['admin_options']);
29
+ });
30
+
31
+ $container['themer'] = $container->service(function(Container $container) {
32
+ return new \WordPressPopularPosts\Themer();
33
+ });
34
+
35
+ $container['output'] = $container->service(function(Container $container) {
36
+ return new \WordPressPopularPosts\Output($container['widget_options'], $container['admin_options'], $container['image'], $container['translate'], $container['themer']);
37
+ });
38
+
39
+ $container['widget'] = $container->service(function(Container $container) {
40
+ return new \WordPressPopularPosts\Widget\Widget($container['widget_options'], $container['admin_options'], $container['output'], $container['image'], $container['translate'], $container['themer']);
41
+ });
42
+
43
+ $container['posts_endpoint'] = $container->service(function(Container $container) {
44
+ return new \WordPressPopularPosts\Rest\PostsEndpoint($container['admin_options'], $container['translate']);
45
+ });
46
+
47
+ $container['view_logger_endpoint'] = $container->service(function(Container $container) {
48
+ return new \WordPressPopularPosts\Rest\ViewLoggerEndpoint($container['admin_options'], $container['translate']);
49
+ });
50
+
51
+ $container['widget_endpoint'] = $container->service(function(Container $container) {
52
+ return new \WordPressPopularPosts\Rest\WidgetEndpoint($container['admin_options'], $container['translate'], $container['output']);
53
+ });
54
+
55
+ $container['rest'] = $container->service(function(Container $container) {
56
+ return new \WordPressPopularPosts\Rest\Controller($container['posts_endpoint'], $container['view_logger_endpoint'], $container['widget_endpoint']);
57
+ });
58
+
59
+ $container['admin'] = $container->service(function(Container $container) {
60
+ return new \WordPressPopularPosts\Admin\Admin($container['admin_options'], $container['image']);
61
+ });
62
+
63
+ $container['front'] = $container->service(function(Container $container) {
64
+ return new \WordPressPopularPosts\Front\Front($container['admin_options'], $container['translate'], $container['output']);
65
+ });
66
+
67
+ $container['wpp'] = $container->service(function(Container $container) {
68
+ return new \WordPressPopularPosts\WordPressPopularPosts($container['i18n'], $container['rest'], $container['admin'], $container['front'], $container['widget']);
69
+ });
70
+ }
71
+ }
src/Front/Front.php CHANGED
@@ -1,516 +1,516 @@
1
- <?php
2
- /**
3
- * The public-facing functionality of the plugin.
4
- *
5
- * Defines hooks to enqueue the public-specific stylesheet and JavaScript.
6
- *
7
- * @package WordPressPopularPosts
8
- * @subpackage WordPressPopularPosts/Front
9
- * @author Hector Cabrera <me@cabrerahector.com>
10
- */
11
-
12
- namespace WordPressPopularPosts\Front;
13
-
14
- use WordPressPopularPosts\Helper;
15
- use WordPressPopularPosts\Output;
16
- use WordPressPopularPosts\Query;
17
-
18
- class Front {
19
-
20
- /**
21
- * Plugin options.
22
- *
23
- * @var array $config
24
- * @access private
25
- */
26
- private $config;
27
-
28
- /**
29
- * Translate object.
30
- *
31
- * @var \WordPressPopularPosts\Translate $translate
32
- * @access private
33
- */
34
- private $translate;
35
-
36
- /**
37
- * Output object.
38
- *
39
- * @var \WordPressPopularPosts\Output $output
40
- * @access private
41
- */
42
- private $output;
43
-
44
- /**
45
- * Construct.
46
- *
47
- * @since 5.0.0
48
- * @param array $config Admin settings.
49
- * @param \WordPressPopularPosts\Translate $translate Translate class.
50
- */
51
- public function __construct(array $config, \WordPressPopularPosts\Translate $translate, \WordPressPopularPosts\Output $output)
52
- {
53
- $this->config = $config;
54
- $this->translate = $translate;
55
- $this->output = $output;
56
- }
57
-
58
- /**
59
- * WordPress public-facing hooks.
60
- *
61
- * @since 5.0.0
62
- */
63
- public function hooks()
64
- {
65
- add_shortcode('wpp', [$this, 'wpp_shortcode']);
66
- add_action('wp_head', [$this, 'inline_loading_css']);
67
- add_action('wp_ajax_update_views_ajax', [$this, 'update_views']);
68
- add_action('wp_ajax_nopriv_update_views_ajax', [$this, 'update_views']);
69
- add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
70
- add_filter('script_loader_tag', [$this, 'convert_inline_js_into_json'], 10, 3);
71
- }
72
-
73
- /**
74
- *
75
- */
76
- public function inline_loading_css()
77
- {
78
- ?>
79
- <style>
80
- @-webkit-keyframes bgslide {
81
- from {
82
- background-position-x: 0;
83
- }
84
- to {
85
- background-position-x: -200%;
86
- }
87
- }
88
-
89
- @keyframes bgslide {
90
- from {
91
- background-position-x: 0;
92
- }
93
- to {
94
- background-position-x: -200%;
95
- }
96
- }
97
-
98
- .wpp-widget-placeholder {
99
- margin: 0 auto;
100
- width: 60px;
101
- height: 3px;
102
- background: #dd3737;
103
- background: -webkit-gradient(linear, left top, right top, from(#dd3737), color-stop(10%, #571313), to(#dd3737));
104
- background: linear-gradient(90deg, #dd3737 0%, #571313 10%, #dd3737 100%);
105
- background-size: 200% auto;
106
- border-radius: 3px;
107
- -webkit-animation: bgslide 1s infinite linear;
108
- animation: bgslide 1s infinite linear;
109
- }
110
- </style>
111
- <?php
112
- }
113
-
114
- /**
115
- * Enqueues public facing assets.
116
- *
117
- * @since 5.0.0
118
- */
119
- public function enqueue_assets()
120
- {
121
- // Enqueue WPP's stylesheet.
122
- if ( $this->config['tools']['css'] ) {
123
- $theme_file = get_stylesheet_directory() . '/wpp.css';
124
-
125
- if ( @is_file($theme_file) ) {
126
- wp_enqueue_style('wordpress-popular-posts-css', get_stylesheet_directory_uri() . "/wpp.css", [], WPP_VERSION, 'all');
127
- } // Load stock stylesheet
128
- else {
129
- wp_enqueue_style('wordpress-popular-posts-css', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/css/wpp.css', [], WPP_VERSION, 'all');
130
- }
131
- }
132
-
133
- // Enqueue WPP's library.
134
- $is_single = 0;
135
-
136
- if (
137
- ( 0 == $this->config['tools']['log']['level'] && ! is_user_logged_in() )
138
- || ( 1 == $this->config['tools']['log']['level'] )
139
- || ( 2 == $this->config['tools']['log']['level'] && is_user_logged_in() )
140
- ) {
141
- $is_single = Helper::is_single();
142
- }
143
-
144
- wp_register_script('wpp-js', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/js/wpp.min.js', [], WPP_VERSION, false);
145
- $params = [
146
- 'sampling_active' => (int) $this->config['tools']['sampling']['active'],
147
- 'sampling_rate' => (int) $this->config['tools']['sampling']['rate'],
148
- 'ajax_url' => esc_url_raw(rest_url('wordpress-popular-posts/v1/popular-posts')),
149
- 'ID' => (int) $is_single,
150
- 'token' => wp_create_nonce('wp_rest'),
151
- 'lang' => function_exists('PLL') ? $this->translate->get_current_language() : 0,
152
- 'debug' => (int) WP_DEBUG
153
- ];
154
- wp_enqueue_script('wpp-js');
155
- wp_add_inline_script('wpp-js', json_encode($params), 'before');
156
- }
157
-
158
- /**
159
- * Converts inline script tag into type=application/json.
160
- *
161
- * This function mods the original script tag as printed
162
- * by WordPress which contains the data for the wpp_params
163
- * object into a JSON script. This improves compatibility
164
- * with Content Security Policy (CSP).
165
- *
166
- * @since 5.2.0
167
- * @param string $tag
168
- * @param string $handle
169
- * @param string $src
170
- * @return string $tag
171
- */
172
- function convert_inline_js_into_json($tag, $handle, $src)
173
- {
174
- if ( 'wpp-js' === $handle ) {
175
- // id attribute found, replace it
176
- if ( false !== strpos($tag, 'wpp-js-js-before') ) {
177
- $tag = str_replace('wpp-js-js-before', 'wpp-json', $tag);
178
- } // id attribute missing, let's add it
179
- else {
180
- $pos = strpos($tag, '>');
181
- $tag = substr_replace($tag, ' id="wpp-json">', $pos, 1);
182
- }
183
-
184
- // type attribute found, replace it
185
- if ( false !== strpos($tag, 'type') ) {
186
- $pos = strpos($tag, 'text/javascript');
187
-
188
- if ( false !== $pos )
189
- $tag = substr_replace($tag, 'application/json', $pos, strlen('text/javascript'));
190
- } // type attribute missing, let's add it
191
- else {
192
- $pos = strpos($tag, '>');
193
- $tag = substr_replace($tag, ' type="application/json">', $pos, 1);
194
- }
195
- }
196
-
197
- return $tag;
198
- }
199
-
200
- /**
201
- * Updates views count on page load via AJAX.
202
- *
203
- * @since 2.0.0
204
- */
205
- public function update_views()
206
- {
207
- if ( ! wp_verify_nonce($_POST['token'], 'wpp-token') || ! Helper::is_number($_POST['wpp_id']) ) {
208
- die( "WPP: Oops, invalid request!" );
209
- }
210
-
211
- $nonce = $_POST['token'];
212
- $post_ID = $_POST['wpp_id'];
213
- $exec_time = 0;
214
-
215
- $start = Helper::microtime_float();
216
- $result = $this->update_views_count($post_ID);
217
- $end = Helper::microtime_float();
218
- $exec_time += round($end - $start, 6);
219
-
220
- if ( $result ) {
221
- die("WPP: OK. Execution time: " . $exec_time . " seconds");
222
- }
223
-
224
- die("WPP: Oops, could not update the views count!");
225
- }
226
-
227
- /**
228
- * Updates views count.
229
- *
230
- * @since 1.4.0
231
- * @access private
232
- * @global object $wpdb
233
- * @param int $post_ID
234
- * @return bool|int FALSE if query failed, TRUE on success
235
- */
236
- private function update_views_count($post_ID) {
237
- /*
238
- TODO:
239
- For WordPress Multisite, we must define the DIEONDBERROR constant for database errors to display like so:
240
- <?php define( 'DIEONDBERROR', true ); ?>
241
- */
242
- global $wpdb;
243
- $table = $wpdb->prefix . "popularposts";
244
- $wpdb->show_errors();
245
-
246
- // Get translated object ID
247
- $post_ID = $this->translate->get_object_id(
248
- $post_ID,
249
- get_post_type($post_ID),
250
- true,
251
- $this->translate->get_default_language()
252
- );
253
- $now = Helper::now();
254
- $curdate = Helper::curdate();
255
- $views = ( $this->config['tools']['sampling']['active'] )
256
- ? $this->config['tools']['sampling']['rate']
257
- : 1;
258
-
259
- // Allow WP themers / coders perform an action
260
- // before updating views count
261
- if ( has_action('wpp_pre_update_views') )
262
- do_action('wpp_pre_update_views', $post_ID, $views);
263
-
264
- // Update all-time table
265
- $result1 = $wpdb->query($wpdb->prepare(
266
- "INSERT INTO {$table}data
267
- (postid, day, last_viewed, pageviews) VALUES (%d, %s, %s, %d)
268
- ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, last_viewed = %s;",
269
- $post_ID,
270
- $now,
271
- $now,
272
- $views,
273
- $views,
274
- $now
275
- ));
276
-
277
- // Update range (summary) table
278
- $result2 = $wpdb->query($wpdb->prepare(
279
- "INSERT INTO {$table}summary
280
- (postid, pageviews, view_date, view_datetime) VALUES (%d, %d, %s, %s)
281
- ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, view_datetime = %s;",
282
- $post_ID,
283
- $views,
284
- $curdate,
285
- $now,
286
- $views,
287
- $now
288
- ));
289
-
290
- if ( !$result1 || !$result2 )
291
- return false;
292
-
293
- // Allow WP themers / coders perform an action
294
- // after updating views count
295
- if ( has_action('wpp_post_update_views' ))
296
- do_action('wpp_post_update_views', $post_ID);
297
-
298
- return true;
299
- }
300
-
301
- /**
302
- * WPP shortcode handler.
303
- *
304
- * @since 1.4.0
305
- * @param array $atts User defined attributes in shortcode tag
306
- * @return string
307
- */
308
- public function wpp_shortcode($atts = null) {
309
- /**
310
- * @var string $header
311
- * @var int $limit
312
- * @var int $offset
313
- * @var string $range
314
- * @var bool $freshness
315
- * @var string $order_by
316
- * @var string $post_type
317
- * @var string $pid
318
- * @var string $cat
319
- * @var string $author
320
- * @var int $title_length
321
- * @var int $title_by_words
322
- * @var int $excerpt_length
323
- * @var int $excerpt_format
324
- * @var int $excerpt_by_words
325
- * @var int $thumbnail_width
326
- * @var int $thumbnail_height
327
- * @var bool $rating
328
- * @var bool $stats_comments
329
- * @var bool $stats_views
330
- * @var bool $stats_author
331
- * @var bool $stats_date
332
- * @var string $stats_date_format
333
- * @var bool $stats_category
334
- * @var string $wpp_start
335
- * @var string $wpp_end
336
- * @var string $header_start
337
- * @var string $header_end
338
- * @var string $post_html
339
- * @var bool $php
340
- */
341
- extract(shortcode_atts([
342
- 'header' => '',
343
- 'limit' => 10,
344
- 'offset' => 0,
345
- 'range' => 'daily',
346
- 'time_unit' => 'hour',
347
- 'time_quantity' => 24,
348
- 'freshness' => false,
349
- 'order_by' => 'views',
350
- 'post_type' => 'post',
351
- 'pid' => '',
352
- 'cat' => '',
353
- 'taxonomy' => 'category',
354
- 'term_id' => '',
355
- 'author' => '',
356
- 'title_length' => 0,
357
- 'title_by_words' => 0,
358
- 'excerpt_length' => 0,
359
- 'excerpt_format' => 0,
360
- 'excerpt_by_words' => 0,
361
- 'thumbnail_width' => 0,
362
- 'thumbnail_height' => 0,
363
- 'rating' => false,
364
- 'stats_comments' => false,
365
- 'stats_views' => true,
366
- 'stats_author' => false,
367
- 'stats_date' => false,
368
- 'stats_date_format' => 'F j, Y',
369
- 'stats_category' => false,
370
- 'stats_taxonomy' => false,
371
- 'wpp_start' => '<ul class="wpp-list">',
372
- 'wpp_end' => '</ul>',
373
- 'header_start' => '<h2>',
374
- 'header_end' => '</h2>',
375
- 'post_html' => '',
376
- 'php' => false
377
- ], $atts, 'wpp'));
378
-
379
- // possible values for "Time Range" and "Order by"
380
- $time_units = ["minute", "hour", "day", "week", "month"];
381
- $range_values = ["daily", "last24hours", "weekly", "last7days", "monthly", "last30days", "all", "custom"];
382
- $order_by_values = ["comments", "views", "avg"];
383
-
384
- $shortcode_ops = [
385
- 'title' => strip_tags($header),
386
- 'limit' => ( ! empty($limit ) && Helper::is_number($limit) && $limit > 0 ) ? $limit : 10,
387
- 'offset' => ( ! empty($offset) && Helper::is_number($offset) && $offset >= 0 ) ? $offset : 0,
388
- 'range' => ( in_array($range, $range_values) ) ? $range : 'daily',
389
- 'time_quantity' => ( ! empty($time_quantity ) && Helper::is_number($time_quantity) && $time_quantity > 0 ) ? $time_quantity : 24,
390
- 'time_unit' => ( in_array($time_unit, $time_units) ) ? $time_unit : 'hour',
391
- 'freshness' => empty($freshness) ? false : $freshness,
392
- 'order_by' => ( in_array($order_by, $order_by_values) ) ? $order_by : 'views',
393
- 'post_type' => empty($post_type) ? 'post,page' : $post_type,
394
- 'pid' => rtrim(preg_replace('|[^0-9,]|', '', $pid), ","),
395
- 'cat' => rtrim(preg_replace('|[^0-9,-]|', '', $cat), ","),
396
- 'taxonomy' => empty($taxonomy) ? 'category' : $taxonomy,
397
- 'term_id' => rtrim(preg_replace('|[^0-9,;-]|', '', $term_id), ","),
398
- 'author' => rtrim(preg_replace('|[^0-9,]|', '', $author), ","),
399
- 'shorten_title' => [
400
- 'active' => ( ! empty($title_length) && Helper::is_number($title_length) && $title_length > 0 ),
401
- 'length' => ( ! empty($title_length) && Helper::is_number($title_length) ) ? $title_length : 0,
402
- 'words' => ( ! empty($title_by_words) && Helper::is_number($title_by_words) && $title_by_words > 0 ),
403
- ],
404
- 'post-excerpt' => [
405
- 'active' => ( ! empty($excerpt_length) && Helper::is_number($excerpt_length) && $excerpt_length > 0 ),
406
- 'length' => ( ! empty($excerpt_length) && Helper::is_number($excerpt_length) ) ? $excerpt_length : 0,
407
- 'keep_format' => ( ! empty($excerpt_format) && Helper::is_number($excerpt_format) && $excerpt_format > 0 ),
408
- 'words' => ( ! empty($excerpt_by_words) && Helper::is_number($excerpt_by_words) && $excerpt_by_words > 0 ),
409
- ],
410
- 'thumbnail' => [
411
- 'active' => ( ! empty($thumbnail_width) && Helper::is_number($thumbnail_width) && $thumbnail_width > 0 ),
412
- 'width' => ( ! empty($thumbnail_width) && Helper::is_number($thumbnail_width) && $thumbnail_width > 0 ) ? $thumbnail_width : 0,
413
- 'height' => ( ! empty($thumbnail_height) && Helper::is_number($thumbnail_height) && $thumbnail_height > 0 ) ? $thumbnail_height : 0,
414
- ],
415
- 'rating' => empty($rating) ? false : $rating,
416
- 'stats_tag' => [
417
- 'comment_count' => empty($stats_comments) ? false : $stats_comments,
418
- 'views' => empty($stats_views) ? false : $stats_views,
419
- 'author' => empty($stats_author) ? false : $stats_author,
420
- 'date' => [
421
- 'active' => empty($stats_date) ? false : $stats_date,
422
- 'format' => empty($stats_date_format) ? 'F j, Y' : $stats_date_format
423
- ],
424
- 'category' => empty($stats_category) ? false : $stats_category,
425
- 'taxonomy' => [
426
- 'active' => empty($stats_taxonomy) ? false : $stats_taxonomy,
427
- 'name' => empty($taxonomy) ? 'category' : $taxonomy,
428
- ]
429
- ],
430
- 'markup' => [
431
- 'custom_html' => true,
432
- 'wpp-start' => empty($wpp_start) ? '' : $wpp_start,
433
- 'wpp-end' => empty($wpp_end) ? '' : $wpp_end,
434
- 'title-start' => empty($header_start) ? '' : $header_start,
435
- 'title-end' => empty($header_end) ? '' : $header_end,
436
- 'post-html' => empty($post_html) ? '<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>' : $post_html
437
- ]
438
- ];
439
-
440
- // Post / Page / CTP filter
441
- $ids = array_filter(explode(",", $shortcode_ops['pid']), 'is_numeric');
442
- // Got no valid IDs, clear
443
- if ( empty($ids) ) {
444
- $shortcode_ops['pid'] = '';
445
- }
446
-
447
- // Category filter
448
- $ids = array_filter(explode(",", $shortcode_ops['cat']), 'is_numeric');
449
- // Got no valid IDs, clear
450
- if ( empty($ids) ) {
451
- $shortcode_ops['cat'] = '';
452
- }
453
-
454
- // Author filter
455
- $ids = array_filter(explode( ",", $shortcode_ops['author']), 'is_numeric');
456
- // Got no valid IDs, clear
457
- if ( empty($ids) ) {
458
- $shortcode_ops['author'] = '';
459
- }
460
-
461
- $shortcode_content = '';
462
-
463
- // is there a title defined by user?
464
- if (
465
- ! empty($header)
466
- && ! empty($header_start)
467
- && ! empty($header_end)
468
- ) {
469
- $shortcode_content .= htmlspecialchars_decode($header_start, ENT_QUOTES) . $header . htmlspecialchars_decode($header_end, ENT_QUOTES);
470
- }
471
-
472
- $cached = false;
473
-
474
- // Return cached results
475
- if ( $this->config['tools']['cache']['active'] ) {
476
-
477
- $key = md5(json_encode($shortcode_ops));
478
- $popular_posts = \WordPressPopularPosts\Cache::get($key);
479
-
480
- if ( false === $popular_posts ) {
481
- $popular_posts = new Query($shortcode_ops);
482
-
483
- $time_value = $this->config['tools']['cache']['interval']['value']; // eg. 5
484
- $time_unit = $this->config['tools']['cache']['interval']['time']; // eg. 'minute'
485
-
486
- // No popular posts found, check again in 1 minute
487
- if ( ! $popular_posts->get_posts() ) {
488
- $time_value = 1;
489
- $time_unit = 'minute';
490
- }
491
-
492
- \WordPressPopularPosts\Cache::set(
493
- $key,
494
- $popular_posts,
495
- $time_value,
496
- $time_unit
497
- );
498
- }
499
-
500
- $cached = true;
501
-
502
- } // Get popular posts
503
- else {
504
- $popular_posts = new Query($shortcode_ops);
505
- }
506
-
507
- $this->output->set_data($popular_posts->get_posts());
508
- $this->output->set_public_options($shortcode_ops);
509
- $this->output->build_output();
510
-
511
- $shortcode_content .= $this->output->get_output();
512
-
513
- return $shortcode_content;
514
- }
515
-
516
- }
1
+ <?php
2
+ /**
3
+ * The public-facing functionality of the plugin.
4
+ *
5
+ * Defines hooks to enqueue the public-specific stylesheet and JavaScript.
6
+ *
7
+ * @package WordPressPopularPosts
8
+ * @subpackage WordPressPopularPosts/Front
9
+ * @author Hector Cabrera <me@cabrerahector.com>
10
+ */
11
+
12
+ namespace WordPressPopularPosts\Front;
13
+
14
+ use WordPressPopularPosts\Helper;
15
+ use WordPressPopularPosts\Output;
16
+ use WordPressPopularPosts\Query;
17
+
18
+ class Front {
19
+
20
+ /**
21
+ * Plugin options.
22
+ *
23
+ * @var array $config
24
+ * @access private
25
+ */
26
+ private $config;
27
+
28
+ /**
29
+ * Translate object.
30
+ *
31
+ * @var \WordPressPopularPosts\Translate $translate
32
+ * @access private
33
+ */
34
+ private $translate;
35
+
36
+ /**
37
+ * Output object.
38
+ *
39
+ * @var \WordPressPopularPosts\Output $output
40
+ * @access private
41
+ */
42
+ private $output;
43
+
44
+ /**
45
+ * Construct.
46
+ *
47
+ * @since 5.0.0
48
+ * @param array $config Admin settings.
49
+ * @param \WordPressPopularPosts\Translate $translate Translate class.
50
+ */
51
+ public function __construct(array $config, \WordPressPopularPosts\Translate $translate, \WordPressPopularPosts\Output $output)
52
+ {
53
+ $this->config = $config;
54
+ $this->translate = $translate;
55
+ $this->output = $output;
56
+ }
57
+
58
+ /**
59
+ * WordPress public-facing hooks.
60
+ *
61
+ * @since 5.0.0
62
+ */
63
+ public function hooks()
64
+ {
65
+ add_shortcode('wpp', [$this, 'wpp_shortcode']);
66
+ add_action('wp_head', [$this, 'inline_loading_css']);
67
+ add_action('wp_ajax_update_views_ajax', [$this, 'update_views']);
68
+ add_action('wp_ajax_nopriv_update_views_ajax', [$this, 'update_views']);
69
+ add_action('wp_enqueue_scripts', [$this, 'enqueue_assets']);
70
+ add_filter('script_loader_tag', [$this, 'convert_inline_js_into_json'], 10, 3);
71
+ }
72
+
73
+ /**
74
+ *
75
+ */
76
+ public function inline_loading_css()
77
+ {
78
+ ?>
79
+ <style>
80
+ @-webkit-keyframes bgslide {
81
+ from {
82
+ background-position-x: 0;
83
+ }
84
+ to {
85
+ background-position-x: -200%;
86
+ }
87
+ }
88
+
89
+ @keyframes bgslide {
90
+ from {
91
+ background-position-x: 0;
92
+ }
93
+ to {
94
+ background-position-x: -200%;
95
+ }
96
+ }
97
+
98
+ .wpp-widget-placeholder {
99
+ margin: 0 auto;
100
+ width: 60px;
101
+ height: 3px;
102
+ background: #dd3737;
103
+ background: -webkit-gradient(linear, left top, right top, from(#dd3737), color-stop(10%, #571313), to(#dd3737));
104
+ background: linear-gradient(90deg, #dd3737 0%, #571313 10%, #dd3737 100%);
105
+ background-size: 200% auto;
106
+ border-radius: 3px;
107
+ -webkit-animation: bgslide 1s infinite linear;
108
+ animation: bgslide 1s infinite linear;
109
+ }
110
+ </style>
111
+ <?php
112
+ }
113
+
114
+ /**
115
+ * Enqueues public facing assets.
116
+ *
117
+ * @since 5.0.0
118
+ */
119
+ public function enqueue_assets()
120
+ {
121
+ // Enqueue WPP's stylesheet.
122
+ if ( $this->config['tools']['css'] ) {
123
+ $theme_file = get_stylesheet_directory() . '/wpp.css';
124
+
125
+ if ( @is_file($theme_file) ) {
126
+ wp_enqueue_style('wordpress-popular-posts-css', get_stylesheet_directory_uri() . "/wpp.css", [], WPP_VERSION, 'all');
127
+ } // Load stock stylesheet
128
+ else {
129
+ wp_enqueue_style('wordpress-popular-posts-css', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/css/wpp.css', [], WPP_VERSION, 'all');
130
+ }
131
+ }
132
+
133
+ // Enqueue WPP's library.
134
+ $is_single = 0;
135
+
136
+ if (
137
+ ( 0 == $this->config['tools']['log']['level'] && ! is_user_logged_in() )
138
+ || ( 1 == $this->config['tools']['log']['level'] )
139
+ || ( 2 == $this->config['tools']['log']['level'] && is_user_logged_in() )
140
+ ) {
141
+ $is_single = Helper::is_single();
142
+ }
143
+
144
+ wp_register_script('wpp-js', plugin_dir_url(dirname(dirname(__FILE__))) . 'assets/js/wpp.min.js', [], WPP_VERSION, false);
145
+ $params = [
146
+ 'sampling_active' => (int) $this->config['tools']['sampling']['active'],
147
+ 'sampling_rate' => (int) $this->config['tools']['sampling']['rate'],
148
+ 'ajax_url' => esc_url_raw(rest_url('wordpress-popular-posts/v1/popular-posts')),
149
+ 'ID' => (int) $is_single,
150
+ 'token' => wp_create_nonce('wp_rest'),
151
+ 'lang' => function_exists('PLL') ? $this->translate->get_current_language() : 0,
152
+ 'debug' => (int) WP_DEBUG
153
+ ];
154
+ wp_enqueue_script('wpp-js');
155
+ wp_add_inline_script('wpp-js', json_encode($params), 'before');
156
+ }
157
+
158
+ /**
159
+ * Converts inline script tag into type=application/json.
160
+ *
161
+ * This function mods the original script tag as printed
162
+ * by WordPress which contains the data for the wpp_params
163
+ * object into a JSON script. This improves compatibility
164
+ * with Content Security Policy (CSP).
165
+ *
166
+ * @since 5.2.0
167
+ * @param string $tag
168
+ * @param string $handle
169
+ * @param string $src
170
+ * @return string $tag
171
+ */
172
+ function convert_inline_js_into_json($tag, $handle, $src)
173
+ {
174
+ if ( 'wpp-js' === $handle ) {
175
+ // id attribute found, replace it
176
+ if ( false !== strpos($tag, 'wpp-js-js-before') ) {
177
+ $tag = str_replace('wpp-js-js-before', 'wpp-json', $tag);
178
+ } // id attribute missing, let's add it
179
+ else {
180
+ $pos = strpos($tag, '>');
181
+ $tag = substr_replace($tag, ' id="wpp-json">', $pos, 1);
182
+ }
183
+
184
+ // type attribute found, replace it
185
+ if ( false !== strpos($tag, 'type') ) {
186
+ $pos = strpos($tag, 'text/javascript');
187
+
188
+ if ( false !== $pos )
189
+ $tag = substr_replace($tag, 'application/json', $pos, strlen('text/javascript'));
190
+ } // type attribute missing, let's add it
191
+ else {
192
+ $pos = strpos($tag, '>');
193
+ $tag = substr_replace($tag, ' type="application/json">', $pos, 1);
194
+ }
195
+ }
196
+
197
+ return $tag;
198
+ }
199
+
200
+ /**
201
+ * Updates views count on page load via AJAX.
202
+ *
203
+ * @since 2.0.0
204
+ */
205
+ public function update_views()
206
+ {
207
+ if ( ! wp_verify_nonce($_POST['token'], 'wpp-token') || ! Helper::is_number($_POST['wpp_id']) ) {
208
+ die( "WPP: Oops, invalid request!" );
209
+ }
210
+
211
+ $nonce = $_POST['token'];
212
+ $post_ID = $_POST['wpp_id'];
213
+ $exec_time = 0;
214
+
215
+ $start = Helper::microtime_float();
216
+ $result = $this->update_views_count($post_ID);
217
+ $end = Helper::microtime_float();
218
+ $exec_time += round($end - $start, 6);
219
+
220
+ if ( $result ) {
221
+ die("WPP: OK. Execution time: " . $exec_time . " seconds");
222
+ }
223
+
224
+ die("WPP: Oops, could not update the views count!");
225
+ }
226
+
227
+ /**
228
+ * Updates views count.
229
+ *
230
+ * @since 1.4.0
231
+ * @access private
232
+ * @global object $wpdb
233
+ * @param int $post_ID
234
+ * @return bool|int FALSE if query failed, TRUE on success
235
+ */
236
+ private function update_views_count($post_ID) {
237
+ /*
238
+ TODO:
239
+ For WordPress Multisite, we must define the DIEONDBERROR constant for database errors to display like so:
240
+ <?php define( 'DIEONDBERROR', true ); ?>
241
+ */
242
+ global $wpdb;
243
+ $table = $wpdb->prefix . "popularposts";
244
+ $wpdb->show_errors();
245
+
246
+ // Get translated object ID
247
+ $post_ID = $this->translate->get_object_id(
248
+ $post_ID,
249
+ get_post_type($post_ID),
250
+ true,
251
+ $this->translate->get_default_language()
252
+ );
253
+ $now = Helper::now();
254
+ $curdate = Helper::curdate();
255
+ $views = ( $this->config['tools']['sampling']['active'] )
256
+ ? $this->config['tools']['sampling']['rate']
257
+ : 1;
258
+
259
+ // Allow WP themers / coders perform an action
260
+ // before updating views count
261
+ if ( has_action('wpp_pre_update_views') )
262
+ do_action('wpp_pre_update_views', $post_ID, $views);
263
+
264
+ // Update all-time table
265
+ $result1 = $wpdb->query($wpdb->prepare(
266
+ "INSERT INTO {$table}data
267
+ (postid, day, last_viewed, pageviews) VALUES (%d, %s, %s, %d)
268
+ ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, last_viewed = %s;",
269
+ $post_ID,
270
+ $now,
271
+ $now,
272
+ $views,
273
+ $views,
274
+ $now
275
+ ));
276
+
277
+ // Update range (summary) table
278
+ $result2 = $wpdb->query($wpdb->prepare(
279
+ "INSERT INTO {$table}summary
280
+ (postid, pageviews, view_date, view_datetime) VALUES (%d, %d, %s, %s)
281
+ ON DUPLICATE KEY UPDATE pageviews = pageviews + %d, view_datetime = %s;",
282
+ $post_ID,
283
+ $views,
284
+ $curdate,
285
+ $now,
286
+ $views,
287
+ $now
288
+ ));
289
+
290
+ if ( !$result1 || !$result2 )
291
+ return false;
292
+
293
+ // Allow WP themers / coders perform an action
294
+ // after updating views count
295
+ if ( has_action('wpp_post_update_views' ))
296
+ do_action('wpp_post_update_views', $post_ID);
297
+
298
+ return true;
299
+ }
300
+
301
+ /**
302
+ * WPP shortcode handler.
303
+ *
304
+ * @since 1.4.0
305
+ * @param array $atts User defined attributes in shortcode tag
306
+ * @return string
307
+ */
308
+ public function wpp_shortcode($atts = null) {
309
+ /**
310
+ * @var string $header
311
+ * @var int $limit
312
+ * @var int $offset
313
+ * @var string $range
314
+ * @var bool $freshness
315
+ * @var string $order_by
316
+ * @var string $post_type
317
+ * @var string $pid
318
+ * @var string $cat
319
+ * @var string $author
320
+ * @var int $title_length
321
+ * @var int $title_by_words
322
+ * @var int $excerpt_length
323
+ * @var int $excerpt_format
324
+ * @var int $excerpt_by_words
325
+ * @var int $thumbnail_width
326
+ * @var int $thumbnail_height
327
+ * @var bool $rating
328
+ * @var bool $stats_comments
329
+ * @var bool $stats_views
330
+ * @var bool $stats_author
331
+ * @var bool $stats_date
332
+ * @var string $stats_date_format
333
+ * @var bool $stats_category
334
+ * @var string $wpp_start
335
+ * @var string $wpp_end
336
+ * @var string $header_start
337
+ * @var string $header_end
338
+ * @var string $post_html
339
+ * @var bool $php
340
+ */
341
+ extract(shortcode_atts([
342
+ 'header' => '',
343
+ 'limit' => 10,
344
+ 'offset' => 0,
345
+ 'range' => 'daily',
346
+ 'time_unit' => 'hour',
347
+ 'time_quantity' => 24,
348
+ 'freshness' => false,
349
+ 'order_by' => 'views',
350
+ 'post_type' => 'post',
351
+ 'pid' => '',
352
+ 'cat' => '',
353
+ 'taxonomy' => 'category',
354
+ 'term_id' => '',
355
+ 'author' => '',
356
+ 'title_length' => 0,
357
+ 'title_by_words' => 0,
358
+ 'excerpt_length' => 0,
359
+ 'excerpt_format' => 0,
360
+ 'excerpt_by_words' => 0,
361
+ 'thumbnail_width' => 0,
362
+ 'thumbnail_height' => 0,
363
+ 'rating' => false,
364
+ 'stats_comments' => false,
365
+ 'stats_views' => true,
366
+ 'stats_author' => false,
367
+ 'stats_date' => false,
368
+ 'stats_date_format' => 'F j, Y',
369
+ 'stats_category' => false,
370
+ 'stats_taxonomy' => false,
371
+ 'wpp_start' => '<ul class="wpp-list">',
372
+ 'wpp_end' => '</ul>',
373
+ 'header_start' => '<h2>',
374
+ 'header_end' => '</h2>',
375
+ 'post_html' => '',
376
+ 'php' => false
377
+ ], $atts, 'wpp'));
378
+
379
+ // possible values for "Time Range" and "Order by"
380
+ $time_units = ["minute", "hour", "day", "week", "month"];
381
+ $range_values = ["daily", "last24hours", "weekly", "last7days", "monthly", "last30days", "all", "custom"];
382
+ $order_by_values = ["comments", "views", "avg"];
383
+
384
+ $shortcode_ops = [
385
+ 'title' => strip_tags($header),
386
+ 'limit' => ( ! empty($limit ) && Helper::is_number($limit) && $limit > 0 ) ? $limit : 10,
387
+ 'offset' => ( ! empty($offset) && Helper::is_number($offset) && $offset >= 0 ) ? $offset : 0,
388
+ 'range' => ( in_array($range, $range_values) ) ? $range : 'daily',
389
+ 'time_quantity' => ( ! empty($time_quantity ) && Helper::is_number($time_quantity) && $time_quantity > 0 ) ? $time_quantity : 24,
390
+ 'time_unit' => ( in_array($time_unit, $time_units) ) ? $time_unit : 'hour',
391
+ 'freshness' => empty($freshness) ? false : $freshness,
392
+ 'order_by' => ( in_array($order_by, $order_by_values) ) ? $order_by : 'views',
393
+ 'post_type' => empty($post_type) ? 'post,page' : $post_type,
394
+ 'pid' => rtrim(preg_replace('|[^0-9,]|', '', $pid), ","),
395
+ 'cat' => rtrim(preg_replace('|[^0-9,-]|', '', $cat), ","),
396
+ 'taxonomy' => empty($taxonomy) ? 'category' : $taxonomy,
397
+ 'term_id' => rtrim(preg_replace('|[^0-9,;-]|', '', $term_id), ","),
398
+ 'author' => rtrim(preg_replace('|[^0-9,]|', '', $author), ","),
399
+ 'shorten_title' => [
400
+ 'active' => ( ! empty($title_length) && Helper::is_number($title_length) && $title_length > 0 ),
401
+ 'length' => ( ! empty($title_length) && Helper::is_number($title_length) ) ? $title_length : 0,
402
+ 'words' => ( ! empty($title_by_words) && Helper::is_number($title_by_words) && $title_by_words > 0 ),
403
+ ],
404
+ 'post-excerpt' => [
405
+ 'active' => ( ! empty($excerpt_length) && Helper::is_number($excerpt_length) && $excerpt_length > 0 ),
406
+ 'length' => ( ! empty($excerpt_length) && Helper::is_number($excerpt_length) ) ? $excerpt_length : 0,
407
+ 'keep_format' => ( ! empty($excerpt_format) && Helper::is_number($excerpt_format) && $excerpt_format > 0 ),
408
+ 'words' => ( ! empty($excerpt_by_words) && Helper::is_number($excerpt_by_words) && $excerpt_by_words > 0 ),
409
+ ],
410
+ 'thumbnail' => [
411
+ 'active' => ( ! empty($thumbnail_width) && Helper::is_number($thumbnail_width) && $thumbnail_width > 0 ),
412
+ 'width' => ( ! empty($thumbnail_width) && Helper::is_number($thumbnail_width) && $thumbnail_width > 0 ) ? $thumbnail_width : 0,
413
+ 'height' => ( ! empty($thumbnail_height) && Helper::is_number($thumbnail_height) && $thumbnail_height > 0 ) ? $thumbnail_height : 0,
414
+ ],
415
+ 'rating' => empty($rating) ? false : $rating,
416
+ 'stats_tag' => [
417
+ 'comment_count' => empty($stats_comments) ? false : $stats_comments,
418
+ 'views' => empty($stats_views) ? false : $stats_views,
419
+ 'author' => empty($stats_author) ? false : $stats_author,
420
+ 'date' => [
421
+ 'active' => empty($stats_date) ? false : $stats_date,
422
+ 'format' => empty($stats_date_format) ? 'F j, Y' : $stats_date_format
423
+ ],
424
+ 'category' => empty($stats_category) ? false : $stats_category,
425
+ 'taxonomy' => [
426
+ 'active' => empty($stats_taxonomy) ? false : $stats_taxonomy,
427
+ 'name' => empty($taxonomy) ? 'category' : $taxonomy,
428
+ ]
429
+ ],
430
+ 'markup' => [
431
+ 'custom_html' => true,
432
+ 'wpp-start' => empty($wpp_start) ? '' : $wpp_start,
433
+ 'wpp-end' => empty($wpp_end) ? '' : $wpp_end,
434
+ 'title-start' => empty($header_start) ? '' : $header_start,
435
+ 'title-end' => empty($header_end) ? '' : $header_end,
436
+ 'post-html' => empty($post_html) ? '<li>{thumb} {title} <span class="wpp-meta post-stats">{stats}</span></li>' : $post_html
437
+ ]
438
+ ];
439
+
440
+ // Post / Page / CTP filter
441
+ $ids = array_filter(explode(",", $shortcode_ops['pid']), 'is_numeric');
442
+ // Got no valid IDs, clear
443
+ if ( empty($ids) ) {
444
+ $shortcode_ops['pid'] = '';
445
+ }
446
+
447
+ // Category filter
448
+ $ids = array_filter(explode(",", $shortcode_ops['cat']), 'is_numeric');
449
+ // Got no valid IDs, clear
450
+ if ( empty($ids) ) {
451
+ $shortcode_ops['cat'] = '';
452
+ }
453
+
454
+ // Author filter
455
+ $ids = array_filter(explode( ",", $shortcode_ops['author']), 'is_numeric');
456
+ // Got no valid IDs, clear
457
+ if ( empty($ids) ) {
458
+ $shortcode_ops['author'] = '';
459
+ }
460
+
461
+ $shortcode_content = '';
462
+
463
+ // is there a title defined by user?
464
+ if (
465
+ ! empty($header)
466
+ && ! empty($header_start)
467
+ && ! empty($header_end)
468
+ ) {
469
+ $shortcode_content .= htmlspecialchars_decode($header_start, ENT_QUOTES) . $header . htmlspecialchars_decode($header_end, ENT_QUOTES);
470
+ }
471
+
472
+ $cached = false;
473
+
474
+ // Return cached results
475
+ if ( $this->config['tools']['cache']['active'] ) {
476
+
477
+ $key = md5(json_encode($shortcode_ops));
478
+ $popular_posts = \WordPressPopularPosts\Cache::get($key);
479
+
480
+ if ( false === $popular_posts ) {
481
+ $popular_posts = new Query($shortcode_ops);
482
+
483
+ $time_value = $this->config['tools']['cache']['interval']['value']; // eg. 5
484
+ $time_unit = $this->config['tools']['cache']['interval']['time']; // eg. 'minute'
485
+
486
+ // No popular posts found, check again in 1 minute
487
+ if ( ! $popular_posts->get_posts() ) {
488
+ $time_value = 1;
489
+ $time_unit = 'minute';
490
+ }
491
+
492
+ \WordPressPopularPosts\Cache::set(
493
+ $key,
494
+ $popular_posts,
495
+ $time_value,
496
+ $time_unit
497
+ );
498
+ }
499
+
500
+ $cached = true;
501
+
502
+ } // Get popular posts
503
+ else {
504
+ $popular_posts = new Query($shortcode_ops);
505
+ }
506
+
507
+ $this->output->set_data($popular_posts->get_posts());
508
+ $this->output->set_public_options($shortcode_ops);
509
+ $this->output->build_output();
510
+
511
+ $shortcode_content .= $this->output->get_output();
512
+
513
+ return $shortcode_content;
514
+ }
515
+
516
+ }
src/Helper.php CHANGED
@@ -1,337 +1,337 @@
1
- <?php
2
-
3
- namespace WordPressPopularPosts;
4
-
5
- class Helper {
6
-
7
- /**
8
- * Checks for valid number.
9
- *
10
- * @since 2.1.6
11
- * @param int number
12
- * @return bool
13
- */
14
- public static function is_number($number)
15
- {
16
- return !empty($number) && is_numeric($number) && (intval($number) == floatval($number));
17
- }
18
-
19
- /**
20
- * Converts a number into a short version, eg: 1000 -> 1k
21
- *
22
- * @see https://gist.github.com/RadGH/84edff0cc81e6326029c
23
- * @since 5.2.0
24
- * @param int
25
- * @param int
26
- * @return mixed string|bool
27
- */
28
- public static function prettify_number($number, $precision = 1)
29
- {
30
- if ( ! is_numeric($number) )
31
- return false;
32
-
33
- if ( $number < 900 ) {
34
- // 0 - 900
35
- $n_format = number_format($number, $precision);
36
- $suffix = '';
37
- } elseif ( $number < 900000 ) {
38
- // 0.9k-850k
39
- $n_format = number_format($number / 1000, $precision);
40
- $suffix = 'k';
41
- } elseif ( $number < 900000000 ) {
42
- // 0.9m-850m
43
- $n_format = number_format($number / 1000000, $precision);
44
- $suffix = 'm';
45
- } elseif ( $number < 900000000000 ) {
46
- // 0.9b-850b
47
- $n_format = number_format($number / 1000000000, $precision);
48
- $suffix = 'b';
49
- } else {
50
- // 0.9t+
51
- $n_format = number_format($number / 1000000000000, $precision);
52
- $suffix = 't';
53
- }
54
-
55
- // Remove unnecessary zeroes after decimal. "1.0" -> "1"; "1.00" -> "1"
56
- // Intentionally does not affect partials, eg "1.50" -> "1.50"
57
- if ( $precision > 0 ) {
58
- $dotzero = '.' . str_repeat('0', $precision);
59
- $n_format = str_replace($dotzero, '', $n_format);
60
- }
61
-
62
- return $n_format . $suffix;
63
- }
64
-
65
- /**
66
- * Checks for valid date.
67
- *
68
- * @since 4.0.0
69
- * @param string $date
70
- * @param string $format
71
- * @return bool
72
- */
73
- public static function is_valid_date($date = null, $format = 'Y-m-d')
74
- {
75
- $d = \DateTime::createFromFormat($format, $date);
76
- return $d && $d->format($format) === $date;
77
- }
78
-
79
- /**
80
- * Returns an array of dates between two dates.
81
- *
82
- * @since 4.0.0
83
- * @param string $start_date
84
- * @param string $end_date
85
- * @param string $format
86
- * @return array|bool
87
- */
88
- public static function get_date_range($start_date = null, $end_date = null, $format = 'Y-m-d')
89
- {
90
- if (
91
- self::is_valid_date($start_date, $format)
92
- && self::is_valid_date($end_date, $format)
93
- ) {
94
- $dates = [];
95
-
96
- $begin = new \DateTime($start_date, new \DateTimeZone(Helper::get_timezone()));
97
- $end = new \DateTime($end_date, new \DateTimeZone(Helper::get_timezone()));
98
-
99
- if ( $begin < $end ) {
100
- while( $begin <= $end ) {
101
- $dates[] = $begin->format($format);
102
- $begin->modify('+1 day');
103
- }
104
- }
105
- else {
106
- while( $begin >= $end ) {
107
- $dates[] = $begin->format($format);
108
- $begin->modify('-1 day');
109
- }
110
- }
111
-
112
- return $dates;
113
- }
114
-
115
- return false;
116
- }
117
-
118
- /**
119
- * Returns server date.
120
- *
121
- * @since 2.1.6
122
- * @access private
123
- * @return string
124
- */
125
- public static function curdate()
126
- {
127
- return current_time('Y-m-d', false);
128
- }
129
-
130
- /**
131
- * Returns mysql datetime.
132
- *
133
- * @since 2.1.6
134
- * @access private
135
- * @return string
136
- */
137
- public static function now()
138
- {
139
- return current_time('mysql');
140
- }
141
-
142
- /**
143
- * Returns current timestamp.
144
- *
145
- * @since 5.0.2
146
- * @return string
147
- */
148
- public static function timestamp()
149
- {
150
- // current_datetime() is WP 5.3+
151
- return ( function_exists('current_datetime') ) ? current_datetime()->getTimestamp() : current_time('timestamp');
152
- }
153
-
154
- /**
155
- * Checks whether a string is a valid timestamp.
156
- *
157
- * @since 5.2.0
158
- * @param string $string
159
- * @return bool
160
- */
161
- public static function is_timestamp($string)
162
- {
163
- if (
164
- ( is_int($string) || ctype_digit($string) )
165
- && strtotime(date('Y-m-d H:i:s', $string)) === (int) $string
166
- ) {
167
- return true;
168
- }
169
-
170
- return false;
171
- }
172
-
173
- /**
174
- * Returns site's timezone.
175
- *
176
- * Code borrowed from Rarst's awesome WpDateTime class: https://github.com/Rarst/wpdatetime
177
- *
178
- * @since 5.0.0
179
- * @return string
180
- */
181
- public static function get_timezone()
182
- {
183
- $timezone_string = get_option('timezone_string');
184
-
185
- if ( ! empty($timezone_string) ) {
186
- return $timezone_string;
187
- }
188
-
189
- $offset = get_option('gmt_offset');
190
- $sign = $offset < 0 ? '-' : '+';
191
- $hours = (int) $offset;
192
- $minutes = abs(($offset - (int) $offset) * 60);
193
- $offset = sprintf('%s%02d:%02d', $sign, abs($hours), $minutes);
194
-
195
- return $offset;
196
- }
197
-
198
- /**
199
- * Returns time.
200
- *
201
- * @since 2.3.0
202
- * @return string
203
- */
204
- public static function microtime_float()
205
- {
206
- list($msec, $sec) = explode(' ', microtime());
207
- return (float) $msec + (float) $sec;
208
- }
209
-
210
- /**
211
- * Merges two associative arrays recursively.
212
- *
213
- * @since 2.3.4
214
- * @link http://www.php.net/manual/en/function.array-merge-recursive.php#92195
215
- * @param array array1
216
- * @param array array2
217
- * @return array
218
- */
219
- public static function merge_array_r(array $array1, array $array2)
220
- {
221
- $merged = $array1;
222
-
223
- foreach( $array2 as $key => &$value ) {
224
- if ( is_array($value) && isset($merged[$key]) && is_array($merged[$key]) ) {
225
- $merged[$key] = self::merge_array_r($merged[$key], $value);
226
- } else {
227
- $merged[$key] = $value;
228
- }
229
- }
230
-
231
- return $merged;
232
- }
233
-
234
- /**
235
- * Debug function.
236
- *
237
- * @since 3.0.0
238
- * @param mixed $v variable to display with var_dump()
239
- * @param mixed $v,... unlimited optional number of variables to display with var_dump()
240
- */
241
- public static function debug($v)
242
- {
243
- if ( !defined('WPP_DEBUG') || !WPP_DEBUG )
244
- return;
245
-
246
- foreach( func_get_args() as $arg ) {
247
- print "<pre>";
248
- var_dump($arg);
249
- print "</pre>";
250
- }
251
- }
252
-
253
- /**
254
- * Truncates text.
255
- *
256
- * @since 4.0.0
257
- * @param string $text
258
- * @param int $length
259
- * @param bool $truncate_by_words
260
- * @return string
261
- */
262
- public static function truncate($text = '', $length = 25, $truncate_by_words = false, $more = '...')
263
- {
264
- if ( '' !== $text ) {
265
- // Truncate by words
266
- if ( $truncate_by_words ) {
267
- $words = explode(" ", $text, $length + 1);
268
-
269
- if ( count($words) > $length ) {
270
- array_pop($words);
271
- $text = rtrim(implode(" ", $words), ",.") . " {$more}";
272
- }
273
- }
274
- // Truncate by characters
275
- elseif ( strlen($text) > $length ) {
276
- $text = rtrim(mb_substr($text, 0, $length , get_bloginfo('charset')), " ,.") . $more;
277
- }
278
- }
279
-
280
- return $text;
281
- }
282
-
283
- /**
284
- * Gets post/page ID if current page is singular
285
- *
286
- * @since 3.1.2
287
- */
288
- public static function is_single()
289
- {
290
- $trackable = [];
291
- $registered_post_types = get_post_types(['public' => true], 'names');
292
-
293
- foreach( $registered_post_types as $post_type ) {
294
- $trackable[] = $post_type;
295
- }
296
-
297
- $trackable = apply_filters('wpp_trackable_post_types', $trackable);
298
-
299
- if (
300
- is_singular($trackable)
301
- && !is_front_page()
302
- && !is_preview()
303
- && !is_trackback()
304
- && !is_feed()
305
- && !is_robots()
306
- && !is_customize_preview()
307
- ) {
308
- return get_queried_object_id();
309
- }
310
-
311
- return false;
312
- }
313
-
314
- /**
315
- * Adds scheme to a given URL.
316
- *
317
- * @since 5.0.0
318
- * @param string $url
319
- * @param string $scheme
320
- * @return string|bool
321
- */
322
- static function add_scheme($url = null, $scheme = 'https://')
323
- {
324
- $url_args = parse_url($url);
325
-
326
- if ( $url_args ) {
327
- // No need to do anything, URL is fine
328
- if ( isset($url_args['scheme']) )
329
- return $url;
330
- // Return URL with scheme
331
- return $scheme . $url_args['host'] . $url_args['path'];
332
- }
333
-
334
- // Invalid/malformed URL
335
- return false;
336
- }
337
- }
1
+ <?php
2
+
3
+ namespace WordPressPopularPosts;
4
+
5
+ class Helper {
6
+
7
+ /**
8
+ * Checks for valid number.
9
+ *
10
+ * @since 2.1.6
11
+ * @param int number
12
+ * @return bool
13
+ */
14
+ public static function is_number($number)
15
+ {
16
+ return !empty($number) && is_numeric($number) && (intval($number) == floatval($number));
17
+ }
18
+
19
+ /**
20
+ * Converts a number into a short version, eg: 1000 -> 1k
21
+ *
22
+ * @see https://gist.github.com/RadGH/84edff0cc81e6326029c
23
+ * @since 5.2.0
24
+ * @param int
25
+ * @param int
26
+ * @return mixed string|bool
27
+ */
28
+ public static function prettify_number($number, $precision = 1)
29
+ {
30
+ if ( ! is_numeric($number) )
31
+ return false;
32
+
33
+ if ( $number < 900 ) {
34
+ // 0 - 900
35
+ $n_format = number_format($number, $precision);
36
+ $suffix = '';
37
+ } elseif ( $number < 900000 ) {
38
+ // 0.9k-850k
39
+ $n_format = number_format($number / 1000, $precision);
40
+ $suffix = 'k';
41
+ } elseif ( $number < 900000000 ) {
42
+ // 0.9m-850m
43
+ $n_format = number_format($number / 1000000, $precision);
44
+ $suffix = 'm';
45
+ } elseif ( $number < 900000000000 ) {
46
+ // 0.9b-850b
47
+ $n_format = number_format($number / 1000000000, $precision);
48
+ $suffix = 'b';
49
+ } else {
50
+ // 0.9t+
51
+ $n_format = number_format($number / 1000000000000, $precision);
52
+ $suffix = 't';
53
+ }
54
+
55
+ // Remove unnecessary zeroes after decimal. "1.0" -> "1"; "1.00" -> "1"
56
+ // Intentionally does not affect partials, eg "1.50" -> "1.50"
57
+ if ( $precision > 0 ) {
58
+ $dotzero = '.' . str_repeat('0', $precision);
59
+ $n_format = str_replace($dotzero, '', $n_format);
60
+ }
61
+
62
+ return $n_format . $suffix;
63
+ }
64
+
65
+ /**
66
+ * Checks for valid date.
67
+ *
68
+ * @since 4.0.0
69
+ * @param string $date
70
+ * @param string $format
71
+ * @return bool
72
+ */
73
+ public static function is_valid_date($date = null, $format = 'Y-m-d')
74
+ {
75
+ $d = \DateTime::createFromFormat($format, $date);
76
+ return $d && $d->format($format) === $date;
77
+ }
78
+
79
+ /**
80
+ * Returns an array of dates between two dates.
81
+ *
82
+ * @since 4.0.0
83
+ * @param string $start_date
84
+ * @param string $end_date
85
+ * @param string $format
86
+ * @return array|bool
87
+ */
88
+ public static function get_date_range($start_date = null, $end_date = null, $format = 'Y-m-d')
89
+ {
90
+ if (
91
+ self::is_valid_date($start_date, $format)
92
+ && self::is_valid_date($end_date, $format)
93
+ ) {
94
+ $dates = [];
95
+
96
+ $begin = new \DateTime($start_date, new \DateTimeZone(Helper::get_timezone()));
97
+ $end = new \DateTime($end_date, new \DateTimeZone(Helper::get_timezone()));
98
+
99
+ if ( $begin < $end ) {
100
+ while( $begin <= $end ) {
101
+ $dates[] = $begin->format($format);
102
+ $begin->modify('+1 day');
103
+ }
104
+ }
105
+ else {
106
+ while( $begin >= $end ) {
107
+ $dates[] = $begin->format($format);
108
+ $begin->modify('-1 day');
109
+ }
110
+ }
111
+
112
+ return $dates;
113
+ }
114
+
115
+ return false;
116
+ }
117
+
118
+ /**
119
+ * Returns server date.
120
+ *
121
+ * @since 2.1.6
122
+ * @access private
123
+ * @return string
124
+ */
125
+ public static function curdate()
126
+ {
127
+ return current_time('Y-m-d', false);
128
+ }
129
+
130
+ /**
131
+ * Returns mysql datetime.
132
+ *
133
+ * @since 2.1.6
134
+ * @access private
135
+ * @return string
136
+ */
137
+ public static function now()
138
+ {
139
+ return current_time('mysql');
140
+ }
141
+
142
+ /**
143
+ * Returns current timestamp.
144
+ *
145
+ * @since 5.0.2
146
+ * @return string
147
+ */
148
+ public static function timestamp()
149
+ {
150
+ // current_datetime() is WP 5.3+
151
+ return ( function_exists('current_datetime') ) ? current_datetime()->getTimestamp() : current_time('timestamp');
152
+ }
153
+
154
+ /**
155
+ * Checks whether a string is a valid timestamp.
156
+ *
157
+ * @since 5.2.0
158
+ * @param string $string
159
+ * @return bool
160
+ */
161
+ public static function is_timestamp($string)
162
+ {
163
+ if (
164
+ ( is_int($string) || ctype_digit($string) )
165
+ && strtotime(date('Y-m-d H:i:s', $string)) === (int) $string
166
+ ) {
167
+ return true;
168
+ }
169
+
170
+ return false;
171
+ }
172
+
173
+ /**
174
+ * Returns site's timezone.
175
+ *
176
+ * Code borrowed from Rarst's awesome WpDateTime class: https://github.com/Rarst/wpdatetime
177
+ *
178
+ * @since 5.0.0
179
+ * @return string
180
+ */
181
+ public static function get_timezone()
182
+ {
183
+ $timezone_string = get_option('timezone_string');
184
+
185
+ if ( ! empty($timezone_string) ) {
186
+ return $timezone_string;
187
+ }
188
+
189
+ $offset = get_option('gmt_offset');
190
+ $sign = $offset < 0 ? '-' : '+';
191
+ $hours = (int) $offset;
192
+ $minutes = abs(($offset - (int) $offset) * 60);
193
+ $offset = sprintf('%s%02d:%02d', $sign, abs($hours), $minutes);
194
+
195
+ return $offset;
196
+ }
197
+
198
+ /**
199
+ * Returns time.
200
+ *
201
+ * @since 2.3.0
202
+ * @return string
203
+ */
204
+ public static function microtime_float()
205
+ {
206
+ list($msec, $sec) = explode(' ', microtime());
207
+ return (float) $msec + (float) $sec;
208
+ }
209
+
210
+ /**
211
+ * Merges two associative arrays recursively.
212
+ *
213
+ * @since 2.3.4
214
+ * @link http://www.php.net/manual/en/function.array-merge-recursive.php#92195
215
+ * @param array array1
216
+ * @param array array2
217
+ * @return array
218
+ */
219
+ public static function merge_array_r(array $array1, array $array2)
220
+ {
221
+ $merged = $array1;
222
+
223
+ foreach( $array2 as $key => &$value ) {
224
+ if ( is_array($value) && isset($merged[$key]) && is_array($merged[$key]) ) {
225
+ $merged[$key] = self::merge_array_r($merged[$key], $value);
226
+ } else {
227
+ $merged[$key] = $value;
228
+ }
229
+ }
230
+
231
+ return $merged;
232
+ }
233
+
234
+ /**
235
+ * Debug function.
236
+ *
237
+ * @since 3.0.0
238
+ * @param mixed $v variable to display with var_dump()
239
+ * @param mixed $v,... unlimited optional number of variables to display with var_dump()
240
+ */
241
+ public static function debug($v)
242
+ {
243
+ if ( !defined('WPP_DEBUG') || !WPP_DEBUG )
244
+ return;
245
+
246
+ foreach( func_get_args() as $arg ) {
247
+ print "<pre>";
248
+ var_dump($arg);
249
+ print "</pre>";
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Truncates text.
255
+ *
256
+ * @since 4.0.0
257
+ * @param string $text
258
+ * @param int $length
259
+ * @param bool $truncate_by_words
260
+ * @return string
261
+ */
262
+ public static function truncate($text = '', $length = 25, $truncate_by_words = false, $more = '...')
263
+ {
264
+ if ( '' !== $text ) {
265
+ // Truncate by words
266
+ if ( $truncate_by_words ) {
267
+ $words = explode(" ", $text, $length + 1);
268
+
269
+ if ( count($words) > $length ) {
270
+ array_pop($words);
271
+ $text = rtrim(implode(" ", $words), ",.") . " {$more}";
272
+ }
273
+ }
274
+ // Truncate by characters
275
+ elseif ( strlen($text) > $length ) {
276
+ $text = rtrim(mb_substr($text, 0, $length , get_bloginfo('charset')), " ,.") . $more;
277
+ }
278
+ }
279
+
280
+ return $text;
281
+ }
282
+
283
+ /**
284
+ * Gets post/page ID if current page is singular
285
+ *
286
+ * @since 3.1.2
287
+ */
288
+ public static function is_single()
289
+ {
290
+ $trackable = [];
291
+ $registered_post_types = get_post_types(['public' => true], 'names');
292
+
293
+ foreach( $registered_post_types as $post_type ) {
294
+ $trackable[] = $post_type;
295
+ }
296
+
297
+ $trackable = apply_filters('wpp_trackable_post_types', $trackable);
298
+
299
+ if (
300
+ is_singular($trackable)
301
+ && !is_front_page()
302
+ && !is_preview()
303
+ && !is_trackback()
304
+ && !is_feed()
305
+ && !is_robots()
306
+ && !is_customize_preview()
307
+ ) {
308
+ return get_queried_object_id();
309
+ }
310
+
311
+ return false;
312
+ }
313
+
314
+ /**
315
+ * Adds scheme to a given URL.
316
+ *
317
+ * @since 5.0.0
318
+ * @param string $url
319
+ * @param string $scheme
320
+ * @return string|bool
321
+ */
322
+ static function add_scheme($url = null, $scheme = 'https://')
323
+ {
324
+ $url_args = parse_url($url);
325
+
326
+ if ( $url_args ) {
327
+ // No need to do anything, URL is fine
328
+ if ( isset($url_args['scheme']) )
329
+ return $url;
330
+ // Return URL with scheme
331
+ return $scheme . $url_args['host'] . $url_args['path'];
332
+ }
333
+
334
+ // Invalid/malformed URL
335
+ return false;
336
+ }
337
+ }
src/I18N.php CHANGED
@@ -1,49 +1,49 @@
1
- <?php
2
- /**
3
- * Define the internationalization functionality
4
- *
5
- * Loads and defines the internationalization files for this plugin
6
- * so that it is ready for translation.
7
- *
8
- * @since 4.0.0
9
- *
10
- * @package WordPressPopularPosts
11
- */
12
-
13
- namespace WordPressPopularPosts;
14
-
15
- class I18N {
16
- /**
17
- * Plugin options.
18
- *
19
- * @var array $config
20
- * @access private
21
- */
22
- private $config;
23
-
24
- /**
25
- * Construct.
26
- *
27
- * @since 5.3.0
28
- */
29
- public function __construct(array $config)
30
- {
31
- $this->config = $config;
32
- }
33
-
34
- /**
35
- * Load the plugin text domain for translation.
36
- *
37
- * @since 1.0.0
38
- */
39
- public function load_plugin_textdomain()
40
- {
41
- // This is basically a "hack" and should be removed in the future
42
- // if/when we figure out why Polylang doesn't load WPP's mo files
43
- // while WPML does that automatically.
44
- if ( ! is_admin() && ! $this->config['tools']['ajax'] && function_exists('PLL') ) {
45
- unload_textdomain('wordpress-popular-posts');
46
- load_textdomain('wordpress-popular-posts', WP_LANG_DIR . '/plugins/wordpress-popular-posts-' . get_locale() . '.mo');
47
- }
48
- }
49
- }
1
+ <?php
2
+ /**
3
+ * Define the internationalization functionality
4
+ *
5
+ * Loads and defines the internationalization files for this plugin
6
+ * so that it is ready for translation.
7
+ *
8
+ * @since 4.0.0
9
+ *
10
+ * @package WordPressPopularPosts
11
+ */
12
+
13
+ namespace WordPressPopularPosts;
14
+
15
+ class I18N {
16
+ /**
17
+ * Plugin options.
18
+ *
19
+ * @var array $config
20
+ * @access private
21
+ */
22
+ private $config;
23
+
24
+ /**
25
+ * Construct.
26
+ *
27
+ * @since 5.3.0
28
+ */
29
+ public function __construct(array $config)
30
+ {
31
+ $this->config = $config;
32
+ }
33
+
34
+ /**
35
+ * Load the plugin text domain for translation.
36
+ *
37
+ * @since 1.0.0
38
+ */
39
+ public function load_plugin_textdomain()
40
+ {
41
+ // This is basically a "hack" and should be removed in the future
42
+ // if/when we figure out why Polylang doesn't load WPP's mo files
43
+ // while WPML does that automatically.
44
+ if ( ! is_admin() && ! $this->config['tools']['ajax'] && function_exists('PLL') ) {
45
+ unload_textdomain('wordpress-popular-posts');
46
+ load_textdomain('wordpress-popular-posts', WP_LANG_DIR . '/plugins/wordpress-popular-posts-' . get_locale() . '.mo');
47
+ }
48
+ }
49
+ }
src/Image.php CHANGED
@@ -1,936 +1,954 @@
1
- <?php
2
- /**
3
- * This class builds/retrieves the thumbnail image of each popular posts.
4
- *
5
- *
6
- * @package WordPressPopularPosts
7
- * @author Hector Cabrera <me@cabrerahector.com>
8
- */
9
-
10
- namespace WordPressPopularPosts;
11
-
12
- class Image {
13
-
14
- /**
15
- * Default thumbnail.
16
- *
17
- * @since 2.2.0
18
- * @var string
19
- */
20
- private $default_thumbnail = '';
21
-
22
- /**
23
- * Plugin uploads directory.
24
- *
25
- * @since 3.0.4
26
- * @var array
27
- */
28
- private $uploads_dir = [];
29
-
30
- /**
31
- * Admin settings.
32
- *
33
- * @since 5.0.0
34
- * @var array
35
- */
36
- private $admin_options = [];
37
-
38
- /**
39
- * Available image sizes.
40
- *
41
- * @since 5.0.0
42
- * @var array
43
- */
44
- private $available_sizes = [];
45
-
46
- /**
47
- * Available image descriptors.
48
- *
49
- * @since 5.3.0
50
- * @var array
51
- */
52
- private $descriptors = [];
53
-
54
- /**
55
- * Construct.
56
- *
57
- * @since 4.0.0
58
- * @param array $admin_options
59
- */
60
- public function __construct(array $admin_options)
61
- {
62
- $this->admin_options = $admin_options;
63
-
64
- // Set default thumbnail
65
- $this->default_thumbnail = plugins_url() . "/wordpress-popular-posts/assets/images/no_thumb.jpg";
66
-
67
- if ( $this->is_image_url($this->admin_options['tools']['thumbnail']['default']) )
68
- $this->default_thumbnail = $this->admin_options['tools']['thumbnail']['default'];
69
-
70
- // Set uploads folder
71
- $wp_upload_dir = wp_get_upload_dir();
72
- $this->uploads_dir['basedir'] = $wp_upload_dir['basedir'] . "/" . 'wordpress-popular-posts';
73
- $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'] . "/" . 'wordpress-popular-posts';
74
-
75
- if ( ! is_dir($this->uploads_dir['basedir']) ) {
76
- // Couldn't create the folder, store thumbnails in Uploads
77
- if ( ! wp_mkdir_p($this->uploads_dir['basedir']) ) {
78
- $this->uploads_dir['basedir'] = $wp_upload_dir['basedir'];
79
- $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'];
80
- }
81
- }
82
-
83
- // Set descriptors
84
- $this->descriptors = [1.5, 2, 2.5, 3];
85
- }
86
-
87
- /**
88
- * Get WPP's uploads folder.
89
- *
90
- * @since 4.0.0
91
- * @access public
92
- * @return array|bool
93
- */
94
- public function get_plugin_uploads_dir()
95
- {
96
- if ( is_array($this->uploads_dir) && ! empty($this->uploads_dir) )
97
- return $this->uploads_dir;
98
- return false;
99
- }
100
-
101
- /**
102
- * Returns an image.
103
- *
104
- * @since 5.0.0
105
- * @param int $post_id Post ID
106
- * @param array $size Image size (width & height)
107
- * @param string $source Image source
108
- * @param bool $crop Whether to crop the image or not
109
- * @param string $build Whether to build the image or get an existing one
110
- * @return string
111
- */
112
- public function get($post_id, $size, $source, $crop = true, $build = 'manual')
113
- {
114
- // Bail, $post_id is not an integer
115
- if ( ! is_numeric($post_id) ) {
116
- return '';
117
- }
118
-
119
- $alt = '';
120
- $classes = ['wpp-thumbnail', 'wpp_' . $source];
121
- $filename = $post_id . '-' . $source . '-' . $size[0] . 'x' . $size[1];
122
- $cached = $this->exists($filename);
123
-
124
- // We have a thumbnail already, return it
125
- if ( $cached ) {
126
- $classes[] = 'wpp_cached_thumb';
127
-
128
- /**
129
- * Filters CSS classes assigned to the thumbnail
130
- *
131
- * @since 5.0.0
132
- * @param array CSS classes
133
- * @param int The post ID
134
- * @return array The new CSS classes
135
- */
136
- $classes = apply_filters(
137
- 'wpp_thumbnail_class_attribute',
138
- $classes,
139
- $post_id
140
- );
141
-
142
- /**
143
- * Filters ALT attribute assigned to the thumbnail
144
- *
145
- * @since 5.0.0
146
- * @param string Original ALT attribute
147
- * @param int The post ID
148
- * @return string The new ALT attribute
149
- */
150
- $alt = apply_filters(
151
- 'wpp_thumbnail_alt_attribute',
152
- $this->get_alt_attribute($post_id, $source),
153
- $post_id
154
- );
155
-
156
- return $this->render(
157
- $cached,
158
- $size,
159
- is_array($classes) ? implode(' ', $classes) : 'wpp-thumbnail wpp_' . $source,
160
- is_string($alt) ? $alt : ''
161
- );
162
- }
163
-
164
- $thumb_url = null;
165
-
166
- // Return image as-is, no need to create a new thumbnail
167
- if (
168
- ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] )
169
- || ( 'featured' == $source && 'predefined' == $build )
170
- ){
171
- // Get custom field image URL
172
- if ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] ) {
173
- $thumb_url = get_post_meta(
174
- $post_id,
175
- $this->admin_options['tools']['thumbnail']['field'],
176
- true
177
- );
178
-
179
- if ( ! $thumb_url || ! $this->is_image_url($thumb_url) ) {
180
- // Is this an attachment ID instead of an image URL?
181
- if ( Helper::is_number($thumb_url) ) {
182
- $thumb_url = wp_get_attachment_image_src($thumb_url, 'full');
183
- $thumb_url = is_array($thumb_url) ? $thumb_url[0] : null;
184
- } else {
185
- $thumb_url = null;
186
- }
187
- }
188
- }
189
- // Get Post Thumbnail
190
- else {
191
- if (
192
- current_theme_supports('post-thumbnails')
193
- && has_post_thumbnail($post_id)
194
- ) {
195
- // Find corresponding image size
196
- $stock_size = null;
197
- $images_sizes = $this->get_sizes();
198
-
199
- foreach ( $images_sizes as $name => $attr ) :
200
- if (
201
- $attr['width'] == $size[0]
202
- && $attr['height'] == $size[1]
203
- && $attr['crop'] == $crop
204
- ) {
205
- $stock_size = $name;
206
- break;
207
- }
208
- endforeach;
209
-
210
- // Couldn't find a matching size so let's go with width/height combo instead
211
- // (this should never happen but better safe than sorry!)
212
- if ( null == $stock_size ) {
213
- $stock_size = $size;
214
- }
215
-
216
- /**
217
- * Filters CSS classes assigned to the thumbnail
218
- *
219
- * @since 5.0.0
220
- * @param array CSS classes
221
- * @param int The post ID
222
- * @return array The new CSS classes
223
- */
224
- $classes = apply_filters(
225
- 'wpp_thumbnail_class_attribute',
226
- $classes,
227
- $post_id
228
- );
229
-
230
- $featured_image = get_the_post_thumbnail(
231
- $post_id,
232
- $stock_size
233
- );
234
-
235
- if ( strpos($featured_image, 'class="') && is_array($classes) && ! empty($classes) )
236
- $featured_image = str_replace('class="', 'class="'. esc_attr(implode(' ', $classes)) . ' ', $featured_image);
237
-
238
- if ( $this->admin_options['tools']['thumbnail']['lazyload'] && false == strpos($featured_image, 'loading="lazy"') ) {
239
- $featured_image = str_replace('src="', 'loading="lazy" src="', $featured_image);
240
- }
241
-
242
- return $featured_image;
243
- }
244
- }
245
- }
246
- // Build a new thumbnail and return it
247
- else {
248
- $file_path = null;
249
-
250
- if ( 'custom_field' == $source && $this->admin_options['tools']['thumbnail']['resize'] ) {
251
- $thumb_url = get_post_meta(
252
- $post_id,
253
- $this->admin_options['tools']['thumbnail']['field'],
254
- true
255
- );
256
-
257
- if ( ! $thumb_url || ! $this->is_image_url($thumb_url) ) {
258
- // Is this an attachment ID instead of an image URL?
259
- // If so, try to fetch the image
260
- if ( Helper::is_number($thumb_url) ) {
261
- $thumb_url = wp_get_attachment_image_src($thumb_url, 'full');
262
- $thumb_url = is_array($thumb_url) ? $thumb_url[0] : null;
263
- } else {
264
- $thumb_url = null;
265
- }
266
- }
267
-
268
- if ( $thumb_url && $this->is_image_url($thumb_url) ) {
269
- $file_path = $this->url_to_path($thumb_url, $post_id);
270
- }
271
- } else {
272
- $file_meta = $this->get_file_meta($post_id, $source);
273
-
274
- if ( is_array($file_meta) && isset($file_meta['path']) ) {
275
- $alt = isset($file_meta['alt']) ? $file_meta['alt'] : '';
276
- $file_path = $file_meta['path'];
277
- }
278
- }
279
-
280
- if ( $file_path ) {
281
- $extension = pathinfo($file_path, PATHINFO_EXTENSION);
282
- $thumb_url = $this->resize(
283
- $file_path,
284
- $filename . '.' . $extension,
285
- $size,
286
- $crop
287
- );
288
- }
289
- }
290
-
291
- if ( ! $thumb_url ) {
292
- $classes[] = 'wpp_def_no_src';
293
- $thumb_url = $this->get_default_url($post_id);
294
- }
295
-
296
- /**
297
- * Filters CSS classes assigned to the thumbnail
298
- *
299
- * @since 5.0.0
300
- * @param array CSS classes
301
- * @param int The post ID
302
- * @return array The new CSS classes
303
- */
304
- $classes = apply_filters(
305
- 'wpp_thumbnail_class_attribute',
306
- $classes,
307
- $post_id
308
- );
309
-
310
- /**
311
- * Filters ALT attribute assigned to the thumbnail
312
- *
313
- * @since 5.0.0
314
- * @param string Original ALT attribute
315
- * @param int The post ID
316
- * @return string The new ALT attribute
317
- */
318
- $alt = apply_filters(
319
- 'wpp_thumbnail_alt_attribute',
320
- $this->get_alt_attribute($post_id, $source),
321
- $post_id
322
- );
323
-
324
- return $this->render(
325
- $thumb_url,
326
- $size,
327
- is_array($classes) ? implode(' ', $classes) : 'wpp-thumbnail wpp_' . $source,
328
- is_string($alt) ? $alt : ''
329
- );
330
- }
331
-
332
- /**
333
- * Checks whether a given thumbnail exists.
334
- *
335
- * @since 5.0.0
336
- * @access private
337
- * @param string $filename
338
- * @return string|bool Full URL to image
339
- */
340
- private function exists($filename)
341
- {
342
- // Do we have thumbnail already?
343
- $file = $this->resolve(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename);
344
-
345
- if ( $file && is_file($file) ) {
346
- $extension = pathinfo($file, PATHINFO_EXTENSION);
347
- return trailingslashit($this->get_plugin_uploads_dir()['baseurl']) . $filename . '.' . $extension;
348
- }
349
-
350
- return false;
351
- }
352
-
353
- /**
354
- * Resolves filename.
355
- *
356
- * @since 5.0.0
357
- * @access private
358
- * @author Ioan Chiriac
359
- * @link https://stackoverflow.com/a/29468093/9131961
360
- * @param string $name
361
- * @return string|bool Resolved path, or false if not found
362
- */
363
- private function resolve($name)
364
- {
365
- $info = pathinfo($name);
366
-
367
- // File already contains an extension, return it
368
- if ( isset($info['extension']) && ! empty($info['extension']) ) {
369
- return $name;
370
- }
371
-
372
- $filename = $info['filename'];
373
- $len = strlen($filename);
374
-
375
- // open the folder
376
- $dh = opendir($info['dirname']);
377
-
378
- if ( ! $dh ) {
379
- return false;
380
- }
381
-
382
- // scan each file in the folder
383
- while ( ($file = readdir($dh)) !== false ) {
384
- if ( strncmp($file, $filename, $len) === 0 ) {
385
- if ( strlen($name) > $len ) {
386
- // if name contains a directory part
387
- $name = substr($name, 0, strlen($name) - $len) . $file;
388
- } else {
389
- // if the name is at the path root
390
- $name = $file;
391
- }
392
-
393
- closedir($dh);
394
- return $name;
395
- }
396
- }
397
-
398
- // file not found
399
- closedir($dh);
400
- return false;
401
- }
402
-
403
- /**
404
- * Retrieves local path to image.
405
- *
406
- * @since 5.0.0
407
- * @access private
408
- * @param string $url
409
- * @param integer $post_ID
410
- * @return string|boolean Path to image, or false if not found
411
- */
412
- private function url_to_path($url, $post_ID = null)
413
- {
414
- if ( $this->is_image_url($url) ) {
415
- $attachment_id = $this->get_attachment_id($url);
416
-
417
- // Image is hosted locally
418
- if ( $attachment_id ) {
419
- return get_attached_file($attachment_id);
420
- }
421
-
422
- // Image hosted elsewhere?
423
- if ( $post_ID && Helper::is_number($post_ID) )
424
- return $this->fetch_external_image($post_ID, $url);
425
- }
426
-
427
- return false;
428
- }
429
-
430
- /**
431
- * Gets image meta.
432
- *
433
- * @since 5.0.0
434
- * @access private
435
- * @param int $id Post ID
436
- * @param string $source Image source
437
- * @return array|bool
438
- */
439
- private function get_file_meta($id, $source)
440
- {
441
- // get thumbnail path from the Featured Image
442
- if ( "featured" == $source ) {
443
- if ( $thumbnail_id = get_post_thumbnail_id($id) ) {
444
- // image path
445
- return [
446
- 'path' => get_attached_file($thumbnail_id),
447
- 'alt' => get_post_meta($thumbnail_id, '_wp_attachment_image_alt', true)
448
- ];
449
- }
450
- }
451
- // get thumbnail path from first image attachment
452
- elseif ( "first_attachment" == $source ) {
453
- $args = [
454
- 'numberposts' => 1,
455
- 'order' => 'ASC',
456
- 'post_parent' => $id,
457
- 'post_type' => 'attachment',
458
- 'post_mime_type' => 'image'
459
- ];
460
- $post_attachments = get_children($args);
461
-
462
- if ( ! empty($post_attachments) ) {
463
- $first_img = array_shift($post_attachments);
464
-
465
- return [
466
- 'path' => get_attached_file($first_img->ID),
467
- 'alt' => get_post_meta($first_img->ID, '_wp_attachment_image_alt', true)
468
- ];
469
- }
470
- }
471
- // get thumbnail path from post content
472
- elseif ( "first_image" == $source ) {
473
- /** @var wpdb $wpdb */
474
- global $wpdb;
475
-
476
- if ( $content = $wpdb->get_var("SELECT post_content FROM {$wpdb->posts} WHERE ID = {$id};") ) {
477
- // at least one image has been found
478
- if ( preg_match('/<img[^>]+>/i', $content, $img) ) {
479
- // get img src attribute from the first image found
480
- preg_match('/(src)="([^"]*)"/i', $img[0], $src_attr);
481
-
482
- if ( isset($src_attr[2]) && ! empty($src_attr[2]) ) {
483
- // get img alt attribute from the first image found
484
- $alt = '';
485
- preg_match('/(alt)="([^"]*)"/i', $img[0], $alt_attr);
486
-
487
- if ( isset($alt_attr[2]) && !empty($alt_attr[2]) ) {
488
- $alt = $alt_attr[2];
489
- }
490
-
491
- // image from Media Library
492
- if ( $attachment_id = $this->get_attachment_id($src_attr[2]) ) {
493
- return [
494
- 'path' => get_attached_file($attachment_id),
495
- 'alt' => $alt
496
- ];
497
- } // external image?
498
- else {
499
- return [
500
- 'path' => $this->fetch_external_image($id, $src_attr[2]),
501
- 'alt' => $alt
502
- ];
503
- }
504
- }
505
- }
506
- }
507
- }
508
-
509
- return false;
510
- }
511
-
512
- /**
513
- * Gets image ALT attribute.
514
- *
515
- * @since 5.0.0
516
- * @access private
517
- * @param int $id Post ID
518
- * @param string $source Image source
519
- * @return string
520
- */
521
- private function get_alt_attribute($id, $source)
522
- {
523
- $alt = '';
524
-
525
- // get thumbnail path from the Featured Image
526
- if ( "featured" == $source ) {
527
- if ( $thumbnail_id = get_post_thumbnail_id($id) ) {
528
- // image path
529
- $alt = get_post_meta($thumbnail_id, '_wp_attachment_image_alt', true);
530
- }
531
- }
532
- // get thumbnail path from first image attachment
533
- elseif ( "first_attachment" == $source ) {
534
- $args = [
535
- 'numberposts' => 1,
536
- 'order' => 'ASC',
537
- 'post_parent' => $id,
538
- 'post_type' => 'attachment',
539
- 'post_mime_type' => 'image'
540
- ];
541
- $post_attachments = get_children($args);
542
-
543
- if ( ! empty($post_attachments) ) {
544
- $first_img = array_shift($post_attachments);
545
- $alt = get_post_meta($first_img->ID, '_wp_attachment_image_alt', true);
546
- }
547
- }
548
- // get thumbnail path from post content
549
- elseif ( "first_image" == $source ) {
550
- /** @var wpdb $wpdb */
551
- global $wpdb;
552
-
553
- if ( $content = $wpdb->get_var("SELECT post_content FROM {$wpdb->posts} WHERE ID = {$id};") ) {
554
- // at least one image has been found
555
- if ( preg_match('/<img[^>]+>/i', $content, $img) ) {
556
- // get img alt attribute from the first image found
557
- preg_match('/(alt)="([^"]*)"/i', $img[0], $alt_attr);
558
-
559
- if ( isset($alt_attr[2]) && !empty($alt_attr[2]) ) {
560
- $alt = $alt_attr[2];
561
- }
562
- }
563
- }
564
- }
565
-
566
- return $alt;
567
- }
568
-
569
- /**
570
- * Get the Attachment ID for a given image URL.
571
- *
572
- * @since 3.0.0
573
- * @access private
574
- * @author Frankie Jarrett
575
- * @link http://frankiejarrett.com/get-an-attachment-id-by-url-in-wordpress/
576
- * @param string $url
577
- * @return int|null
578
- */
579
- private function get_attachment_id($url)
580
- {
581
- $url = Helper::add_scheme(
582
- $url,
583
- is_ssl() ? 'https://' : 'http://'
584
- );
585
-
586
- // Split the $url into two parts with the wp-content directory as the separator.
587
- $parse_url = explode(parse_url(WP_CONTENT_URL, PHP_URL_PATH), $url);
588
-
589
- // Get the host of the current site and the host of the $url, ignoring www.
590
- $this_host = str_ireplace('www.', '', parse_url(home_url(), PHP_URL_HOST));
591
- $file_host = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));
592
-
593
- // Return nothing if there aren't any $url parts or if the current host and $url host do not match.
594
- if (
595
- ! isset($parse_url[1])
596
- || empty($parse_url[1])
597
- || ($this_host != $file_host)
598
- ) {
599
- return false;
600
- }
601
-
602
- // Now we're going to quickly search the DB for any attachment GUID with a partial path match.
603
- // Example: /uploads/2013/05/test-image.jpg
604
- global $wpdb;
605
-
606
- if ( ! $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->prefix}posts WHERE guid RLIKE %s;", $parse_url[1])) ) {
607
- // Maybe it's a resized image, so try to get the full one
608
- $parse_url[1] = preg_replace('/-[0-9]{1,4}x[0-9]{1,4}\.(jpg|jpeg|png|gif|bmp)$/i', '.$1', $parse_url[1]);
609
- $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->prefix}posts WHERE guid RLIKE %s;", $parse_url[1]));
610
- }
611
-
612
- // Returns null if no attachment is found.
613
- return isset($attachment[0]) ? $attachment[0] : NULL;
614
- }
615
-
616
- /**
617
- * Fetchs external images.
618
- *
619
- * @since 2.3.3
620
- * @access private
621
- * @param int $id Post ID.
622
- * @param string $url Image url.
623
- * @return string|bool Image path, or false on failure.
624
- */
625
- private function fetch_external_image($id, $url)
626
- {
627
- $full_image_path = trailingslashit($this->get_plugin_uploads_dir()['basedir']) . "{$id}_" . sanitize_file_name(rawurldecode(wp_basename($url)));
628
-
629
- // if the file exists already, return URL and path
630
- if ( file_exists($full_image_path) )
631
- return $full_image_path;
632
-
633
- $url = Helper::add_scheme(
634
- $url,
635
- is_ssl() ? 'https://' : 'http://'
636
- );
637
-
638
- $accepted_status_codes = [200, 301, 302];
639
- $response = wp_remote_head($url, ['timeout' => 5, 'sslverify' => false]);
640
-
641
- if (
642
- ! is_wp_error($response)
643
- && in_array(wp_remote_retrieve_response_code($response), $accepted_status_codes)
644
- ) {
645
- require_once(ABSPATH . 'wp-admin/includes/file.php');
646
-
647
- $url = str_replace('https://', 'http://', $url);
648
- $tmp = download_url($url);
649
-
650
- // File was downloaded successfully
651
- if ( ! is_wp_error($tmp) ) {
652
- // Determine image type
653
- if ( function_exists('exif_imagetype') ) {
654
- $image_type = exif_imagetype($tmp);
655
- } else {
656
- $image_type = getimagesize($tmp);
657
- $image_type = ( isset($image_type[2]) ) ? $image_type[2] : NULL;
658
- }
659
-
660
- // Valid image, save it
661
- if ( in_array($image_type, [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG]) ) {
662
- // move file to Uploads
663
- if ( @rename($tmp, $full_image_path) ) {
664
- // borrowed from WP - set correct file permissions
665
- $stat = stat(dirname($full_image_path));
666
- $perms = $stat['mode'] & 0000644;
667
- @chmod($full_image_path, $perms);
668
-
669
- return $full_image_path;
670
- }
671
- }
672
-
673
- // Invalid file, remove it
674
- @unlink($tmp);
675
- }
676
- }
677
-
678
- return false;
679
- }
680
-
681
- /**
682
- * Creates thumbnails.
683
- *
684
- * @since 3.0.0
685
- * @access private
686
- * @param string $path Image path
687
- * @param string $filename Image filename
688
- * @param array $size Image size
689
- * @param bool $crop Whether to crop the image or not
690
- * @return string|bool Image URL on success, false on error
691
- */
692
- private function resize($path, $filename, $size, $crop = true)
693
- {
694
- $image = wp_get_image_editor($path);
695
-
696
- // valid image, create thumbnails
697
- if ( ! is_wp_error($image) ) {
698
- $original_size = $image->get_size();
699
- $sizes = [
700
- '1x' => $size
701
- ];
702
- $thumbnail = '';
703
-
704
- /**
705
- * Hook to enable/disable retina support.
706
- * @since 5.3.0
707
- */
708
- $retina_support = apply_filters('wpp_retina_support', true);
709
-
710
- if ( $retina_support ) {
711
- // Calculate thumbnail sizes
712
- foreach( $this->descriptors as $descriptor ) {
713
- $new_size_width = $descriptor * $size[0];
714
- $new_size_height = $descriptor * $size[1];
715
-
716
- if (
717
- $new_size_width <= $original_size['width']
718
- && $new_size_height <= $original_size['height']
719
- ) {
720
- $sizes[$descriptor . 'x'] = [$new_size_width, $new_size_height];
721
- }
722
- }
723
- }
724
-
725
- $path_parts = null;
726
-
727
- // Generate thumbnails
728
- foreach( $sizes as $d => $s ) {
729
- if ( '1x' == $d ) {
730
- $thumbnail = $this->generate_thumbnail($path, $filename, $s, $crop);
731
-
732
- // Image could not be generated, let's bail early.
733
- if ( ! $thumbnail )
734
- break;
735
- } else {
736
- if ( ! $path_parts )
737
- $path_parts = pathinfo($filename);
738
-
739
- $filename_with_descriptor = $path_parts['filename'] . "@{$d}." . $path_parts['extension'];
740
- $this->generate_thumbnail($path, $filename_with_descriptor, $s, $crop);
741
- }
742
- }
743
-
744
- return $thumbnail;
745
- }
746
-
747
- return false;
748
- }
749
-
750
- /**
751
- * Creates image.
752
- *
753
- * @since 5.3.0
754
- * @access private
755
- * @param string $path Image path
756
- * @param string $filename Image filename
757
- * @param array $size Image size
758
- * @param bool $crop Whether to crop the image or not
759
- * @return string|bool Image URL on success, false on error
760
- */
761
- private function generate_thumbnail($path, $filename, $size, $crop = true)
762
- {
763
- $image = wp_get_image_editor($path);
764
-
765
- // valid image, create thumbnail
766
- if ( ! is_wp_error($image) ) {
767
- /**
768
- * Hook to change the image compression quality of WPP's thumbnails.
769
- * @since 4.2.1
770
- */
771
- $quality = apply_filters('wpp_thumbnail_compression_quality', null);
772
-
773
- if ( ! ctype_digit($quality) )
774
- $quality = null; // Fallback to core's default
775
-
776
- $image->set_quality($quality);
777
-
778
- $image->resize($size[0], $size[1], $crop);
779
- $new_img = $image->save(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename);
780
-
781
- if ( ! is_wp_error($new_img) )
782
- return trailingslashit($this->get_plugin_uploads_dir()['baseurl']) . $filename;
783
- }
784
-
785
- return false;
786
- }
787
-
788
- /**
789
- * Generates srcset attribute for this image.
790
- *
791
- * @since 5.3.0
792
- * @param string $src
793
- * @return string
794
- */
795
- private function get_srcset($src)
796
- {
797
- /**
798
- * Hook to enable/disable retina support.
799
- * @since 5.3.0
800
- */
801
- $retina_support = apply_filters('wpp_retina_support', true);
802
-
803
- if ( ! $retina_support )
804
- return '';
805
-
806
- $path_parts = pathinfo($src);
807
- $srcset = [$src];
808
-
809
- foreach( $this->descriptors as $descriptor ) {
810
- $d = "{$descriptor}x";
811
- $filename = $path_parts['filename'] . "@{$d}." . $path_parts['extension'];
812
-
813
- if ( @file_exists(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename) ) {
814
- $srcset[] = $path_parts['dirname'] . '/' . $filename . ' ' . $d;
815
- }
816
- }
817
-
818
- return ( count($srcset) > 1 ) ? ' srcset="' . implode(', ', $srcset) . '" ' : '';
819
- }
820
-
821
- /**
822
- * Render image tag.
823
- *
824
- * @since 3.0.0
825
- * @access public
826
- * @param string $src Image URL
827
- * @param array $dimension Image's width and height
828
- * @param string $class CSS class
829
- * @param object $alt Alternative text
830
- * @param string $error Error, if the image could not be created
831
- * @return string
832
- */
833
- public function render($src, $size, $class, $alt = '', $error = null)
834
- {
835
- $img_tag = '';
836
-
837
- if ( $error ) {
838
- $img_tag = '<!-- ' . $error . ' --> ';
839
- }
840
-
841
- $srcset = $this->get_srcset($src);
842
- $src = 'src="' . esc_url(is_ssl() ? str_ireplace("http://", "https://", $src) : $src) . '"' . $srcset;
843
- $lazyload = ( $this->admin_options['tools']['thumbnail']['lazyload'] ) ? ' loading="lazy"' : '';
844
-
845
- $img_tag .= '<img ' . $src . ' width="' . $size[0] . '" height="' . $size[1] . '" alt="' . esc_attr($alt) . '" class="' . esc_attr($class) . '"' . $lazyload . ' />';
846
-
847
- return apply_filters('wpp_render_image', $img_tag);
848
- }
849
-
850
- /**
851
- * Gets list of available thumbnails sizes
852
- *
853
- * @since 3.2.0
854
- * @link http://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
855
- * @param string $size
856
- * @return array|bool
857
- */
858
- public function get_sizes($size = '')
859
- {
860
- if ( ! is_array($this->available_sizes) || empty($this->available_sizes) ) {
861
- global $_wp_additional_image_sizes;
862
-
863
- $this->available_sizes = [];
864
- $get_intermediate_image_sizes = get_intermediate_image_sizes();
865
-
866
- // Create the full array with sizes and crop info
867
- foreach( $get_intermediate_image_sizes as $_size ) {
868
- if ( in_array($_size, ['thumbnail', 'medium', 'large']) ) {
869
- $this->available_sizes[$_size]['width'] = get_option($_size . '_size_w');
870
- $this->available_sizes[$_size]['height'] = get_option($_size . '_size_h');
871
- $this->available_sizes[$_size]['crop'] = (bool) get_option($_size . '_crop');
872
- } elseif ( isset($_wp_additional_image_sizes[$_size]) ) {
873
- $this->available_sizes[$_size] = [
874
- 'width' => $_wp_additional_image_sizes[$_size]['width'],
875
- 'height' => $_wp_additional_image_sizes[$_size]['height'],
876
- 'crop' => $_wp_additional_image_sizes[$_size]['crop']
877
- ];
878
- }
879
- }
880
- }
881
-
882
- // Get only 1 size if found
883
- if ( $size ) {
884
- if ( isset($this->available_sizes[$size]) ) {
885
- return $this->available_sizes[$size];
886
- }
887
- return false;
888
- }
889
-
890
- return $this->available_sizes;
891
- }
892
-
893
- /**
894
- * Returns the URL of the default thumbnail image.
895
- *
896
- * @since 5.0.0
897
- * @param int|null
898
- * @return string
899
- */
900
- public function get_default_url($post_ID = null)
901
- {
902
- if ( has_filter('wpp_default_thumbnail_url') ) {
903
- $default_thumbnail_url = apply_filters('wpp_default_thumbnail_url', $this->default_thumbnail, $post_ID);
904
-
905
- if ( $default_thumbnail_url != $this->default_thumbnail && $this->is_image_url($default_thumbnail_url) )
906
- return $default_thumbnail_url;
907
- }
908
-
909
- return $this->default_thumbnail;
910
- }
911
-
912
- /**
913
- * Checks whether an URL points to an actual image.
914
- *
915
- * @since 5.0.0
916
- * @access private
917
- * @param string
918
- * @return array|bool
919
- */
920
- private function is_image_url($url)
921
- {
922
- $path = parse_url($url, PHP_URL_PATH);
923
- $encoded_path = array_map('urlencode', explode('/', $path));
924
- $parse_url = str_replace($path, implode('/', $encoded_path), $url);
925
-
926
- if ( ! filter_var($parse_url, FILTER_VALIDATE_URL) )
927
- return false;
928
-
929
- // sanitize URL, just in case
930
- $image_url = esc_url($url);
931
- // remove querystring
932
- preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $image_url, $matches);
933
-
934
- return ( is_array($matches) && ! empty($matches) ) ? $matches : false;
935
- }
936
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class builds/retrieves the thumbnail image of each popular posts.
4
+ *
5
+ *
6
+ * @package WordPressPopularPosts
7
+ * @author Hector Cabrera <me@cabrerahector.com>
8
+ */
9
+
10
+ namespace WordPressPopularPosts;
11
+
12
+ class Image {
13
+
14
+ /**
15
+ * Default thumbnail.
16
+ *
17
+ * @since 2.2.0
18
+ * @var string
19
+ */
20
+ private $default_thumbnail = '';
21
+
22
+ /**
23
+ * Plugin uploads directory.
24
+ *
25
+ * @since 3.0.4
26
+ * @var array
27
+ */
28
+ private $uploads_dir = [];
29
+
30
+ /**
31
+ * Admin settings.
32
+ *
33
+ * @since 5.0.0
34
+ * @var array
35
+ */
36
+ private $admin_options = [];
37
+
38
+ /**
39
+ * Available image sizes.
40
+ *
41
+ * @since 5.0.0
42
+ * @var array
43
+ */
44
+ private $available_sizes = [];
45
+
46
+ /**
47
+ * Available image descriptors.
48
+ *
49
+ * @since 5.3.0
50
+ * @var array
51
+ */
52
+ private $descriptors = [];
53
+
54
+ /**
55
+ * Construct.
56
+ *
57
+ * @since 4.0.0
58
+ * @param array $admin_options
59
+ */
60
+ public function __construct(array $admin_options)
61
+ {
62
+ $this->admin_options = $admin_options;
63
+
64
+ // Set default thumbnail
65
+ $this->default_thumbnail = plugins_url() . "/wordpress-popular-posts/assets/images/no_thumb.jpg";
66
+
67
+ if ( $this->is_image_url($this->admin_options['tools']['thumbnail']['default']) )
68
+ $this->default_thumbnail = $this->admin_options['tools']['thumbnail']['default'];
69
+
70
+ // Set uploads folder
71
+ $wp_upload_dir = wp_get_upload_dir();
72
+ $this->uploads_dir['basedir'] = $wp_upload_dir['basedir'] . "/" . 'wordpress-popular-posts';
73
+ $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'] . "/" . 'wordpress-popular-posts';
74
+
75
+ if ( ! is_dir($this->uploads_dir['basedir']) ) {
76
+ // Couldn't create the folder, store thumbnails in Uploads
77
+ if ( ! wp_mkdir_p($this->uploads_dir['basedir']) ) {
78
+ $this->uploads_dir['basedir'] = $wp_upload_dir['basedir'];
79
+ $this->uploads_dir['baseurl'] = $wp_upload_dir['baseurl'];
80
+ }
81
+ }
82
+
83
+ // Set descriptors
84
+ $this->descriptors = ['1.5', '2', '2.5', '3'];
85
+ }
86
+
87
+ /**
88
+ * Get WPP's uploads folder.
89
+ *
90
+ * @since 4.0.0
91
+ * @access public
92
+ * @return array|bool
93
+ */
94
+ public function get_plugin_uploads_dir()
95
+ {
96
+ if ( is_array($this->uploads_dir) && ! empty($this->uploads_dir) )
97
+ return $this->uploads_dir;
98
+ return false;
99
+ }
100
+
101
+ /**
102
+ * Returns an image.
103
+ *
104
+ * @since 5.0.0
105
+ * @param int $post_id Post ID
106
+ * @param array $size Image size (width & height)
107
+ * @param string $source Image source
108
+ * @param bool $crop Whether to crop the image or not
109
+ * @param string $build Whether to build the image or get an existing one
110
+ * @return string
111
+ */
112
+ public function get($post_id, $size, $source, $crop = true, $build = 'manual')
113
+ {
114
+ // Bail, $post_id is not an integer
115
+ if ( ! is_numeric($post_id) ) {
116
+ return '';
117
+ }
118
+
119
+ $alt = '';
120
+ $classes = ['wpp-thumbnail', 'wpp_' . $source];
121
+ $filename = $post_id . '-' . $source . '-' . $size[0] . 'x' . $size[1];
122
+ $cached = $this->exists($filename);
123
+
124
+ // We have a thumbnail already, return it
125
+ if ( $cached ) {
126
+ $classes[] = 'wpp_cached_thumb';
127
+
128
+ /**
129
+ * Filters CSS classes assigned to the thumbnail
130
+ *
131
+ * @since 5.0.0
132
+ * @param array CSS classes
133
+ * @param int The post ID
134
+ * @return array The new CSS classes
135
+ */
136
+ $classes = apply_filters(
137
+ 'wpp_thumbnail_class_attribute',
138
+ $classes,
139
+ $post_id
140
+ );
141
+
142
+ /**
143
+ * Filters ALT attribute assigned to the thumbnail
144
+ *
145
+ * @since 5.0.0
146
+ * @param string Original ALT attribute
147
+ * @param int The post ID
148
+ * @return string The new ALT attribute
149
+ */
150
+ $alt = apply_filters(
151
+ 'wpp_thumbnail_alt_attribute',
152
+ $this->get_alt_attribute($post_id, $source),
153
+ $post_id
154
+ );
155
+
156
+ return $this->render(
157
+ $cached,
158
+ $size,
159
+ is_array($classes) ? implode(' ', $classes) : 'wpp-thumbnail wpp_' . $source,
160
+ is_string($alt) ? $alt : ''
161
+ );
162
+ }
163
+
164
+ $thumb_url = null;
165
+
166
+ // Return image as-is, no need to create a new thumbnail
167
+ if (
168
+ ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] )
169
+ || ( 'featured' == $source && 'predefined' == $build )
170
+ ){
171
+ // Get custom field image URL
172
+ if ( 'custom_field' == $source && ! $this->admin_options['tools']['thumbnail']['resize'] ) {
173
+ $thumb_url = get_post_meta(
174
+ $post_id,
175
+ $this->admin_options['tools']['thumbnail']['field'],
176
+ true
177
+ );
178
+
179
+ if ( ! $thumb_url || ! $this->is_image_url($thumb_url) ) {
180
+ // Is this an attachment ID instead of an image URL?
181
+ if ( Helper::is_number($thumb_url) ) {
182
+ $thumb_url = wp_get_attachment_image_src($thumb_url, 'full');
183
+ $thumb_url = is_array($thumb_url) ? $thumb_url[0] : null;
184
+ } else {
185
+ $thumb_url = null;
186
+ }
187
+ }
188
+ }
189
+ // Get Post Thumbnail
190
+ else {
191
+ if (
192
+ current_theme_supports('post-thumbnails')
193
+ && has_post_thumbnail($post_id)
194
+ ) {
195
+ // Find corresponding image size
196
+ $stock_size = null;
197
+ $images_sizes = $this->get_sizes();
198
+
199
+ foreach ( $images_sizes as $name => $attr ) :
200
+ if (
201
+ $attr['width'] == $size[0]
202
+ && $attr['height'] == $size[1]
203
+ && $attr['crop'] == $crop
204
+ ) {
205
+ $stock_size = $name;
206
+ break;
207
+ }
208
+ endforeach;
209
+
210
+ // Couldn't find a matching size so let's go with width/height combo instead
211
+ // (this should never happen but better safe than sorry!)
212
+ if ( null == $stock_size ) {
213
+ $stock_size = $size;
214
+ }
215
+
216
+ /**
217
+ * Filters CSS classes assigned to the thumbnail
218
+ *
219
+ * @since 5.0.0
220
+ * @param array CSS classes
221
+ * @param int The post ID
222
+ * @return array The new CSS classes
223
+ */
224
+ $classes = apply_filters(
225
+ 'wpp_thumbnail_class_attribute',
226
+ $classes,
227
+ $post_id
228
+ );
229
+
230
+ $featured_image = get_the_post_thumbnail(
231
+ $post_id,
232
+ $stock_size
233
+ );
234
+
235
+ if ( strpos($featured_image, 'class="') && is_array($classes) && ! empty($classes) )
236
+ $featured_image = str_replace('class="', 'class="'. esc_attr(implode(' ', $classes)) . ' ', $featured_image);
237
+
238
+ if ( $this->admin_options['tools']['thumbnail']['lazyload'] && false == strpos($featured_image, 'loading="lazy"') ) {
239
+ $featured_image = str_replace('src="', 'loading="lazy" src="', $featured_image);
240
+ }
241
+
242
+ return $featured_image;
243
+ }
244
+ }
245
+ }
246
+ // Build a new thumbnail and return it
247
+ else {
248
+ $file_path = null;
249
+
250
+ if ( 'custom_field' == $source && $this->admin_options['tools']['thumbnail']['resize'] ) {
251
+ $thumb_url = get_post_meta(
252
+ $post_id,
253
+ $this->admin_options['tools']['thumbnail']['field'],
254
+ true
255
+ );
256
+
257
+ if ( ! $thumb_url || ! $this->is_image_url($thumb_url) ) {
258
+ // Is this an attachment ID instead of an image URL?
259
+ // If so, try to fetch the image
260
+ if ( Helper::is_number($thumb_url) ) {
261
+ $thumb_url = wp_get_attachment_image_src($thumb_url, 'full');
262
+ $thumb_url = is_array($thumb_url) ? $thumb_url[0] : null;
263
+ } else {
264
+ $thumb_url = null;
265
+ }
266
+ }
267
+
268
+ if ( $thumb_url && $this->is_image_url($thumb_url) ) {
269
+ $file_path = $this->url_to_path($thumb_url, $post_id);
270
+ }
271
+ } else {
272
+ $file_meta = $this->get_file_meta($post_id, $source);
273
+
274
+ if ( is_array($file_meta) && isset($file_meta['path']) ) {
275
+ $alt = isset($file_meta['alt']) ? $file_meta['alt'] : '';
276
+ $file_path = $file_meta['path'];
277
+ }
278
+ }
279
+
280
+ if ( $file_path ) {
281
+ $extension = pathinfo($file_path, PATHINFO_EXTENSION);
282
+ $thumb_url = $this->resize(
283
+ $file_path,
284
+ $filename . '.' . $extension,
285
+ $size,
286
+ $crop
287
+ );
288
+ }
289
+ }
290
+
291
+ if ( ! $thumb_url ) {
292
+ $classes[] = 'wpp_def_no_src';
293
+ $thumb_url = $this->get_default_url($post_id);
294
+ }
295
+
296
+ /**
297
+ * Filters CSS classes assigned to the thumbnail
298
+ *
299
+ * @since 5.0.0
300
+ * @param array CSS classes
301
+ * @param int The post ID
302
+ * @return array The new CSS classes
303
+ */
304
+ $classes = apply_filters(
305
+ 'wpp_thumbnail_class_attribute',
306
+ $classes,
307
+ $post_id
308
+ );
309
+
310
+ /**
311
+ * Filters ALT attribute assigned to the thumbnail
312
+ *
313
+ * @since 5.0.0
314
+ * @param string Original ALT attribute
315
+ * @param int The post ID
316
+ * @return string The new ALT attribute
317
+ */
318
+ $alt = apply_filters(
319
+ 'wpp_thumbnail_alt_attribute',
320
+ $this->get_alt_attribute($post_id, $source),
321
+ $post_id
322
+ );
323
+
324
+ return $this->render(
325
+ $thumb_url,
326
+ $size,
327
+ is_array($classes) ? implode(' ', $classes) : 'wpp-thumbnail wpp_' . $source,
328
+ is_string($alt) ? $alt : ''
329
+ );
330
+ }
331
+
332
+ /**
333
+ * Checks whether a given thumbnail exists.
334
+ *
335
+ * @since 5.0.0
336
+ * @access private
337
+ * @param string $filename
338
+ * @return string|bool Full URL to image
339
+ */
340
+ private function exists($filename)
341
+ {
342
+ // Do we have thumbnail already?
343
+ $file = $this->resolve(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename);
344
+
345
+ if ( $file && is_file($file) ) {
346
+ $extension = pathinfo($file, PATHINFO_EXTENSION);
347
+ return trailingslashit($this->get_plugin_uploads_dir()['baseurl']) . $filename . '.' . $extension;
348
+ }
349
+
350
+ return false;
351
+ }
352
+
353
+ /**
354
+ * Resolves filename.
355
+ *
356
+ * @since 5.0.0
357
+ * @access private
358
+ * @author Ioan Chiriac
359
+ * @link https://stackoverflow.com/a/29468093/9131961
360
+ * @param string $name
361
+ * @return string|bool Resolved path, or false if not found
362
+ */
363
+ private function resolve($name)
364
+ {
365
+ $info = pathinfo($name);
366
+
367
+ // File already contains an extension, return it
368
+ if ( isset($info['extension']) && ! empty($info['extension']) ) {
369
+ return $name;
370
+ }
371
+
372
+ $filename = $info['filename'];
373
+ $len = strlen($filename);
374
+
375
+ // open the folder
376
+ $dh = opendir($info['dirname']);
377
+
378
+ if ( ! $dh ) {
379
+ return false;
380
+ }
381
+
382
+ // scan each file in the folder
383
+ while ( ($file = readdir($dh)) !== false ) {
384
+ if ( strncmp($file, $filename, $len) === 0 ) {
385
+ if ( strlen($name) > $len ) {
386
+ // if name contains a directory part
387
+ $name = substr($name, 0, strlen($name) - $len) . $file;
388
+ } else {
389
+ // if the name is at the path root
390
+ $name = $file;
391
+ }
392
+
393
+ closedir($dh);
394
+ return $name;
395
+ }
396
+ }
397
+
398
+ // file not found
399
+ closedir($dh);
400
+ return false;
401
+ }
402
+
403
+ /**
404
+ * Retrieves local path to image.
405
+ *
406
+ * @since 5.0.0
407
+ * @access private
408
+ * @param string $url
409
+ * @param integer $post_ID
410
+ * @return string|boolean Path to image, or false if not found
411
+ */
412
+ private function url_to_path($url, $post_ID = null)
413
+ {
414
+ if ( $this->is_image_url($url) ) {
415
+ $attachment_id = $this->get_attachment_id($url);
416
+
417
+ // Image is hosted locally
418
+ if ( $attachment_id ) {
419
+ return get_attached_file($attachment_id);
420
+ }
421
+
422
+ // Image hosted elsewhere?
423
+ if ( $post_ID && Helper::is_number($post_ID) )
424
+ return $this->fetch_external_image($post_ID, $url);
425
+ }
426
+
427
+ return false;
428
+ }
429
+
430
+ /**
431
+ * Gets image meta.
432
+ *
433
+ * @since 5.0.0
434
+ * @access private
435
+ * @param int $id Post ID
436
+ * @param string $source Image source
437
+ * @return array|bool
438
+ */
439
+ private function get_file_meta($id, $source)
440
+ {
441
+ // get thumbnail path from the Featured Image
442
+ if ( "featured" == $source ) {
443
+ if ( $thumbnail_id = get_post_thumbnail_id($id) ) {
444
+ // image path
445
+ return [
446
+ 'path' => get_attached_file($thumbnail_id),
447
+ 'alt' => get_post_meta($thumbnail_id, '_wp_attachment_image_alt', true)
448
+ ];
449
+ }
450
+ }
451
+ // get thumbnail path from first image attachment
452
+ elseif ( "first_attachment" == $source ) {
453
+ $args = [
454
+ 'numberposts' => 1,
455
+ 'order' => 'ASC',
456
+ 'post_parent' => $id,
457
+ 'post_type' => 'attachment',
458
+ 'post_mime_type' => 'image'
459
+ ];
460
+ $post_attachments = get_children($args);
461
+
462
+ if ( ! empty($post_attachments) ) {
463
+ $first_img = array_shift($post_attachments);
464
+
465
+ return [
466
+ 'path' => get_attached_file($first_img->ID),
467
+ 'alt' => get_post_meta($first_img->ID, '_wp_attachment_image_alt', true)
468
+ ];
469
+ }
470
+ }
471
+ // get thumbnail path from post content
472
+ elseif ( "first_image" == $source ) {
473
+ /** @var wpdb $wpdb */
474
+ global $wpdb;
475
+
476
+ if ( $content = $wpdb->get_var("SELECT post_content FROM {$wpdb->posts} WHERE ID = {$id};") ) {
477
+ // at least one image has been found
478
+ if ( preg_match('/<img[^>]+>/i', $content, $img) ) {
479
+ // get img src attribute from the first image found
480
+ preg_match('/(src)="([^"]*)"/i', $img[0], $src_attr);
481
+
482
+ if ( isset($src_attr[2]) && ! empty($src_attr[2]) ) {
483
+ // get img alt attribute from the first image found
484
+ $alt = '';
485
+ preg_match('/(alt)="([^"]*)"/i', $img[0], $alt_attr);
486
+
487
+ if ( isset($alt_attr[2]) && !empty($alt_attr[2]) ) {
488
+ $alt = $alt_attr[2];
489
+ }
490
+
491
+ // image from Media Library
492
+ if ( $attachment_id = $this->get_attachment_id($src_attr[2]) ) {
493
+ return [
494
+ 'path' => get_attached_file($attachment_id),
495
+ 'alt' => $alt
496
+ ];
497
+ } // external image?
498
+ else {
499
+ return [
500
+ 'path' => $this->fetch_external_image($id, $src_attr[2]),
501
+ 'alt' => $alt
502
+ ];
503
+ }
504
+ }
505
+ }
506
+ }
507
+ }
508
+
509
+ return false;
510
+ }
511
+
512
+ /**
513
+ * Gets image ALT attribute.
514
+ *
515
+ * @since 5.0.0
516
+ * @access private
517
+ * @param int $id Post ID
518
+ * @param string $source Image source
519
+ * @return string
520
+ */
521
+ private function get_alt_attribute($id, $source)
522
+ {
523
+ $alt = '';
524
+
525
+ // get thumbnail path from the Featured Image
526
+ if ( "featured" == $source ) {
527
+ if ( $thumbnail_id = get_post_thumbnail_id($id) ) {
528
+ // image path
529
+ $alt = get_post_meta($thumbnail_id, '_wp_attachment_image_alt', true);
530
+ }
531
+ }
532
+ // get thumbnail path from first image attachment
533
+ elseif ( "first_attachment" == $source ) {
534
+ $args = [
535
+ 'numberposts' => 1,
536
+ 'order' => 'ASC',
537
+ 'post_parent' => $id,
538
+ 'post_type' => 'attachment',
539
+ 'post_mime_type' => 'image'
540
+ ];
541
+ $post_attachments = get_children($args);
542
+
543
+ if ( ! empty($post_attachments) ) {
544
+ $first_img = array_shift($post_attachments);
545
+ $alt = get_post_meta($first_img->ID, '_wp_attachment_image_alt', true);
546
+ }
547
+ }
548
+ // get thumbnail path from post content
549
+ elseif ( "first_image" == $source ) {
550
+ /** @var wpdb $wpdb */
551
+ global $wpdb;
552
+
553
+ if ( $content = $wpdb->get_var("SELECT post_content FROM {$wpdb->posts} WHERE ID = {$id};") ) {
554
+ // at least one image has been found
555
+ if ( preg_match('/<img[^>]+>/i', $content, $img) ) {
556
+ // get img alt attribute from the first image found
557
+ preg_match('/(alt)="([^"]*)"/i', $img[0], $alt_attr);
558
+
559
+ if ( isset($alt_attr[2]) && !empty($alt_attr[2]) ) {
560
+ $alt = $alt_attr[2];
561
+ }
562
+ }
563
+ }
564
+ }
565
+
566
+ return $alt;
567
+ }
568
+
569
+ /**
570
+ * Get the Attachment ID for a given image URL.
571
+ *
572
+ * @since 3.0.0
573
+ * @access private
574
+ * @author Frankie Jarrett
575
+ * @link http://frankiejarrett.com/get-an-attachment-id-by-url-in-wordpress/
576
+ * @param string $url
577
+ * @return int|null
578
+ */
579
+ private function get_attachment_id($url)
580
+ {
581
+ $url = Helper::add_scheme(
582
+ $url,
583
+ is_ssl() ? 'https://' : 'http://'
584
+ );
585
+
586
+ // Split the $url into two parts with the wp-content directory as the separator.
587
+ $parse_url = explode(parse_url(WP_CONTENT_URL, PHP_URL_PATH), $url);
588
+
589
+ // Get the host of the current site and the host of the $url, ignoring www.
590
+ $this_host = str_ireplace('www.', '', parse_url(home_url(), PHP_URL_HOST));
591
+ $file_host = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));
592
+
593
+ // Return nothing if there aren't any $url parts or if the current host and $url host do not match.
594
+ if (
595
+ ! isset($parse_url[1])
596
+ || empty($parse_url[1])
597
+ || ($this_host != $file_host)
598
+ ) {
599
+ return false;
600
+ }
601
+
602
+ // Now we're going to quickly search the DB for any attachment GUID with a partial path match.
603
+ // Example: /uploads/2013/05/test-image.jpg
604
+ global $wpdb;
605
+
606
+ if ( ! $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->prefix}posts WHERE guid RLIKE %s;", $parse_url[1])) ) {
607
+ // Maybe it's a resized image, so try to get the full one
608
+ $parse_url[1] = preg_replace('/-[0-9]{1,4}x[0-9]{1,4}\.(jpg|jpeg|png|gif|bmp)$/i', '.$1', $parse_url[1]);
609
+ $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->prefix}posts WHERE guid RLIKE %s;", $parse_url[1]));
610
+ }
611
+
612
+ // Returns null if no attachment is found.
613
+ return isset($attachment[0]) ? $attachment[0] : NULL;
614
+ }
615
+
616
+ /**
617
+ * Fetchs external images.
618
+ *
619
+ * @since 2.3.3
620
+ * @access private
621
+ * @param int $id Post ID.
622
+ * @param string $url Image url.
623
+ * @return string|bool Image path, or false on failure.
624
+ */
625
+ private function fetch_external_image($id, $url)
626
+ {
627
+ if ( ! $this->is_image_url($url) )
628
+ return false;
629
+
630
+ $full_image_path = trailingslashit($this->get_plugin_uploads_dir()['basedir']) . "{$id}_" . sanitize_file_name(rawurldecode(wp_basename($url)));
631
+
632
+ // if the file exists already, return URL and path
633
+ if ( file_exists($full_image_path) )
634
+ return $full_image_path;
635
+
636
+ $url = Helper::add_scheme(
637
+ $url,
638
+ is_ssl() ? 'https://' : 'http://'
639
+ );
640
+
641
+ $accepted_status_codes = [200, 301, 302];
642
+ $response = wp_remote_head($url, ['timeout' => 5, 'sslverify' => false]);
643
+
644
+ if (
645
+ ! is_wp_error($response)
646
+ && in_array(wp_remote_retrieve_response_code($response), $accepted_status_codes)
647
+ ) {
648
+ require_once(ABSPATH . 'wp-admin/includes/file.php');
649
+
650
+ $url = str_replace('https://', 'http://', $url);
651
+ $tmp = download_url($url);
652
+
653
+ // File was downloaded successfully
654
+ if ( ! is_wp_error($tmp) ) {
655
+ // Determine image type
656
+ if ( function_exists('exif_imagetype') ) {
657
+ $image_type = exif_imagetype($tmp);
658
+ } else {
659
+ $image_type = getimagesize($tmp);
660
+ $image_type = ( isset($image_type[2]) ) ? $image_type[2] : NULL;
661
+ }
662
+
663
+ // Valid image, save it
664
+ if ( in_array($image_type, [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG]) ) {
665
+ // move file to Uploads
666
+ if ( @rename($tmp, $full_image_path) ) {
667
+ // borrowed from WP - set correct file permissions
668
+ $stat = stat(dirname($full_image_path));
669
+ $perms = $stat['mode'] & 0000644;
670
+ @chmod($full_image_path, $perms);
671
+
672
+ return $full_image_path;
673
+ }
674
+ }
675
+
676
+ // Invalid file, remove it
677
+ @unlink($tmp);
678
+ }
679
+ }
680
+
681
+ return false;
682
+ }
683
+
684
+ /**
685
+ * Creates thumbnails.
686
+ *
687
+ * @since 3.0.0
688
+ * @access private
689
+ * @param string $path Image path
690
+ * @param string $filename Image filename
691
+ * @param array $size Image size
692
+ * @param bool $crop Whether to crop the image or not
693
+ * @return string|bool Image URL on success, false on error
694
+ */
695
+ private function resize($path, $filename, $size, $crop = true)
696
+ {
697
+ $image = wp_get_image_editor($path);
698
+
699
+ // valid image, create thumbnails
700
+ if ( ! is_wp_error($image) ) {
701
+ $original_size = $image->get_size();
702
+ $sizes = [
703
+ '1x' => $size
704
+ ];
705
+ $thumbnail = '';
706
+
707
+ /**
708
+ * Hook to enable/disable retina support.
709
+ * @since 5.3.0
710
+ */
711
+ $retina_support = apply_filters('wpp_retina_support', true);
712
+
713
+ if ( $retina_support ) {
714
+ // Calculate thumbnail sizes
715
+ foreach( $this->descriptors as $descriptor ) {
716
+ $new_size_width = floor($descriptor * $size[0]);
717
+ $new_size_height = floor($descriptor * $size[1]);
718
+
719
+ if (
720
+ $new_size_width <= $original_size['width']
721
+ && $new_size_height <= $original_size['height']
722
+ ) {
723
+ $sizes[$descriptor . 'x'] = [$new_size_width, $new_size_height];
724
+ }
725
+ }
726
+ }
727
+
728
+ $path_parts = null;
729
+
730
+ // Generate thumbnails
731
+ foreach( $sizes as $d => $s ) {
732
+ if ( '1x' == $d ) {
733
+ $thumbnail = $this->generate_thumbnail($path, $filename, $s, $crop);
734
+
735
+ // Image could not be generated, let's bail early.
736
+ if ( ! $thumbnail )
737
+ break;
738
+ } else {
739
+ if ( ! $path_parts )
740
+ $path_parts = pathinfo($filename);
741
+
742
+ $filename_with_descriptor = $path_parts['filename'] . "@{$d}." . $path_parts['extension'];
743
+ $this->generate_thumbnail($path, $filename_with_descriptor, $s, $crop);
744
+ }
745
+ }
746
+
747
+ return $thumbnail;
748
+ }
749
+
750
+ return false;
751
+ }
752
+
753
+ /**
754
+ * Creates image.
755
+ *
756
+ * @since 5.3.0
757
+ * @access private
758
+ * @param string $path Image path
759
+ * @param string $filename Image filename
760
+ * @param array $size Image size
761
+ * @param bool $crop Whether to crop the image or not
762
+ * @return string|bool Image URL on success, false on error
763
+ */
764
+ private function generate_thumbnail($path, $filename, $size, $crop = true)
765
+ {
766
+ $image = wp_get_image_editor($path);
767
+
768
+ // valid image, create thumbnail
769
+ if ( ! is_wp_error($image) ) {
770
+ /**
771
+ * Hook to change the image compression quality of WPP's thumbnails.
772
+ * @since 4.2.1
773
+ */
774
+ $quality = apply_filters('wpp_thumbnail_compression_quality', null);
775
+
776
+ if ( ! ctype_digit($quality) )
777
+ $quality = null; // Fallback to core's default
778
+
779
+ $image->set_quality($quality);
780
+
781
+ $image->resize($size[0], $size[1], $crop);
782
+ $new_img = $image->save(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename);
783
+
784
+ if ( ! is_wp_error($new_img) )
785
+ return trailingslashit($this->get_plugin_uploads_dir()['baseurl']) . $filename;
786
+ }
787
+
788
+ return false;
789
+ }
790
+
791
+ /**
792
+ * Generates srcset attribute for this image.
793
+ *
794
+ * @since 5.3.0
795
+ * @param string $src
796
+ * @return string
797
+ */
798
+ private function get_srcset($src)
799
+ {
800
+ /**
801
+ * Hook to enable/disable retina support.
802
+ * @since 5.3.0
803
+ */
804
+ $retina_support = apply_filters('wpp_retina_support', true);
805
+
806
+ if ( ! $retina_support )
807
+ return '';
808
+
809
+ $path_parts = pathinfo($src);
810
+ $srcset = [$src];
811
+
812
+ foreach( $this->descriptors as $descriptor ) {
813
+ $d = "{$descriptor}x";
814
+ $filename = $path_parts['filename'] . "@{$d}." . $path_parts['extension'];
815
+
816
+ if ( @file_exists(trailingslashit($this->get_plugin_uploads_dir()['basedir']) . $filename) ) {
817
+ $srcset[] = $path_parts['dirname'] . '/' . $filename . ' ' . $d;
818
+ }
819
+ }
820
+
821
+ return ( count($srcset) > 1 ) ? ' srcset="' . implode(', ', $srcset) . '" ' : '';
822
+ }
823
+
824
+ /**
825
+ * Render image tag.
826
+ *
827
+ * @since 3.0.0
828
+ * @access public
829
+ * @param string $src Image URL
830
+ * @param array $dimension Image's width and height
831
+ * @param string $class CSS class
832
+ * @param object $alt Alternative text
833
+ * @param string $error Error, if the image could not be created
834
+ * @return string
835
+ */
836
+ public function render($src, $size, $class, $alt = '', $error = null)
837
+ {
838
+ $img_tag = '';
839
+
840
+ if ( $error ) {
841
+ $img_tag = '<!-- ' . $error . ' --> ';
842
+ }
843
+
844
+ // Make sure we use the right protocol
845
+ $src = esc_url(is_ssl() ? str_ireplace("http://", "https://", $src) : $src);
846
+ // Get srcset, if available
847
+ $srcset = $this->get_srcset($src);
848
+
849
+ $src = 'src="' . $src. '"' . $srcset;
850
+
851
+ // Lazy Load attribute, if enabled
852
+ $lazyload = ( $this->admin_options['tools']['thumbnail']['lazyload'] ) ? ' loading="lazy"' : '';
853
+
854
+ $img_tag .= '<img ' . $src . ' width="' . $size[0] . '" height="' . $size[1] . '" alt="' . esc_attr($alt) . '" class="' . esc_attr($class) . '"' . $lazyload . ' />';
855
+
856
+ return apply_filters('wpp_render_image', $img_tag);
857
+ }
858
+
859
+ /**
860
+ * Gets list of available thumbnails sizes
861
+ *
862
+ * @since 3.2.0
863
+ * @link http://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
864
+ * @param string $size
865
+ * @return array|bool
866
+ */
867
+ public function get_sizes($size = '')
868
+ {
869
+ if ( ! is_array($this->available_sizes) || empty($this->available_sizes) ) {
870
+ global $_wp_additional_image_sizes;
871
+
872
+ $this->available_sizes = [];
873
+ $get_intermediate_image_sizes = get_intermediate_image_sizes();
874
+
875
+ // Create the full array with sizes and crop info
876
+ foreach( $get_intermediate_image_sizes as $_size ) {
877
+ if ( in_array($_size, ['thumbnail', 'medium', 'large']) ) {
878
+ $this->available_sizes[$_size]['width'] = get_option($_size . '_size_w');
879
+ $this->available_sizes[$_size]['height'] = get_option($_size . '_size_h');
880
+ $this->available_sizes[$_size]['crop'] = (bool) get_option($_size . '_crop');
881
+ } elseif ( isset($_wp_additional_image_sizes[$_size]) ) {
882
+ $this->available_sizes[$_size] = [
883
+ 'width' => $_wp_additional_image_sizes[$_size]['width'],
884
+ 'height' => $_wp_additional_image_sizes[$_size]['height'],
885
+ 'crop' => $_wp_additional_image_sizes[$_size]['crop']
886
+ ];
887
+ }
888
+ }
889
+ }
890
+
891
+ // Get only 1 size if found
892
+ if ( $size ) {
893
+ if ( isset($this->available_sizes[$size]) ) {
894
+ return $this->available_sizes[$size];
895
+ }
896
+ return false;
897
+ }
898
+
899
+ return $this->available_sizes;
900
+ }
901
+
902
+ /**
903
+ * Returns the URL of the default thumbnail image.
904
+ *
905
+ * @since 5.0.0
906
+ * @param int|null
907
+ * @return string
908
+ */
909
+ public function get_default_url($post_ID = null)
910
+ {
911
+ if ( has_filter('wpp_default_thumbnail_url') ) {
912
+ $default_thumbnail_url = apply_filters('wpp_default_thumbnail_url', $this->default_thumbnail, $post_ID);
913
+
914
+ if ( $default_thumbnail_url != $this->default_thumbnail && $this->is_image_url($default_thumbnail_url) )
915
+ return $default_thumbnail_url;
916
+ }
917
+
918
+ return $this->default_thumbnail;
919
+ }
920
+
921
+ /**
922
+ * Checks whether an URL points to an actual image.
923
+ *
924
+ * @since 5.0.0
925
+ * @access private
926
+ * @param string
927
+ * @return array|bool
928
+ */
929
+ private function is_image_url($url)
930
+ {
931
+ $path = parse_url($url, PHP_URL_PATH);
932
+ $encoded_path = array_map('urlencode', explode('/', $path));
933
+ $parse_url = str_replace($path, implode('/', $encoded_path), $url);
934
+
935
+ if ( ! filter_var($parse_url, FILTER_VALIDATE_URL) )
936
+ return false;
937
+
938
+ // Check extension
939
+ $file_name = basename($path);
940
+ $file_name = sanitize_file_name($file_name);
941
+ $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
942
+ $allowed_ext = ['jpg', 'jpeg', 'png', 'gif'];
943
+
944
+ if ( ! in_array($ext, $allowed_ext) )
945
+ return false;
946
+
947
+ // sanitize URL, just in case
948
+ $image_url = esc_url($url);
949
+ // remove querystring
950
+ preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $image_url, $matches);
951
+
952
+ return ( is_array($matches) && ! empty($matches) ) ? $matches : false;
953
+ }
954
+ }
src/Output.php CHANGED
@@ -1,934 +1,934 @@
1
- <?php
2
- /**
3
- * This class f